[CMake] linker scripts and dependencies

Michael Hertling mhertling at online.de
Fri May 28 18:26:32 EDT 2010


On 05/28/2010 12:23 AM, Chris Bayley wrote:
> I am getting to grip with cmake on an embedded system (ARM Cortex M3), 
> but I can't figure out if there is a better way to specify the linker 
> script file than with:
> 
> set(CMAKE_EXE_LINKER_FLAGS "-T ${LINKER_SCRIPT}")
> 
> if that then is way to do it, then what is the best way to add 
> ${LINKER_SCRIPT} as dependency of the target EXE ?
> i.e every touch of the linker script should cause the target to be relinked.

There're three approaches I could offer, but none is really convincing:

1) Create an empty source file, say, dummy.c and add it to the target's
source file list, e.g. ADD_EXECUTABLE(EXE ... dummy.c). Set the source
files property OBJECT_DEPENDS on dummy.c to your linker script. This
results in dummy.c being recompiled and, thus, EXE relinked when the
linker script is touched, and since dummy.c is empty, EXE should be
hardly affected:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKERSCRIPT C)
FILE(WRITE main.c "void main(){}")
# dummy.c must exist:
ADD_EXECUTABLE(EXE main.c dummy.c)
# linkerscript must exist:
SET_SOURCE_FILES_PROPERTIES(
    dummy.c PROPERTIES OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/linkerscript
)

2) Add a custom command that will touch CMakeFiles/EXE.dir/link.txt and
depends on your linker script, then add CMakeFiles/EXE.dir/link.txt to
EXE's source file list. Since this file is a prerequisite of EXE's link
line, the latter is relinked when the linker scripts has changed:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKERSCRIPT C)
FILE(WRITE main.c "void main(){}")
ADD_CUSTOM_COMMAND(
    OUTPUT CMakeFiles/EXE.dir/link.txt
    COMMAND ${CMAKE_COMMAND} -E touch CMakeFiles/EXE.dir/link.txt
    DEPENDS linkerscript
)
ADD_EXECUTABLE(
    EXE main.c ${CMAKE_BINARY_DIR}/CMakeFiles/EXE.dir/link.txt
)

3) Build a static library libdummy.a from an empty source file dummy.c,
add a custom command which touches dummy.c and depends on your linker
script and use TARGET_LINK_LIBRARIES() to link EXE against libdummy.a.
This is similar to (1), but uses TARGET_LINK_LIBRARIES()'s capability
of tracking dependencies to rebuild libdummy.a and relink EXE when the
linker script has changed:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKERSCRIPT C)
FILE(WRITE main.c "void main(){}")
ADD_EXECUTABLE(EXE main.c)
# dummy.c must exist:
ADD_LIBRARY(dummy STATIC dummy.c)
# linkerscript must exist:
ADD_CUSTOM_COMMAND(
    OUTPUT dummy.c
    COMMAND ${CMAKE_COMMAND} -E touch dummy.c
    DEPENDS linkerscript
)
TARGET_LINK_LIBRARIES(EXE dummy)

Personally, I'd prefer (1) as this is reasonably straight, high-level
and portable, while (2) possibly is not generator-independent due to
the quite critical reference to CMakeFiles, i.e. CMake internals, and
finally, (3) with its usage of a whole dummy library is really weird.

As far as I understand, the actual issue is that files from a target's
source file list which aren't associated with a language supported by
CMake don't cause a fully-fledged dependency of the target on them;
otherwise, you could just say

ADD_EXECUTABLE(EXE ... linkerscript)

and EXE would be rebuilt, i.e. relinked, if it's older than linkerscript
although the latter doesn't contribute to the target. In this regard, a
command like the above currently limits itself to updating linkerscript
if EXE is checked for being out of date and linkerscript is covered by a
rule defined by ADD_CUSTOM_COMMAND(OUTPUT ...). Alternatively, I could
imagine a target property, say, TARGET_DEPENDS for the specification of
arbitrary file-level dependencies for targets like the OBJECT_DEPENDS
property does for source files. Perhaps, this would be worth a feature
request.

'hope that helps.

Regards,

Michael


More information about the CMake mailing list