再议GCC编译时的静态库依赖顺序问题

简介: GCC编译时的静态库依赖次顺问题.pdf 相关博文1:http://blog.chinaunix.net/uid-20682147-id-76330.html相关博文:http://blog.

img_e25d4fb2f8de1caf41a735ec53088516.pngGCC编译时的静态库依赖次顺问题.pdf


相关博文1:http://blog.chinaunix.net/uid-20682147-id-76330.html
相关博文:http://blog.chinaunix.net/uid-20682147-id-5096676.html

假设有如三个源代码文件:

$ cat a.cpp

void a()

{

}

 

$ cat b.cpp

extern void a();

void b()

{

    a(); // 调用a.cpp中的a()

}

 

$ cat x.cpp

extern void b();

int main()

{

    b(); // 调用b.cpp中的b()

    return 0;

}

 

对应的Makefile文件:

all: x

 

liba.a: a.o

libb.a: b.o

x: x.o liba.a libb.a 问题出在这儿

    g++ -g -o $@ $^

 

a.o: a.cpp

    g++ -g -c $^

b.o: b.cpp

    g++ -g -c $^

x.o: x.cpp

    g++ -g -c $^

 

clean:

    rm -f a.o b.o x.o x

 

使用上面的Makefile编译,将会遇到如下所示的“undefined reference”问题:

g++ -g -c x.cpp

g++ -g -c a.cpp

g++ -g -c b.cpp

g++ -g -o x x.o liba.a libb.a # 改成“g++ -g -o x x.o libb.a liba.a”即可解决

libb.a(b.o): In function `b()':

/tmp/b.cpp:2: undefined reference to `a()'

collect2: ld returned 1 exit status

make: *** [x] Error 1

 

这个问题的原因是b.cpp依赖a.cppgcc要求(实际是ld要求)libb.a须放在liba.a前面,即需要改成:g++ -g -o x x.o libb.a liba.a,也就是被依赖的库需要放在后头。

 

这是最常规的解决办法,除此之外,只需要加入--start-group--end-group两个链接参数,即可保持被依赖的库放在前头,也就是改成如下即可:g++ -g -o $@ -Wl,--start-group $^ -Wl,--end-group。

 

这里的“-Wl,”表示后面跟着的参数是传递给链接器ld的,gcc不关心具体是啥。“--start-group”表示范围的开始;“--end-group”表示范围的结束,是可选的。位于“--end-group”之后的仍然要求被依赖的库放在后头。注意“--start-group”不能重复,相关链接参数:--whole-archive 和 --no-whole-archive。

 

相关文章
|
前端开发 C语言
gcc动态库升级
gcc动态库升级
|
存储 编译器 C语言
深入理解GCC 和 G++ 编译器
GCC 和 G++ 是 GNU 工具链中的核心编译器,支持 C 和 C++ 程序开发。本文详细介绍其编译流程、常用选项及动态链接与静态链接的区别。编译过程分为预处理、编译、汇编和链接四个阶段,每个阶段有特定任务和命令选项。常用选项如 `-E`、`-S`、`-c` 和 `-o` 分别用于预处理、生成汇编代码、生成目标文件和指定输出文件。动态链接节省空间且易于更新,但依赖运行时库;静态链接独立高效,但文件较大且更新困难。合理选择优化选项(如 `-O0` 至 `-O3`)可提升程序性能。掌握这些知识有助于开发者更高效地编写、调试和优化代码。
深入理解GCC 和 G++ 编译器
|
编译器 Linux C语言
gcc的编译过程
GCC(GNU Compiler Collection)的编译过程主要包括四个阶段:预处理、编译、汇编和链接。预处理展开宏定义,编译将代码转换为汇编语言,汇编生成目标文件,链接将目标文件与库文件合并成可执行文件。
554 11
|
编译器 开发工具 C语言
Gcc 链接文件
Gcc 链接文件
213 4
|
编译器 Linux 开发工具
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么?
221 0
006.gcc编译器
|
存储 NoSQL 算法
从一个crash问题展开,探索gcc编译优化细节
问题分析的过程也正是技术成长之路,本文以一个gcc编译优化引发的crash为切入点,逐步展开对编译器优化细节的探索之路,在分析过程中打开了新世界的大门……
|
编译器 C语言 C++
MinGW安装gcc
MinGW安装gcc
517 0
|
C语言
gcc的简易用法
【5月更文挑战第10天】gcc的简易用法。
215 8
|
C语言
gcc的简易用法(编译、参数与链接)
【5月更文挑战第14天】gcc的简易用法(编译、参数与链接)。
230 1