我们的团队正在开发一个新版本的科学 C++ 库。然而,我们在 MacOS Catalina 上尝试将 boost 包含在 CMake 中时遇到了一个我们无法完全理解的问题。
首先,我将更详细地描述这个问题。最后,我将提供一个最小的工作示例,根据我的理解,总结问题。
大目标
我们的总体目标是在我们的软件包中使用boost 库。为此,我们在 CMakeFile 中使用B2 。我们boost.cmake
是基于这个文件的。调用时已经出现问题bootstrap.sh
。
问题
B2 检查本地编译器是否能够执行一个简单的 c++11 文件(这发生在build.sh
,执行的 cxx 文件是check_cxx11.cpp
)。这似乎在 Linux 系统上开箱即用。然而,在 macOS Catalina 上,由于找不到<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>
但是,如果我在终端中使用 clang++ 或 g++ 编译 cpp 示例,则不会出现错误。
我能够发现问题是由于CMakeCXX
设置的环境变量(已经使用 line )。/Library/Developer/CommandLineTools/usr/bin/c++
project(test LANGUAGES CXX)
CXX
在调用 CMake 之前未定义时确实会发生错误。如果我CXX=/usr/bin/clang++
在执行 Cmake 之前导出,则会发生同样的错误。但是,如果我 export CXX=/usr/bin/g++
,一切正常。
再现性
我能够在 macOS Catalina (10.15.7) 的全新安装中重现此问题,其中仅安装了 CMake 和 xcode,因此我确信这不仅是我机器上的问题,而且至少是一般问题这个特定的 OSX 版本。
最小(非)工作示例
因为我发现这个问题与CXX
变量有关,所以我创建了一个最小的工作示例来总结这个问题。
我的CMakeLists.txt看起来像这样:
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(); }
}
如果我在运行 cmake 之前不导出CXX
,则输出为
-- CXX: /Library/Developer/CommandLineTools/usr/bin/c++
并且代码失败。
如果我 export CXX=/usr/bin/clang++
,输出是
-- CXX: /Library/Developer/CommandLineTools/usr/bin/clang++
并且代码失败。
如果我 export CXX=/usr/bin/g++
,输出是
-- CXX: /Library/Developer/CommandLineTools/usr/bin/g++
并且代码有效。
问题
我们想了解为什么会发生这种情况:为什么 CMake 将CXX
变量更改为(显然)错误?为什么代码可以与 g++ 一起使用,但不能与 clang++ 一起使用?
对于 MacOS 用户,安装过程应该是开箱即用的,无需导出任何环境变量。最好通过理解问题来解决这个问题,而不是仅仅通过硬编码使代码工作的东西。