[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
Sun Jul 14 00:58:16 EDT 2019


Filed new bug https://gitlab.kitware.com/cmake/cmake/issues/19475

Le jeu. 13 juin 2019 à 11:06, Marc Herbert <marc.herbert at gmail.com> a
écrit :

> 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/20190713/22999a03/attachment.html>


More information about the CMake mailing list