Don’t do that. None
is not generally a valid build type, and it’s not a robust way to get the behavior you want.
I agree, but in the absence of any other way to control the CMake default flags this is what at least Arch Linux ended up writing into our guidelines.
In your case, you want to explicitly control the exact flags used, so it sounds to me like you should be setting the non-INIT variables. If a project is trying to modify these variables (which used to be common many years ago in the early days of CMake, but is actively discouraged now), then it depends on how they try to do that. They would already be expecting the cache variables to be defined by the time they get a chance to read or modify them (well, technically that is after the first project()
or enable_language()
call that enables the language they want to control the flags for). Hopefully they are only setting non-cache variables and they are doing so by appending to the existing values, but you’re really at the mercy of whatever they decide to do.
Well, all of this is true. As you correctly note, many free software projects have broken or just sloppily written build systems, and it would be clearly infeasible for us (or any other distribution) to patch or thoroughly review all of them.
This is exactly why my intent/request here is precisely to behave exactly as vanilla CMake would behave, except that -O3
should not be part of the default Release flags.
If you want to only change the defaults and still let the project control these flag variables (which they shouldn’t be setting to begin with, but that’s a whole other topic), you can set the CMAKE_<LANG>_FLAGS_INIT
and CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
variables instead. These are only used on the first run in a build directory, and they are used to initialise the non-INIT variables I mentioned in my previous reply. Again, you can set them either on the command line or in a toolchain file.
Unfortunately, this was the first thing I tried. Setting any of the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
variables on the command line results in CMake default flags being appended to the specified flags. Observe:
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.28)
project(hello)
set(CMAKE_CXX_STANDARD 17)
add_executable(hello_cpp main.cpp)
add_executable(hello_c main.c)
$ env CFLAGS="-O2 -g" CXXFLAGS="-O2 -g" \
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS_RELEASE_INIT="-DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELEASE_INIT="-DNDEBUG" \
-S . -B cmake-build-release
-- The C compiler identification is GNU 14.1.1
-- The CXX compiler identification is GNU 14.1.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/intelfx/devel/landfill/hello/cmake-build-release
$ grep -E '(C|CXX)_FLAGS_RELEASE:STRING' cmake-build-release/CMakeCache.txt
CMAKE_CXX_FLAGS_RELEASE:STRING=-DNDEBUG -O3 -DNDEBUG
CMAKE_C_FLAGS_RELEASE:STRING=-DNDEBUG -O3 -DNDEBUG
So, the unwanted -O3
flag still makes it to the resulting CMake cache.
Any other ideas?