1. GCC命令行选项

当调用GCC时,它通常进行预处理、编译、汇编和链接。“overall option”允许你在中间阶段停止这个过程。例如,-c 选项表示不运行链接器。然后输出由汇编程序输出的对象文件组成。

其他选项被传递到处理的一个阶段。一些选项控制预处理器,其他的控制编译器本身。有的用于控制汇编器和链接器,但是一般不使用。大多数命令行选项可以用于C程序,如果只用于其他某个语言,会做特别说明。如果没有说明其源语言,则表明可以用于所有支持的语言。

gcc程序接受选项options和文件名file names作为操作数。由多个字母组成的选项不能拆开,单个字母组成的选项不能合并。例如,-dv不同于-d -v

可以将参数和选项进行混合使用。大部分时候,顺序无关紧要。但是,当使用同一种的多个选项时,顺序非常重要。例如,如果多次指定-L,目录按照指定的顺序进行搜索,并且-l 在命令中的位置非常重要。

许多选项以-f 或者 -W 开始,名称很长,例如:-fmove-loop-invariants-Wformat 等等。大多数这些选项都有正负两种形式;-ffoo 的负形式为-fno-foo。文档中一般只记录正负两种形式中的一个,没有一种是默认的。

官方文档

1.1 控制输出类型的选项

编译可以分为四个阶段:预处理、编译、汇编和链接,总是按顺序进行。GCC能够将数个文件预处理并编译为一个或多个汇编输入文件,随后每个汇编输入文件产生一个对象文件,并将所有对象文件(新编译的和指定的输入文件)链接组合成一个可执行文件。

对于任何类型的输入文件,文件名后缀决定完成什么类型的编译。

suffix 后缀 相关处理
.c 必须预处理的c源文件
.i 不应该预处理的c源文件
.m Objective-C源代码。注意,必须与libobjc库链接,以使程序工作。
.mi 不应该预处理的Objective-C源代码。
.mm .M Objective-C++源代码。注意,必须与libobjc库链接,以使程序工作。
.mii 不应该预处理的Objective-C++源代码。
.h C, C++, Objective-C或者Objective-C++头文件。
.cc .cp .cxx .cpp .c++ .C 必须进行预处理的C++源代码。
.ii 不应该预处理的C++源文件
.s 汇编代码
.S .sx 必须预处理的汇编代码

可以通过-x 选项显式地指定输入语言:

为下列输入文件显式地指定语言(而不是让编译器根据文件后缀名默认地选择语言)。这些选项将会应用到所有后续的输入文件,直到下一个-x 选项。可能的输入语言为:

1
2
3
4
5
6
7
c   c-header    cpp-output
c++ c++-header c++-cpp-output
objective-c objective-c-header objective-c-cpp-output
objective-c++ objective-c++-header objective-c++-cpp-output
assembler assembler-with-cpp
go
java
  • -x none

    关闭任何语言的指定。所以后续的文件通过后缀名进行处理(就像根本没有使用-x)。

  • -pass-exit-codes

    通常情况下,如果编译器的任何一个阶段返回一个非成功返回码,那么gcc程序将退出,退出代码为1。如果指定了-pass-exit-codes,gcc程序将会返回数值上最大的错误码,由产生错误信号的任何阶段产生。如果内部编译器出现错误,C、C++、Fortran前端将会返回4。

如果只需要编译某些阶段,可以使用-x(或者文件后缀名)告诉gcc何处开始,并用-c-S 或者 -E告诉gcc何处停止。注意,某些组合(如:-x cpp-output -E)指示gcc不做任何事情。

  • -c

    编译或者汇编源文件,但不链接。链接阶段根本没有完成。最终的输出是每个源文件的对象文件的形式。默认地,源文件名通过将文件的后缀“.c .i .s”等替换为“.o”得到。不识别的输入文件,不需要编译或者汇编,将被忽略。

  • -S

    编译完成后停止,而不进行汇编。对于每个指定的非汇编输入文件,输出以汇编代码文件的形式给出。默认地,汇编文件名通过将文件的后缀“.c .i .s”等替换为“.S”得到。不需要编译的输入文件将被忽略。

  • -E

    在预处理阶段之后停止,不会正常运行编译器。输出是预处理的源代码的形式,被发送到标准输出。不需要预处理的输入文件会被忽视。

  • -o file

    将输出放到文件file中。这适用于正被生成的任何类型的输出,不管是否是执行文件、对象文件、汇编文件或者预处理C代码。如果-o 没有指定,默认是把一个可执行文件放到a.out中,source.suffix的对象文件放到source.o中,它的汇编文件放到source.s中,预编译头文件在source.suffix.gch中,所有的预处理C源代码在标准输出中。

  • -v

    打印所有被执行以运行编译阶段的命令。也打印编译器驱动程序的版本号,以及预处理器和编译器的版本号。

1.2 链接选项

