Splitting this discussion from this issue comment.
Basically I am considering how to allow a project to set its default custom build type without affecting other project’s build type.
Setup:
- Project A: fetches Project B
- Project A: sets default
CMAKE_BUILD_TYPE
toCustomReleaseA
as local variable (maybe with anif
-guard before/afterproject
) - Project B: sets default
CMAKE_BUILD_TYPE
toCustomReleaseB
as local variable (maybe with andif
-guard before/afterproject
)
Case1: user does not set CMAKE_BUILD_TYPE
as -D
option
- Expectation: Project A and B are built against a default that they wish to implement
- Users: Default behavior for (end-)users
CustomReleaseA
andCustomReleaseB
are expected to be used, but probably that would not happen becauseCMAKE_BUILD_TYPE
is set as a local variable by Project A and propagated to Project B. I don’t think there is a clean way to get such an outcome right now.- The above behavior could be fixed if within
project
the cache variable is always set toset(CMAKE_BUILD_TYPE "" CACHE STRING ...)
byproject()
, the local variable is reset to the cache variable, and the projects use:project(...) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE CustomReleaseA) endif()
Case2: user provides CMAKE_BUILD_TYPE
as -D
option
- Expectation: Both project A and B are built against a configuration that they both recognize
RelWithDebInfo/Debug
- Users: Packagers where typically
RelWithDebInfo
is set, or developers who would requireDebug
- Would always work as intended if the project use an
if
-guard as above
Why have such a design?
This allows the project to define their own default configuration that builds on top of Release
which they would want the typical user to use as a default, e.g. adding native build flags, compiler specific fixes or optimizations, etc. But if the packager like spack always uses Release
as their CMAKE_BUILD_TYPE
, this will ensure that the packager can overwrite those defaults and use the CMake specific defaults to build on top of.
I think I came up to thinking about this issue when seeing a project (ab)use CMAKE_<LANG>_FLAGS_<CONFIG>
and appending flags manually to those. For the most cases that project can change to using target-scoped compile flags, but there could be some merit of putting the project’s default flags into CMAKE_<LANG>_FLAGS_<CustomRelease>
so that they can be overwritten individually for each project.