[CMake] In add_subdirectory( binary_dir), binary_dir/ is just a decoy when there's no sub-target

Marc Herbert marc.herbert at gmail.com
Thu Jun 13 14:06:04 EDT 2019


Ping?

I'd like to file a bug but I don't know what is the intended behavior:
1. Should binary_dir work even when no target?
2. Should CMake warn/error that binary_dir is not supported unless targets
are used?

Marc

Le mar. 4 juin 2019 à 12:05, Marc Herbert <marc.herbert at gmail.com> a écrit :

> tl;dr: should there be at least one target per CMakeLists.txt?
>
> https://cmake.org/cmake/help/v3.14/command/add_subdirectory.html
> > add_subdirectory(source_dir [binary_dir] )
> > "The binary_dir specifies the directory in which to place the output
> files. [...] If binary_dir is not specified, the value of source_dir,
> before expanding any relative path, will be used (the typical usage)."
>
> I found this part of the documentation to be correct ONLY when the
> subdirectory defines and uses its own "sub-"target(s). If the subdirectory
> refers to higher main targets instead then binary_dir/ is just a decoy: the
> subdirectory build happens elsewhere. binary_dir is a decoy whether it's
> explicit or default. It exists but there are only totally generic and
> unused files there.
>
> Example:
>
> mainsrc/
> ├── CMakeLists.txt
> ├── inmodule
> │   ├── CMakeLists.txt
> │   ├── infile.c
> └── mainfile.c
>
>
> # mainsrc/CMakeLists.txt
> add_executable(mainexe mainfile.c)
> add_subdirectory(inmodule [ decoy_binary_dir ] )
>
> # mainsrc/inmodule/CMakeLists.txt
> target_sources(mainexe PRIVATE infile.c) # <= direct reference, no
> sub-target
>
>
> cmake -GNinja -B build -S mainsrc && ninja -C build
>
> build
> ├── CMakeFiles
> │   ├──
> │   ├── mainexe.dir
> │   │   ├──
> │   │   ├──
> │   │   ├── inmodule       <= ACTUAL binary_dir!
> │   │   │   └── infile.c.o
> │   │   ├── mainfile.c.o
> │   │   ├──
> │   │   :
> │   ├──
> │   :
> ├── inmodule       <= decoy with unused, boilerplate files and no
> reference to any code
> │   ├── CMakeFiles/
> │   ├── cmake_install.cmake
>
>
> The midly irritating part is that cmake complains about the lack of a
> binary_dir argument if the module is an _out-of-tree_ subdirectory:
>
> CMake Error at CMakeLists.txt:5 (add_subdirectory):
>   add_subdirectory not given a binary directory but the given source
>   directory "~/cmake-test/outmodule" is not a subdirectory of
>   "~/cmake-test/maindir".  When specifying an out-of-tree source
>   a binary directory must be explicitly specified.
>
> That request makes sense of course except... when given that binary_dir
> argument it requested, it's still becomes a decoy as described above.
> This is the actual (and funny) binary_dir /in this out-of-tree case:
> build
> ├── CMakeFiles
> │   ├── mainexe.dir
> │   │   └── home
> │   │       └── joe
> │   │           └── cmake-test
> │   │               └── outmodule
> │   │                   └── outfile.c.o
>
>
>
> Reproduced with cmake version 3.14.4. No difference between make and ninja.
>
> Researching the interwebs most people, tutorials and other documents seem
> to assume (at least) one target per CMakeLists.txt. Should such a
> recommendation be made more official to avoid the sort of confusion above?
> Could this recommendation avoid other, unrelated problems I haven't
> experienced? Yet?
>
> Marc
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190613/a23dc027/attachment.html>


More information about the CMake mailing list