当编译器将对象文件链接为可执行输出文件时这些选项起作用。如果编译器不执行链接步骤时,这些选项将无意义。

  • object-file-name

    不以特殊识别后缀名结尾的文件名被认为是对象文件或者库文件的名称。(根据内容,对象文件会被链接器与库文件区别开。)如果链接完成,这些对象文件会被用作链接器的输入。

  • -c -S -E

    如果使用了其中任何一个选项,链接器将不会工作,并且对象文件名不能够作为参数。

  • -llibrary

    -l library

    (“-l”与“library”之间有无空格)。

    搜索名称为library的库文件。第二种选项是将library作为独立的参数,但是这只适用于POSIX标准,并不推荐。在命令行中何处使用该选项,效果大不相同。链接器按照指定的顺序搜索并处理库文件和对象文件。因此,“foo.o -lz bar.o”在搜索foo.o之后搜索“z”,但是在搜索bar.o之前。如果bar.o引用了z中的函数,这些函数将不会被加载。

    链接器搜索一个标准列表的库目录,实际上文件名为liblibary.a. 链接器随后使用这个文件,就像通过文件名精确指定了一样。

    被搜索的目录包含多个标准系统目录,以及你通过“-L”指定的任何目录。

    一般情况下,通过这种方式找到的文件是库文件(library files)—成员是目标文件(object files)的归档文件(archive files)。链接器通过扫描归档文件对其进行处理,扫描其成员中被引用但未被定义的符号。但是如果找到的文件是二进制对象文件,那么将以普通方式进行链接。与使用“-l”选项并指定文件名的不同之处在于,“-l”选项将library与“lib”和“.a”拼接并搜索多个目录。

  • -s

    从可执行文件中移除所有符号表和重定位信息。

  • -static

    在支持动态链接的系统中,避免链接到共享库。在其他系统中,这个选项没有影响。

  • -shared-libgcc

    -static-libgcc

    在提供libgcc为共享库的系统上,这些选项分别强制使用共享或静态版本。如果在配置编译器时没有构建共享版本的libgcc,这些选项将不会生效。​

  • -Wl, option

    option作为一个选项传递给链接器。如果option中存在逗号,则将option在逗号处划分为多个选项。可以使用此语法将参数传递给option。例如,-Wl,-Map,output.map-Map,output.map传递给链接器。

1.3 Options to Request or Suppress Warnings

  • -fmax-error=n

    将最大错误信息量限制为n,此刻gcc将退出而不是继续处理源代码。如果n是0(默认),则将不会对错误信息量进行限制。如果也指定了“-Wfatal-errors”,那么-Wfatal-errors将会覆盖这条指令。

  • -Wall

    This enables all the warnings about constructions that some users consider questionable, and that easy to avoid (or modify to prevent the warning), even in conjunction with macros.

  • -Wextra

    This enables some extra warning flags that are not enabled by -Wall. (This option used to be called -w. The older name is still supported, but the newer name is more descriptive.)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -Wclobbered  
    -Wempty-body
    -Wignored-qualifiers
    -Wmissing-field-initializers
    -Wmissing-parameter-type (C only)
    -Wold-style-declaration (C only)
    -Woverride-init
    -Wsign-compare
    -Wtype-limits
    -Wuninitialized
    -Wunused-parameter (only with -Wunused or -Wall)
    -Wunused-but-set-parameter (only with -Wunused or -Wall)

    This option -Wextra also prints warning messages for the following case:

    • A pointer is compared against integer zero with <, <=, > or >=.
    • (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
    • (C++ only) Ambiguous virtual bases.
    • (C++ only) Subscripting an array that has been declared register.
    • (C++ only) Taking the address of a variable that has been declared register.
    • (C++ only) A base class is not initialized in a derived class’s copy constructor.
  • -Wno-deprecated

    对于已弃用的特性的使用不返回警告。

1.4 Code Generation Options

这些依赖机器的指令用于在代码生成中控制借口。

  • -fpic

    在目标库支持下,生成适合于共享库中使用的位置无关代码(PIC)。这样的代码通过全局偏移表(GOT)访问所有固定地址。动态加载器在程序启动时处理GOT条目(动态加载器不是gcc的一部分,它是操作系统的一部分)。如果链接的可执行程序的GOT大小超过了机器指定的最大空间,将会从链接器收到错误信息,表示 -fpic不工作;在这种情况下,使用-fPIC替代并重新编译。

    位置无关代码需要特殊的支持,因此只能在特定的机器上工作。对于x86,GCC对System V提供了PIC支持,但是对Sun 386i不支持。对于IBM RS/6000生成的代码都是位置无关的。

1.5 其他

  • -g

    以操作系统的本地格式生成调试信息(stabs, COFF, XCOFF, or DWARF 2)。GDB可以使用这个调试信息。

  • -Bstatic

    -Bdynamic

    这些选项是为VxWorks目标定义的。这些选项将会被传递给链接器,他们被定义为与Diab兼容。​