gcc链接静态库时对待.a文件和.o文件的不同

  很多人都知道,gcc在链接静态库时是从前往后找符号。因此如果一份文件foo引用了静态库bar.a,那么在链接命令中,bar.a必须放在foo的后面,也就是像gcc ... foo ... bar.a这样;否则链接时会报找不到定义的错误(即undefined reference to ...)。

  .a文件其实没什么特别的地方,它不过是将多个.o文件打包成一份文件。如果我们在链接命令中,直接用.o文件替换.a文件,那也需要遵循gcc的这种链接顺序吗?可以用gcc .. bar.o ... foo这样的链接命令吗?可以做个简单的试验。

  假设我们有两份源代码文件。一份是foo.c,定义了一个foo函数。

void foo()
{
}

  另一份是main.c,里面引用了foo函数:

void foo();

int main()
{
    foo();
}

  我们将foo.c编译成foo.o,然后打包成foo.a:

$ gcc -c foo.c

$ ar rcs foo.a foo.o

  如果我们让main.c链接foo.a,并且将foo.a放在main.c的前面,那就会如期望的那样出现链接错误:

$ gcc -o test foo.a main.c

C:\Users\ADMINI~1\AppData\Local\Temp\ccan3qBI.o:main.c:(.text+0xc): undefined reference to `foo‘

collect2.exe: error: ld returned 1 exit status

  但如果将foo.a换成foo.o,链接就不会报错了:

$ gcc -o test foo.o main.c

  所以结论是:.o文件在链接中并不遵循.a文件那样的链接顺序,看来链接器找符号时,一定会搜索命令中的.o文件。

  StackOverflow里的这篇帖子也提到了类似的事:http://stackoverflow.com/questions/11231101/gcc-linking-object-file-and-library-what-is-the-difference

时间: 2024-10-13 12:16:36

gcc链接静态库时对待.a文件和.o文件的不同的相关文章

Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别

昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [[email protected] tcpmsg]# gcc -o hello main.c -lmyhello /usr/bin/ld: cannot find -lmyhello collect2: error: ld returned 1 exit status 1 gcc链接动态库时的搜索路径 自以为在当前工程中设置好了环境变量 LD_LI

cmake 强制链接静态库

add_executable(main main.cpp) target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a) 静态库和动态库共存时,cmake会默认先链接静态库,如果要强制使用静态库,在CMakeLists.txt中如此直接指明 或者这样做也可以 So, if you want to link to a static library, you need to search for that static library:

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

Background MSDN中对于在不同的配置下Link的LIB作了说明: C Runtime Library: 开关 对应的库 版本 /MD MSVCRT.LIB 多线程DLL的Release版本 /MDd MSVCRTD.LIB 多线程DLL的Debug版本 /MT LIBCMT.LIB 多线程静态链接的Release版本 /MTd LIBCMTD.LIB 多线程静态链接的Debug版本 /clr MSVCMRT.LIB 托管代码和非托管代码混合 /clr:pure MSVCURT.LIB

链接静态库

在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库.使用方式为:gcc test.cpp -L. -ltestlib如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so.如果要指定为连接静态库则使用:gcc test.cpp -L. -static -ltestlib使用静态库进行连接. 当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式.这时需

iOS 静态库冲突 连个不同的.o 文件冲突 ,静态库分离

在开发期间集成ZBar 和 支付 的时候,发现很多提示是.o文件冲突,最常见的时base64冲突,原因是由于不少第三方静态库中都有base64这个文件 在网上查了许久,发现都是转载的同一篇文章,由于对console命令不熟悉,也花费了一番功夫,请教了高手,,终于还是搞定了 下面附上方法, 打开console终端,找到要解剖的.a文件(可以先拷贝一份,我是拷贝一份放到桌面了),执行下列命令查看库包含的cpu架构代码: xcrun -sdk iphoneos lipo -info libx.a Ar

Ubuntu下makefile及gcc生成静态库动态库的简单使用举例

环境:Ubuntu-13.10  32位(虚拟机).gcc4.8.1 首先创建一个test_makefile_gcc文件夹,此test_makefile_gcc文件夹下包括:src文件夹用于存放源文件: include文件夹用于存放头文件:bin文件夹用于存放生成的动态库.so文件:lib文件夹用于存放生成的静态库.a文件:project_makefile文件夹存放此工程的makefile文件:test文件夹存放用来测试静态库和动态库的源文件:另外在test_makefile_gcc文件夹下还包

解决遇到动态库链接静态库

场景: 二进制Link-->动态库-->第三方静态库 Linux环境中需要动态库链接第三方的静态库 错误: /usr/bin/ld: ../../3rdpart/x64/muduo/lib/libbase.a(AsyncLogging.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC ../../3rdpart/x64/mu

引用外部静态库时,(类别)目录方法无法加载问题(转)

这个 bug 在 xcode 4.3 以下会出现,4.3 以后已经修正了. 解决方法为:找到 target 的图标,更改其 Other Linker Flags 为: -all_load 或 -force_load -force_load,后跟随一个文件位置,可以更精确地加载所需文件. 苹果的解释为 : http://developer.apple.com/library/mac/#qa/qa1490/_index.html 简单点说就是,Objective-C 的动态特性使得需要,为链接器添加

链接(extern、static关键词\头文件\静态库\共享库)

原文链接:http://www.orlion.ga/781/ 一. 多目标文件的链接 假设有两个文件:stack.c: /* stack.c */ char stack[512]; int top = -1; void push(char c) {         stack[++top] = c; } char pop(void) {         return stack[top--]; } int is_empty(void) {         return top == -1; }