[CMake] Handling of generated files in POST_BUILD custom commands

Pedro Navarro pnavarro at netflix.com
Fri Aug 24 20:19:56 EDT 2018


Hi all,

I'm trying to build an executable that has its debug symbols in a separate
file. I implemented that with a POST_BUILD custom command:

add_executable(foo a.cpp)
add_custom_command(TARGET foo
    POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} --only-keep-debug foo foo.sym
    COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=foo.sym foo
    COMMAND ${CMAKE_STRIP} --strip-debug foo
    BYPRODUCTS foo.sym
    COMMENT "Creating symbols"
)

The problem is that if I delete foo.sym, in order for it to be created
again it's not enough with running the custom command steps as we have
stripped the file and the debug symbols are gone: we need to relink the
executable so the debug information is available again.

The ninja generator makes this situation possible with the use of
byproducts. By adding BYPRODUCTS foo.sym to the custom command if I change
foo.sym the target is relinked. Unfortunately the GNU Makefiles generator
ignores byproducts, so I want to relink the executable I need to remove it.
Also the byproducts are added to ninja's clean target, but not for GNU
Makefiles.

I have tried to achieve the same result with a custom command:

add_custom_command(OUTPUT foo
    DEPENDS foo
    COMMAND ${CMAKE_OBJCOPY} --only-keep-debug foo foo.sym
    COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=foo.sym foo
    COMMAND ${CMAKE_STRIP} --strip-debug foo
    BYPRODUCTS foo.sym
    COMMENT "Creating symbols"
    USES_TERMINAL
)

add_custom_target(foo_symbols ALL
    DEPENDS foo.sym
)

But I get the same results, the target does not get relinked. Also, it
seems that there is an issue of some sort because every time I type make
the steps to create the file foo.sym are executed, resulting in an error
message from objcopy ('debuglink section already exists'). If I touch the
CMakeLists.txt file (by adding a space, removing it and saving), make after
that correctly does not execute the steps to create foo.sym. I understand
that targets created by add_custom_target are always out of date, but I
thought there shouldn't be a need to re-run the custom command.

*lgux-pnavarro4 ~/tests/cm2/b $ cmake --version*
cmake version 3.10.2

CMake suite maintained and supported by Kitware (kitware.com/cmake).
*lgux-pnavarro4 ~/tests/cm2/b $ rm -rf * && cmake -DCMAKE_BUILD_TYPE=Debug
..*
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/local/bin/cc
-- Check for working C compiler: /usr/local/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/local/bin/c++
-- Check for working CXX compiler: /usr/local/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: /home/pnavarro/tests/cm2/b
*lgux-pnavarro4 ~/tests/cm2/b $ make*
make: Entering directory '/home/pnavarro/tests/cm2/b'
make[1]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
Scanning dependencies of target foo
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
[ 33%] Building CXX object CMakeFiles/foo.dir/a.cpp.o
[ 66%] Linking CXX executable foo
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[ 66%] Built target foo
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
Scanning dependencies of target foo_symbols
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
[100%] Creating symbols
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[100%] Built target foo_symbols
make[1]: Leaving directory '/home/pnavarro/tests/cm2/b'
make: Leaving directory '/home/pnavarro/tests/cm2/b'
*lgux-pnavarro4 ~/tests/cm2/b $ make*
make: Entering directory '/home/pnavarro/tests/cm2/b'
make[1]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[ 66%] Built target foo
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
[100%] Creating symbols
/usr/bin/objcopy: stkkJQMo: debuglink section already exists
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[100%] Built target foo_symbols
make[1]: Leaving directory '/home/pnavarro/tests/cm2/b'
make: Leaving directory '/home/pnavarro/tests/cm2/b'
*lgux-pnavarro4 ~/tests/cm2/b $ *

*<touch CMakeLists.txt>*

*lgux-pnavarro4 ~/tests/cm2/b $ make*
make: Entering directory '/home/pnavarro/tests/cm2/b'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pnavarro/tests/cm2/b
make[1]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[ 66%] Built target foo
make[2]: Entering directory '/home/pnavarro/tests/cm2/b'
make[2]: Leaving directory '/home/pnavarro/tests/cm2/b'
[100%] Built target foo_symbols
make[1]: Leaving directory '/home/pnavarro/tests/cm2/b'
make: Leaving directory '/home/pnavarro/tests/cm2/b'


This leads me to the following questions:
1) Is is possible to achieve what I want (relink the target if a file
created after POST_BUILD is deleted) with GNU Make files?
2) As the documentation says that byproducts are ignored but the files
marked as GENERATED, shouldn't GENERATED files created by POST_BUILD be
added as a trigger for a new link?
3) Byproducts are added to the clean target in ninja, but in GNU Makefiles
you need to add them to ADDITIONAL_MAKE_CLEAN_FILES. Shouldn't GENERATED
files in POST_BUILD be automatically added to the make clean target? At
least it will give parity between ninja and make's behaviors.
4) Is my issue with foo_symbols not being executed after touching
CMakelists.txt a bug?

Thanks!
Pedro
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180824/5cbcef9a/attachment.html>


More information about the CMake mailing list