如何在基于 arm gcc make 的编译中不包含 C 文件

问题描述 投票:0回答:1

在我的arm cortex-m项目中,我使用cmake生成makefile并运行make编译项目。如果我细读 LD 输出的映射文件,它会链接到一个目标文件中,该文件甚至还没有在项目中的任何地方使用过,并且在 .text 部分中有一个未使用的函数的名称。 我想弄清楚是否有 LD 的命令开关来垃圾收集任何未使用的目标文件。我已经使用了 gc-sections 标志,但没有这样做。有没有办法丢弃这个输出的目标文件,使其不被放置在二进制文件中的某个地方?

在我的 cmakelists.txt 中,我确实指定包含所有 C 源文件,所以显然我可以在其中删除一些目标文件,但这看起来很乏味。

c gcc makefile ld
1个回答
0
投票

请参阅关于避免链接时操作自有代码的好建议,如果您不需要它,请考虑在编译时将其删除。

注意 这种方法可能导致删除一些需要的部分。阅读这位作者如何使用

--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

流程

  1. 使用未使用的符号创建手臂精灵(之前)
  2. 修改 arm elf 以删除不使用的符号(之后)

输入

这里是命令,代码基于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

startup.s

.global _Reset
_Reset:
 LDR sp, =stack_top
 BL c_entry
 B .

test.ld

ENTRY(_Reset)
SECTIONS
{
 . = 0x10000;
 .startup . : { startup.o(.text) }
 .text : { *(.text) }
 .data : { *(.data) }
 .bss : { *(.bss COMMON) }
 . = ALIGN(8);
 . = . + 0x1000; /* 4kB of stack memory */
 stack_top = .;
}

test.c

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");
}
© www.soinside.com 2019 - 2024. All rights reserved.