gcc编译优化系列gcc编译链接时候--specs=kernel.specs链接属性究竟是个啥?

Posted 架构师李肯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gcc编译优化系列gcc编译链接时候--specs=kernel.specs链接属性究竟是个啥?相关的知识,希望对你有一定的参考价值。


1 问题来源

近来关注rt-thread的论坛稍微少了一些,今天突然在论坛里面看到这么一个问题

为何会对这个问题感兴趣呢?
主要有以下两个原因:

  • 最近都在研究一些gcc编译链接相关的知识,做了一些笔记,方便自己加深理解和记忆;
  • 这个specs选项,隐约记得在哪里见过,但是又记不清楚来龙去脉,看来还是记忆不够深刻。

于是乎,我决定趁着这个机会,好好扒一扒这个specs选项。

2 初步分析

2.1 内事不决问百度,外事不决问谷歌

二话不说,先baidu之,如下:

没找到合适的,那google一下?无奈,没有梯子,那就bing一下吧:

问题答案没找到,倒是把问题自己给找到了。

2.2 开发不懂问‘男人’

都说男人靠得住,母猪都上树,但是作为一个长期混迹在Linux开发环境下的程序猿,我可以很负责任地告诉,男人是最不会骗人的,不信你man一下:

recan@ubuntu:~$ man gcc | grep "specs"
           -specs=file  -wrapper @file  -ffile-prefix-map=old=new -fplugin=file  -fplugin-arg-name=arg -fdump-ada-spec[-slim]
           -fconstexpr-loop-limit=n -fconstexpr-ops-limit=n -fno-elide-constructors -fno-enforce-eh-specs -fno-gnu-keywords
           -dletters  -dumpspecs  -dumpmachine  -dumpversion -dumpfullversion  -fchecking  -fchecking=n  -fdbg-cnt-list
           -mshort-calls -nodevicelib  -nodevicespecs -Waddr-space-convert  -Wmisspelled-isr
           declaration).  Such files are also called specs.
       -specs=file
           Process file after the compiler reads in the standard specs file, in order to override the defaults which the gcc
           driver program uses when determining what switches to pass to cc1, cc1plus, as, ld, etc.  More than one -specs=file
           For C and C++ source and include files, generate corresponding Ada specs.
           In conjunction with -fdump-ada-spec[-slim] above, generate Ada specs as child units of parent unit.
       -fno-enforce-eh-specs
           used in filesystem paths and specs. Depending on how the compiler has been configured it can be just a single number
       -dumpspecs
           Print the compiler's built-in specs---and don't do anything else.  (This is used when GCC itself is being built.)
troff: <standard input>:17361: warning [p 110, 20.7i]: can't break line
       -nodevicespecs
           Don't add -specs=device-specs/specs-<mcu> to the compiler driver's command line.  The user takes responsibility for
           (/usr/lpp/ppe.poe/), or the specs file must be overridden with the -specs= option to specify the appropriate

这句命令行的意思就是在man gcc的结果里面搜索specs关键字,注意仔细看,我们发现了有-specs=file这个关键信息,不用猜,就是它了。
为了更好地说明,我把这段描述完整地拎出来:

-specs=file
           Process file after the compiler reads in the standard specs file, in order to override the defaults which the gcc
           driver program uses when determining what switches to pass to cc1, cc1plus, as, ld, etc.  More than one -specs=file
           can be specified on the command line, and they are processed in order, from left to right.

需要点英文理解能力,但是语意并不难,实在不行,用翻译软件也可以搞定:

-specs=文件
编译器读入标准规范文件后处理文件,以覆盖gcc使用的默认值
驱动程序用于确定要传递给cc1、cc1plus、as、ld等的开关。多个-specs=文件
可以在命令行上指定,并按从左到右的顺序处理。

OK,意思已经很明确了,就是用于覆盖gcc默认的传递参数,这些新的参数是在一个新的文件里面里面指定,比如问题中的就是kernel.specs

2.3 gcc默认的specs参数

如果你好好读man gcc的返回,你会发现有这么一个-dumpspec选项,它就是记录了gcc默认的specs参数,为了说明下specs文件长啥样,我把它导出来看看:(说明下,我这个是x64环境下的gcc,如果是交叉编译的gcc,替换对应的gcc即可,方法都是一样的。)

recan@ubuntu:~$ gcc -dumpspecs > default.specs
recan@ubuntu:~$ 
recan@ubuntu:~$ cat default.specs 
*asm:
%m16|m32:--32  %m16|m32|mx32:;:--64  %mx32:--x32  %msse2avx:%!mavx:-msse2avx

*asm_debug:
%%:debug-level-gt(0):%gstabs*:--gstabs%!gstabs*:%g*:--gdwarf2 %fdebug-prefix-map=*:--debug-prefix-map %*

*asm_final:
%gsplit-dwarf: 
       objcopy --extract-dwo     %c:%o*:%*%!o*:%b%O%!c:%U%O      %c:%o*:%:replace-extension(%o*:%* .dwo)%!o*:%b.dwo%!c:%b.dwo 
       objcopy --strip-dwo       %c:%o*:%*%!o*:%b%O%!c:%U%O     

