准备以下main.c文件
#include <stdio.h>
int add(int,int);
int main()
{
int a = 3;
int b = 5;
printf("add(3,5) = %d\n",add(a,b));
}
int add(int a, int b){
return a+b;
}
执行命令
gcc -c main.c
生产main.o 文件,这是一个二进制文件
执行
nm -O main.o
结果,有地址的函数定义在这个文件中。
0000000000000043 T add
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
U printf
删除add的实现,只保留声明,仍然可以通过编译。此时在执行nm -O命令,add地址在外面。
然后将add.c的实现放到另外一个源文件中。
执行
gcc -c add.c
可以通过编译,然后对add.c执行nm-O,发现add.c中又nm的实现。
下面通过命令将两个文件链接到一起。
gcc main.o add.o
单独执行gcc main.o出现常见链接错误,找不到add符号。
如果我们在main函数中,也加上add的实现,那么就会报重定义错误。
思考为什么声明和定义要分开?
理解了编译和链接两个过程,下面我们在代码中使用第三方库,我们以gtest为例子,去github下载Google Test
之后就是常规C++项目的编译,注意到该项目有CMakeList.txt, 我们新建一个build文件, 进入到build,执行
cmake ..
生成makefile,然后执行
make -j4
编译完源代码之后,我们得到lib文件夹是函数的定义,头文件在include文章夹中。
我们将这两个拷贝到项目路径下,新建一个main.cpp文件
#include <gtest/gtest.h>
int add(int a, int b){
return a+b;
}
TEST(TEST,ADD1){
EXPECT_EQ(add(3,4),7);
}
int main()
{
testing::InitGoogleTest();
return RUN_ALL_TESTS();
}
如果直接编译g++ main.cpp报错,没有找到gtest/gtest.h头文件, 增加预编译路径
g++ -I./include main.cpp
出现常见链接错误, 链接相应实现后
g++ -I./include -L./lib main.cpp -lgtest -lpthread
完成功能的实现