2

I have a subdirectory foo/ which I want to build

CMakeLists.txt:

add_subdirectory(foo)

Inside foo/ I have a number of targets I want to build, and I want to "group" them under a single phony target, also called foo.

foo/CMakeLists.txt:

add_custom_target(foo ALL)

add_library   (foo_lib ...)
add_executable(foo_bin ...)
add_executable(foo_tests ...)

add_dependencies(foo foo_lib)
add_dependencies(foo foo_bin)
add_dependencies(foo foo_test)

This will allow me to build all these related targets by typing make foo

This works fine, except when I am in the directory above foo/

make foo in the directory in which foo subdirectory exists does nothing.

I believe this is because make considers foo a target that is not out of date, since the directory exists. The fix is to mark it as a PHONY target.

According to the CMake documentation on add_custom_target, the target will always be considered out-of-date (ie: in make parlance, it will be a PHONY target).

Question:

Why is my foo custom target not being built inside the directory containing the foo subdirectory?

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
  • 1
    Having a target with the same name as the directory is asking for trouble. Does it work for a different target name? – usr1234567 Sep 05 '16 at 07:34
  • As to my knowledge CMake does not generate `PHONY` targets for the subdirectories. They are all on root level. `make help` should list what you can call. Have you considered to add it as an external project? – Florian Sep 05 '16 at 07:35
  • @usr1234567 yes, it does work for other targets. This almost certainly is because of the directory with the same name. When you say it's asking for trouble, I can't help but imagine a lot of people have a subdirectory with the same name as an app they're creating, so the target matches the directory name? Ie, this must be a situation which happens a lot? – Steve Lorimer Sep 05 '16 at 07:38
  • In my experience, the only "legal" place where to launch the build from is the `${CMAKE_BINARY_DIR}`, where you generate the folder. Launching `make` from any other place it's "undefined behaviour". If I find the documentation, I'll post a proper answer. – Antonio Sep 05 '16 at 12:07
  • BTW, what happens if you rename your directory `foo2` and of course use instead `add_subdirectory(foo2)`? (Keeping unchanged the `foo` target) – Antonio Sep 05 '16 at 12:19
  • @Antonio changing the dir name works. That's not a suitable solution though (for my use case). I can't believe cmake forces you to build all or nothing. The fact that makefiles exist throughout the build tree makes me think that building in a sub tree is by design, and hence, this is a bug rather than undefined behavior. – Steve Lorimer Sep 05 '16 at 12:24
  • I didn't mean you have to build all or nothing, but that from the main directory you have to specify the target in the command line. Would it be an option to use [ninja](https://ninja-build.org/) to build? About the modularity, at least for ninja the `build.ninja` file exists only in the main build directory. (BTW, this is a very interesting problem) P.S. Please specify the cmake version. – Antonio Sep 05 '16 at 12:59
  • CMake + Ninja can only build targets from the ${CMAKE_BINARY_DIR}, IIRC. – usr1234567 Sep 05 '16 at 16:59
  • 1
    I once raised [an issue](https://cmake.org/Bug/view.php?id=15614) in CMake's bug tracker with a [related problem](http://stackoverflow.com/questions/30719275/add-custom-command-is-not-generating-a-target) and got the following reply: "CMake is not intended to produce specific content in a Makefile. Top-level target names created by add_custom_target are always logical (i.e. phony) names. It is simply not allowed to have a file of the same name." – Florian Sep 06 '16 at 07:06
  • 1
    @usr1234567 Yep, I confirm. But you can specify any target in the command line, and the directory with the same name of the target shouldn't be a problem. All my subdirectory CMakeLists.txt files begin with `get_filename_component(targetname "${CMAKE_CURRENT_SOURCE_DIR}" NAME)` – Antonio Sep 06 '16 at 08:21

0 Answers0