• GCC Reference


    本文简单整理了GCC编译的命令项,可作为后续使用的参考。

    编译

    本文以GCC为主,默认编译*.c的c语言源代码。

    源文件->可执行文件

    gcc -Wall test.c -o test
    gcc -Wall a.c b.c -o main

    这里a.c、b.c一起编译生成一个可执行文件。

    注意 -Wall选项表示打开所有最常用的编译警告,也是gcc最推荐使用的选项。

    分段编译通常是先生成中间文件(*.o),然后通过链接器生成可执行文件。GCC也提供了类似机制。

    源文件->中间文件(*.o)

    gcc -Wall -c test.c
    gcc -Wall -c a.c b.c main.c

    多个*.c文件表示同时生成对应的中间目标文件。

    中间文件(*.o)->可执行文件

    gcc test.o -o test
    gcc a.o b.o main.o -o test

    依赖项设置

    外部库文件依赖

    对于需要引用库的情况,可以使用-l(小写字母L)指定依赖库,或者使用绝对路径引入。比如,:

    import libm.a
    gcc -Wall calc.c -lm -o calc
    gcc -Wall calc.c /usr/lib/libm.a -o calc

    默认情况下GCC会在/usr/local/include/usr/include目录中搜索头文件;在/usr/local/lib/usr/lib中搜索库。同时可以单独使用-I-L分别指定包含头文件、包含库文件的搜索路径。
    比如下面命令:

    gcc -Wall test.c -I/header -L/lib -o test

    在Shell脚本中也可以通过环境变量指定默认搜索的头文件和库文件路径,分别使用C_INCLUDE_PATH和LIBRARY_PATH参数。

    对于动态链接的情况,还有一个比较重要的环境变量,LD_LIBRARY_PATH,设置默认加载动态库的目录。

    预处理和宏

    GCC支持使用"-DNAME"的形式在编译时定义宏。
    比如下面指令,会在test.c文件中定义TEST宏

    gcc -Wall -DTEST test.c -o test

    宏也可以带有参数,比如下面指令,

    gcc -Wall -DNUM=100 val.c -o value
    gcc -Wall -DNUM val.c -o value

    在不指定的值的情况下,gcc会将宏默认赋值为1。也支持宏展开

    gcc -Wall -DNUM="2+2" val.c -o value

    下面是val.c的代码,感兴趣的可以验证下上面语句的实际输出情况

    #include <stdio.h>
    int main(void)
    {
    	printf("Value of NUM is %d", NUM);
    	return 0;
    }
    

    生成预处理之后的文件(*.i)

    gcc -E test.c -o test.i

    或者使用-save-temps选项。

    带有调试信息编译

    GCC提供了“-g”调试选项在对象文件(*.o)和可执行文件中存储额外的调试信息。使用“-g”选项除了允许程序在调试器控制下运行外,还可以找到程序崩溃的环境。当程序异常退出时,操作系统会在当前目录生成“core”文件。程序员可以从core文件中查询到程序退出的位置和当时的变量值。
    可以使用下面格式加载core文件。

    gdb EXECUTABLE-FILE CORE-FILE
    gdb backtrace 显示调用堆栈

    编译优化

    GCC提供了"-OLEVEL",用于选择哪一种优化,LEVEL可取值0、1、2、3、s。默认GCC使用“-O0”或者“-O”(大写字母o)。通常我们在实际开发调试时使用默认的“-O0”调试,发布或者部署时使用“-O2”。
    至于具体含义建议参考GCC用户手册。优化的含义是在运行速度或者可执行程序大小上优化,当然优化级别越高,与源代码差距越大,可读性越差。
    GNU 发行的软件包默认都打开了调试选项“-g”和优化选项“-O2”。

    c++编译

    c++编译需要使用g++,例如:

    g++ -Wall test.cpp -o test

    其他编译指令跟gcc类似

    生成静态库

    GCC提供了ar生成静态库,通常静态库是一系列对象文件(.o)的集合。
    可以用下面指令将两个对象文件打包成linux下的静态库文件(
    .a)。

    gcc -Wall -c init.c uninit.c
    ar cr libhello.a init.o uninit.o
    查看*.a中的内容列表
    ar t libhello.a

    生成动态库

    编译时使用“-fpic”选项,用于指定输出的目标文件是按照可重定位地址(relocatable addressing)方式生成的。pic表示position independent code。并在链接时使用“-shared”生成最终动态库。
    以下指令将两个源代码生成一个*.so文件。

    gcc -Wall -c -fpic first.c second.c
    gcc -Wall -shared first.o second.o -o hello.so

    生成文件查看及分析

    查看可执行文件类型

    使用file指令,可以查看可执行文件的类型。比如下面输出:

    $ file a.out
    a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

    查看符号表

    使用nm指令,比如:

    nm test.o

    查看动态库依赖项

    使用ldd指令,可查看可执行模块的外部库依赖项

    c程序中文件后缀说明

    • .a 静态对象库,是目标文件的封装格式。
    • .c c语言源代码
    • .h 源代码的头文件
    • .i 预处理之后的c语言源代码,是GCC编译中间产物
    • .o 目标文件,汇编之后的模块,是GCC编译中间产物
    • .s 汇编语言代码,是GCC中间产物。
    • .so 共享对象库

    源代码(*.c)通过预处理,生成*.i文件;经过词法分析和语法分析之后生成伪代码形式的*.s文件;然后通过汇编之后生成依赖特定平台的目标文件(*.o);最后使用链接器将多个目标文件生成一个可执行文件。

    备注

    本文主要参考“An Introduction to GCC”整理。算是简单的GCC编译指令汇总。

  • 相关阅读:
    你好,这里有一份2019年目标检测指南
    谷歌2019 学术指标发榜:CVPR首次进入Top 10,何恺明论文引用最高!
    魔图互联:知识图谱推荐系统-给人们带来更个性化的推荐
    NLPer入门指南 | 完美第一步
    一文总结数据科学家常用的Python库(下)
    一文总结数据科学家常用的Python库(上)
    一文看懂NLP神经网络发展历史中最重要的8个里程碑!
    如何为计算机视觉任务选择正确的标注类型
    C. Queen Codeforces Round #549 (Div. 2) dfs
    D. Equalize Them All Codeforces Round #550 (Div. 3)
  • 原文地址:https://www.cnblogs.com/tocy/p/gcc-simple-reference.html
Copyright © 2020-2023  润新知