1 【GCC编译优化系列】-specs=kernel.specs-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【GCC编译优化系列】-specs=kernel.specs

嵌入式物联网开发 来源:嵌入式物联网开发 作者:嵌入式物联网开发 2022-07-11 09:25 次阅读

【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: :17361: warning [p 110, 20.7i]: can't break line
       -nodevicespecs
           Don't add -specs=device-specs/specs- 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:%W{o*}%{!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:%W{o*}}

*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:%W{o*}%{!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}                    %{m16|m32:-m elf_i386}                    %{mx32:-m elf32_x86_64}   --hash-style=gnu   --as-needed   %{shared:-shared}   %{!shared:     %{!static:       %{!static-pie:     %{rdynamic:-export-dynamic}     %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-i386.so.1;:/lib/ld-linux.so.2}}}}       %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:%{mmusl:/lib/ld-musl-x86_64.so.1;:/lib64/ld-linux-x86-64.so.2}}}}         %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:%{mmusl:/lib/ld-musl-x32.so.1;:/libx32/ld-linux-x32.so.2}}}}}}     %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}};:%{m16|m32|mx32:;:-m elf_x86_64}                    %{m16|m32:-m elf_i386}                    %{mx32:-m elf32_x86_64}   --hash-style=gnu   --as-needed   %{shared:-shared}   %{!shared:     %{!static:       %{!static-pie:      %{rdynamic:-export-dynamic}     %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-i386.so.1;:/lib/ld-linux.so.2}}}}       %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:%{mmusl:/lib/ld-musl-x86_64.so.1;:/lib64/ld-linux-x86-64.so.2}}}}     %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:%{mmusl:/lib/ld-musl-x32.so.1;:/libx32/ld-linux-x32.so.2}}}}}}     %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}} %{shared: -Bsymbolic}}

*lib:
%{!mandroid|tno-android-ld:%{pthread:-lpthread} %{shared:-lc}    %{!shared:%{profile:-lc_p}%{!profile:-lc}};:%{shared:-lc}    %{!shared:%{profile:-lc_p}%{!profile:-lc}} %{!static: -ldl}}

*link_gomp:


*libgcc:
%{static|static-libgcc|static-pie:-lgcc -lgcc_eh}%{!static:%{!static-libgcc:%{!static-pie:%{!shared-libgcc:-lgcc --push-state --as-needed -lgcc_s --pop-state}%{shared-libgcc:-lgcc_s%{!shared: -lgcc}}}}}

*startfile:
%{!mandroid|tno-android-ld:%{shared:;      pg|p|profile:%{static-pie:grcrt1.o%s;:gcrt1.o%s};      static:crt1.o%s;      static-pie:rcrt1.o%s;      !no-pie:Scrt1.o%s;      :crt1.o%s} crti.o%s    %{static:crtbeginT.o%s;      shared|static-pie|!no-pie:crtbeginS.o%s;      :crtbegin.o%s}    %{fvtable-verify=none:%s;      fvtable-verify=preinit:vtv_start_preinit.o%s;      fvtable-verify=std:vtv_start.o%s} %{fopenacc|fopenmp:crtoffloadbegin%O%s};:%{shared: crtbegin_so%O%s;:  %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}}

*cross_compile:
0

*version:
9.3.0

*multilib:
. !m32 !m64 !mx32;32:../lib32:i386-linux-gnu m32 !m64 !mx32;64:../lib:x86_64-linux-gnu !m32 m64 !mx32;x32:../libx32:x86_64-linux-gnux32 !m32 !m64 mx32;

*multilib_defaults:
m64

*multilib_extra:


*multilib_matches:
m32 m32;m64 m64;mx32 mx32;

*multilib_exclusions:


*multilib_options:
m32/m64/mx32

*multilib_reuse:


*linker:
collect2

*linker_plugin_file:


*lto_wrapper:


*lto_gcc:


*post_link:


*link_libgcc:
%D

*md_exec_prefix:


*md_startfile_prefix:


*md_startfile_prefix_1:


