gcc中动态库和静态库的链接顺序

so文件:动态库
a文件: 静态库
exe文件:可执行程序(linux下以文件属性来标示是否是可执行文件,与后缀名无关)

经过自己写的一些测试程序,大致了解了下gcc中链接顺序问题,总结出以下几点:
1,动态库中可以包含另一个静态库,通过参数 -lxxx 把静态库libxxx.a加入so文件中,这样so文件中
   就包含了libxxx.a的所有实现。当然,如果不包含libxxx.a也没有问题,这样生成的so会小一点。
   如果不包含libxxx.a,最终使用这个so的可执行文件,在其生成时必须加入 -lxxx。
2, 2个so文件可以包含同一个静态库libxxx.a,最终生成exe文件时,不会产生冲突。更广泛的说,生成
   exe文件时候,可以链接多个so文件和a文件,如果其中的a文件有多份实现,最终只会有一份生效,其他
   都会被忽略。不用担心冲突。
3,当生成exe时候,当a文件有多份实现时,最左边指定的a文件才生效。

具体例子来说:
     libstatic.a :   一个静态库文件
     libdynamic1.so:需要使用libstatic.a中的函数,但是没有包含libstatic.a
     libdynamic2.so:需要使用libstatic.a中的函数,包含libstatic.a
     libdynamic3.so:需要使用libstatic.a中的函数,也包含libstatic.a
     test.exe:最终的生成的可执行文件(linux对后缀没有要求,为了说明文件,姑且用exe后缀来表示可执行文件)
     
     gcc -o test.exe -ldynamic1 :错误,libdynamic1.so中没有包含libstatic.a,找不到libstatic.a的实现。
     
     gcc -o test.exe -ldynamic1 -lstatic:正确,so中没有,但是指定了libstatic.a,可以编译过
     
     gcc -o test.exe -ldynamic2 :正确,libdynamic2.so中有libstatic.a的实现。
     
     gcc -o test.exe -ldynamic1 -ldynamic2:正确,libdynamic1.so中没有libstatic.a,但是libdynamic2.so中有。
     
     gcc -o test.exe -ldynamic2 -ldynamic3:正确,虽然libdynamic2.so和libdynamic3.so都含有静态库,但是不会冲突,
                                           最终只会有一份存在,并且是libdynamic2.so中的静态库有效。
                                           
     gcc -o test.exe -ldynamic2 -ldynamic3 -lstatic:同样正确,最终只会有一份存在,并且是libdynamic2.so中的静态库有效。
     
     gcc中库的链接顺序是从右往左进行,所以要把最基础实现的库放在最后,这样左边的lib就可以调用右边的lib中的代码。同时,当一个函数的实现代码在多个lib都存在时,最左边的lib代码最后link,所以也将最终保存下来。

时间: 2024-12-31 12:02:10

gcc中动态库和静态库的链接顺序的相关文章

Linux系统中“动态库”和“静态库”那点事儿【转】

转自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情.       在Linux操作系统中,普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式.ELF(Executable and Linking Format,可执行连接格式)是UNIX系统实验室(USL)作为应

Linux下生成使用动态库和静态库

Linux中有两类函数库,动态库和静态库 静态库: 这类库一般都是以.a为后缀名的文件,利用静态库函数编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中. 编译后的执行程序就不需要外部的函数库支持,但也有其缺点,就是一旦静态函数库改变了,那么程序就必须重新编译. 动态库: 这类库的一般都是以.so为后缀名的,相对于静态库函数库来说,动态函数库在编译的时候并没有被编译进目标代码中.当程序执行到相关函数时才调用该函数库里的相应函数,因此动态库函数库所产生的可执行文件比较小,由于函数库

自己在linux上编译、链接、动态库和静态库的学习笔记

