4

I have a custom target, and I want it to depend on the default target (the one that is built with make).

add_custom_target(foo ....)
add_dependency(foo default_target_name_goes_here)

What is the name of the default target?

I've tried ALL, ALL_BUILD, MyProjectsName, DEFAULT,...

Finding anything in the CMake documentation is always an unsuccessful adventure...

UPDATE: it seems CMake was designed in such a way that this is extremely hard to fix/implement: bugreport getting +1's since 2009. Who indeed would like to have a custom target that depends on, for example, the all target? Or in other words: who does ever write make && make test?...

gnzlbg
  • 7,135
  • 5
  • 53
  • 106

2 Answers2

4

The default build target does not exist as a CMake target at CMake configure time. It is only exists in the generated build system. Therefore it is not possible to have the default target depend on a custom target.

sakra
  • 62,199
  • 16
  • 168
  • 151
  • "use the ALL option": this adds my target to ALL. I want to add ALL to my target as a dependency. This cannot be done. There is a bugreport/feature request from 2009 here: http://public.kitware.com/Bug/view.php?id=8438 – gnzlbg May 29 '15 at 15:33
  • Rephrase your question to "I want the default target to depend on it". – sakra May 29 '15 at 15:36
  • What is unclear in the first sentence of my question: "I have a custom target, and I want it to depend on the default target " ? – gnzlbg May 29 '15 at 15:37
  • I read it as "I want it (my custom target) to depend on the default target". That is different to "I want the default target to depend on my custom target". – sakra May 29 '15 at 15:40
  • Your reading was correct. What ALL does is add a custom target to the `ALL` target, so that when you build the ALL target, that custom target is also built. I do not want this. I want the `ALL` target to be built when I write `make my_target`. That is: I want `make my_target` to be equivalent to `make && make my_target`. – gnzlbg May 29 '15 at 15:42
1

I think a possible solution depends strongly on the use case. E.g. if this is for executing a test after the system has been build you would use CTest instead of calling make directly.

To your CMakeLists.txt you would add:

 add_test(NAME foo COMMAND ...)

and then use CTest for building and executing:

 ctest --build-and-test ...

More generally speaking and not considering the question of why you would like to do it - I think the best thing would be to just name and rely on concrete target dependencies instead of just taking ALL targets - I just wanted to add two possibilities to do what you wanted to do.

One would be to determine/track the list of all targets used as discussed here. This would look e.g. for library targets like this (getting your own/private GlobalTargetList):

macro(add_library _target)
    _add_library(${_target} ${ARGN})
    set_property(GLOBAL APPEND PROPERTY GlobalTargetList ${_target})
endmacro()

and use it at the end of your main CMakeLists.txt with

get_property(_allTargets GLOBAL PROPERTY GlobalTargetList)
add_dependencies(foo ${_allTargets})

Edit: Global BUILDSYSTEM_TARGETS property was released with CMake 3.7

The second - less favorable - approach does require that the foo target is not part of the ALL build (otherwise you end-up in an endless loop):

add_custom_target(foo)
set_target_properties(foo PROPERTIES EXCLUDE_FROM_ALL 1) 

add_custom_command(
    TARGET foo
    PRE_BUILD
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ALL_BUILD --config $<CONFIGURATION>
)
Florian
  • 39,996
  • 9
  • 133
  • 149
  • CMake likes to put everything into the ALL target by default (e.g. external projects). Building anything generally requires building the ALL target first: I'd rather write `make tests` instead of `make && make tests`. This problem gets worse as the number of targets increases. User-defined targets cannot depend on any of the builtin targets: ALL, INSTALL, ... The "simplest" solution I found is to collect anything added to ALL into different targets, and then add dependencies to these. Not as comfortable, but works. – gnzlbg Jun 01 '15 at 16:41
  • If you are refering to the `include_external_msproject()` command, I admit I have patched my CMake 2.8.10 version to default the `EXCLUDE_FROM_ALL` property to `TRUE` (see `cmIncludeExternalMSProjectCommand.cxx`). And I generally prefer to have the `EXCLUDE_FROM_ALL` set to `TRUE` (e.g. via the corresponding directory property). That allows in an complex build environment to selectivly compile only specific targets and their dependencies. But when I have setup the cross-target depencies correctly, it works for me just fine (including make enviroments using parallel build engines). – Florian Jun 01 '15 at 19:28
  • Actually I was referring to "ExternalProject_Add", but yes, `EXCLUDE_FROM_ALL` is a better default :) – gnzlbg Jun 02 '15 at 18:26