*asm_options:
%-target-help:%:print-asm-header() %v %w:-W %I*  %gz|gz=zlib:--compress-debug-sections=zlib %gz=none:--compress-debug-sections=none %gz=zlib-gnu:--compress-debug-sections=zlib-gnu %a %Y %c:%Wo*%!o*:-o %w%b%O%!c:-o %d%w%u%O

*invoke_as:
%!fwpa*:   %fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()   %!S:-o %|.s |
 as %(asm_options) %m.s %A   

*cpp:
%posix:-D_POSIX_SOURCE %pthread:-D_REENTRANT

*cpp_options:
%(cpp_unique_options) %1 %m* %std*&ansi&trigraphs %W*&pedantic* %w %f* %g*:%%:debug-level-gt(0):%g* %!fno-working-directory:-fworking-directory %O* %undef %save-temps*:-fpch-preprocess %(distro_defaults)

*cpp_debug_options:
%d*

*cpp_unique_options:
%!Q:-quiet %nostdinc* %C %CC %v %@I*&F* %P %I %MD:-MD %!o:%b.d%o*:%.d%* %MMD:-MMD %!o:%b.d%o*:%.d%* %M %MM %MF* %MG %MP %MQ* %MT* %!E:%!M:%!MM:%!MT:%!MQ:%MD|MMD:%o*:-MQ %* %remap %g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD %!iplugindir*:%fplugin*:%:find-plugindir() %H %C %D*&U*&A* %i* %Z %i %E|M|MM:%Wo*

*trad_capable_cpp:
cc1 -E %traditional|traditional-cpp:-traditional-cpp

*cc1:
%!mandroid|tno-android-cc:%(cc1_cpu) %profile:-p;:%(cc1_cpu) %profile:-p %!mglibc:%!muclibc:%!mbionic: -mbionic %!fno-pic:%!fno-PIC:%!fpic:%!fPIC: -fPIC

*cc1_options:
%pg:%fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible %!iplugindir*:%fplugin*:%:find-plugindir() %1 %!Q:-quiet %!dumpbase:-dumpbase %B %d* %m* %aux-info* %fcompare-debug-second:%:compare-debug-auxbase-opt(%b)  %!fcompare-debug-second:%c|S:%o*:-auxbase-strip %*%!o*:-auxbase %b%!c:%!S:-auxbase %b  %g* %O* %W*&pedantic* %w %std*&ansi&trigraphs %v:-version %pg:-p %p %f* %undef %Qn:-fno-ident %Qy: %-help:--help %-target-help:--target-help %-version:--version %-help=*:--help=%* %!fsyntax-only:%S:%Wo*%!o*:-o %b.s %fsyntax-only:-o %j %-param* %coverage:-fprofile-arcs -ftest-coverage %fprofile-arcs|fprofile-generate*|coverage:   %!fprofile-update=single:     %pthread:-fprofile-update=prefer-atomic

*cc1plus:


*link_gcc_c_sequence:
%static|static-pie:--start-group %G %!nolibc:%L    %static|static-pie:--end-group%!static:%!static-pie:%G

*distro_defaults:
%!fno-asynchronous-unwind-tables:-fasynchronous-unwind-tables %!fno-stack-protector:%!fstack-protector-all:%!ffreestanding:%!nostdlib:%!fstack-protector:-fstack-protector-strong %!Wformat:%!Wformat=2:%!Wformat=0:%!Wall:-Wformat %!Wno-format-security:-Wformat-security %!fno-stack-clash-protection:-fstack-clash-protection %!fcf-protection*:%!fno-cf-protection:-fcf-protection

*link_ssp:
%fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:

*endfile:
%!mandroid|tno-android-ld:%Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s    %mpc32:crtprec32.o%s    %mpc64:crtprec64.o%s    %mpc80:crtprec80.o%s %fvtable-verify=none:%s;      fvtable-verify=preinit:vtv_end_preinit.o%s;      fvtable-verify=std:vtv_end.o%s    %static:crtend.o%s;      shared|static-pie|!no-pie:crtendS.o%s;      :crtend.o%s crtn.o%s %fopenacc|fopenmp:crtoffloadend%O%s;:%Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s    %mpc32:crtprec32.o%s    %mpc64:crtprec64.o%s    %mpc80:crtprec80.o%s %shared: crtend_so%O%s;: crtend_android%O%s

*link:
%!r:--build-id %!static|static-pie:--eh-frame-hdr %!mandroid|tno-android-ld:%m16|m32|mx32:;:-m elf_x86_64                

以上是关于gcc编译优化系列gcc编译链接时候--specs=kernel.specs链接属性究竟是个啥?的主要内容,如果未能解决你的问题,请参考以下文章

gcc 的基本使用

(Linux)gcc进行优化编译的参数是啥?

gcc的常用编译命令

静态库与动态库

基于GCC的编译器的优化等级的执行原理

linux下c语言gcc编译的时候如果不知道.c文件怎么链接的?