How to propagate file-level dependency (custom command + custom target) via interface library?
I have a following scenario:
- project I work on is mostly a static library
- as this is an embedded project I also have linker scripts
- each linker script requires some preprocessing before it can be used
- static library, include paths, compiler flags and the linker flag to use preprocessed linker script are propagated to users via interface library.
This generally works fine, however there's only target-level dependency between user's application and preprocessed linker script (via interface library). There is no file-level dependency, so when I modify the source of the linker script, the preprocessed linker script gets regenerated, however user's application is not relinked.
Here's a test case
$ ls
CMakeLists.txt dummy.c linker-script.ld-source main.c
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(a_test)
add_custom_command(OUTPUT linker-script.ld
COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/linker-script.ld-source linker-script.ld
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker-script.ld-source)
add_custom_target(linker-script DEPENDS linker-script.ld)
add_library(static-library STATIC
dummy.c)
add_library(interface-library INTERFACE)
target_link_libraries(interface-library INTERFACE
# -Tlinker-script.ld
static-library)
add_dependencies(interface-library linker-script)
add_executable(application
main.c)
target_link_libraries(application interface-library)
$ cat main.c
int main(void)
{
return 0;
}
dummy.c
and linker-script.ld-source
are just empty. Generated linker script is not actually used, but the commended fragment shows how I intend to use it. Let's run it:
$ mkdir output
$ cd output
$ cmake ..
-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake/output
$ make
Scanning dependencies of target static-library
[ 20%] Building C object CMakeFiles/static-library.dir/dummy.c.o
[ 40%] Linking C static library libstatic-library.a
[ 40%] Built target static-library
Scanning dependencies of target linker-script
[ 60%] Generating linker-script.ld
[ 60%] Built target linker-script
Scanning dependencies of target application
[ 80%] Building C object CMakeFiles/application.dir/main.c.o
[100%] Linking C executable application
[100%] Built target application
OK, everything seems fine. Now let's say that source of linker script is updated:
$ touch ../linker-script.ld-source
$ make
[ 40%] Built target static-library
[ 60%] Generating linker-script.ld
[ 60%] Built target linker-script
[100%] Built target application
As you see, the application is not relinked and this is a problem here. Any ideas how such scenario could be solved?