Linux编译多个不同目录下的文件以及静态库、动态库的使用

先看两篇博文,作为基础知识。如果对C/C++编译链接过程都了解的话,可以跳过不看。

一、编译不同目录下的多个文件

各个文件的布局如下:

head.h文件的代码:

#ifndef HEAD_H#define HEAD_Hint add(int a, int b);#endif /*HEAD_H*/

head.cpp文件的代码:

#include "head.h"int add(int a, int b){return a + b;}

main.cpp文件的代码(head.h头文件还没包含)

#include <iostream>using namespace std;int main(int argc, char *argv[]){cout<<add(3, 5)<<endl;return 0;}1)以相对路径的方式直接包含头文件

为了能够使用add函数,必须包含add所在的头文件。 最简单的方法是直接在main.cpp文件中,用相对路径包含head.h文件.即 #include”function/head.h”。完整代码为

#include <iostream>#include "function/head.h"using namespace std;int main(int argc, char *argv[]){cout<<add(3, 5)<<endl;return 0;}

此时,编译命令为 :$g++ main.cpp function/head.cpp -o main

这种用相对路径包含头文件的方式有很多弊端。当function目录改成其它名字,或者head.h文件放到其它目录了,这时都要对main.cpp文件进行修改,如果head.h头文件被很多其它文件包含的话,这个工作量就大多了。

2)用编译选项 –I(大写i)

其实,可以想一下,为什么iostream文件不在当前目录下,就可以直接使用呢?这是因为,编译器会在一些默认的目录下(/usr/include,/usr/inlucde/c++/4.4.3等目录)搜索头文件。所以,iostream头文件不用添加。但我们不能每写一个头文件就放到那里。

知道了原理,现在来用一下一个编译选项 –I(include的缩写)用来告诉编译器,还可以去哪里找头文件。

使用这个编译命令,$g++ main.cpp function/head.cpp -Ifunction -o main

此时main.cpp文件写成

#include <iostream>#include <head.h>using namespace std;int main(int argc, char *argv[]){cout<<add(3, 5)<<endl;return 0;}

可以看到head.h文件是用<>而不是””。想一下C语言书中,两者的区别。这说明,用-I选项,相当于说明了一条标准路径。

3)使用.o文件

此时,对于head.cpp文件,在编译命令中,还是要用到路径function/head.cpp。现在的想法是去掉这个。这时可以先根据head.cpp文件生成一个.o文件,然后就可以了去掉那个路径了。

先cd 到function目录。

输入命令:$g++ -c head.cpp -o head.o

生成一个head.o目标文件,

此时把生成的head.o文件复制到function的父目录,就是main.cpp所在的目录。

然后回到function的父目录,输入命令$g++ main.cpp head.o -Ifunction -o main

此时,直接使用head.o即可,无需head.cpp了。但头文件head.h还是要的。因为编译的时候要用到。链接的时候不用头文件。这个可以拆分成两条命令

$g++ -c main.cpp -Ifunction -o main.o

$g++ main.o head.o -o main

第一条是编译命令,后一条是链接命令。

二、静态库

虽然上面说到的先生成.o目标文件,但如果function目录下有多个.cpp文件。那么就要为每一个.cpp文件都生成一个.o文件,这个工作量是会比较大。此时可以用静态库。静态库是把多个目标文件打包成一个文件。Anarchive(or static library) is simply a collection of object filesstored as a single file(摘自《Advanced Linux Programming》)。

下面介绍静态库

此时,文件布局为:

head.h文件代码

#ifndef HEAD_H#define HEAD_Hint add(int a, int b);int sub(int a, int b);#endif /*HEAD_H*/

add.cpp文件代码

#include "head.h"int add(int a, int b){return a + b;}

sub.cpp文件代码

#include "head.h"int sub(int a, int b){return a – b;}

首先,生成.o目标文件。

cd进入function目录,输入命令$g++ -c sub.cpp add.cpp 这会分别为两个源文件目标文件,即生成sub.o和add.o文件。

然后,打包生成静态库,即.a文件。

输入命令$ar -cr libhead.a add.o sub.o

注意:

1) 命令中,.a文件要放到 .o文件的前面

2) .a文件的格式。要以lib作为前缀, .a作为后缀。

选项 c是代表create,创建.a文件。

r是代表replace,如果之前有创建过.a文件,现在为了提高性能而更改了add函数里面的代码,此时,就可以用r选项来代替之前.a文件里面的add.o

可以用命令$ar -t libhead.a 查看libhead.a文件里面包含了哪些目标文件。其执行结果自然为add.o sub.o

现在回过头来关注main.cpp文件。

呼唤你前往另一个地方,过上另一种生活。

Linux编译多个不同目录下的文件以及静态库、动态库的使用

相关文章:

你感兴趣的文章:

标签云: