devtk
devtk

Reputation: 2169

CMake: How to specify a different link script for each target

I have multiple targets that are being made in a CMake project. Each target has a different linkscript (LD file). How do I write the CMakeLists.txt file to make this happen? This is for an embedded project with C/C++/ASM files.

This is what I have so far. The problem is that LINKER_SCRIPT is defined globally and not per-target.

# add alpha target
add_executable(alpha.elf ${SOURCES})
target_compile_definitions(alpha.elf PUBLIC -DALPHA_DEFINED)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/Linker/alpha.ld)

# add beta target
add_executable(beta.elf ${SOURCES})
target_compile_definitions(beta.elf PUBLIC -DBETA_DEFINED)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/Linker/beta.ld)

set(CMAKE_EXE_LINKER_FLAGS
    "${CMAKE_EXE_LINKER_FLAGS} -T ${LINKER_SCRIPT}")

The problem is that LINKER_SCRIPT gets overwritten and the last definition is the one used. How can I make this work?

I have tried to define per-target variable using the following, however the output is not as expected. The file gets compiled, however things are not where they should be. For example, the generated HEX file does not start at 0x08000000 which is where it should be defined per the LD file.

set_target_properties(alpha.elf PROPERTIES
        CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_BINARY_DIR}/alpha.elf.map -T ${CMAKE_SOURCE_DIR}/Linker/alpha.ld")

Upvotes: 1

Views: 3399

Answers (1)

fdk1342
fdk1342

Reputation: 3564

The variable LINKER_SCRIPT is just being over-ridden the second time you set it to a value. It doesn't have global scope but sub-directory / function scope. But like any variable it takes on its latest value.

CMAKE_EXE_LINKER_FLAGS is being used for both targets in this case. Splitting this into separate sub-directories may work but I've never tried it.

There are no per-target variables that I am aware of. set_target_properties is used to set properties. Some properties are known to CMake, but the property CMAKE_EXE_LINKER_FLAGS is not one of them. It should just be ignored when generating the build files.

Try using target_link_options to set per-target property LINK_OPTIONS which is known and the option will show up when linking the executable.

For example target_link_options(alpha.elf PRIVATE -T${CMAKE_SOURCE_DIR}/Linker/alpha.ld). I haven't used it with options that have a space in them so that might be a problem.

To re-link if the linker script changes then refer to this answer: https://stackoverflow.com/a/42138375/1028434

Upvotes: 1

Related Questions