add_custom_target not executing

144 views Asked by At

I am trying to get cmake to execute a custom command of mine. Several other people struggle with this, but I can't get any of the solutions to run.

As an MRE, create a project folder with the CMakeLists.txt and following contents:

# MRE add_custom_command doesn't run

cmake_minimum_required(VERSION 3.20)
project(MRECustomCmd VERSION 0.1)

set(COMPILE_INPUT_LIST
    shaders/a.cu
    shaders/b.cu
)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shaders/a.optixir
    DEPENDS shaders/a.cu
    COMMAND "echo compiling..."
    COMMAND "mkdir ${CMAKE_CURRENT_BINARY_DIR}/shaders"
    COMMAND "echo \"a\" >> shaders/a.optixir"
    VERBATIM
)

add_executable(${PROJECT_NAME}
    src/main.cpp

    shaders/a.cu
    shaders/b.cu
)

add_dependencies(${PROJECT_NAME}
    ${CMAKE_CURRENT_BINARY_DIR}/shaders/a.optixir
)

Where the files `shaders/a.cu' and 'shaders/b.cu' exist (but for this MRE are empty), and 'src/main.cpp' is just

int main(){
    return 0;
}

When I do

cd MreProject
mkdir build
cd build
cmake ..

The output is:

CMake Error at CMakeLists.txt:28 (add_dependencies):

The dependency target

"C:/Users/lobner/Dev/MreCustomCmd/build/shaders/a.optixir" of target

"MRECustomCmd" does not exist.

In the CMake docs it says:

If DEPENDS is not specified, the command will run whenever the OUTPUT is missing; if the command does not actually create the OUTPUT, the rule will always run.

For this reason, I tried my MRE without the DEPENDS line as well - after all it "will always run". But that didn't work either.

Later on, in my actual code I run the custom command in a 'FOREACH' loop, I tried the way to add a new target, which depends on the output file and add the target as a dependency to my project, nothing has executed it so far. So for now, I'd like to "fix" my MRE and see what I did wrong.

1

There are 1 answers

6
KamilCuk On

add_dependencies is for targets where you specify that a target depends on a different target. C:/Users/lobner/Dev/MreCustomCmd/build/shaders/a.optixir is not target, it is a file - the error message informs you of that, however I see it is confusing.

Typically, you add a custom target, you see pairs of add_custom_command followed by add_custom_target.

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shaders/a.optixir
    ...
)
add_custom_target(a_optixir DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shaders/a.optixir)

add_dependencies(${PROJECT_NAME} a_optixir)

Note that add_dependencies add ordering, not dependency, between targets. If you want PROJECT_NAME object files to be rebuilt when a.optixir changes, you have to add OBJECT_DEPENDS or LINK_DEPENDS properties on specific files or targets.