如何输出 CMake 项目创建的最终可执行文件的汇编列表?

How to output the assembly listing of the final executable created by a CMake project?

我目前正在开发一个嵌入式项目,使用 avr-gcc 编译器在 Atmel ATMega328p 微控制器上 运行。我决定使用 CMake 来创建我的构建系统,因为这样可以很容易地将我的项目集成到带有 Intellisense 的 VS Code 中。

我想在我的项目中设置的一个设置是编译完成后输出一个 *.map 文件以查看内存映射,以及每个编译对象的 *.lst 文件和最终的二进制文件。我通过将 -Wl,-Map=${CMAKE_PROJECT_NAME}.map 添加到 CMAKE_EXE_LINKER_FLAGS 解决了地图文件的创建问题。我还通过将 -Wa,-anhlmsd=<OBJECT>.lst 添加到 CMAKE_C_COMPILE_OBJECT.

来解决编译对象 lst 文件的创建

我无法解决的问题是如何为最终的二进制文件创建最终的 lst 文件,在本例中为“avr-bootloader.elf”。我已将 -Wa,-adhlns=${CMAKE_PROJECT_NAME}.lst 放入 CMAKE_EXE_LINKER FLAGS 并且 Ninja 正在 运行 最终调用 avr-gcc 并在预期位置放置标志。我期待在 CMake 生成适当的 makefile 之后在构建目录中找到“avr-bootloader.lst”,然后 运行s 构建,但我没有得到这样的文件。设置绝对路径并不能解决问题。删除等号并查看标准输出显示 avr-gcc 没有打印任何程序集列表。令我困惑的是地图文件的创建是如何毫无问题地工作的。关于为什么这个 CMake 项目没有创建最终装配清单,我是否遗漏了任何细节?我查找的所有搜索都只提到该功能的使用及其输出,而不是任何输出为空或不存在的情况。

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(avr-bootloader VERSION 0.1.0)

enable_language(C ASM)

set(mcu atmega328p)

set(CMAKE_EXE_LINKER_FLAGS -mmcu=${mcu})

add_compile_options(
    -mmcu=${mcu}
    -Os
    -g3
    -Wall
    -Wextra
    -Wdouble-promotion
    -Wno-main
    -Wstack-usage=255
    -Wconversion
)

set (src
    main.c)

# Output lst and map file
set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -Wa,-adhlns=${CMAKE_PROJECT_NAME}.lst -Wl,-Map=${CMAKE_PROJECT_NAME}.map")
set(CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT} -Wa,-anhlmsd=<OBJECT>.lst")



add_executable(avr-bootloader.elf ${src})
target_link_libraries(avr-bootloader.elf printf_min)
target_include_directories(avr-bootloader.elf PRIVATE .)

经过进一步调查,似乎 在 CMake 的最终 gcc 调用期间没有使用汇编程序选项,我传递的任何参数都不会输出任何内容。因此,最好的选择是使用自定义命令在构建完成时调用 avr-objdump

add_custom_command(OUTPUT ${CMAKE_PROJECT_NAME}.lst
    MAIN_DEPENDENCY $<TARGET_FILE:${CMAKE_PROJECT_NAME}.elf>
    COMMAND ${CMAKE_OBJDUMP} -h -S $<TARGET_FILE:${CMAKE_PROJECT_NAME}.elf> > ${CMAKE_PROJECT_NAME}.lst
    COMMENT "Invoking: Cross AVR GNU Create Listing")