Custom target is not being built unless the ALL keyword is included

My understanding is that custom targets which depend on another executable or library target should always be built after the dependent target is built.

Example:

project(foo)

add_executable(foo foo.cpp)

add_custom_target(print COMMAND echo "Some printed text." COMMENT "Running the print custom target.")

add_dependencies(print foo)

However, using the CMakeListst.txt included does not result in the print target being built.

If I add the ALL keyword to add_custom_target, it builds. However, I wouldn’t have expected the ALL keyword to be required here.

I am using CMake version 3.22. I’ve tried the same CMakeLists.txt on Windows 10 and Debian 10.

Here are the cmake commands I am using to build:

$ cmake -S . -B build
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: [path]/build

$ cmake --build build
[ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o
[100%] Linking CXX executable foo
[100%] Built target foo

Given the COMMENT on the print custom target, I would have expected the message "Running the print custom target." to be printed to the standard output stream here, as well as the message "Some printed text.".

This is correct.

ALL depends on foo
print depends on foo

So, foo is built before print.

however

when you build ALL then foo is built first. There is no reason why print should be build, it is not needed for ALL.

Have a look at CMake options and try to build print instead of ALL.

1 Like

I think the “always be built after” makes it not correct. It will be built after if it needs to be built. If you want something that builds with the target, there is add_custom_command(POST_BUILD).

1 Like

Thanks for your thoughtful responses, @hex and @ben.boeckel! That clears things up.

@hex - After drawing out the target dependency graph based on the description your provided, things suddenly clicked.

For reference, this is what my understanding of the target dependency graph looks like:


@ben.boeckel thanks for pointing out this important distinction.

I misinterpreted the add_custom_target documentation. In particular, the following line threw me off:

“The target has no output file and is always considered out of date…”

This gave me the impression that a custom target will always be rebuilt to bring it up to date.

However, I see now that there isn’t always a need to build a custom target. For example, if ALL doesn’t depend on print, then nothing depends on print, so building it would be wasteful.

I greatly appreciate all of your help!

2 Likes