背景
プロジェクトを開発する場合、コンパイルされた実行可能ファイルが非常に大きい引き起こし、静的ライブラリファイル.A、サードパーティ製の多くを使用します。この1は、ROMスペースを占有し、そして第二に、(スタートアッププロジェクトは時間に非常に敏感である)プログラムが遅いロード時間を開始します。実際には、これらの静的ライブラリの機能は、すべて、プロジェクトが小さい部分のみを使用していますと呼ばれていません。この場合、GCCの「-Wl、-gc-セクション」パラメータが便利です。
パラメータ説明
-Wl、英語の元、-gc-セクションの説明は、次のとおりです。
6.3.3.2コンパイルオプション
最終的な実行から未使用コードおよびデータを除去する操作を直接リンカーによって実行されます。-ffunctionセクション-fdata-セクション:これを実行するためには、次のオプションでコンパイルされたオブジェクトで動作するように持っています。
これらのオプションは、CやAdaのファイルで使用可能です。彼らは、結果として得られるオブジェクト・ファイル内の別々のセクションにそれぞれの機能またはデータを配置します。
オブジェクトと静的ライブラリは、これらのオプションを使用して作成されると、リンカはデッドコード削除を行うことができます。あなたは、GCCコマンドに-Wl、-gc-セクションのオプションを設定することによって、またはgnatmakeの-largsセクションでこれを行うことができます。これは参照されないコードとデータのガベージコレクションを実行します。
リンカは部分リンク(-rリンカオプション)を実行する場合は、-e / --entryリンカオプションを使用してエントリポイントを提供する必要があります。
-ffunction・セクションと-fdataセクションのオプションを指定せずにコンパイルされたオブジェクトがまだ実行ファイルとリンクすることに注意してください。しかし、デッドコード削除は(あるとして、彼らはリンクされます)これらのオブジェクトに対して実行されません。
GNATの静的ライブラリは現在、いくつかのプラットフォームで-ffunction・セクションと-fdataセクションでコンパイルされています。これは、あなたの実行ファイルからGNATライブラリの未使用コードとデータを排除することができます。
実質的に、次のとおりです。
- コンパイルC、Adaのソースファイル(C ++であってもよい)、GCC / G ++コンパイラオプションで、増加
-ffunction-sections
、-fdata-sections
で生成されたの.oコンパイルされたオブジェクトファイル、であろう様々な個々の独立の各機能又はデータセグメントsection
の; - 場合であれば、最終的な実行可能ファイルを生成するリンク
-Wl,--gc-sections
パラメータとを有する以前にコンパイルされたオブジェクトファイル-ffunction-sections
、-fdata-sections
パラメータ、関数がそれによって実行可能ファイルのサイズを小さく、未使用リンカLDをリンクしていません。 - 場合は
-r
、リンクパラメータは、出力の再配置を生成するために、あなたはコール表示する必要があり-e
、プログラムのエントリを指定するパラメータを。それ以外の場合は-Wl,--gc-sections
動作しません。
GNUの注意事項は、より多くのパラメータが参照できるldの公式サイト。
使用例
Section_test.c試験手順は以下のとおりです。
#include <stdio.h>
void func_0(void) {
printf("%s\n\r", __func__);
}
void func_1(void) {
printf("%s\n\r", __func__);
}
void func_2(void) {
printf("%s\n\r", __func__);
}
void func_3(void) {
printf("%s\n\r", __func__);
}
void func_4(void) {
printf("%s\n\r", __func__);
}
void func_5(void) {
printf("%s\n\r", __func__);
}
void func_6(void) {
printf("%s\n\r", __func__);
}
void func_7(void) {
printf("%s\n\r", __func__);
}
int main(void) {
func_0();
return 0;
}
Makefileは次の通り:
.PHONY: test_sections test_normal
all: test_sections test_normal
test_sections:
gcc -ffunction-sections -fdata-sections -c section_test.c
gcc -Wl,--gc-sections -o $@ section_test.o
mv section_test.o with_section.o
test_normal:
gcc -c section_test.c
gcc -o $@ section_test.o
mv section_test.o no_section.o
clean:
rm -rf *.o main_sections main_normal
実行はmake
、コンパイラは2つの.oファイルと2つの実行を生成しますno_section.o
、with_section.o
、test_normal
、test_sections
。
まず、によってls -l
実行可能ファイルのサイズを表示します。あなたは何のリンク未使用の関数が存在しない、見ることができますtest_sections
わずかに小さいが。より多くのプロジェクトで使用される.aの静的ライブラリーよりも、また機能しませんでしたが、多くの単語を使用している場合は、効果がより顕著になります。
-rwxr-xr-x 1 user user 8864 9月 10 14:40 test_normal
-rwxr-xr-x 1 user user 8272 9月 10 14:40 test_sections
その後、GCCコンパイラオプションで.oオブジェクトファイルを表示-ffunction-sections -fdata-sections
するかどうかの違いをもたらすために:
- いいえ
-ffunction-sections -fdata-sections
ターゲットファイルのオプションない、一つだけtest
、とrodata
。 -ffunction-sections -fdata-sections
それぞれのターゲットファイルのオプション、text.func_0
のtext.func_7
と同様に、8rodata.__func__
。説明GCCときにコンパイルされたオブジェクトファイル、様々な個々の独立した上で、各機能またはデータセグメントsection
。
$ readelf -t no_section.o
There are 13 section headers, starting at offset 0xa08:
Section Headers:
[Nr] Name
Type Address Offset Link
Size EntSize Info Align
Flags
[ 0]
NULL NULL 0000000000000000 0000000000000000 0
[ 1] .text
PROGBITS PROGBITS 0000000000000000 0000000000000040 0
[ 2] .rela.text
RELA RELA 0000000000000000 0000000000000670 10
[ 3] .data
PROGBITS PROGBITS 0000000000000000 0000000000000148 0
[ 4] .bss
NOBITS NOBITS 0000000000000000 0000000000000148 0
[ 5] .rodata
PROGBITS PROGBITS 0000000000000000 0000000000000148 0
$ readelf -t with_section.o
There are 38 section headers, starting at offset 0xce8:
Section Headers:
[Nr] Name
Type Address Offset Link
Size EntSize Info Align
Flags
[ 0]
NULL NULL 0000000000000000 0000000000000000 0
[ 1] .text
PROGBITS PROGBITS 0000000000000000 0000000000000040 0
[ 2] .data
PROGBITS PROGBITS 0000000000000000 0000000000000040 0
[ 3] .bss
NOBITS NOBITS 0000000000000000 0000000000000040 0
[ 4] .rodata
PROGBITS PROGBITS 0000000000000000 0000000000000040 0
[ 5] .text.func_0
PROGBITS PROGBITS 0000000000000000 0000000000000045 0
[ 6] .rela.text.func_0
RELA RELA 0000000000000000 0000000000000808 35
[ 7] .text.func_1
PROGBITS PROGBITS 0000000000000000 0000000000000064 0
[ 8] .rela.text.func_1
RELA RELA 0000000000000000 0000000000000850 35
[ 9] .text.func_2
PROGBITS PROGBITS 0000000000000000 0000000000000083 0
[10] .rela.text.func_2
RELA RELA 0000000000000000 0000000000000898 35
[11] .text.func_3
PROGBITS PROGBITS 0000000000000000 00000000000000a2 0
[12] .rela.text.func_3
RELA RELA 0000000000000000 00000000000008e0 35
[13] .text.func_4
PROGBITS PROGBITS 0000000000000000 00000000000000c1 0
[14] .rela.text.func_4
RELA RELA 0000000000000000 0000000000000928 35
[15] .text.func_5
PROGBITS PROGBITS 0000000000000000 00000000000000e0 0
[16] .rela.text.func_5
RELA RELA 0000000000000000 0000000000000970 35
[17] .text.func_6
PROGBITS PROGBITS 0000000000000000 00000000000000ff 0
[18] .rela.text.func_6
RELA RELA 0000000000000000 00000000000009b8 35
[19] .text.func_7
PROGBITS PROGBITS 0000000000000000 000000000000011e 0
[20] .rela.text.func_7
RELA RELA 0000000000000000 0000000000000a00 35
[21] .text.main
PROGBITS PROGBITS 0000000000000000 000000000000013d 0
[22] .rela.text.main
RELA RELA 0000000000000000 0000000000000a48 35
[23] .rodata.__func__.2250
PROGBITS PROGBITS 0000000000000000 000000000000014d 0
[24] .rodata.__func__.2254
PROGBITS PROGBITS 0000000000000000 0000000000000154 0
[25] .rodata.__func__.2258
PROGBITS PROGBITS 0000000000000000 000000000000015b 0
[26] .rodata.__func__.2262
PROGBITS PROGBITS 0000000000000000 0000000000000162 0
[27] .rodata.__func__.2266
PROGBITS PROGBITS 0000000000000000 0000000000000169 0
[28] .rodata.__func__.2270
PROGBITS PROGBITS 0000000000000000 0000000000000170 0
[29] .rodata.__func__.2274
PROGBITS PROGBITS 0000000000000000 0000000000000177 0
[30] .rodata.__func__.2278
PROGBITS PROGBITS 0000000000000000 000000000000017e 0
最後に、なしで、別のを見て-Wl,–gc-sections
生成された実行可能ファイルのパラメータ、およびと-Wl,–gc-sections
実行可能ファイルを結果として異なるパラメータ。明らかに、とのリンク処理で-Wl,–gc-sections
のパラメータ、実行可能ファイルは、関数呼び出しを構築します。
$ readelf -a test_normal | grep func_
55: 00000000000006c6 31 FUNC GLOBAL DEFAULT 14 func_4
57: 000000000000064a 31 FUNC GLOBAL DEFAULT 14 func_0
58: 0000000000000688 31 FUNC GLOBAL DEFAULT 14 func_2
60: 0000000000000704 31 FUNC GLOBAL DEFAULT 14 func_6
71: 00000000000006a7 31 FUNC GLOBAL DEFAULT 14 func_3
72: 0000000000000669 31 FUNC GLOBAL DEFAULT 14 func_1
73: 0000000000000723 31 FUNC GLOBAL DEFAULT 14 func_7
74: 00000000000006e5 31 FUNC GLOBAL DEFAULT 14 func_5
readelf -a test_sections | grep func_
48: 000000000000064a 31 FUNC GLOBAL DEFAULT 14 func_0