使用-Os选项,gcc生成大小为0的二进制文件

4

我有一个简单的FreeRTOS应用程序,它只在主循环中切换LED。

当我使用-Os编译它时,生成的二进制文件大小为0。没有使用-Os时,一切都按预期工作。这是怎么回事?

我的CFLAGS是:

CPUFLAG = -mthumb -mcpu=cortex-m4
FPUFLAG = -mfpu=fpv4-sp-d16 -mfloat-abi=hard
WFLAG   = -Wall -Wextra -Werror -Wstrict-prototypes

CFLAGS  += -std=gnu99 $(WFLAG) $(CPUFLAG) $(FPUFLAG) -mlittle-endian -mthumb -nostartfiles
CFLAGS  += -ffunction-sections -fdata-sections -fno-builtin
LDFLAGS += -nostdlib --gc-sections -static

main基本上是TI的闪烁演示:

int main(void)
{
    volatile uint32_t ui32Loop;

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;

    //
    // Do a dummy read to insert a few cycles after enabling the peripheral.
    //
    ui32Loop = SYSCTL_RCGC2_R;

    //
    // Enable the GPIO pin for the LED (PF3).  Set the direction as output, and
    // enable the GPIO pin for digital function.
    //
    GPIO_PORTF_DIR_R = 0x08;
    GPIO_PORTF_DEN_R = 0x08;

    //
    // Loop forever.
    //
    while(1)
    {
        //
        // Turn on the LED.
        //
        GPIO_PORTF_DATA_R |= 0x08;

        //
        // Delay for a bit.
        //
        for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
        {
        }

        //
        // Turn off the LED.
        //
        GPIO_PORTF_DATA_R &= ~(0x08);

        //
        // Delay for a bit.
        //
        for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
        {
        }
    }

    return 0;
}

使用 -Os 编译选项将生成以下内容:
   text    data     bss     dec     hex filename
      0       0       0       0       0 image.elf

否则
   text    data     bss     dec     hex filename
   2012       4     728    2744     ab8 image.elf

编辑.map 文件的差异


1
GPIO_PORTF_DATA_R和相关变量是如何声明的? - unwind
image.elf文件是否真的为空,还是只是像size命令所报告的那样大小为0?ls -l image.elf - Keith Thompson
ls -sh image.* 命令输出 0 image.bin* 4,0K image.elf* - user1273684
1
你看过地图文件吗?我相信它会给出答案。例如,可能是节命名。 - artless noise
没有地图文件 - 这里是整个Makefile - user1273684
显示剩余3条评论
1个回答

4

由于你指定了-nostartfiles选项,标准启动文件和其入口点不会被使用,因此没有对你的main函数的引用,并且--gc-sections会将整个部分视为未使用而丢弃。

要修复此问题,请尝试将你的函数命名为start或将-e _main添加到ld标志中。


实际的启动代码将在复位中断中,我应该导出它并告诉链接器吗? - user1273684
这是有道理的,但似乎适用于 -Os 或默认优化器,除非他在工具链中使用了 LTO(链接时优化)。无论如何,指定入口点是一个好建议。 - artless noise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接