Running target from post build

Hi,

I am trying to get a project to invoke a target after the build completes. I do not want a separate target but instead the target should be invoked after the build completes (compile and link). In my case we do some signing, file copy, and other actions. These are complex actions that already exist in separate targets. I just want to invoke these targets from post build. Since these actions are complex we cannot just have the POST_BUILD execute them as a command.

In addition we are trying to move away from the VS generators and use the Ninja generators. When we were using the VS generators this seemed to work as I would expect but now with ninja this is not working. I am assuming that there is a dependency that VS implicitly added that ninja is not.

Here is a simplified example of what I am trying to do,

set(TARGET_NAME test)

set(SOURCE_FILES main.cc)
add_executable(${TARGET_NAME} ${SOURCE_FILES})

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.stamped
    COMMAND ${CMAKE_COMMAND} -E echo "creating stamp file"
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.stamped
    DEPENDS ${TARGET_NAME}
)

add_custom_target(${TARGET_NAME}-stamped DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.stamped)

add_custom_command(TARGET ${TARGET_NAME}
    POST_BUILD
    DEPENDS ${TARGET_NAME}-stamped
    COMMAND ${CMAKE_COMMAND} -E echo "hello from post build"
)

In this case if I just build the test target it only build the executable and the postbuild runs which we can see the “hello from post build” in the output. However the stamp file is not created.

If I explicitly run the test-stamped target it first builds the test target then, postbuild runs, then finally the stamp command is run. I would expect this to run the stamp before the post build runs.

I am clearly missing something to get the dependencies set correctly so that the target should get build, then the stamp file is created, and finally the postbuild should run. Can someone help me figure out what I am missing.

Thanks for any help with this.

I had similar problems:

TL;DR::File-level dependencies of custom targets are not propagated
Just add the file level dependency to the custom command dependency: (not tested by me)

add_custom_command(TARGET ${TARGET_NAME}
POST_BUILD
DEPENDS ${TARGET_NAME}-stamped
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.stamped
COMMAND ${CMAKE_COMMAND} -E echo “hello from post build”)

Details: CMake: dependencies between targets and files and custom commands – Sam Thursfield

Have a look at Operating on Target after it's built to modify based on input file - #5 by ClausKlein

Thanks for the pointer. I will give that a try

cmake_minimum_required(VERSION 3.28...4.0)

project(test_post_build LANGUAGES CXX)

set(TARGET_NAME ${PROJECT_NAME})
set(SOURCE_FILES main.cpp)
add_executable(${TARGET_NAME} ${SOURCE_FILES})

add_custom_command(
    # XXX NO! TARGET ${TARGET_NAME} POST_BUILD
    DEPENDS $<TARGET_FILE:${TARGET_NAME}>
    OUTPUT ${TARGET_NAME}-stamped
    COMMAND ${CMAKE_COMMAND} -E touch ${TARGET_NAME}-stamped
)

add_custom_target(
    checksum
    ALL
    DEPENDS ${TARGET_NAME}-stamped
    COMMAND
        ${CMAKE_COMMAND} -E sha256sum $<TARGET_FILE:${TARGET_NAME}> > ${TARGET_NAME}.md5
)

this works for my with ninja!