GCC编译选项参数

GCC 编译选项参数

1 常用选项

GCC编译选项参数_第1张图片

2 预处理器选项

-includefile
在处理常规输入文件之前,首先处理文件file,其结果是,文件file的内容先得到编译.命令行上任何-D'和-U’选项永远在-includefile'之前处理,无论他们在命令行上的顺序如何.然而-include’和`-imacros’选项按书写顺序处理.

-imacros file
在处理常规输入文件之前,首先处理文件file,但是忽略输出结果.由于丢弃了文件file的 输出内容, -imacrosfile'选项的唯一效果就是使文件file中的宏定义生效,可以用于其他输入文件.在处理-imacrosfile’选项之前,预处理器首先处理-D'和-U’选项,并不在乎他们在命令行上的顺序.然而-include'和-imacros’选项按书写顺序处理.

-idirafter dir
把目录dir添加到第二包含路径中.如果某个头文件在主包含路径(用`-I’添加的路径)中没有 找到,预处理器就搜索第二包含路径.

-iprefix prefix
指定prefix作为后续`-iwithprefix’选项的前缀.

-iwithprefix dir
把目录添加到第二包含路径中.目录名由prefix和dir合并而成,这里prefix被先前的`-iprefix’选项指定.

-nostdinc
不要在标准系统目录中寻找头文件.只搜索-I'选项指定的目录(以及当前目录,如果合适).结合使用-nostdinc’和`-I-'选项,你可以把包含文件搜索限制在显式指定的目录.

