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

rbl8hiat  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(134)

在我的arm cortex-m项目中,我使用cmake生成makefile并运行make编译项目,如果仔细查看LD输出的map文件,会发现它链接了一个在项目中还没有用到的目标文件。和它的一个未使用的函数的名称在。text部分。我试图弄清楚是否有一个命令开关,LD垃圾收集任何未使用的目标文件。我已经使用了gc-sections标志,但是没有用。有没有一种方法可以丢弃这个输出的目标文件,以免它被放在二进制文件的某个地方?
在我的cmakelists.txt中,我确实指定了包括所有C源文件,所以很明显,我可以在那里修剪一些目标文件,但这似乎很乏味。

vmdwslir

vmdwslir1#

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

也许这能帮上忙,这是我对这个答案的体验...

问题

如何丢弃生成的elf文件中未使用的符号

输出

显示未使用的函数foo包含在before elf文件中,并在after elf文件中删除。

# 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.使用未使用的符号创建手臂精灵(之前)
1.修改手臂精灵以移除未使用的符号(之后)

输入

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

启动. s

.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 = .;
}

测试. 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");
}

链接.a而不是.o

关于使用库的评论看起来很有趣,所以我写了这个实验。基于下面的特定链接器和命令,foo被包含在结果elf中。仍然可能是不同链接器或更好命令的解决方案。尽管想法很酷。

arm-none-eabi-ar rcs libtest-before.a test-before.o
arm-none-eabi-ld --static -T test.ld libtest-before.a startup.o -o test-before-lib.elf
arm-none-eabi-readelf -a test-before-lib.elf 
. . .
    25: 00010068    24 FUNC    GLOBAL DEFAULT    2 foo
    26: 00010000     0 NOTYPE  GLOBAL DEFAULT    1 _Reset

相关问题