PREFACE: I am only talking about compiling locally, not about installing projects. This is because I haven't done enough research on proper install
with CMake, though please chime in if my question directly relates to install
practices (seems likely).
TL;DR
In what scenarios do you not want to gather all project libraries being built into the same directory? Why doesn't anybody ever
CACHE
theCMAKE_*_OUTPUT_DIRECTORY
paths?Is there ever a need to perform
$<CONFIG>
level specifications directly?Should the general default be to
CMAKE_BINARY_DIR
,CMAKE_CURRENT_BINARY_DIR
, orPROJECT_BINARY_DIR
?
1. To cache or not to cache?
From this excellent answer
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
which you see in many projects across the web.
- A parent
CMakeLists.txt
cannot override these. - If a parent project wants to / needs to change these, e.g. to put all in the same folder, it is impossible.
So the suggested revision would be to always CACHE PATH "description"
:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE PATH "Where to place compiled static libraries.")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE PATH "Where to place compiled shared libraries.")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE PATH "Where to place compiled executables.")
- Is there any reason not to cache?
2. Treatment of $<CONFIG>
builds
This should pretty much always be left to the generator, yes? My understanding (and experience) is by setting the non-config one, generators (Visual Studio, XCode, ...) that use folders per-config build are still content to place things where they ordinarily would. AKA by not setting config level CMAKE_*_OUTPUT_DIRECTORY_*
I am passing control to the generator to let it decide.
3. BINARY_DIR
, CURRENT_BINARY_DIR
, or PROJECT_BINARY_DIR
?
On the other hand, say a developer does not want other projects they are building to end up in the same directory. Should it not further be the case that I use CMAKE_CURRENT_BINARY_DIR
OR PROJECT_BINARY_DIR
? In the event that just a raw CMAKE_BINARY_DIR
is used, without a CACHE
, then I have absolutely no way to prevent a sub-project I am building from ending up next to mine.
By using either CMAKE_CURRENT_BINARY_DIR
or PROJECT_BINARY_DIR
, if a user does not want this library to end up next to the parent project they can simply set the CMAKE_*_OUTPUT_DIRECTORY
variables after configuring this one.
Summary
Basically, there don't seem to be any standards for how these variables ought to be used. I'm thrilled at how versatile CMake is, I'm not saying they should be doing any defaults here at all -- that is to be determined by the project. I'm trying to understand what the most appropriate default choice is, that also allows developers to bypass my defaults if they so choose.