-nostdinc++
不要在C++专用标准目录中寻找头文件,但是仍然搜索其他标准目录. (当建立`libg++'时使用 这个选项.)

-undef
不要预定义任何非标准宏. (包括系统结构标志).

-E
仅运行C预处理器.预处理所有指定的C源文件,结果送往标准输出或指定的输出文件.

-C
在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的

-P
告诉预处理器不要产生#line'命令.配合-E’选项使用.

-M [ -MG ]
告诉预处理器输出一个适合make的规则,用于描述各目标文件的依赖关系.对于每个源文件,预处理器输出 一个make规则,该规则的目标项(target)是源文件对应的目标文件名,依赖项(dependency)是源文件中#include引用的所有文件.生成的规则可以是单行,但如果太长,就用’-换行符续成多行.规则 显示在标准输出,不产生预处理过的C程序.
-M'隐含了-E’选项.
-MG'要求把缺失的头文件按存在对待,并且假定他们和源程序文件在同一目录下.必须和-M’选项一起用.

-MM [ -MG ]
-M'选项类似,但是输出结果仅涉及用户头文件,象这样#includefile"’.忽略系统头文件如`#include '.

-MD
-M'选项类似,但是把依赖信息输出在文件中,文件名通过把输出文件名末尾的.o’替换为.d'产生.同时继续指定的编译工作----MD’不象-M'那样阻止正常的编译任务. Mach的实用工具md’能够合并.d'文件,产生适用于make’命令的单一的 依赖文件.

-MMD
和`-MD’选项类似,但是输出结果仅涉及用户头文件,忽略系统头文件.

-H
除了其他普通的操作, GCC显示引用过的头文件名.

-Aquestion(answer)
如果预处理器做条件测试,如`#if #question(answer)’,该选项可以断言(Assert)question的答案是answer.-A-'关闭一般用于描述目标机的标准断言.

-Dmacro
定义宏macro,宏的内容定义为字符串`1’.

-Dmacro=defn
定义宏macro的内容为defn.命令行上所有的-D'选项在-U’选项之前处理.

-Umacro
取消宏macro. -U'选项在所有的-D’选项之后处理,但是优先于任何-include'或-imacros’选项.

-dM
告诉预处理器输出有效的宏定义列表(预处理结束时仍然有效的宏定义).该选项需结合`-E’选项使用.

-dD
告诉预处理器把所有的宏定义传递到输出端,按照出现的顺序显示.

-dN
-dD'选项类似,但是忽略宏的参量或内容.只在输出端显示#definename.

3 链接选项

-flinker-output=type
此选项控制链接时间优化器的代码生成。默认情况下,链接器输出由链接器插件自动确定。为了调试编译器,并且如果需要与non-LTO目标文件进行增量链接,则手动控制类型可能很有用。
如果类型为“exec”,代码生成会生成静态二进制文件。在这种情况下-fpic 和 -fpie 都被禁用。
如果类型为“dyn”,代码生成产生一个共享库。在这种情况下-fpic 要么 -fPIC保留,但不会自动启用。这样就可以在可能的体系结构(即x86)上构建不带位置无关代码的共享库。
如果类型为“pie”,代码生成会产生一个 -fpie 可执行文件。这样会产生与“执行’ 除了那个 -fpie 如果在编译时指定,则不禁用。
如果类型为“rel’,编译器假定已完成增量链接。包含用于链接时间优化的中间代码的部分将合并,预先优化,然后输出到生成的目标文件中。另外,如果 -ffat-lto-objects如果指定,将生成二进制代码以用于将来的no-LTO链接。通过增量链接生成的目标文件比从相同目标文件生成的静态库小。在链接时,假设使用了库中的大多数对象,则增量链接的结果也比静态库加载得更快。
“nolto-rel”将编译器配置为进行增量链接,其中强制执行代码生成,生成最终的二进制文件,并剥离用于后续链接时间优化的中间代码。当将多个目标文件链接在一起时,与禁用链接时优化(例如,发生跨模块内联)相比,对结果代码的优化效果更好,但是整个程序优化的大部分好处都将丢失。
在增量链接期间(通过 -r)链接器插件默认为 rel。但是,使用GNU Binutils的当前接口,不可能将LTO对象和no-LTO对象增量链接到单个混合对象文件中。如果增量链接中的任何目标文件不能用于链接时优化,则链接器插件会发出警告并使用“nolto-rel”。为了保持整个程序的优化,建议将此类对象链接到静态库中。

-fuse-ld=bfd
使用bfd链接器而不是默认链接器。

-fuse-ld=gold
使用gold链接器而不是默认链接器。

-fuse-ld=lld
使用LLVM lld链接器而不是默认链接器。

-llibrary
-l library

链接时搜索名为library的库。(使用库作为单独参数的第二种替代方法仅是为了符合POSIX,不建议这样做。)
-l选项由GCC直接传递给链接器。
链接器在标准目录列表中搜索该库。搜索的目录包括几个标准系统目录以及您指定的任何目录-L。
静态库是目标文件的档案,其文件名类似于 liblibrary.a。一些目标还支持共享库,这些共享库的名称通常如下liblibrary.so。如果同时找到静态库和共享库,则链接器将优先选择与共享库链接,除非 –static被使用选项。
在命令中写入此选项的位置会有所不同。链接器按照指定的顺序搜索和处理库和目标文件。因此,”foo.o -lz bar.o”搜索库”z”文件后 foo.o 且在bar.o之前的文件。如果bar.o指的是”z”,则可能不会加载这些功能。

-lobjc
您需要这种特殊情况 -l 选项以链接Objective-C或Objective-C ++程序。

-nostartfiles
链接时请勿使用标准的系统启动文件。通常使用标准系统库,除非-nostdlib, -nolibc, 要么 -nodefaultlibs 用来。

-nodefaultlibs
链接时请勿使用标准系统库。仅将您指定的库传递给链接器,如-static-libgcc 或者-shared-libgcc,否则将被忽略。正常使用标准启动文件,除非-nostartfiles 被使用。
编译器可能调用memcmp, memset,memcpy和memmove。这些条目通常由libc中的条目解析。指定此选项后,应通过其他某种机制来提供这些入口点。

-nolibc
链接时,请勿使用紧密连接的C库或系统库。仍然链接启动文件,libgcc 或工具链提供的语言支持库,例如 libgnat, libgfortran,libstdc++,除非也使用阻止其包含的选项。

-nostdlib
链接时,请勿使用标准的系统启动文件或库。没有启动文件,只有指定的库才传递给链接器,选项指定系统库的链接,例如 -static-libgcc 或-shared-libgcc,否则也将被忽略。

-e entry
–entry=entry

指定程序入口点为entry。参数由链接器解释;GNU链接器接受符号名称或地址。

-pie
在支持它的目标上生成一个动态链接的位置无关可执行文件。为了获得可预测的结果,还必须指定用于编译的相同选项集(-fpie, -fPIE,或model suboptions)。

-no-pie
不要产生动态链接的位置无关可执行文件。

-static-pie
在支持静态目标的可执行文件上生成独立于静态位置的可执行文件。静态位置独立的可执行文件与静态可执行文件相似,但是可以在没有动态链接器的情况下加载到任何地址。为了获得可预测的结果,还必须指定用于编译的相同选项集(-fpie, -fPIE,或model suboptions)。

-pthread
与POSIX线程库链接。GNU / Linux目标,大多数其他Unix派生以及x86 Cygwin和MinGW目标都支持此选项。在某些目标上,此选项还会为预处理器设置标志,因此应始终将其用于编译和链接。

-r
产生可重定位的对象作为输出。这也称为部分链接。

-rdynamic
通过标志-export-dynamic在支持它的目标上连接到ELF链接器。这指示链接器将所有符号(不仅是已使用的符号)添加到动态符号表中。对于某些用途的使用dlopen或允许从程序中获取回溯,此选项是必需的

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

-static
在支持动态链接的系统上,此设置会覆盖 -pie 并阻止与共享库的链接。在其他系统上,此选项无效。

-shared
产生一个动态库,然后可以将其与其他对象链接以形成可执行文件。并非所有系统都支持此选项。为了获得可预测的结果,还必须指定用于编译的相同选项集(-fpic, -fPIC,或model suboptions)。用法:gcc -shared foo.o -o libfoo.so

-shared-libgcc
-static-libgcc

在提供以下功能的系统上 libgcc作为共享库,这些选项分别强制使用动态版本或静态版本。如果没有共享版本libgcc 是在配置编译器时生成的,这些选项无效。

-static-libasan
当-fsanitize=address 选项用于链接程序,GCC驱动程序自动链接libasan。如果libasan可以作为动态库使用,并且 -static 选项未使用,则此链接指向的动态的libasan。-static-libasan选项指示GCC驱动程序静态链接libasan,而不必静态链接其他库。

-static-libtsan
当-fsanitize=thread 选项用于链接程序,GCC驱动程序自动链接libtsan。如果libtsan可以作为共享库使用,并且 -static选项未使用,则此链接指向动态的libtsan。-static- libtsan选项指示GCC驱动程序静态链接libtsan,而不必静态链接到其他库。

-static-liblsan
当-fsanitize=leak选项用于链接程序,GCC驱动程序自动链接libtsan。如果libtsan可以作为共享库使用,并且 -static 选项未使用,则此链接指向的动态的libtsan。-static-liblsan 选项指示GCC驱动程序链接静态的libtsan,而不必静态链接其他库。

-static-libubsan
当-fsanitize=undefined选项用于链接程序,GCC驱动程序自动链接libubsan。如果libubsan可以作为动态库使用,并且 -static 选项未使用,则此链接指向的动态版本的libubsan。-static-libubsan 选项指示GCC驱动程序静态链接libubsan,而不必静态链接其他库。

-static-libstdc++
当g++程序用于链接C ++程序时,通常会自动链接到libstdc++。如果 libstdc++ 可以作为动态库使用,并且 -static 选项未使用,则此链接指向的动态的libstdc++。-static-libstdc ++选项指示g++驱动程序静态链接libstdc++,而不必静态链接其他库。

-symbolic
构建共享库时,将对全局符号的引用绑定。警告任何未解决的引用(除非被链接编辑器选项覆盖)-Xlinker -z -Xlinker defs)。只有少数系统支持此选项。

