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

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Marc Herbert
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

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: In add_subdirectory( binary_dir), binary_dir/ is just a decoy when there's no sub-target

Marc Herbert
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 <[hidden email]> 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

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake