0

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
  • I am not entirely sure, what triggered it, but it works now (though when building in VS, not when just generating with the cmake .. command). I did update from cmake 3.26.4 to 3.27.7, but I doubt custom_command was broken in 3.26.4, it seems rather central to me. Commented Oct 16, 2023 at 16:59

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Okay, thanks so far. If anything, I'd want to rebuild when a.cu changes. I added a custom target, like you suggested (but with the DEPENDS to the a.cu file) and changed the dependency to the custom target. Now I don't get an error, but the custom command still is not run.
Though for completenes sake, I tried with the DEPENDS to a.optixir as well. It, too, doesn't generate an error but doesn't run the custom command either.
I'd want to rebuild Rebuild what exactly?
The .cu files are Cuda (/Optix) files. They contain code that mostly runs on the graphics card, but some of it can be run on the CPU, e.g. a data structure can be shared between the two. If that changes, then I'd need to rebuild basically the entire project (or at least anything that depends on the .cu file)
I know nothing about CUDA, the question stands. CMake has already utilities for CUDA, like cliutils.gitlab.io/modern-cmake/chapters/packages/CUDA.html .
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.