-T script
使用脚本作为链接描述文件。大多数使用GNU链接器的系统都支持此选项。在某些目标上,例如没有操作系统的裸板目标,-T 链接时可能需要该选项,以避免引用未定义的符号。

-Xlinker option
通过选项作为链接器的选项。您可以使用它来提供GCC无法识别的特定于系统的链接器选项。

-Wl,option
一般通过-Wl,option来传递参数给链接器。。如果option包含逗号,则会在逗号处将其拆分为多个选项。您可以使用此语法将参数传递给选项。例如,-Wl,-Map,output.map通过–Map output.map去链接。
使用GNU链接器时,您还可以通过以下方式获得相同的效果-Wl,-Map=output.map。

-u symbol
假设符号符号未定义,以强制链接库模块对其进行定义。您可以使用-u 多次使用不同的符号来强制加载其他库模块。

-soname
-soname用于指定动态链接库名字,用法: -Wl,-soname,libxxx.so。

–gc-sections
–gc-sections表示依赖库中不使用的sections将不被链接,可以减小链接目标的大小,一般跟-ffunction-sections一起使用。用法:-Wl,–gc-sections。

–whole-archive
–whole-archive用来告诉链接器,将后面库中出现的所有符号都链接进来,这样有一个好处是链接的时候不需要考虑中间文件和库文件的顺序,以保证链接能够成功。

–no-whole-archive
–no-whole-archive用于重置设置的 --whole-archive。

-z,noexecstack
标记当前链接的目标文件是不需要executable stack的。

-z,execstack
标记当前链接的目标文件需要executable stack。

-z,relro
relro:Relocation Read Only。Create an ELF “PT_GNU_RELRO” segment header in the object。也就是会创建一个PT_GNU_RELRO段,这个重定向区域时只读的。这个是用来保护目标文件防止被篡改,编译器一般都会默认带上此参数。

-z,now
-z,now常用于跟-z,relro一起使用,用于保护生成的目标文件被篡改。ld的手册中是这样介绍的:When generating an executable or shared library, mark it to tell the dynamic linker to resolve all symbols when the program is started, or when the shared library is linked to using dlopen, instead of deferring function call resolution to the point when the function is first called.设置这个参数表明在程序运行或者dlopen这个库的时候就将所有的动态符号加载并绑定进来,而不是在动态符号需要使用的时候加载。

–build-id
–build-id用于创建elf文件中".note.gnu.build-id"段信息。这个段中的信息是链接时的唯一标识,一般使用md5或者哈希计算(md5或者sha1),如果不使用可以传入"none"。

–fatal-warnings
–fatal-warnings将所有警告当错误处理,相当于-Werror,可以通过–no-fatal-warnings取消。

–no-undefined
链接的时候如果依赖库中包含未定义符号,那么没有设置–no-undefined选项的时候,链接是不会报错的,但是运行时如果用到了未定义符号则运行时报错。加入了-Wl,–no-undefined,编译链接时会报错。

-rpath
-rpath指定运行时搜索路径。用法:-Wl,-rpath,/data/data/testlib/lib,这样在运行的时候,linker会在/data/data/testlib/lib下查找依赖库。

4 目录选项

-Idir
表示增加dir为头文件的搜索路径,这个路径优先于系统的默认路径,所以用自己指定的头文件来替代系统默认的头文件。但是不要用这个选项来指定路径不要包括供应商提供的系统头文件(这个情况可以用-isystem),如果有多个-I选项,则路径的搜索先后顺序是从左到右的。,即在前面的路径会被选搜索。另外,如果dir以=号开头即如–I=dir,而其中的=号为被sysroot前缀替换。
如果一个标准系统包含的目录或者用-isystem选项指定的目录同时用了-I选项,则-I选项会被忽略。那个目录仍然会被搜索,只是和没有指定-I选项时一样。这是为了确保GCC程序能过够修复系统头文件的bug和非故意的改变include_next指令的顺序。如果你确实需要改变系统路径的搜索顺序,那你可以用”-nostdinc” 和/或者“-isystem”选项。

-nostdinc
该选项指示不要搜索头文件的标准路径(即默认路径),而只搜索-I选项指定的路径和当前路径。

-isysroot dir
该选项和—sysroot选项差不多,但只用于搜索头文件。

–sysroot=dir
用dir作为头文件和库文件的逻辑根目录,例如,正常情况下,如果编译器在/usr/include搜索头文件,在/usr/lib下搜索库文件,它将用dir/usr/include和dir/usr/lib替代原来的相应路径。如果你同时使用了-isysroot选项,则—sysroot会应用于库文件的搜索而-isysroot会用于搜索头文件。

