在我的arm cortex-m项目中,我使用cmake生成makefile并运行make编译项目。如果我细读 LD 输出的映射文件,它会链接到一个目标文件中,该文件甚至还没有在项目中的任何地方使用过,并且在 .text 部分中有一个未使用的函数的名称。 我想弄清楚是否有 LD 的命令开关来垃圾收集任何未使用的目标文件。我已经使用了 gc-sections 标志,但没有这样做。有没有办法丢弃这个输出的目标文件,使其不被放置在二进制文件中的某个地方?
在我的 cmakelists.txt 中,我确实指定包含所有 C 源文件,所以显然我可以在其中删除一些目标文件,但这看起来很乏味。
请参阅关于避免链接时操作自有代码的好建议,如果您不需要它,请考虑在编译时将其删除。
注意 这种方法可能导致删除一些需要的部分。阅读这位作者如何使用
--print-gc-sections
来审查和发现删除的部分。
回顾 本演示文稿使用 GNU 工具链消除链接时间死代码和数据
问得好,这里是如何分离函数和数据并使用
gc-sections
去除符号。
也许这会有所帮助,这就是我对这个答案进行实验的方式......
如何丢弃生成的 elf 文件中未使用的符号
显示未使用的功能
foo
包含在前精灵文件中并在后精灵文件中删除。
# BEFORE SHOWS THAT SYMBOL FOO EXIST
arm-none-eabi-readelf -a test-before.elf
. . .
25: 00010068 24 FUNC GLOBAL DEFAULT 2 foo
# AFTER SHOWS THAT SYMBOL FOO ABSENT
arm-none-eabi-readelf -a test-after.elf
. . .
25: 00010068 28 FUNC GLOBAL DEFAULT 3 c_entry
26: 00010000 0 NOTYPE GLOBAL DEFAULT 1 _Reset
这里是命令,代码基于Hello World for bare metal ARM
arm-none-eabi-as -mcpu=arm926ej-s -g startup.s -o startup.o
arm-none-eabi-gcc -c -mcpu=arm926ej-s -g test.c -o test-before.o
arm-none-eabi-gcc -fdata-sections -ffunction-sections -c -mcpu=arm926ej-s -g test.c -o test-after.o
arm-none-eabi-ld --gc-sections -T test.ld test-before.o startup.o -o test-before.elf
arm-none-eabi-ld --gc-sections -T test.ld test-after.o startup.o -o test-after.elf
arm-none-eabi-readelf -a test-before.elf
arm-none-eabi-readelf -a test-after.elf
# SEE OUTPUT FOR RESULTS OF READELF SHOWING UNUSED SYMBOL foo WAS REMOVED
.global _Reset
_Reset:
LDR sp, =stack_top
BL c_entry
B .
ENTRY(_Reset)
SECTIONS
{
. = 0x10000;
.startup . : { startup.o(.text) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
. = ALIGN(8);
. = . + 0x1000; /* 4kB of stack memory */
stack_top = .;
}
volatile unsigned int * const UART0DR = (unsigned int *)0x101f1000;
void print_uart0(const char *s) {
while(*s != '\0') { /* Loop until end of string */
*UART0DR = (unsigned int)(*s); /* Transmit char */
s++; /* Next char */
}
}
void foo()
{
}
void c_entry() {
print_uart0("Hello world!\n");
}