在平常的项目中,我们都是使用公司要求的makefile.makedebug一类的文件,因此,在编译.链接.生成和链接动态库与静态库的时候,我们只是简单的使用一些已经设置的变量,只是简单的修改.添加一些文件名,或许这次我们编译通过了,但是,在某一个时候,可能出现了一个问题,无论简单与否,因为平常没有留意,导致的结果可能是花了好长时间才能解决.而如果平常只是简单的留一下心,或许这些问题都是可以避免的. 因此,今天我自己使用几个文件,编译动态库.静态库以及动态库和静态库的嵌套调用等问题,尽量还原我在项

c++-linux动态库与静态库之间的调用问题

问题描述 linux动态库与静态库之间的调用问题 linux程序编译通过,运行时出错symbol lookup error: /usr/lib/libE.so: undefined symbol: test_D1 静态库libD.a中: 提供函数接口test_D(),test_D1(),test_D2() 动态库libE.so中:提供函数接口test_E() int test_E() { test_D(); return 0; } 应用程序make时,链接了动态库libE.so,将静态库libD

动态库调用静态库示例讲解_Linux

生成动态库: 需要的目标文件得用-fPIC选项生成. 而静态库所需的目标文件可以不用-fPIC选项. 例: 复制代码 代码如下: /////// static.h void static_print(); ///////static.cpp #include <iostream> #include "static.h" void static_print() {      std::cout<<"This is static_print functio

VC下动态库dll,静态库lib的编写和使用方法

  在一些项目中,考虑到系统的安全性和稳定性,经常要封装一些DLL或者LIB库供别人使用,那么怎么制作DLL或者LIB文件呢?今天特酷吧根据自己的实际情况给大家讲解下基本的制作方法.以下是我亲自操作的记录:1,动态库dll的编写方法:新建一个动态链接库: 填好工程名称即可选择工程类型,如果没有特别的要求,选择一个空工程即可.会看到这里和标准的控制台工程一样,没有任何系统默认建立的文件 下面就需要我们添加一些文件.建立动态库dll文件 , 我们不需要写main函数.只需要一个一个的实现我们需要实现

动态库和静态库

 1.静态库不需要main函数,要想生成lib,要修改属性à常规à配置类型à改成dll 2.静态库中的头文件只是说明,是给程序员看的,其实lib里面已经有了接口. 3.链接lib的时候程序的体积就变大了. 4.静态库更新的时候,需要重新生成,然后调用 5.动态库调用就不用重新生成. 6.动态库的调用代码:(使用的是HMODULELoadLibraryA的方式进行调用) 接口 7.编写的动态库如下: #include<stdio.h> #include<stdlib.h> #in

【C/C++学院】0801-重定向以及文件扫描/二进制加密解密/简单加密/按照密码加密/动态库与静态库

重定向以及文件扫描 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> void main1() { char str[100] = { 0 }; scanf("%s", str); printf("str=%s\n", str); system(str); } void main2() { char str[100] = { 0 }; fs

Linux下,动态库和静态库之间是否能够相互转化?

问题描述 Linux下,动态库和静态库之间是否能够相互转化? Linux下,动态库和静态库之间是否能够相互转化呢?现在我有一些动态共享库.so,但发布程序的时候总得在目标服务器上安装这些库,程序才能运行,我想把它们转化为静态库.a,能做到么?有这样的工具吗?谢谢大家. 解决方案 通过makefile编译的时候,生成一份动态,一份静态 解决方案二: 我有动态库文件so,但是没有源码.我现在希望做的是:动态库.so转化为静态库.a.大家帮帮忙啊.

Linux 创建静态库以及静态库的使用

目录: 1 手动建立静态库 2 静态库的使用 3 通过makefile文件建立静态库 1 手动建立静态库 将建立一个简单的静态库 -1: 将所需的源文件编译成目标文件 ------ helpguy.h #ifndef __helpguy_h__ #define __helpguy_h__ #include <stdlib.h> #include <stdio.h> #include <unistd.h> void err_msg(const char* errMsg,