赞
踩
微信扫一扫,关注公众号“音频算法与工程实践”
简介
Linux开发三个基本技能:gcc、makefile和git。各自涉及的命令和选项设置繁多,计划写三篇文章,当做简易手册使用,以备开发时查阅。
gcc与g++分别是gnu的c&c++编译器,gcc/g++在执行编译工作的时候,总共需要4步:预处理、编译、汇编、链接。
1、预处理,生成 .i 的文件[预处理器cpp]
2、将预处理后的文件转换成汇编语言,生成文件 .s [编译器egcs]
3、有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]
4、连接目标代码,生成可执行程序 [链接器ld]
A
gcc基本参数
https://www.runoob.com/w3cnote/gcc-parameter-detail.html
不同参数的先后顺序对执行结果没有影响,只有在使用同类参数时的先后顺序才需要考虑。gcc编译器的调用参数大约有100多个,多数参数我们根本就用不到。
-E只激活预处理,这个不生成文件, 你需要把它重定向到一个输出文件里面。
gcc -E hello.c -o hello.i
-S只激活预处理和编译,就是指把文件编译成为汇编代码。
gcc -S hello.c
-c只激活预处理,编译,和汇编,也就是他只把程序做成obj文件。
gcc -c hello.c
-o指定目标名称, 默认时gcc 编译出来的可执行文件是a.out。
gcc -o hello hello.c
gcc -o hello.asm -S hello.c
-Dmacro相当于 C 语言中的 #define macro
-Dmacro=defn相当于 C 语言中的 #define macro=defn
-Umacro相当于 C 语言中的 #undef macro
-undef取消对任何非标准宏的定义
-Idir指定编译时搜索头文件的路径。
-Ldir指定编译时搜索库的路径。
-llibrary用来指定编译时要链接的库,数学库是libm.a,多线程是libpthread.a。android-ndk-r19c加上-lpthread编so库失败。ndk下的libpthread库是包含在libc中的 makefile里不需要-lpthread。[ https://blog.csdn.net/huozhihao/article/details/9194955 ]
gcc -lm test.c
-g编译的时候产生调试信息。附加数字1、2、3指定在代码中加入调试信息的多少。默认的级别是2(-g2)。调试选项都会使最终生成的二进制文件的大小急剧增加,同时增加程序在执行时的开销,通常仅在软件的开发和调试阶段使用。
-O0、-O1、-O2、-O3编译器的优化选项的4个级别,-O0表示没有优化, -O1为默认值,-O3优化级别最高。
-static此选项将禁止使用动态库,强制使用静态链接库,所以生成文件一般都很大,不需要动态连接库就可以运行。由于运行环境的原因(32位armv8l),linaro编译可执行文件要加-static,android-ndk-r19c 32位不用,64位需要。
-share此选项将尽量使用动态库,所以生成文件比较小,但是需要系统有动态库。
-w不生成任何警告信息。
-Wall生成所有警告信息。
B
gcc高级参数
一、交叉编译
https://blog.csdn.net/wf19930209/article/details/124789136
-mcpu指定CPU类型,例如cortex-a7、cortex-a9、cortex-a53、cortex-a73之类的。
-march用于指定CPU指令集,例如armv6、armv7。一般都是直接指定-mcpu,编译器能正确推断出-march的值。
-mfloat-abi用于指定软浮点还是硬浮点。一般armv5是soft,armv6以上的是hard,softfp的比较少。不同mfloat-abi编译出来的库一般不兼容,所以整个linux系统中所有程序和库的mfloat-abi应该保持一致。
soft软浮点。
softfp硬件浮点但是参数传递使用普通寄存器,中断的时候,只需要保存普通寄存器,中断负荷小,但性能较差,参数需要转换成浮点的再计算。
hard硬浮点并且参数传递使用硬浮点寄存器,省去了转换,性能最好,但是中断负荷高。
https://blog.csdn.net/Windgs_YF/article/details/113571892
-mfpu用于指定硬浮点的类型,可以是vfp,vfpv3,neon-vfpv4。一般32位CPU选择vfp或者vfpv3,64位CPU选择neon-vfpv4,或者不选择,让编译器根据CPU选择默认值即可。linaro编译neon代码要加-mfpu=neon,android-ndk-r19c不用。
https://zhuanlan.zhihu.com/p/435342281
-ftree-vectorize向量优化选项,有助于将C代码生成NEON代码。-O3会自动使能它。
二、静态库的编译与使用
gcc -c sum.c
ar -rc libsum.a sum.o
gcc -o test test.c -L./ –lsum
./test
ar rcs libxxx.a xx1.o xx2.o 创建静态库.a文件
r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
c:创建一个库。不管库是否存在,都将创建。
s:创建目标文件索引,这在创建较大的库时能加快时间。
三、动态库的编译与使用
https://www.cnblogs.com/liuzhenbo/p/11031052.html
gcc -fPIC -c sum.c
gcc -shared -o libsum.so sum.o
gcc -o test test.c -L./ -lsum
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/audio/test/
./test
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码。
-share指定生成动态库。
-L、-l需要在编译期间让编译器检查动态库的语法与定义。
LD_LIBRARY_PATH环境变量指定动态库的路径,用于程序运行期间查找动态链接库的搜索路径(系统默认路径之外)。https://blog.csdn.net/sjsjnsjnn/article/details/125836184
-Wl,option此选项传递option给链接器。如果option中间有逗号,就将option分成多个选项,然后传递给会连接程序。
-Wl,-soname=libx.so soname是库的区分标志,关键功能是提供了兼容性的标准。https://blog.csdn.net/weixin_42319496/article/details/119371225
-Wl,--whole-archive -Wl,--no-whole-archive是链接器选项。“--whole-archive”告诉链接器将后面库中所有符号都链接进来,参数“-no-whole-archive”则是重置,以避免后面库的所有符号被链接进来。https://blog.csdn.net/lanhuazui10/article/details/107895036
https://blog.csdn.net/guotianqing/article/details/94304193
-ldl指定dl库。在linux系统中,动态库都是通过ld.so来进行管理的。使用动态链接库时,源程序要包含dlfcn.h头文件,编译时采用-rdynamic -ldl以产生可调用动态链接库的执行文件。https://blog.csdn.net/A493203176/article/details/78792274
-rdynamic用来通知链接器将所有符号添加到动态符号表中。https://blog.csdn.net/Bluenapa/article/details/119205993
C
gcc非常用参数
-x language filename
-x none filename
-pipe
-ansi
-std=c99、-std=gnu++11跨平台代码尽量不使用避免编译错误,比如int64_t类型。
-fno-strict-prototype
-fthis-is-varialble
-fcond-mismatch
-funsigned-char、-fno-signed-char、-fsigned-char、-fno-unsigned-char
-include file、-imacros file、-I-、-idirafter dir、-iprefix prefix 、-iwithprefix dir
-nostdinc
-nostdin C++
-C
-M、-MM、-MD、-MMD
-Wa,option此选项传递option给汇编程序。如果option中间有逗号,就将option分成多个选项,然后传递给汇编程序。
-gstabs、-gstabs+、-ggdb
-traditional
-pedantic、-Werror、-Wcast-align
-v输出gcc工作的详细过程
--target-help显示目前所用的gcc支持CPU类型
-Q显示编译过程的统计数据和每一个函数名
-p、-pg会将剖析(Profiling)信息加入到最终生成的二进制代码中。剖析信息对于找出程序的性能瓶颈很有帮助,是协助Linux程序员开发出高性能程序的有力工具。
-print-multi-lib选项,可以查看编译器支持的选项。
-ffast-math 选项定义了预处理器宏 __FAST_MATH__, 指示编译不必遵循 IEEE 和 ISO 的浮点运算标准。https://www.cnblogs.com/sky-heaven/p/6742610.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。