cmake 在检查 header 文件时使用正确的 C++ 标准
cmake using corrext c++ standard when checking for header files
我正在使用 cmake 构建一个项目,该项目使用 Google 的密集哈希映射。我需要检查相应的 header 文件是否存在。因此我添加了
set (CMAKE_CXX_STANDARD 11)
INCLUDE (CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)
给我的 CMakeLists.txt
。但是,我编译时找不到 header
在一些旧的编译器上。问题是 header 必须编译在
C++11 和这些编译器默认不是 C++11:
/usr/bin/clang++ -o CMakeFiles/cmTC_4186d.dir/CheckIncludeFile.cxx.o -c /home/florent/src/IVMPG/HPCombi/build/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx
In file included from /home/florent/src/IVMPG/HPCombi/build/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx:1:
In file included from /usr/local/include/sparsehash/dense_hash_map:102:
In file included from /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/type_traits:35:
/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
因此 CMake 认为该文件不存在。
所以问题是:如何确保我使用的是 c++11
(甚至 c++14
)
当我测试一些包含或符号时?
宏 CHECK_INCLUDE_FILE_CXX
内部使用 try_compile, which preserves compiler flags in CMAKE_CXX_COMPILE_FLAGS variable, but, until CMake 3.8, it didn't preserve 语言标准 (如 CMAKE_CXX_STANDARD 变量)。
因此,如果您的 CMake 版本为 3.7 或更低,确保检查使用 c++11 的唯一方法是将与标准相关的选项添加到 CMAKE_REQUIRED_FLAGS 调用前的变量 CHECK_INCLUDE_FILE_CXX
:
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
...
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)
是的,CMAKE_CXX_STANDARD 的跨平台方面在那种情况下被破坏了。
如果您有 CMake 3.8 或更高版本,默认 CMake 的行为仍然是忽略语言标准。这样做是为了与旧版本兼容。为了保留语言标准,将策略 CMP0067 设置为 NEW:
cmake_policy(SET CMP0067 NEW)
...
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)
我正在使用 cmake 构建一个项目,该项目使用 Google 的密集哈希映射。我需要检查相应的 header 文件是否存在。因此我添加了
set (CMAKE_CXX_STANDARD 11)
INCLUDE (CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)
给我的 CMakeLists.txt
。但是,我编译时找不到 header
在一些旧的编译器上。问题是 header 必须编译在
C++11 和这些编译器默认不是 C++11:
/usr/bin/clang++ -o CMakeFiles/cmTC_4186d.dir/CheckIncludeFile.cxx.o -c /home/florent/src/IVMPG/HPCombi/build/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx
In file included from /home/florent/src/IVMPG/HPCombi/build/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx:1:
In file included from /usr/local/include/sparsehash/dense_hash_map:102:
In file included from /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/type_traits:35:
/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
因此 CMake 认为该文件不存在。
所以问题是:如何确保我使用的是 c++11
(甚至 c++14
)
当我测试一些包含或符号时?
宏 CHECK_INCLUDE_FILE_CXX
内部使用 try_compile, which preserves compiler flags in CMAKE_CXX_COMPILE_FLAGS variable, but, until CMake 3.8, it didn't preserve 语言标准 (如 CMAKE_CXX_STANDARD 变量)。
因此,如果您的 CMake 版本为 3.7 或更低,确保检查使用 c++11 的唯一方法是将与标准相关的选项添加到 CMAKE_REQUIRED_FLAGS 调用前的变量 CHECK_INCLUDE_FILE_CXX
:
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
...
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)
是的,CMAKE_CXX_STANDARD 的跨平台方面在那种情况下被破坏了。
如果您有 CMake 3.8 或更高版本,默认 CMake 的行为仍然是忽略语言标准。这样做是为了与旧版本兼容。为了保留语言标准,将策略 CMP0067 设置为 NEW:
cmake_policy(SET CMP0067 NEW)
...
CHECK_INCLUDE_FILE_CXX("sparsehash/dense_hash_map" HAVE_SPARSEHASH)