-system dir
该选项用于搜索头文件,但该选项指定的目录估在-I选项指定的目录后搜索而在系统默认路径前搜索。如果dir前有“=”号,则该“=”号会被sysroot前缀替换。

-iquotedir
增加用于搜索#include “file”类型的头文件的路径,并且不搜索#include类型的头文件,要不就和-I选项一样了。

-Ldir
增加-l选项指定的库文件的搜索路径,即编译器会到dir路径下搜索-l指定的库文件。

-Bprefix
这个选项指定GCC到哪去查找自己的可执行文件、库文件、头文件和数据文件。编译器驱动程序运行一个或多个子程序如ccp,cc1,as,ld。当编译器需要运行某个子程序时,它将prefix作业子程序的前缀(如prefix/as)。为了正确运行每个子程序,编译器驱动程序首先-B选项指定的前缀,如果那个可文件(如prefix/as)没有查找到或者没有指定-B选项,则编译器驱动程序将尝试使用标准前缀:/usr/lib/gcc/ 和/usr/local/lib/gcc/。如果用这两个前缀也没查找到,则使用没有修改过的程序名(如as)在PATH环境变量指定的路径下查找。

编译器会核查-B选项提供的前缀(目录),必要情况下编译器会在最后加一个分隔符。如-B/usr/bin 则最后的前缀会为:/usr/bin/,编译器在最后增加了分隔符。

-B选项指定的前缀同样对链接器查找库文件有效,因为编译器会将该选项转换为-L选项。另外-B选项同样也对预处理器查找头文件时有效,因为编译器会将该选项转换为预处理器中的-isystem选项,在这种情况下,编译器会在prefix最后加上“include”即prefix/include。

如果需要,运行时库文件“libgcc.a”同样会通过-B选项指定的前缀来查找,如果没找到,则接着会尝试用上面提到的那两个标准前缀查找,如果还没有找到,则会忽略掉对libgcc.a的链接。

另外一种指定prefix前缀的方式是通过环境变量GCC_EXEC_PREFIX来指定,不过会在-B选项指定的前缀之后搜索。即先尝试用-B选项指定的前缀再尝试使用GCC_EXEC_PREFIX指定的前缀,再用标准前缀。其实前面提到的两个标准前缀应该是在安装编译器是指它的!!所以每个系统可能还不一样。

-specs=file
为了复盖GCC传递给cc1、cc1plus、as、ld等子程序的默认开关选项,编译器会在读取标准的“specs”文件后再处理file文件。如果在-specs中指定了多个文件,则这些文件会被按照从左到右的顺序来处理。

-print-file-name=library
打印出链接时将用到的library的绝对路径,这样可以看看链接的是不是确实是自己想要的库文件。

-print-libgcc-file-name
打印出所使用的libgcc.a文件的路径,这个特别是在使用了-nostdlib或者-nodefaultlibs选项时有用。等价于-print-file-name=libgcc.a

-print-search-dirs
打印出GCC安装路径、程序列表和GCC标准的默认搜索路径。

-print-sysroot-headers-suffix
打印出头文件的根目录。

-dumpmachine
打印出GCC编译的程序的目标机器。

-dumpspecs
打印出GCC的内建specs文件,这个文件在编译GCC时会用到
GCC_EXEC_PREFIX
该环境变量用于指定编译器子程序(如as,cc1等)的前缀,编译器不会给该前缀增加“/”,但你可以自己增加。如果GCC_EXEC_PREFIX变量没有设置的话,GCC会尝试gcc所在路径为前缀。如果用指定的前缀没有找到子程序的话,GCC将在默认位置查找子程序。
GCC_EXEC_PREFIX的默认值为:‘prefix/lib/gcc/’这里的prefix为安装gcc时指定的prefix,一般与configure配置时指定的一样。
用-B指定的前缀会在该环境变量前缀前先搜索。该环境变量指定的前缀同样也用于查找链接所需的文件如“crt0.o”.
除此之外,GCC还用这个指定的前缀来搜索头文件,对于一个标准头文件的目录来说一般都以“/usr/local/lib/gcc”(更精确定的是用GCC_INCLUDE_DIR来指定),GCC首先会尝试用GCC_EXEC_PREFIX指定的前缀去替换掉“/usr/local/lib/gcc”查找头文件,然后才在标准的前缀目录下搜索头文件。

COMPILER_PATH
GCC在该环境变量指定的目录下查找子程序,但是会在GCC_EXEC_PREFIX指定的目录后搜索。

LIBRARY_PATH
GCC如果在GCC_EXEC_PREFIX没有找到链接文件的话,然后会在该环境变量指定的目录下查找链接文件,另外还在-L指定的目录后搜索。

CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH

这些变量指定的目录的分隔符为分号(windows),或者为冒号(linux)。CPATH指定的路径的功能与-I项指定的一样,只是会在-I选项指定的目录后查找,另外对任何语言都适用。其它的两个环境变量是对特定语言的,同-isystem选项一样,但会在-system选项指定的目录后搜索。在这些环境变量中,一个空的元素是指示编译器在当前目录下查找。

5 警告选项

5.1 基本使用

-w
禁止编译警告的打印。这个警告不建议使用。Makefile里面默认使用了-w,因而代码一直没有警告,而一些代码笔误很容易导致的BUG,而这些问题可以从编译警告中知道,不建议使用-w选项。

-Werror
将所有的警告当成错误处理。此选项谨慎建议加上。有的开源库警告很多(大名鼎鼎的ffmpeg也有很多警告呢),一一改掉耗时耗人力,必要性也不大。

