IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    linux GCC编译和使用方法(一)

    cjhust发表于 2014-11-19 16:10:50
    love 0

    1、写在前面

    最近同事的一个新feature+nginx+我的一个模块合并在一起的时候,发现运行1分钟左右的时候一直在core,而nginx+我的模块已经在线上运行了很长一段时间了。

    虽然比较倾向于怀疑是新feature的问题,但是core的地方一直在我的那个模块,因此不得不“心虚”起来,于是拼命地review自己的模块,经过一段时间后,终于将目标锁定到a.c代码中的这一行(void *)peers = get_peers()(在b.c中定义声明),发现当get_peers()返回的地址超过4字节时,比如0x7de01020304,peers会将地址截断成0x01020304或者0xffffffff…。

    最后发现是编译的时候忽略了一个warning: initialization makes pointer from integer without a cast 。。。。。。,编译器居然说我的函数返回的是一个 integer。后来增加一个b.h声明void *get_peers(),a.c中include b.h问题得以解决。

    事后真的非常心虚,很后怕,很感慨一直有隐患的代码在线上运行了这么长时间,竟然没有造成交易下跌和故障,这件事给我的心得是不要忽略编译器的任何抱怨,否则会死的很惨,也让我重新审视了下自己的基础非常不扎实(nginx“非常友善”地帮我们包装了很多底层的调用,导致自己真正在实现底层功能的时候,发现已经不会使用了)。

    2、知识百科

    编译步骤

    第一步:进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程。

    gcc -E hello.c -o hello.i

    预处理的宏定义插入到hello.i中

    typedef unsigned long int __dev_t;

    typedef unsigned int __uid_t;

    typedef unsigned int __gid_t;

    typedef unsigned long int __ino_t;

    typedef unsigned long int __ino64_t;

    typedef unsigned int __mode_t;

    typedef unsigned long int __nlink_t;

    typedef long int __off_t;

    typedef long int __off64_t;

    typedef int __pid_t;

    typedef struct { int __val[2]; } __fsid_t;

    第二步:是将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将所有的警告当成错误进行处理;

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

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

    6、-v 启动所有警报;

    7、-w 禁止所有的报警。


    库依赖

    1、Linux下的大多数函数都默认:

    头文件放到/usr/include/目录下

    库文件则放到/usr/lib/目录下

    2、GCC在编译时必须有自己的办法来查找所需要的头文件和库文件。

    -I选项可以向GCC的头文件搜索路径中添加新的目录。

    例如,如果在/home/xiaowp/include/目录下有编译时所需要的头文件,为了让GCC能够顺利地找到它们,就可以使用-I选项:

    gcc -o test test.c -I /home/xiaowp/include

    -L选项向GCC的库文件搜索路径中添加新的目录

    例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so,为了让GCC能够顺利地找到它,可以使用下面的命令

    gcc -o test test.c -L /home/xiaowp/lib -lfoo

    值得好好解释一下的是-l选项,它指示GCC去连接库文件libfoo.so。

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

    -static选项,强制使用静态链接库

    如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so和libfoo。a

    为了让GCC在链接时只用到静态链接库,可以使用下面的命令:

    gcc -o test test。c -L /home/xiaowp/lib -static -lfoo


    加速编译

    使用管道代替编译中临时文件,

    -pipe 加速编译

    gcc -pipe foo.c -o foo



沪ICP备19023445号-2号
友情链接