cmakecmake-custom-command

cmake add_custom_command and DEPENDS/TARGET


I have this in my toplevel CMakeLists.txt:

add_subdirectory (src) # add_executable (${PROJECT_NAME} ${_SOURCES})
add_subdirectory (data)

In data subdirectory I want to create a file, when ${PROJECT_NAME} is build. The following doesn't work, returns target "foo" does not exist:

add_custom_command(
        OUTPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.desktop"
        WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
        COMMAND ${INTLTOOLMERGE} -d -u ../po ${PROJECT_NAME}.desktop.in "${PROJECT_NAME}.desktop"
        COMMENT "Creating desktop file"
        DEPENDS ${PROJECT_NAME}
    )

This also doesn't work. Returns: The target name "foo" is unknown in this context

add_custom_command(
        TARGET ${PROJECT_NAME}
        WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
        COMMAND ${INTLTOOLMERGE} -d -u ../po ${PROJECT_NAME}.desktop.in "${PROJECT_NAME}.desktop"
        COMMENT "Creating desktop file"
    )

But this works as expected:

add_custom_command(
        OUTPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.desktop"
        WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
        COMMAND ${INTLTOOLMERGE} -d -u ../po ${PROJECT_NAME}.desktop.in "${PROJECT_NAME}.desktop"
        COMMENT "Creating desktop file"
    )
    add_custom_target (desktopfile DEPENDS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.desktop")
    add_dependencies (${PROJECT_NAME} desktopfile)

Question:

1.- How can I use add_custom_command to run the command when "foo" is build without using a target?

2.- How come add_dependencies knows about "foo" but pure add_custom_command doesn't?

update #1: Simple code:

# /CMakeLists.txt
cmake_minimum_required (VERSION 3.0)
project ("foo")

add_subdirectory (src)
add_subdirectory (data)

# : EOF~

# src/CMakeLists.txt
add_executable (${PROJECT_NAME} main.c)

# : EOF:~

# data/CMakeLists.txt

add_custom_command (
    TARGET ${PROJECT_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E sleep 5
    COMMENT "We're going to try to pause here for 5 seconds"
)

# EOF:~

# src/main.c
#include <stdio.h>

int main () {
    printf ("Hello world");
    return 0;
}

Solution

  • Please use POST_BUILD option.

    From the cmake documentation:

     add_custom_command(TARGET target
                         PRE_BUILD | PRE_LINK | POST_BUILD
                         COMMAND command1 [ARGS] [args1...]
                         [COMMAND command2 [ARGS] [args2...] ...]
                         [WORKING_DIRECTORY dir]
                         [COMMENT comment] [VERBATIM])
    

    This defines a new command that will be associated with building the specified target. When the command will happen is determined by which of the following is specified:

    PRE_BUILD - run before all other dependencies PRE_LINK - run after other dependencies POST_BUILD - run after the target has been built

    Note that the PRE_BUILD option is only supported on Visual Studio 7 or later. For all other generators PRE_BUILD will be treated as PRE_LINK.