-Wfatal-errors
遇到第一个错误就停止,减少查找错误时间。建议加上。很多人遇到错误,没有意识到从第一个开始排查。不管是编译错误,还是程序运行出错,从最开始的错误查起,是个好的做法。

-Wall
开启“所有”的警告。强烈建议加上,并推荐该选项成为共识。如case语句没有default处理,有符号、无符号处理,未使用变量(特别是函数有大量未使用的数组,占用栈空间,测试发现,开辟一个未使用的8MB的数组,程序有coredump),用%d来打印地址,或%s打印int值,等,都可以发出警告。

-Wextra
除-Wall外其它的警告。建议加上。
在GCC编译时,加上必要的警告选项,可以避免很多低级错误引发的问题,我就在实际工程代码中遇到用“==”来赋值,我自己写的代码也出现过把“=”当成判断的。但是,有些错误却不是用GCC选项能解决的。比如一般项目都会自定义调试信息打印函数,但在处理可变参数类型时,往往不注意。

5.2 具体使用

-Wall选项,顾名思义,就是“所有”的意思,它包括:
GCC编译选项参数_第2张图片
GCC编译选项参数_第3张图片
-Wall不会激活的警告选项:
GCC编译选项参数_第4张图片

6 优化选项

gcc默认提供了5级优 化选项的集合:
-O0:无优化(默认)
-O和-O1:使用能减少目标文件大小以及执行时间并且不会使编译时间明显增加的优化。在编译大型程序的时候会显著增加编译时内存的使用。
-O2::包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。编译器不执行循环展开以及函数内联。此选项将增加编译时间和目标文件的执行性能。
-Os:专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项.并且执行专门减小目标文件大小的优化选项。
-O3::打开所有-O2的优化选项并且增加 -finline-functions,,-funswitch-loops,-fpredictive-commoning,,-fgcse-after-reload 和 -ftree-vectorize优化选项。

-O1包含的选项-O1通常可以安全的和调试的选项一起使用:
-fauto-inc-dec -fcprop-registers -fdce -fdefer-pop -fdelayed-branch
-fdse -fguess-branch-probability -fif-conversion2 -fif-conversion
-finline-small-functions -fipa-pure-const -fipa-reference
-fmerge-constants -fsplit-wide-types -ftree-ccp -ftree-ch
-ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse
-ftree-fre -ftree-sra -ftree-ter -funit-at-a-time
以下所有的优化选项需要在名字 前加上-f,如果不需要此选项可以使用-fno-:
defer-pop: 延迟到只在必要时从函数参数栈中pop参数;
thread- jumps:使用跳转线程优化,避免跳转到另一个跳转;
branch-probabilities:分支优化;
cprop-registers:使用寄存器之间copy-propagation传值;
guess-branch-probability:分支预测;
omit-frame-pointer:可能的情况下不产生栈帧;

-O2:以下是-O2在-O1基础上增加的优化选项:
-falign-functions -falign-jumps -falign-loops -falign-labels
-fcaller-saves -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks -fexpensive-optimizations -fgcse
-fgcse-lm -foptimize-sibling-calls -fpeephole2 -fregmove
-freorder-blocks -freorder-functions -frerun-cse-after-loop
-fsched-interblock -fsched-spec -fschedule-insns
-fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-pre
-ftree-vrp
cpu架构的优化选项,通常是-mcpu(将被取消),-march,-mtune

7 ARM架构相关的选项

-mabi=name
为指定的ABI生成代码。参数选项有:apcs-gnu’, ‘atpcs’, ‘aapcs’, ‘aapcs-linux’ and ‘iwmmxt’。

-mapcs-frame
生成对于所有功能都符合《 ARM过程调用标准》的堆栈框架,即使对于正确执行代码并非绝对必要。-fomit-frame-pointer,则不会为叶函数生成堆栈帧。默认是-mno-apcs-frame。不建议使用此选项。

-mthumb-interwork
生成支持ARM和Thumb指令集之间调用的代码。如果没有此选项,则在v5之前的体系结构上,无法在一个程序中可靠地使用两个指令集。默认是-mno-thumb-interwork。

-mno-sched-prolog
防止对函数序言中的指令进行重新排序,或防止将这些指令与函数主体中的指令合并。这意味着所有功能都以一组可识别的指令开始(或者实际上是从一小组不同功能序言中选择的一个),并且该信息可用于在可执行代码段中定位功能的开始。默认是-msched-prolog。

-mfloat-abi=name
指定要使用的浮点ABI类型。参数选项有:‘soft’, ‘softfp’ and ‘hard’。
soft:导致GCC生成包含浮点运算库调用的输出;
softfp:允许使用硬件浮点指令生成代码,但仍使用软浮点调用约定;
hard:允许生成浮点指令并使用FPU特定的调用约定。

-mlittle-endian
为在低端模式下运行的处理器生成代码。这是所有标准配置的默认设置。

-mbig-endian
为以big-endian模式运行的处理器生成代码;默认情况是为小端处理器编译代码。