*startfile_prefix_spec:


*sysroot_spec:
--sysroot=%R

*sysroot_suffix_spec:


*sysroot_hdrs_suffix_spec:


*self_spec:


*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch)   %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}

*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:    %(linker) %{!fno-use-linker-plugin:%{!fno-lto:     -plugin %(linker_plugin_file)     -plugin-opt=%(lto_wrapper)     -plugin-opt=-fresolution=%u.res     %{flinker-output=*:-plugin-opt=-linker-output-known}     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}}     }}%{flto|flto=*:%*}>

由于specs文件这块知识在我这,确实是个盲区,我还得记住巨人的肩膀,我找到了一篇参考价值比较大的文章。 具体我不再细说里面的内容了,大家可以对照着来学习,简单捋一遍就会印象更深刻。

2.4 specs文件都放在哪里?

起初,当我们知道-specs=kernel.specs中的kernel.specs是一个文件的时候,我第一感觉就是:“嗯,应该在源码的bsp目录里面”,结果我拉去rt-smart的源码搜了一遍也没搜到:

takeout@newnew MINGW64 /c/llc/git_repos/rt-thread-share/rt-thread (rt-smart)
$ find . -name "kernel.specs"

takeout@newnew MINGW64 /c/llc/git_repos/rt-thread-share/rt-thread (rt-smart)
$ find . -name "*.specs"

这类名称的specs文件一个没搜到,倒是搜关键字的时候,有的bsp提到了nano.specs:

在这里插入图片描述

既然有些bsp的链接选项,明目张胆地引入nano.specs文件,而且编译不会报错,自然肯定有地方能找到它。 既然不在源码目录,那么还有一个可能就是在交叉编译工具链的目录里面,我们来找一找。 以我手上的gcc-arm-none-eabi-5_4-2016q3为例子:

