linux gcc用法

GCC使用
在使用GCC编译程序时,编译过程可以被细分为四个阶段:
预处理(Pre-Processing)
编译(Compiling)汇编(Assembling)
链接(Linking)。
例如:        
#include 
int main(void)
{
           
printf ("Hello world, Linux programming!\n");
                            
return 0;
}
      然后执行下面的命令编译和运行这段程序:
# gcc hello.c -o hello
#
./hello
Hello world, Linux programming!
    
GCC需要调用预处理程序cpp,由它负责展开在源文件中定义的宏,并向其中插入“#include”语句所包含的内容;接着,GCC会调用ccl和as将处理后的源代码编译成目标代码;最后,GCC会调用链接程序ld,把生成的目标代码链接成一个可执行程序。
    
第一步是进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程:
  gcc -E hello.c -o
hello.i
    
此时若查看hello.cpp文件中的内容,会发现stdio.h的内容确实都插到文件里去了,而其它应当被预处理的宏定义也都做了相应的处理。下一步是将hello.i编译为目标代码, 这可以通过使用-c参数来完成:
  gcc -c hello.i -o
hello.o
    
GCC默认将.i文件看成是预处理后的C语言源代码, 因此上述命令将自动跳过预处理步骤而开始执行编译过程,也可以使用-x参数让GCC从指定的步骤开始编译。最后一步是将生成的目标文件链接成可执行文件:
  gcc hello.o -o hello
    
在采用模块化的设计思想进行软件开发时,通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用GCC能够很好地管理这些编译单元。假设
有一个由foo1.c和foo2.c两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序foo,可以使用下面这条命令
  gcc foo1.c foo2.c -o
foo
    
如果同时处理的文件不止一个,GCC仍然会按照预处理、编译和链接的过程依次进行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令:
# gcc -c foo1.c -o foo1.o
#
gcc -c foo2.c -o foo2.o
# gcc foo1.o foo2.o -o foo
在项目文件代码较多时,还要借助
像Make这样的工具。
GDB调试:
列文件清单  
          List
(gdb) list line1,line2 
显示数据    
         print 
检查各个变量的值(gdb)
print p (p为变量名) 
         whatis
显示某个变量的类型     (gdb)
whatis p
断点(breakpoint)  
      break
line-number 使程序恰好在执行给定行之前停止。 
      break
function-name 使程序恰好在进入指定的函数之前停止。
      break
line-or-function if condition 如果condition(条件)是真,程序到达指定行或函数时停止。
      break
routine-name 在指定例程的入口处设置断点 
      (gdb) break
filename:line-number        
如果该程序是由很多原文件构成的,在各个原文件中设置断点
      (gdb) break
filename:function-name 
      要想设置一个条件断点,可以利用break
if命令,如下所示: 
      (gdb) break
line-or-function if expr 例:(gdb)
break 46 if testsize==100   
      countinue 命令
断点继续运行
      显示当前gdb的断点信息:
(gdb) info break 
      会以如下的形式显示所有的断点信息:
Num Type Disp Enb Address What 
                             
1 breakpoint keep y 0x000028bc in
init_random at qsort2.c:155 
                             
2 breakpoint keep y 0x0000291c in
init_organ at qsort2.c:168 (gdb) 
      删除指定的某个断点: (gdb)
delete breakpoint 1 该命令将会删除编号为1的断点,
      如果不带编号参数,将删除所有的断点
(gdb) delete breakpoint 
      禁止使用某个断点 (gdb)
disable breakpoint 1 该命令将禁止断点 1,同时断点信息的
(Enb)域将变为 n
      允许使用某个断点 (gdb)
enable breakpoint 1 该命令将允许断点 1,同时断点信息的
(Enb)域将变为 y
      清除原文件中某一代码行上的所有断点
(gdb)clean number 
                          
注:number 为原文件的某个代码行的行号
信号  
gdb
通常可以捕捉到发送给它的大多数信号,通过捕捉信号,例如,按CTRL-C将中断信号发送给gdb,通常就会终止gdb。但是你或许不想中断gdb,真正
的目的是要中断gdb正在运行的程序,因此,gdb要抓住该信号并停止它正在运行的程序,这样就可以执行某
些调试操作。 
             

Handle命令可控制信号的处理,他有两个参数,一个是信号名,另一个是接受到信号时该作什么


博客园   http://www.cnblogs.com/ymy124/archive/2012/04/28/2474819.html

编译:
第一步、是进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程:
gcc -E hello.c -o hello.i
预处理的宏定义插入到hello.i中

第二步、是将hello.i编译为目标代码,这可以通过使用-c参数来完成:
gcc -c hello.i -o hello.o
也可以通过源文件直接生成
gcc -c hello.c