-march=name
这指定了目标ARM体系结构的名称。GCC使用此名称来确定生成汇编代码时可以发出的指令类型。此选项可与或结合使用-mcpu=option。参数选项有:armv2’, ‘armv2a’, ‘armv3’, ‘armv3m’, ‘armv4’, ‘armv4t’, ‘armv5’, ‘armv5e’, ‘armv5t’, ‘armv5te’, ‘armv6’, ‘armv6-m’, ‘armv6j’, ‘armv6k’, ‘armv6kz’, ‘armv6s-m’, ‘armv6t2’, ‘armv6z’, ‘armv6zk’, ‘armv7’, ‘armv7-a’, ‘armv7-m’, ‘armv7-r’, ‘armv7e-m’, ‘armv7ve’, ‘armv8-a’, ‘armv8-a+crc’, ‘armv8.1-a’, ‘armv8.1-a+crc’, ‘armv8-m.base’, ‘armv8-m.main’, ‘armv8-m.main+dsp’, ‘iwmmxt’, ‘iwmmxt2’。
早于“armv4t已弃用。
-march=armv6s-m 是个 'armv6-m支持(现在强制)SVC指令的架构。
-march=armv6zk 是“armv6kz”的别名,为了向后兼容而存在。
-march=armv7ve 是 “armv7-a”具有虚拟化扩展的架构。
-march=armv8-a+crc 支持ARMv8-A架构的代码生成以及可选的CRC32扩展。
-march=armv8.1-a启用对ARMv8.1-A体系结构的编译器支持。这也启用了-march=armv8-a + crc。
-march=armv8.2-a启用对ARMv8.2-A架构的编译器支持。这也启用了-march=armv8.1-a。
-march=armv8.2-a+fp16通过可选的FP16指令扩展支持编译器对ARMv8.2-A架构的支持。这也启用了-march=armv8.1-a,并隐式定义 -mfp16-format=ieee。
-march=armv8.2-a+dotprod通过可选的“Dot”指令扩展,启用对ARMv8.2-A架构的编译器支持。这也启用了-march=armv8.1-a。
-march=armv8.2-a+fp16+dotprod通过可选的FP16和“Dot”指令扩展,为ARMv8.2-A体系结构提供编译器支持。这也启用了-march=armv8.1-a 并暗示 -mfp16-format=ieee。
-march=native
使编译器自动检测构建计算机的体系结构。目前,仅GNU / Linux支持此功能,并且并非所有体系结构都可以识别。如果自动检测失败,则该选项无效。

-mtune=name
此选项指定GCC为其调整代码性能的目标ARM处理器的名称。对于某些ARM实现,可以使用此选项获得更好的性能。参数选项有:arm2’, ‘arm250’, ‘arm3’, ‘arm6’, ‘arm60’, ‘arm600’, ‘arm610’, ‘arm620’, ‘arm7’, ‘arm7m’, ‘arm7d’, ‘arm7dm’, ‘arm7di’, ‘arm7dmi’, ‘arm70’, ‘arm700’, ‘arm700i’, ‘arm710’, ‘arm710c’, ‘arm7100’, ‘arm720’, ‘arm7500’, ‘arm7500fe’, ‘arm7tdmi’, ‘arm7tdmi-s’, ‘arm710t’, ‘arm720t’, ‘arm740t’, ‘strongarm’, ‘strongarm110’, ‘strongarm1100’, ‘strongarm1110’, ‘arm8’, ‘arm810’, ‘arm9’, ‘arm9e’, ‘arm920’, ‘arm920t’, ‘arm922t’, ‘arm946e-s’, ‘arm966e-s’, ‘arm968e-s’, ‘arm926ej-s’, ‘arm940t’, ‘arm9tdmi’, ‘arm10tdmi’, ‘arm1020t’, ‘arm1026ej-s’, ‘arm10e’, ‘arm1020e’, ‘arm1022e’, ‘arm1136j-s’, ‘arm1136jf-s’, ‘mpcore’, ‘mpcorenovfp’, ‘arm1156t2-s’, ‘arm1156t2f-s’, ‘arm1176jz-s’, ‘arm1176jzf-s’, ‘generic-armv7-a’, ‘cortex-a5’, ‘cortex-a7’, ‘cortex-a8’, ‘cortex-a9’, ‘cortex-a12’, ‘cortex-a15’, ‘cortex-a17’, ‘cortex-a32’, ‘cortex-a35’, ‘cortex-a53’, ‘cortex-a57’, ‘cortex-a72’, ‘cortex-a73’, ‘cortex-r4’, ‘cortex-r4f’, ‘cortex-r5’, ‘cortex-r7’, ‘cortex-r8’, ‘cortex-m33’, ‘cortex-m23’, ‘cortex-m7’, ‘cortex-m4’, ‘cortex-m3’, ‘cortex-m1’, ‘cortex-m0’, ‘cortex-m0plus’, ‘cortex-m1.small-multiply’, ‘cortex-m0.small-multiply’, ‘cortex-m0plus.small-multiply’, ‘exynos-m1’, ‘marvell-pj4’, ‘xscale’, ‘iwmmxt’, ‘iwmmxt2’, ‘ep9312’, ‘fa526’, ‘fa626’, ‘fa606te’, ‘fa626te’, ‘fmp626’, ‘fa726te’, ‘xgene1’。
另外,此选项可以指定GCC应该为big.LITTLE系统调整代码的性能。参数选项有:cortex-a15.cortex-a7’, ‘cortex-a17.cortex-a7’, ‘cortex-a57.cortex-a53’, ‘cortex-a72.cortex-a53’, ‘cortex-a72.cortex-a35’, ‘cortex-a73.cortex-a53’。

-mtune=generic-arch指定GCC应该为架构arch中的处理器混合调整性能。目的是生成可在当前最流行的处理器上良好运行的代码,在使该范围内的某些CPU受益的优化之间取得平衡,并避免其他CPU的性能缺陷。 随着CPU型号的出现,此选项的影响在将来的GCC版本中可能会发生变化。

