c++的.o文件的链接顺序

时间:2022-12-19 05:58:17

linker对链接顺序要求很严格,如果顺序有误,多半就会报undefined reference to xxxxxx的错误

文件目录:

c++的.o文件的链接顺序

代码:

main.cpp

1 #include "Test.h"
2
3 using namespace std;
4
5 int main()
6 {
7 Test::testLiftOff();
8 return 0;
9 }

 

Test.cpp

 1 #include "Test.h"
2
3 #include "LiftOff.h"
4
5 #include <zthread/Thread.h>
6
7 #include <iostream> // std::cout
8
9 void Test::testLiftOff()
10 {
11 using namespace ZThread;
12
13 try {
14 for (int i = 0; i < 5; ++i)
15 {
16 Thread th(new LiftOff(10, i));
17 }
18 std::cout << "waiting for lift off" << std::endl;
19 } catch (Synchronization_Exception &e) {
20 std::cerr << e.what() << std::endl;
21 }
22 }
23
24 Test::Test()
25 {
26 //ctor
27 }
28
29 Test::~Test()
30 {
31 //dtor
32 }

 

LiftOff.cpp

 1 #include "LiftOff.h"
2
3 #include <iostream>
4
5 using namespace std;
6
7 LiftOff::LiftOff(int countDown_, int id_)
8 :countDown(countDown_), id(id_)
9 {
10 // do nothing
11 }
12
13 LiftOff::~LiftOff()
14 {
15 cout << "LiftOff" << id << " destroyed" << endl;
16 }
17
18 void LiftOff::run()
19 {
20 while (countDown--)
21 cout << id << " count: " << countDown << endl;
22 cout << id << "LiftOff!" << endl;
23 }

 

Test.h

 1 #ifndef TEST_H
2 #define TEST_H
3
4
5 class Test
6 {
7 public:
8 static void testLiftOff();
9
10 private:
11 Test();
12 ~Test();
13 };
14
15 #endif // TEST_H

 

LiftOff.h

 1 #ifndef LIFTOFF_H
2 #define LIFTOFF_H
3
4 #include <zthread/Runnable.h>
5
6 class LiftOff : public ZThread::Runnable
7 {
8 public:
9 LiftOff(int countDown_, int id_);
10 ~LiftOff();
11 void run();
12 private:
13 int countDown;
14 int id;
15 };
16
17 #endif // LIFTOFF_H

显然,main.cpp 通过 Test.h 引用 Test.cpp 的 implementation 。 说人话? 好吧 。。。 具体来说就是linker在发现main.cpp 中的 Test::testLiftOff() 调用的时候, 需要去找Test::testLiftOff()的implementation,去哪找?当然是Test.cpp中,编译为obj文件后,其实就是main.o 依赖于 Test.o

我们把这种关系描述为 main.o < Test.o

类似的还有 Test.o < LiftOff.o  、 Test.o < zthread_win3.a

总的原则就是:如果A.o依赖于B.o,那么在linker命令中,A.o必须在B.o的左边(可以不相邻)

所以在链接的时候,命令为:

g++ -o test.exe main.o Test.o LiftOff.o -s zthread_win32.a // linker command 1

其实,只要顺序不违反上面的关系定义,后面的顺序是可以任意调整的,例如,实际上LiftOff.o与-s zthread_win3.a的顺序调一下也是可以的

g++ -o test.exe main.o Test.o -s zthread_win32.a LiftOff.o // linker command 2

总结:

你编译上面的代码为:

g++ -c *.cpp

链接的时候上面给出的linker command 1、linker command 2任意选一个都行

 

另外:

事实上,在linux下,由于ZThread依赖于Posix Thread Library,在 -s zthread_xxx.a之后还需要-lpthread来加载Posix Thread Library,也是这个原因,见这篇随笔