CMake compiles a temporary C program to detect values for CMAKE_SIZEOF_VOID_P
and other variables.
I have a toolchain file that defined the linker flag -pie
for executable targets and for the temporary program to compile and set CMAKE_SIZEOF_VOID_P
correctly it requires the compiler flags -fPIC
or -fPIE
.
But if I put -fPIC
immediately after -Werror
in CMAKE_C_FLAGS
in the toolchain file then it would have no effect on the temporary program. It would simply get removed along with -Werror
thus causing the temporary program fails to compile and CMAKE_SIZEOF_VOID_P
left unset.
The minimum reproducible example:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.14.1)
project(test)
message("CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}")
# toolchain.cmake
set(CMAKE_C_FLAGS "-Werror -fPIC")
set(CMAKE_EXE_LINKER_FLAGS "-pie")
By executing cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake .
with CMake 3.20.5 I get the following output which shows that CMAKE_SIZEOF_VOID_P
is unset:
CMAKE_SIZEOF_VOID_P:
I expect the following output on my 64 bit machine as a lower version of CMake (such as CMake 3.16.5) would correctly output:
CMAKE_SIZEOF_VOID_P: 8
I believe the problem is introduced by the following change to “Handle NVCC-style -Werror flags” which was first released in CMake 3.19 or so. While handling the “NVCC-style flags” it also erroneously removes other unrelated flags which can cause problems.
https://gitlab.kitware.com/cmake/cmake/-/commit/079ea66468a6ffe0b02c3d6622bc0230fdf455b0
I fixed it by setting -Werror
as the last flag of CMAKE_C_FLAGS
so no flags will be removed along with it but it is rather hackish. I hope that CMake could do a better job at handling -Werror
removal possibly by modifying the regular expression to treat flags immediately after -Werror
that start with a -
differently so that they aren’t mistaken as NVCC Werror arguments and therefore not removed incorrectly.