相关博文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.cpp,gcc要求(实际是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。

再议GCC编译时的静态库依赖顺序问题的更多相关文章

  1. 再议GCC编译时的静态库依赖次顺问题

    假设有如三个源代码文件: $ cat a.cpp void a() { } $ cat b.cpp extern void a(); void b() { a(); // 调用a.cpp中的a() } ...

  2. gcc编译时指定链接库的查找目录

    gcc编译时,如果需要链接的库的目录不在标准目录,则需要通过将保护库的目录/aa/bb/cc通过-L/aa/bb/cc 添加到搜索路径中,如: gcc -o xmltest xml_test.cpp ...

  3. gcc编译时头文件库文件搜索顺序(转)

    原文: http://blog.csdn.net/silentfly1987/article/details/6119195

  4. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  5. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  6. 在Linux使用GCC编译C语言共享库

    在Linux使用GCC编译C语言共享库 对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例 ...

  7. 【转】Linux下gcc生成和使用静态库和动态库详解

    一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...

  8. Linux下GCC生成和使用静态库和动态库【转】

    本文转载自:http://www.cppblog.com/deane/articles/165216.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本 ...

  9. gcc编译时对'xxxx'未定义的引用问题

    gcc编译时对’xxxx’未定义的引用问题 gcc编译时对’xxxx’未定义的引用问题 原因 解决办法 gcc 依赖顺序问题 在使用gcc编译的时候有时候会碰到这样的问题,编译为.o(obj) 文件没 ...

随机推荐

  1. Python常用时间转换

    1 import time 2 import math 3 4 # 定义一些时间段的常量(秒) 5 TimeSec_Hour = 3600 6 TimeSec_Day = 86400 7 TimeSe ...

  2. [状压DP]子矩阵

    子 矩 阵 子矩阵 子矩阵 题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵 如,下面左图中选取第 2 . 4 ...

  3. java面试-JVM调优和参数配置,如何查看JVM系统参数默认值

    一.JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式(先编译后执行) -Xint  解释执行 -Xcomp 第一次使用就编译 ...

  4. JavaWeb 补充(Cookie&JSP&Session)

    1. 会话技术     1. Cookie     2. Session 2. JSP:入门学习 会话技术 1. 会话:一次会话中包含多次请求和响应.     * 一次会话:浏览器第一次给服务器资源发 ...

  5. 如何自己设计一个类似dubbo的rpc框架?

    (1)上来你的服务就得去注册中心注册吧,你是不是得有个注册中心,保留各个服务的信息,可以用zookeeper来做,对吧 (2)然后你的消费者需要去注册中心拿对应的服务信息吧,对吧,而且每个服务可能会存 ...

  6. Vue学习笔记(三)

    1 监听 在Vue.js中可以通过watch来监听数据的变化,比如通过watch实现的简单计数器: <div id="app"> <p>计数器:{{coun ...

  7. Go-27-import导包

    import 导入包 包的搜索顺序: import ( "fmt" "net/http" "mypkg" ) 编译器会根据上面指定的相对路径 ...

  8. 击鼓传花联想到了Java设计模式:责任链模式

    目录 应用场景 简单示例 责任链模式 定义 意图 主要解决问题 何时使用 优缺点 击鼓传花的故事 应用场景 http web请求处理,请求过来后将经过转码.解析.参数封装.鉴权等一系列的处理(责任), ...

  9. 002-Java的标识符和关键字

    目录 一.标识符 1.什么是标识符 2.标识符的命名规则 3.标识符的命名规范 二.关键字 1.什么是关键字 2.Java中的关键字 一.标识符 1.什么是标识符   标识符就是程序员自己规定的代表一 ...

  10. JAVAEE_Servlet_07_设置网站欢迎页面

    Web站点的欢迎页面的设置 * 欢迎页面怎么设置? - 假设在WebContent下创建login.html,想让login.html作为站点的欢迎页面. - 打开web.xml文件,添加<we ...