` 在这里插入图片描述

这么一说,我想起了为何之前对specs有些印象,就是这两个nano.specsnosys.specs;baidu之,这下资料就很多了,这里给几个有效的参考链接:

  • RISC-V GCC:-specs=nano.specs 的作用
  • stm32 基于ARM GCC Compliler(EmBitz IDE) print重定向到串口打印输出 com serial
在这里插入图片描述在这里插入图片描述

看了第二个nosys.specs,再次勾起回忆,之前RRT论坛就有一个问题跟这个有关的,需要通过加入nosys.specs来解决的,当然我还看到它的解决思路,还真的是有点印象,仅此而已。 找到当时我回答的那个问题,大家也可以顺带看看当时我的思路。

在这里插入图片描述

另外,相关的问题我给出链接,大家有空都可以去看看,说不定能解决你的一些疑问。

  • https://club.rt-thread.org/ask/search.html?module=question&type=new&keyword=_sbrk
  • sbrk话题

2.5 愉快地结束

看到这里,楼主的疑问已经解答了,我自己对这个知识点也加深了理解,看来还是要多记笔记,真正进入到自己脑海里的东西才是自己的,否则永远只存在于搜索引擎中。

3 更多分享

欢迎大家关注我的github仓库01workstation,欢迎指正问题。

同时也非常欢迎关注我的CSDN主页和专栏:

【http://yyds.recan-li.cn】

【C/C++语言编程专栏】

【GCC专栏】

【信息安全专栏】

有问题的话,可以跟我讨论,知无不答,谢谢大家。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • GCC
    GCC
    +关注

    关注

    0

    文章

    107

    浏览量

    24835
  • RT-Thread
    +关注

    关注

    31

    文章

    1285

    浏览量

    40076
  • specs
    +关注

    关注

    0

    文章

    5

    浏览量

    1583
收藏 人收藏

    评论

    相关推荐

    GCC编译优化系列】前后编译的两版本固件bin大小不一样?

    GCC编译优化系列】前后编译的两个版本固件bin大小不一样,怎么办?
    的头像 发表于 09-09 09:01 4690次阅读
    【<b class='flag-5'>GCC</b><b class='flag-5'>编译</b><b class='flag-5'>优化</b><b class='flag-5'>系列</b>】前后<b class='flag-5'>编译</b>的两版本固件bin大小不一样?

    Linux 下GCC编译

    一、Linux 下多文件编译 在上一篇 Linux 下的 C 编程我们知道了 Linux 下的编译器为 GCC ,以及如何使用 GCC 进行编译
    的头像 发表于 09-11 15:18 2618次阅读
    Linux 下<b class='flag-5'>GCC</b>的<b class='flag-5'>编译</b>

    使用stm32h745zi-q nucleo开发板调试时,发现使用-specs=nano.specs时sscanf返回值错误,为什么?

    使用stm32h745zi-q nucleo开发板调试时,发现使用-specs=nano.specs时sscanf返回值错误,使用标准c库时返回值正确,但内存溢出了,请教如何查找问题。
    发表于 04-01 08:00

    使用gcc编译优化与不优化问题

    同样的程序,使用gcc编译优化与不优化的结果不一代码如下:1. #include 2.3. int main()4. {5.int i = 1;6.7.i
    发表于 09-27 10:33

    带有HP SPECS的高级参数测试仪

    Advanced Parametric Tester with HP SPECS
    发表于 03-14 06:31

    如何从脚本中删除specs=nano.specs呢?

    我使用“属性”菜单向链接描述文件添加了一个-fexceptions标志,但找不到如何从脚本中删除--specs=nano.specs属性->C/C++ 构建->MCU
    发表于 12-15 06:20

    AVR系列单片机GCC免费编译工具

    AVR系列单片机GCC免费编译工具
    发表于 04-13 15:23 54次下载

    Noise Specs Confusing

    Noise Specs Confusing
    发表于 03-24 14:51 0次下载

    浅谈gcc编译

    3.3 gcc编译器 GNU CC(简称为gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言
    发表于 10-18 13:48 0次下载

    常见gcc编译警告整理以及解决方法

     GCC有很多的编译选项,警告选项;指定头文件、库路径;优化选项。本文针整理一下GCC的警告选项以及gcc
    发表于 11-14 11:19 2.1w次阅读

    GCC编译优化指南

    (cpp) → 编译(gcc或g++) → 汇编(as) → 连接(ld) ;括号中表示每个阶段所使用的程序,它们分别属于 GCC 和 Binutils 软件包。显然的,优化应当从
    发表于 04-02 14:36 537次阅读

    gcc编译优化系列】如何获取gcc默认的链接脚本

    我们都知道在一般的嵌入式开发中,使用gcc编译固件的一般流程是,先把所有的.c文件和.s文件编译成.o文件,然后把所有的.o文件链接成一个elf文件,最后由elf文件导出bin文件。 那么在链接成
    的头像 发表于 07-11 09:15 3565次阅读

    GCC编译优化系列】实战分析C代码遇到的编译问题及解决思路

    GCC编译优化系列】实战分析C工程代码可能遇到的编译问题及其解决思路
    的头像 发表于 07-10 23:15 1410次阅读
    【<b class='flag-5'>GCC</b><b class='flag-5'>编译</b><b class='flag-5'>优化</b><b class='flag-5'>系列</b>】实战分析C代码遇到的<b class='flag-5'>编译</b>问题及解决思路

    GCC编译优化系列】multiple-definition

    GCC编译优化系列】这种让人看不懂的multiple-definition真的有点让人头疼
    的头像 发表于 07-11 09:26 7118次阅读
    【<b class='flag-5'>GCC</b><b class='flag-5'>编译</b><b class='flag-5'>优化</b><b class='flag-5'>系列</b>】multiple-definition

    如何从GCC源码学编译原理

    本文结合编译原理理论和GCC实践做了一个总结,希望能给需要了解编译原理和底层知识的同学一个更快的学习路径。
    的头像 发表于 03-02 16:15 3117次阅读
    如何从<b class='flag-5'>GCC</b>源码学<b class='flag-5'>编译</b>原理