利用参数控制gcc的编译进度本文浅析gcc在构建多文件项目,使用静态链接库,动态链接库中,各个编译参数的含义和常见用法。
这是gcc常处理的文件类型:
- .c / .cpp:c,cpp源码
- .s:汇编源码
- .m:objective-c源码
- .i:c预处理结果文件
- .ii:cpp预处理结果文件
- .S:汇编预处理结果文件
- .h:头文件
- .o:编译后得到的目标文件
- .so:动态链接库文件(一种特殊的目标文件)
- .a:静态链接库
- .out:可执行文件。
实际可执行文件没有统一的后缀,系统根据文件属性来区分可执行文件和不可执行文件。
缺省情况下gcc生成的可执行文件名为a.out。
- 预处理:生成.i或.ii文件
- 编译:将.i或.ii文件编译成为汇编语言,生成.s文件
- 汇编:将汇编语言进行汇编处理,生成目标文件,即.o文件
- 链接:将一个或多个.o文件链接,生成可执行程序文件
编译选项上述中间在用户指定分步进行时会得到保留,但在一次性完成编译时会被删除
gcc的命令格式为"gcc [options][filenames]"。
其常用编译选项有:
options取值 | 说明 | 示例 |
---|---|---|
-c | 编译并汇编指定的文件,但不进行链接。 生成.o文件,通常用于编译不包含主程序的子程序文件 | gcc -c test1.c test2.c |
-S | 编译指定的源文件,不进行汇编,生成.s汇编文件 | gcc -S circle.c,这将生成circle.s文件 |
-E | 预处理指定的源文件,不进行编译。 默认情况下预处理器的输出会被导入到标准输出流,可以通过-o选项将其导入到某个文件中 | gcc -E circle.c -o circle.i |
-o filename | 指定输出文件的名称。 如果不给出这个选项,gcc生成的可执行文件将名为a.out | gcc main.c func.c -o app.out |
-g | 在可执行程序中包含调试信息 | |
-L library_path | 在库文件的搜索路径列表中添加library_path路径 | |
-llibrary | 链接时搜索指定的函数库library。 gcc会默认链接libc.a或者libc.so,但是要想链接到其它库则需要手动添加 | 使用-l选项链接数学库,gcc main.c -o main.out -lm |
-I head_path | 在头文件的搜索路径列表中添加head_path路径 | |
-static | 进行静态编译,且链接静态库,禁止链接动态库 | |
-shared | 和-fPIC配合使用 | |
-fPIC | 生成使用相对地址的位置无关的目标代码 |
创建静态链接库的技术栈相对动态链接库要简单。
首先我们需要生成一批目标文件:
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc -c test3.c -o test3.o
然后利用ar对它们进行打包:
ar src libtest.a test1.o test2.o test3.o
这将生成一个名为libtest.a的静态链接库。
ar的命令格式是"ar 静态库文件名 目标文件列表"。
src参数的含义是:
- s:创建目标文件索引,这再创建较大的库时能提高速度
- r:替换库中已有的目标文件,或加入新的目标文件
- c:创建一个库,不管库是否存在,都将创建它
一种选择,从源文件生成动态链接库:
gcc -fPIC -shared test.c -o libtest.so
另一种选择,从目标文件生成动态链接库:
gcc -fPIC -c test.c -o test.o
gcc -shared test.o -o libtest.so
链接到动态库的编译:
gcc main.c libtest.so -o app.out
直接执行app.out将触发链接失败,我们有这三种方式将链接器引导至我们的动态链接库:
- 将动态库保存在标准目录下,比如/usr/lib
- 把动态库所在的路径添加到环境变量LD_LIBRARY_PATH中,在shell中输入命令"export LD_LIBRARY_PATH=libraryDIR:$LD_LIBRARY_PATH"或
- 把动态库所在的路径libraryDir添加到/etc/ld.so.conf中然后执行ldconfig或者以动态 库所在路径libraryDir为参数执行ldconfig
- 修改~/.bashrc这个配置文件,对本用户有效。
该配置文件将在bash启动时被运行
需要注意的是,上面第二种方式会再重启终端后失效。
另外我做了一点实验,这三条命令都可以短暂的让动态库的路径生效:
export LD_LIBRARY_PATH=libpath:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:libpath
export LD_LIBRARY_PATH=libpath
它们都是可行的。
此上即通过gcc创建动/静态链接库的基本流程,和动态库链接路径的正确引导方式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)