第三步、是将生成的目标文件链接成可执行文件:
gcc hello.o -o hello
也可以通过源文件直接生成
gcc -o hello hello.c

警告:
1、-pedantic 选项,那么使用了扩展语法的地方将产生相应的警告信息
2、-Wall 使用它能够使GCC产生尽可能多的警告信息
3、-Werror,它要求GCC将所有的警告当成错误进行处理

库依赖:
1、Linux下的大多数函数都默认:
头文件放到/usr/include/目录下
而库文件则放到/usr/lib/目录下
2、GCC在编译时必须有自己的办法来查找所需要的头文件和库文件。
-I选项可以向GCC的头文件搜索路径中添加新的目录。
例如,如果在/home/yy/include/目录下有编译时所需要的头文件,为了让GCC能够顺利地找到它们,就可以使用-I选项:
gcc -o test test.c -I /home/yy/include

-L选项向GCC的库文件搜索路径中添加新的目录
例如,如果在/home/yy/lib/目录下有链接时所需要的库文件libfoo.so,为了让GCC能够顺利地找到它,可以使用下面的命令
gcc -o test test.c -L /home/yy/lib -lfoo

值得好好解释一下的是-l选项,它指示GCC去连接库文件libfoo.so。
Linux下的库文件在命名时有一个约定,那就是应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在用-l选项指定链接的库文件名时可以省去lib三个字母,也就是说GCC在对-lfoo进行处理时,会自动去链接名为libfoo.so的文件。

-static选项,强制使用静态链接库
如果在/home/yy/lib/目录下有链接时所需要的库文件libfoo.so和libfoo.a
为了让GCC在链接时只用到静态链接库,可以使用下面的命令:
gcc -o  test  test.c  -L /home/yy/lib  -static  -lfoo

 

编译成动态库:

g++  -fPIC  -shared  -o libfunc.so  func.cpp

-fPIC参数
表示编译为位置独立的代码,用于编译共享库。目标文件需要创建成位置无关码,概念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。


选项-O可以告诉GCC同时减小代码的长度和执行时间,其效果等价于-O1。
在这一级别上能够进行的优化类型虽然取决于目标处理器,但一般都会包括线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。

选项-O2告诉GCC除了完成所有-O1级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。

选项-O3则除了完成所有-O2级别的优化之外,还包括循环展开和其它一些与处理器特性相关的优化工作。

通常来说,数字越大优化的等级越高,同时也就意味着程序的运行速度越快。

许多Linux程序员都喜欢使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点。

time ./test 查看程序执行时间

优化虽然能够给程序带来更好的执行性能,但在如下一些场合中应该避免优化代码:

程序开发的时候优化等级越高,消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候,才考虑对最终生成的代码进行优化。

资源受限的时候一些优化选项会增加可执行代码的体积,如果程序在运行时能够申请到的内存资源非常紧张(如一些实时嵌入式设备),那就不要对代码进行优化,因为由这带来的负面影响可能会产生非常严重的后果。

跟踪调试的时候在对代码进行优化的时候,某些代码可能会被删除或改写,或者为了取得更佳的性能而进行重组,从而使跟踪和调试变得异常困难。
加速:
使用管道代替编译中临时文件,
-pipe 加速编译
gcc -pipe foo.c -o foo

GCC常用选项
-c 通知GCC取消链接步骤,即编译源码并在最后生成目标文件;

-Dmacro 定义指定的宏,使它能够通过源码中的#ifdef进行检验;

-E 不经过编译预处理程序的输出而输送至标准输出;

-g3 获得有关调试程序的详细信息,它不能与-o选项联合使用;

-Idirectory 在包含文件搜索路径的起点处添加指定目录;

-llibrary 提示链接程序在创建最终可执行文件时包含指定的库;

-O、-O2、-O3 将优化状态打开,该选项不能与-g选项联合使用;

-S 要求编译程序生成来自源代码的汇编程序输出;

-v 启动所有警报;

-Wall 在发生警报时取消编译操作,即将警报看作是错误;

-Werror 在发生警报时取消编译操作,即把报警当作是错误;

-w 禁止所有的报警。

 

静态链接

  在这种连接方式下,函数的代码将直接拷贝到最终的可执行文件中。该程序被执行时候,会被装入该进程的虚拟地址空间中。静态链接库实际上是一个或若干目标文件。

 

动态链接

  这种方式下,函数的代码被放到称作动态连接库或共享对象的某个目标文件中。链接程序此时的工作只是在生成的可执行文件中,记录下共享对象的名字以及少量关键信息。动态连接库可以被多个进程共享,在运行时候内存中只有一个实例。

 

二者比较

  使用动态链接能够使可执行文件较小,并且当共享对象被多个进程使用时节省内存。但有时候系统运行改变或升级,不能保证动态连接库一定可用、有效。


你可能感兴趣的:(linux gcc用法)