Handling of generated files in POST_BUILD custom commands

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Handling of generated files in POST_BUILD custom commands

CMake mailing list
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


--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake