【GCC編譯優(yōu)化系列】GCC編譯鏈接時(shí)候--specs=kernel.specs鏈接屬性究竟是個(gè)啥
1 問題來源
近來關(guān)注rt-thread的論壇稍微少了一些,今天突然在論壇里面看到這么一個(gè)問題:
為何會(huì)對(duì)這個(gè)問題感興趣呢? 主要有以下兩個(gè)原因:
- 最近都在研究一些gcc編譯鏈接相關(guān)的知識(shí),做了一些筆記,方便自己加深理解和記憶;
- 這個(gè)specs選項(xiàng),隱約記得在哪里見過,但是又記不清楚來龍去脈,看來還是記憶不夠深刻。
于是乎,我決定趁著這個(gè)機(jī)會(huì),好好扒一扒這個(gè)specs選項(xiàng)。
2 初步分析
2.1 內(nèi)事不決問百度,外事不決問谷歌
二話不說,先baidu之,如下:
沒找到合適的,那google一下?無奈,沒有梯子,那就bing一下吧:
問題答案沒找到,倒是把問題自己給找到了。
2.2 開發(fā)不懂問‘男人’
都說男人靠得住,母豬都上樹
,但是作為一個(gè)長期混跡在Linux開發(fā)環(huán)境下的程序猿,我可以很負(fù)責(zé)任地告訴,男人是最不會(huì)騙人的
,不信你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
的結(jié)果里面搜索specs
關(guān)鍵字,注意仔細(xì)看,我們發(fā)現(xiàn)了有-specs=file
這個(gè)關(guān)鍵信息,不用猜,就是它了。 為了更好地說明,我把這段描述完整地拎出來:
-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.
需要點(diǎn)英文理解能力,但是語意并不難,實(shí)在不行,用翻譯軟件也可以搞定:
-specs=文件
編譯器讀入標(biāo)準(zhǔn)規(guī)范文件后處理文件,以覆蓋gcc使用的默認(rèn)值
驅(qū)動(dòng)程序用于確定要傳遞給cc1、cc1plus、as、ld等的開關(guān)。多個(gè)-specs=文件
可以在命令行上指定,并按從左到右的順序處理。
OK,意思已經(jīng)很明確了,就是用于覆蓋gcc默認(rèn)的傳遞參數(shù),這些新的參數(shù)是在一個(gè)新的文件里面里面指定,比如問題中的就是kernel.specs
。
2.3 gcc默認(rèn)的specs參數(shù)
如果你好好讀man gcc
的返回,你會(huì)發(fā)現(xiàn)有這么一個(gè)-dumpspec
選項(xiàng),它就是記錄了gcc默認(rèn)的specs參數(shù),為了說明下specs文件長啥樣,我把它導(dǎo)出來看看:(說明下,我這個(gè)是x64環(huán)境下的gcc,如果是交叉編譯的gcc,替換對(duì)應(yīng)的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文件這塊知識(shí)在我這,確實(shí)是個(gè)盲區(qū),我還得記住巨人的肩膀,我找到了一篇參考價(jià)值比較大的文章。 具體我不再細(xì)說里面的內(nèi)容了,大家可以對(duì)照著來學(xué)習(xí),簡單捋一遍就會(huì)印象更深刻。
2.4 specs文件都放在哪里?
起初,當(dāng)我們知道
-specs=kernel.specs
中的kernel.specs
是一個(gè)文件的時(shí)候,我第一感覺就是:“嗯,應(yīng)該在源碼的bsp目錄里面”,結(jié)果我拉去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文件一個(gè)沒搜到,倒是搜關(guān)鍵字的時(shí)候,有的bsp提到了
nano.specs
:
既然有些bsp的鏈接選項(xiàng),明目張膽地引入
nano.specs
文件,而且編譯不會(huì)報(bào)錯(cuò),自然肯定有地方能找到它。 既然不在源碼目錄,那么還有一個(gè)可能就是在交叉編譯工具鏈的目錄里面,我們來找一找。 以我手上的gcc-arm-none-eabi-5_4-2016q3
為例子:
這么一說,我想起了為何之前對(duì)
specs
有些印象,就是這兩個(gè)nano.specs
和nosys.specs
;baidu之,這下資料就很多了,這里給幾個(gè)有效的參考鏈接:
看了第二個(gè)
nosys.specs
,再次勾起回憶,之前RRT論壇就有一個(gè)問題跟這個(gè)有關(guān)的,需要通過加入nosys.specs
來解決的,當(dāng)然我還看到它的解決思路,還真的是有點(diǎn)印象,僅此而已。 找到當(dāng)時(shí)我回答的那個(gè)問題,大家也可以順帶看看當(dāng)時(shí)我的思路。
另外,相關(guān)的問題我給出鏈接,大家有空都可以去看看,說不定能解決你的一些疑問。
-
https://club.rt-thread.org/ask/search.html?module=question&type=new&keyword=_sbrk
-
sbrk話題
2.5 愉快地結(jié)束
看到這里,樓主的疑問已經(jīng)解答了,我自己對(duì)這個(gè)知識(shí)點(diǎn)也加深了理解,看來還是要多記筆記,真正進(jìn)入到自己腦海里的東西才是自己的,否則永遠(yuǎn)只存在于搜索引擎中。
3 更多分享
歡迎大家關(guān)注我的github倉庫01workstation,歡迎指正問題。
同時(shí)也非常歡迎關(guān)注我的CSDN主頁和專欄:
【http://yyds.recan-li.cn】
【C/C++語言編程專欄】
【GCC專欄】
【信息安全專欄】
有問題的話,可以跟我討論,知無不答,謝謝大家。
審核編輯:湯梓紅
-
GCC
+關(guān)注
關(guān)注
0文章
107瀏覽量
24857 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1300瀏覽量
40264 -
specs
+關(guān)注
關(guān)注
0文章
5瀏覽量
1588
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論