标签:nsf 程序 ref 位置 错误 else param 对照表 gcc编译
gcc与g++ 分别是GNU的c与c++的编译器 ,gcc和g++的用法一样,由于c和c++的库文件命名方式不同,所以主要区别在于gcc编译c文件,g++默认编译c++文件。但是g++可以用来编译c文件,因为g++碰到c文件会调用gcc去编译。
gcc和g++指令的一般格式为:[gcc|g++] [选项] 要编译的文件 [选项] [目标文件]。
设定文件所使用的语言, 使后缀名无效, 对以后的多个有效。也就是根据约定 C 语言的后缀名称是 .c 的,而 C++ 的后缀名是 .C 或者 .cpp。
如下:将hello.pi看成c语言文件。
gcc -x c hello.pig
-x none filename
关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型 。
如下:在编译hello2.c时使用后缀识别。
gcc -x c hello.pig -x none hello2.c
只激活预处理,编译,和汇编,生成.o文件或.obj文件。
gcc -c hello.c
只激活预处理和编译,就是指把文件编译成为汇编代码。
gcc -S hello.c
只激活预处理,这个不生成文件, 你需要把它重定向到一个输出文件里面。
#输出到hello.i gcc -E hello.c -o hello.i #重定向到hello.txt gcc -E hello.c > hello.txt #more查看 gcc -E hello.c | more
制定目标名称, 默认的时候, gcc 编译出来的文件是 a.out。
如下:输出hello文件
gcc hello.c -o hello
在预处理时,不删除注释信息。
一般与-E一起使用。
gcc -C -E hello.c -o hello.i
产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。
此选项将尽可能的生成 gdb 的可以使用的调试信息。
编译器的优化选项的 4 个级别,-O0 表示没有优化, -O1 为默认值,-O3 优化级别最高。对程序进行优化编译l链接,整个源代码会在编译、链接过程中进行优化处理,产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。
此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么动态连接库,就可以运行。
制定编译的时候使用的库。
打印出编译器内部编译各过程的命令行信息和编译器的版本。
在头文件的搜索路径列表中添加dir目录
在库文件的搜索路径列表中添加dir目录
生成文件关联的信息。包含目标文件所依赖的所有源代码。
如下图分为4个阶段:
gcc hello.c -o hello
gcc hello.c
预编译过程主要处理那些源代码文件中的以 "#" 开始的预编译指令。gcc使用的预编译器为cpp。
cpp hello.c > hello.i
#或者
gcc -E hello.c -o hello.i
编译过程通过词法和语法分析,确认所有指令符合语法规则(否则报编译错),之后翻译成对应的中间码,在Linux中被称为RTL(Register Transfer Language),通常是平台无关的,这个过程也被称为编译前端。编译后端对RTL树进行裁减,优化,得到在目标机上可执行的汇编代码。gcc采用as作为其汇编器,所以汇编码是AT&T格式的,而不是Intel格式,所以在用gcc编译嵌入式汇编时,也要采用AT&T格式。
gcc -S hello.i -o hello.s
汇编器将上面生成的汇编代码转为机器可以执行的指令。每一条汇编语句对应一条机器指令。所以汇编过程比编译过程简单,没有复杂的语法、语义,也不需要优化指令。只是根据汇编指令和机器指令的对照表一一翻译就可以了,最终输出的是目标文件.o,即机器码。
as hello.s -o hello.o #或者 gcc -c hello.c -o hello.s
在成功编译之后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库。
在Hello World 程序中并没有定义 "printf" 的函数实现,且在预编译中包含进的 "stdio.h" 中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现"printf" 函数的呢?系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径 "/usr/lib" 下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数"printf" 了,而这也就是链接的作用。
函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为 ".a" 。动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为 ".so",如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。
链接器ld将各个目标文件组装在一起,解决符号依赖,库依赖关系,并生成可执行文件。链接的时候还会用到静态链接库和动态连接库。静态库和动态库都是 .o目标文件的集合。动态库在链接时只创建一些符号表,而在运行的时候才将有关库的代码装入内存,映射到运行时相应进程的虚地址空间。如果出错,如找不到对应的.so文件,会在执行的时候报动态连接错(可用LD_LIBRARY_PATH指定路径)。
《深入理解计算机系统》
https://zhaoyang.blog.csdn.net/article/details/84770797
https://www.runoob.com/w3cnote/gcc-parameter-detail.html
标签:nsf 程序 ref 位置 错误 else param 对照表 gcc编译
原文地址:https://www.cnblogs.com/chen-cs/p/12918133.html