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?
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.
I'm with @Tsyvarev. I don't see the user of a CMake enabled project wanting to change the output path of the build artifacts, only the install path.
1. To cache or not to cache?
Just don't set the
CMAKE_*_OUTPUT_DIRECTORY
variables as cached, because if another CMake project uses yours as a sub-project you would under certain circumstances overwrite your parent project's settings (cached variables are global).2. Treatment of
$<CONFIG>
buildsYes. It's only given when the generator's defaults are not fitting ("Config Name" = "Sub Folder Name").
3.
CMAKE_BINARY_DIR
,CMAKE_CURRENT_BINARY_DIR
, orPROJECT_BINARY_DIR
?So I would say the save variant would be to first check with an
if ()
statement if someone else has already set the variable and also to use ofPROJECT_BINARY_DIR
:Then a user of your project may still set the variables from the outside or a parent project could set it and you have a default if it was not set.