Issue
Let's say I have a custom C compiler for a special target (not GCC-like). Therefore, I use a custom toolchain file with cmake. Among other things, the linker is supposed to generate multiple outputs at once (elf, hex and map files). The primary output is the ELF file, others are nice-to-have.
So I define something like this in the toolchain file:
set(CMAKE_C_LINK_EXECUTABLE ... --elf-output <TARGET>.elf --hex-output <TARGET>.hex --map-output <TARGET>.map)
The problem with this approach is that the resulting build config does not have the proper dependency. The generated target has its simple name without any suffix. Therefore, multiple calls of the build keep rerunning the linker. I tried working around this the same way it's done on Windows and specified set(CMAKE_EXECUTABLE_SUFFIX_C ".elf")
and removed .elf from the mentioned variable. This makes the default target name look right and the linker rerunning issue is gone. But the disadvantage is that now the additional outputs get this .elf suffix into their filenames, i.e. I get foo.elf.hex
and foo.elf.map
.
Is there a proper way to access the <TARGET>
contents without the suffix, which would work in the toolchains definitions?
I could obviously drop this part from the toolchain definition completely and do that path manipulation the cmake project code and attach the proper options via target_link_options, but it just doesn't feel right.
Solution
Use TARGET_BASE
. From https://github.com/Kitware/CMake/blob/master/Modules/CMakeCInformation.cmake :
# variables supplied by the generator at use time
# <TARGET>
# <TARGET_BASE> the target without the suffix
...
Examples:
$ cd /usr/share/cmake/Modules
$ ag TARGET_BASE
Compiler/ARMCC.cmake
33: set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> --list <TARGET_BASE>.map")
Compiler/ARMClang.cmake
138: set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list=<TARGET_BASE>.map")
Answered By - KamilCuk Answer Checked By - Pedro (WPSolving Volunteer)