MAKE_TERMOUT environment variable causes a number of CMake generated variables to not be set correctly

When using the Unix Makefiles generator, if the MAKE_TERMOUT environment variable is set to a non-empty value at CMake generation time (for example, if invoking cmake from a Makefile recipe), many CMake variables are not resolved correctly. This leads to CMake failing to be able to find some libraries (eg. zlib on Ubuntu).

Using CMake 4.1.0 from snap on Ubuntu 24.04 as an example environment, and focusing on CMAKE_LIBRARY_ARCHITECTURE:

echo "cmake_minimum_required(VERSION 4.0)" > CMakeLists.txt
mkdir build{1,2}
cmake -G"Unix Makefiles" -B build1
MAKE_TERMOUT="anything" cmake -G"Unix Makefiles" -B build2
grep -r CMAKE_LIBRARY_ARCHITECTURE

Output:

build1/CMakeFiles/4.1.0/CMakeCCompiler.cmake:  set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
build1/CMakeFiles/4.1.0/CMakeCXXCompiler.cmake:  set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
build2/CMakeFiles/4.1.0/CMakeCCompiler.cmake:  set(CMAKE_LIBRARY_ARCHITECTURE "")
build2/CMakeFiles/4.1.0/CMakeCXXCompiler.cmake:  set(CMAKE_LIBRARY_ARCHITECTURE "")

Many other CMAKE_* variables are also set as empty or with default/incorrect values - diff -r build1 build2 shows many such cases.

By bisecting, I found this behaviour appears to have been introduced by StdIo: Replace uses of KWSys Terminal with StdIo::Print (509c4244) · Commits · CMake / CMake · GitLab - prior to this the environment variable did not appear to have this effect.

From Special Variables (GNU make)

If you invoke a sub-make and redirect its stdout or stderr it is your responsibility to reset or unexport these variables as well, if your makefiles rely on them.

Is it the responsibility of the CMake caller to handle this variable with something like env -u and the previous behaviour was not necessarily supported, or should CMake be responsible for this internally and this is a bug?

I can’t comment on the main topic of your post, but the example CMakeLists.txt file you’re generating is invalid. It needs a project() call after cmake_minimum_required(). See if the behavior changes after you fix that.

Thanks for pointing that out. It doesn’t make a difference to the behaviour I’m seeing - I just went a little too far in trying to make a minimal example.

In practice I observed this since I was invoking a library’s CMake via a Makefile recipe and, while it worked using CMake 3.28, when I tried using CMake 4.1.0 it started failing to find zlib. Some further investigation led to finding this particular environment variable appearing to be the cause.

A more complete example CMakeLists.txt

cmake_minimum_required(VERSION 3.28)

project(Example)

find_package(ZLIB REQUIRED)

With the MAKE_TERMOUT variable set to non-empty value, 3.28 output contains:

Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.3")

whereas 4.1 output contains:

Could NOT find ZLIB (missing: ZLIB_LIBRARY) (found version "1.3")

Ok, that’s a much better example. Could you please open a new bug report in our issue tracker for this, and include that last example with the description. This sounds like a regression in one of the recent releases.

https://gitlab.kitware.com/cmake/cmake/-/issues/new

1 Like

I suspect this was caused by the same problem fixed by CMake MR 11080.