GCC 简单使用

来源:互联网 发布:正知正见是什么意思 编辑:程序博客网 时间:2024/05/20 20:45

编译生成目标文件(.*),  -I表示被检索的头文件路径

 

gcc -c Main.m -I/GNUstep/System/Library/Headers/

 

 

-I   表示头文件查找的路径

-L   表示库文件查找路径

-  l 表示需要链接的库文件

 

 

gcc -o helloworld helloworld.m /
-fconstant-string-class=NSConstantString /         
-I /GNUstep/System/Library/Headers/ /
-L /GNUstep/System/Library/Libraries/ /
-lobjc /
-lgnustep-base

注意:helloworld.m必须出现在-lobjc和-lgnustep-base的前面,否则会出错。

 

 

 

gcc工作过程概述

gcc 工作的过程,分为以下4个步骤
proprocessing: 预处理程序会展开源文件中的宏并在其中插入#include文件所包含的内容
compilation:将预处理后的结果文件编译成汇编文件
assembly:将汇编文件生成具体cpu上的目标文件 .o
linking: 连接程序ld将目标文件.o链成可执行文件。$gcc helloworld.c,生成a.out
默认情况下,gcc不留痕迹地完成了上述4个步骤

gcc的中间文件

使用-save-temps 选项保存编译过程中产生的临时文件
   $ gcc -save-temps helloworld.c
   生成以下文件 
helloworld.i : 预处理后的代码
helloworld.s : 汇编文件
helloworld.o : 目标文件(类似win下的.obj) 
a.out            :可执行文件(类似win下的exe)
编译各个步骤所需临时文件默认是用文件来通讯的,如果想提高编译效率可以考虑使用管道-pipe 。

使用-E选项只进行预处理
$gcc -E helloworld.c 生成helloworld.i
使用-S选项生成汇编
$gcc -S helloworld.c 
生成helloworld.s,即汇编代码,AT&T风格的
使用-c选项生成目标文件.o
$gcc -c helloworld.c 生成helloworld.o 
使用-o选项指定输出文件名
$gcc -o aa helloworld.o 生成名为aa的可执行文件

mangled name

使用gcc或者g++时需要注意"mangled name"问题,见extern "C"的文章。本质是不同语言编译器产生不同的符号表的问题。一般使用nm工具查看可执行文件或者lib库的符号表。下面是wiki上关于nm的说明
The nm command ships with a number of later versions of Unix and similar operating systems. nm is used to examine binary files (including libraries, compiled object modules, shared-object files, and standalone executables) and to display the contents of those files, or meta information stored in them, specifically the symbol table. The output from nm distinguishes between various symbol types, for example it differentiates between a function which is supplied by an object module and a function which is required by it. nm is used as an aid for debugging, to help resolve problems arising from name conflicts and C++ name mangling, and to validate other parts of the toolchain.The GNU Project ships an implementation of nm as part of the GNU Binutils package.

gcc依靠文件的扩展名来决定如何处理文件
.c文件,则使用c编译器
.cpp、.cc文件,则使用c++编译器,但不链接stdc++库
g++使用c++编译器,并默认链接stdc++库

经常会用到的几个:-lcrypto(加密库), -lpthread(线程库), -lm(数学库), -lz(压缩/解压缩库)
被依赖的库一般写在依赖者的后面

告警选项:

-W 警告
-Wall表示打开所有告警, -w表示关闭所有警告。
-W(warning) 标记打开指定警告。如-Wshadow表示当某个局部变量屏蔽了另一个局部变量是给出告警。
-Wno-(warning)标记关闭指定警告。如使用-Wno-unused关掉无用变量警告。 
所有告警的列表http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
建议-Wall –W。加-W可以把一些额外的warning给打出来,比如一个unsigned的值与0做大小比较。
对每一条warning都不能忽视,要写warning free的代码
加上-Werror ,视告警为错误;出现任何警告的代码就不能通过编译

我喜欢用如下编译选项:
CPPFLAGS = -g -Werror -D_GUN_SOURCE -Wfloat-equal -Wall -Wunused -Winline -pipe -D__VERSION_ID__="/"$(VERSION_ID)/""

其他常用编译选项:

-static和-dynamic
默认动态链接
链接时推荐链接静态库(*.a)
-static无法保证gcc的所有库都能静态链接,不推荐使用。
-g 在程序中包含标准调试信息,给gdb使用。
-pg 在程序中加入gprof能够读取的剖析符号信息,以方便做性能分析。
-fPIC 编译位置无关的代码 64位动态库可能会用到

优化选项:

编译优化
-O1、-O2、-O3、-Os
每一级优化功能集合会随gcc版本的不同而不同
优化级别越高,并不表示速度越快
-f{flag} 特定优化(不推荐使用)
    -funroll-loops 循环展开
    -fprefetch-loop-arrays 数组预取
    -finline_functions “简单”函数内联 
所有优化选项见 http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
我较少使用优化,因不方便追查问题。优化时注意对逻辑关系复杂、多线程访问的变量,使用violate。
编译的时候如果加上-O2或O3 去编译,可以发现更多warning。

 

 

原创粉丝点击