I am currently working on an embedded project using the avr-gcc
compiler to run on an Atmel ATMega328p microcontroller. I decided to use CMake to create my build system as that would be an easy to way integrate my project into VS Code with Intellisense.
One of the settings I would like to set up in my project is the output of a *.map file to view the memory map after the compilation has finished, and a *.lst file for each compilation object and the final binary. I have solved the creation of the map file by adding -Wl,-Map=${CMAKE_PROJECT_NAME}.map
to CMAKE_EXE_LINKER_FLAGS
. I have also solved the creation of the compilation object lst files by adding -Wa,-anhlmsd=<OBJECT>.lst
to CMAKE_C_COMPILE_OBJECT
.
The issue I cannot resolve is how to create the final lst file for the final binary, which in this case is "avr-bootloader.elf". I have put -Wa,-adhlns=${CMAKE_PROJECT_NAME}.lst
into CMAKE_EXE_LINKER FLAGS
and Ninja is running the final call to avr-gcc
with the flag in the expected spot. I'm anticipating to find "avr-bootloader.lst" in the build directory after CMake generates the appropriate makefiles and then runs the build but I do not get such a file. Setting an absolute path does not solve the issue. Removing the equal sign and viewing stdout shows that avr-gcc
isn't printing any assembly listing out whatsoever. What perplexes me is how the map file creation works without a problem. Is there any detail I'm missing as to why this CMake project isn't creating the final assembly listing? All searches I look up only mention the use of the feature and it's output, not about any situation where it's output is empty or nonexistant.
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 .)
After further investigation, it seems like the assembler options aren't used during CMake's final gcc
call and any arguments I pass won't output anything. As a result, the best option is to use a custom command to just call avr-objdump
when the build is complete.
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")