-mtune=native使编译器自动检测生成计算机的CPU。目前,仅GNU / Linux支持此功能,并且并非所有体系结构都可以识别。如果自动检测失败,则该选项无效。

-mcpu=name
这指定目标ARM处理器的名称。 GCC使用该名称来推导目标ARM体系结构的名称(如由-march指定)和要针对其性能进行调整的ARM处理器类型(如由-mtune指定)。 如果将此选项与-march或-mtune结合使用,则这些选项优先于此选项的适当部分。
此选项的允许名称与-mtune的名称相同。
-mcpu = generic-arch也是允许的,并且等效于-march = arch -mtune = generic-arch。 有关更多信息,请参见-mtune。
-mcpu = native使编译器自动检测构建计算机的CPU。 目前,仅GNU / Linux支持此功能,并且并非所有体系结构都可以识别。 如果自动检测失败,则该选项无效。

-mfpu=name
这指定目标上可用的浮点硬件(或硬件仿真)。参数选项有:vfpv2’, ‘vfpv3’, ‘vfpv3-fp16’, ‘vfpv3-d16’, ‘vfpv3-d16-fp16’, ‘vfpv3xd’, ‘vfpv3xd-fp16’, ‘neon-vfpv3’, ‘neon-fp16’, ‘vfpv4’, ‘vfpv4-d16’, ‘fpv4-sp-d16’, ‘neon-vfpv4’, ‘fpv5-d16’, ‘fpv5-sp-d16’, ‘fp-armv8’, ‘neon-fp-armv8’ and ‘crypto-neon-fp-armv8’。”neon”是”neon-vfpv3”的别名,”vfp”是”vfpv2”的别名。

如果指定了-msoft-float,则指定浮点值的格式。

如果所选浮点硬件包括NEON扩展名(例如-mfpu =“ neon”),请注意,除非也指定了-funsafe-math-optimizations,否则GCC的自动矢量化过程不会生成浮点运算。 这是因为NEON硬件没有完全实现IEEE 754标准的浮点运算(特别是将非正规值视为零),因此使用NEON指令可能会导致精度下降。

-mfp16-format =name
指定__fp16半精度浮点类型的格式。允许的名称为“ none”,“ ieee”和“ alternate”;默认值为“无”,在这种情况下未定义__fp16类型。有关更多信息,请参见半精度。

-mstructure-size-boundary = n
所有结构和联合的大小均四舍五入为该选项设置的位数的倍数。允许值为8、32和64。默认值因工具链而异。对于以COFF为目标的工具链,默认值为8。仅在基础ABI支持时,才允许使用64。

指定更大的数字可以生成更快,更有效的代码,但也可以增加程序的大小。不同的值可能不兼容。如果使用结构或联合交换信息,则用一个值编译的代码不一定期望与使用另一值编译的代码或库一起工作。

-mabort-on-noreturn
在noreturn函数结束时生成对函数abort的调用。 如果函数尝试返回,则执行它。

-mlong-calls
-mno-long-calls

通过首先将函数的地址加载到寄存器中,然后对该寄存器执行子例程调用,来告诉编译器执行函数调用。如果目标函数位于子例程调用指令的基于偏移量的版本的64 MB寻址范围之外,则需要此开关。
即使启用此开关,也不是所有功能调用都变成长调用。启发式方法是:静态函数,具有short_call属性的函数,在#pragma no_long_calls指令范围内的函数以及定义已在当前编译单元中编译的函数不会转换为长调用。该规则的例外是弱函数定义,具有long_call属性或section属性的函数以及在#pragma long_calls指令范围内的函数始终会转换为长调用。

默认情况下不启用此功能。指定-mno-long-calls可以恢复默认行为,就像将函数调用放在#pragma long_calls_off指令的范围内一样。注意,这些开关对编译器如何生成代码以通过函数指针处理函数调用没有影响。

-ms-pic-base
将用于PIC寻址的寄存器视为只读,而不是将其加载到每个功能的序言中。 运行系统负责在执行开始之前使用适当的值初始化该寄存器。

-mpic-register=reg
指定用于PIC寻址的寄存器。 对于标准PIC基本情况,默认值为编译器确定的任何合适的寄存器。 对于单个PIC基本情况,如果目标是基于EABI的或启用了堆栈检查,则默认值为“ R9”,否则默认值为“ R10”。

-mpic数据是相对文本
假定文本段和数据段之间的位移在静态链接时间是固定的。 这允许使用相对于PC的寻址操作来访问已知在数据段中的数据。 对于非VxWorks RTP目标,默认情况下启用此选项。 在此类目标上禁用时,默认情况下将启用-msingle-pic-base。

-mthumb
-marm

在生成以ARM和Thumb状态执行的代码之间进行选择。 大多数配置的默认设置是生成在ARM状态下执行的代码,但是可以通过使用–with-mode = state configure选项配置GCC来更改默认设置。
您还可以通过使用target(“ thumb”)和target(“ arm”)函数属性(请参见ARM Function Attributes)或编译指示(请参见Function Specific Option Pragmas)来覆盖每个功能的ARM和Thumb模式。

-mtpcs-frame
为所有非叶函数生成一个与Thumb过程调用标准兼容的堆栈框架。 (叶函数是不调用任何其他函数的函数。)缺省值为-mno-tpcs-frame。

-mtpcs-leaf-frame
为所有叶子函数生成一个符合Thumb过程调用标准的堆栈框架。 (叶函数是不调用任何其他函数的函数。)缺省值为-mno-apcs-leaf-frame。

