Our team is working on a new release of a scientific C++ library. However, we encountered a problem on MacOS Catalina when trying to include boost with CMake that we are unable to understand in its entirety.
First, I will described the problem in more detail. At the end, I will provide a minimal working example that, from my understanding, summarizes the problem.
Big-picture goal
Our big picture goal is to use the boost library in our software package. For that, we use B2 inside our CMakeFile. Our boost.cmake
is based on this file. The problem occurs already when calling bootstrap.sh
.
Problem
B2 checks whether the local compiler is able to execute a simple c++11 file (this happens in build.sh
, the executed cxx file is check_cxx11.cpp
).
This seems to work out-of-the-box on Linux systems. On macOS Catalina however, this fails due to not finding <wchar.h>
:
In file included from check_cxx11.cpp:14:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:86:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iosfwd:95:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/wchar.h:118:15: fatal error: 'wchar.h' file not found
#include_next <wchar.h>
However, if I compile the cpp example with clang++ or g++ out of the terminal, I get no errors.
I was able to find out that the problem is due to the CXX
environmental variable which has been set to /Library/Developer/CommandLineTools/usr/bin/c++
by CMake (already with the line project(test LANGUAGES CXX)
).
The error does occur when CXX
is undefined before calling CMake. If I export CXX=/usr/bin/clang++
before executing Cmake, the same error occurs. However, if I export CXX=/usr/bin/g++
, everything works fine.
Reproducability
I was able to reproduce this issue on a clean installation of macOS Catalina (10.15.7), where only CMake and xcode have been installed, so I am certain that this is not only a problem on my machine but a general issue on at least this specific OSX version.
Minimal (not)-working-example
Since I found out that this issue is related to the CXX
variable, I created a minimal working example that should summarize this issue.
My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.14.3)
project(test LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include(boost)
boost.cmake:
message(STATUS "CXX: " $ENV{CXX})
execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/build_file.sh $ENV{CXX}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
build_shell.sh:
$1 -x c++ -std=c++11 check_cxx11.cpp
check_cxx11.cpp:
#include <thread>
int main()
{
// Check for basic thread calls.
{ auto _ = std::thread::hardware_concurrency(); }
}
If I do not export CXX
before running cmake, the output is
-- CXX: /Library/Developer/CommandLineTools/usr/bin/c++
and the code fails.
If I export CXX=/usr/bin/clang++
, the output is
-- CXX: /Library/Developer/CommandLineTools/usr/bin/clang++
and the code fails.
If I export CXX=/usr/bin/g++
, the output is
-- CXX: /Library/Developer/CommandLineTools/usr/bin/g++
and the code works.
Question
We would like to understand why this happens: Why does CMake change the CXX
variable to be (apparently) wrong? Why does the code work with g++, but not with clang++?
The installation process should work out-of-the-box for MacOS users, without having to export any environmental variables. It would be nice to fix this problem by understanding the problem and not by just hardcoding something that just somehow makes the code work.