-mcallee-super-interworking
为正在编译的文件中的所有外部可见函数提供ARM指令集标头,该标头在执行其余功能之前会切换到Thumb模式。这允许从非交互代码中调用这些功能。此选项在AAPCS配置中无效,因为默认情况下启用了互通。

-mcaller-super-interworking
允许通过函数指针(包括虚拟函数)进行的调用正确执行,而不管目标代码是否已为互通而编译。如果启用此选项,则执行函数指针的开销很小。此选项在AAPCS配置中无效,因为默认情况下启用了互通。

-mtp=name
指定线程本地存储指针的访问模型。有效的模型是“软”和“自动”,分别对__aeabi_read_tp和cpae进行调用,而cp15从cp15直接获取线程指针(在arm6k架构中受支持),而auto则对所选处理器使用最佳可用方法。默认设置为“自动”。

-mtls-dialect=dialect
指定用于访问线程本地存储的方言。支持两种方言-“ gnu”和“ gnu2”。 “ gnu”方言选择了原始的GNU方案来支持本地和全局动态TLS模型。 “ gnu2”方言选择了GNU描述符方案,该方案为共享库提供了更好的性能。 GNU描述符方案与原始方案兼容,但确实需要新的汇编器,链接器和库支持。初始和本地exec TLS模型不受此选项的影响,并且始终使用原始方案。

-mword-relocations
仅对字大小的值(即R_ARM_ABS32)生成绝对重定位。默认情况下,在运行时加载程序施加此限制的目标(uClinux,SymbianOS)上,并且在指定-fpic或-fPIC时,将启用此功能。

-mfix-cortex-m3-ldrd
当使用目标地址和基址寄存器重叠的ldrd指令时,某些Cortex-M3内核可能会导致数据损坏。此选项避免生成这些指令。当指定-mcpu = cortex-m3时,默认情况下启用此选项。

-munaligned-access
-mno-unaligned-access

启用(或禁用)未对齐16位或32位地址的16位和32位值的读取和写入。默认情况下,对所有ARMv6之前的版本,所有ARMv6-M和ARMv8-M基准体系结构禁用未对齐访问,并对所有其他体系结构启用未对齐访问。如果未启用未对齐访问,则一次访问一个打包数据结构中的字一个字节。

根据此选项的设置,在生成的目标文件中将ARM属性Tag_CPU_unaligned_access设置为true或false。如果启用了未对齐访问,则还将定义预处理器符号__ARM_FEATURE_UNALIGNED。

-mneon-for-64bits
允许使用Neon处理标量64位操作。由于将数据从核心寄存器移至Neon的成本很高,因此默认情况下禁用此功能。

-mslow-flash-data
假设从闪存加载数据比获取指令要慢。因此,字面负载被最小化以获得更好的性能。仅当编译ARMv7 M-profile时才支持此选项,并且默认情况下处于禁用状态。

-masm-syntax-unified
假设内联汇编器使用统一的asm语法。当前默认关闭,这意味着语法已分开。此选项对Thumb2没有影响。但是,这可能会在以后的GCC版本中发生变化。分开的语法应视为已弃用。

-mrestrict-it
限制IT块的生成以符合ARMv8的规则。 IT块只能包含一组选定指令中的单个16位指令。对于ARMv8拇指模式,此选项默认为打开。

-mprint-tune-info
将CPU调整信息打印为汇编文件中的注释。此选项仅用于编译器的回归测试,不适用于编译代码中的常规用途。默认情况下禁用此选项。

-mpure-code
不允许将常量数据放在代码段中。此外,在编译ELF对象格式时,请为所有文本节提供ELF处理器特定的节属性SHF_ARM_PURECODE。仅当为ARMv7-M目标生成非图片代码时,此选项才可用

8 调试选项

在gcc编译源代码时指定-g选项可以产生带有调试信息的目标代码,gcc可以为多个不同平台上帝不同调试器提供调试信息,默认gcc产生的调试信息是为gdb使用的,可以使用-gformat 指定要生成的调试信息的格式以提供给其他平台的其他调试器使用.常用的格式有:

-ggdb:生成gdb专用的调试信息,使用最适合的格式(DWARF 2,stabs等)会有一些gdb专用的扩展,可能造成其他调试器无法运行。

-gstabs:使用 stabs格式,不包含gdb扩展,stabs常用于BSD系统的DBX调试器。

-gcoff:产生COFF格式的调试信息,常用于System V下的SDB调试器。

-gxcoff:产生XCOFF格式的调试信息,用于IBM的RS/6000下的DBX调试器。

-gdwarf-2:产生DWARF version2 的格式的调试信息,常用于IRIXX6上的DBX调试器。GCC会使用DWARF version3的一些特性。

可以指定调试信息的等级:在指定的调试格式后面加上等级:
如:-ggdb2 等,0代表不产生调试信息,在使用-gdwarf-2时因为最早的格式为-gdwarf2会造成混乱,所以要额外使用一个-glevel来指定调试信息的等级,其他格式选项也可以另外指定等级。
gcc可以使用-p选项指定生成信息以供porf使用。

9 其他选项

Standard options:
GCC编译选项参数_第5张图片
C options:
GCC编译选项参数_第6张图片
C++ options:
GCC编译选项参数_第7张图片
Machine options:
GCC编译选项参数_第8张图片

你可能感兴趣的:(GNU浅学,GCC,gcc编译选项,GCC优化)