CMake로 컴파일러의 C ++ 11 지원을 감지하는 방법
컴파일러가 C ++ 11을 지원하는지 여부를 CMake가 자동으로 감지하도록하는 방법이 있습니까?
컴파일러가 C ++ 11을 지원하지 않기 때문에 코드가 컴파일되지 않는다는 것을 CMake 실행 중에 사용자에게 알리는 것이 좋습니다. 지금은 C ++ 11 플래그를 설정했습니다. 그러나 컴파일러가이를 지원하지 않는 경우 사용자는 CMake 실행 중에 오류 대신 컴파일 오류를받습니다.
Perfect는 find_package()
. 그러나 필요한 기능을 제공하는 모듈이나 기능을 찾지 못했습니다.
또한 컴파일러에 플래그 std=c++0x
또는 .NET Framework가 필요한지 감지하는 기능이 있으면 좋을 것 std=c++11
입니다.
사용 가능한 것이 있습니까? 아니면 직접 개발해야합니까?
아래는 지금까지 사용하는 코드이지만 GNU'c GCC 컴파일러에서만 작동합니다. 더 일반적인 해결책이 있다면 좋을 것입니다.
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
message(STATUS "C++11 activated.")
add_definitions("-std=gnu++11")
elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
message(WARNING "C++0x activated. If you get any errors update to a compiler which fully supports C++11")
add_definitions("-std=gnu++0x")
else ()
message(FATAL_ERROR "C++11 needed. Therefore a gcc compiler with a version higher than 4.3 is needed.")
endif()
else(CMAKE_COMPILER_IS_GNUCXX)
add_definitions("-std=c++0x")
endif(CMAKE_COMPILER_IS_GNUCXX)
CMake 버전 3.1.0 이상이있는 경우 C ++ 컴파일러가 지원하는 C ++ 기능을 감지 할 수 있습니다.
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
message("Your C++ compiler supports these C++ features:")
foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
message("${i}")
endforeach()
그러나 일반적으로 CMake 스크립트에서 CMake 변수 CMAKE_CXX_COMPILE_FEATURES 를 사용할 필요가 없습니다 . 대신 C ++ 표준을 명시 적으로 지정하거나 필요한 C ++ 기능을 지정하고 C ++ 표준을 유도하여 C ++ 파일을 컴파일해야하는 C ++ 표준을 CMake에 알리는 두 가지 방법이 있습니다. CMake는 C ++ 컴파일러가 올바른 명령 줄 플래그 (예 : -std = c ++ 11)로 호출되는지 확인합니다.
1. 명시 적으로 C ++ 표준 지정
CMake 타겟에 대해 CMake 속성 CXX_STANDARD 및 CXX_STANDARD_REQUIRED 를 설정하여 C ++ 표준을 명시 적으로 지정할 수 있습니다.
$ cat /tmp/src/CMakeLists.txt
project(foobar CXX)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
add_executable(prog main.cc)
set_property(TARGET prog PROPERTY CXX_STANDARD 11)
set_property(TARGET prog PROPERTY CXX_STANDARD_REQUIRED ON)
$ cat /tmp/src/main.cc
int main() {
return 0;
}
$ mkdir /tmp/build
$ cd /tmp/build
$ cmake /tmp/src
-- The CXX compiler identification is GNU 4.8.2
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
$ make VERBOSE=1 | grep main.cc | grep -- "-c"
/usr/bin/c++ -std=gnu++11 -o CMakeFiles/prog.dir/main.cc.o -c /tmp/src/main.cc
$
2. 필요한 C ++ 기능을 지정하고 CMake가 C ++ 표준을 유도하도록합니다.
CMake 명령 target_compile_features 를 사용하여 CMake 대상에서 사용되는 C ++ 기능을 지정할 수 있습니다 . 이 목록에서 CMake는 사용할 C ++ 표준을 유도합니다. CMake 전역 속성 CMAKE_CXX_KNOWN_FEATURES 는 선택할 수있는 C ++ 기능을 나열합니다.
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
message("Your CMake version supports these C++ features:")
get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
foreach(i ${known_features})
message("${i}")
endforeach()
예를 들어, main.cc 파일 이름을 가진이 C ++ 프로그램 은 C ++ 11 기능을 사용합니다. cxx_strong_enums , cxx_constexpr , cxx_auto_type
#include <cstdlib>
int main(int argc, char *argv[]) {
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
constexpr float a = 3.1415f;
auto b = a;
return EXIT_SUCCESS;
}
이 CMakeLists.txt 파일이 빌드합니다.
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
set(needed_features
cxx_strong_enums
cxx_constexpr
cxx_auto_type)
target_compile_features(foobar PRIVATE ${needed_features})
이 시점에서 CMake에는 C ++ 11을 지원하는 편리한 형식이 없습니다. 이상적으로는 다음과 같은 C ++ 11 프로젝트를 지정합니다.
project(foo CXX11)
시작 부분에 CMakeLists.txt
. 그러나 CXX11
프로젝트 유형은 존재하지 않습니다 (아직). 그때까지는 2 단계 기술을 사용할 수 있습니다.
- 컴파일러 유형 및 버전 확인
- 그에 따라 빌드 플래그를 조정하십시오.
예를 들어 다음은 Clang 및 GCC에서 C ++ 11을 지원하는 데 사용하는 것입니다.
# Initialize CXXFLAGS.
set(CMAKE_CXX_FLAGS "-Wall -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
# Compiler-specific C++11 activation.
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
else ()
message(FATAL_ERROR "Your C++ compiler does not support C++11.")
endif ()
필요한 것을 정확히 수행한다고 주장하는 이 CMake 스크립트 를 찾았습니다 . 또한 개별 C ++ 11 기능을 확인할 수도 있습니다. 나는 사이에서 결정 수 있다고 생각하지 않습니다 std=C++0x
및 std=C++11
하지만.
At the time of this writing (pre-GCC 4.8), it may not be a good idea to detect C++11 flags and add them. This is because changing the standard (at least for GCC) breaks ABI compatibility, which can result in link errors.
Therefore, the use of the C++11 standard should explicitly specified with the compiler setting during the initial CMake configuration of the project, e.g.
CXX='g++ -std=c++11' cmake /path/to/source
That is, the use of -std=c++11 should be treated like a separate compiler, which should not be mixed or changed in a project.
Use:
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} has no C++11 support.")
endif()
This is from Enabling C++11 (C++0x) in CMake with minor changes.
In CMake 3.1* the proper, simple way to do this is to use the CXX_STANDARD
property for a given target. For example, given this simple example using auto
(named main.cpp
):
#include <iostream>
int main() {
auto num = 10;
std::cout << num << std::endl;
return 0;
}
The following CMakeLists.txt
will enable C++11 support:
cmake_minimum_required(VERSION 3.3)
project(Hello CXX)
set(SOURCE_FILES main.cpp)
add_executable(Hello ${SOURCE_FILES})
set_property(TARGET Hello PROPERTY
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
)
This will add any flags necessary such as -std=c++11
. Note that the CXX_STANDARD_REQUIRED
property will prevent the standard from decaying to an earlier version.
The proper, not-as-simple way to specify the CMAKE_CXX_KNOWN_FEATURES
that you use, such as cxx_auto_type
:
cmake_minimum_required(VERSION 3.3)
project(Hello CXX)
set(SOURCE_FILES main.cpp)
add_executable(Hello ${SOURCE_FILES})
target_compile_features(Hello PRIVATE cxx_auto_type)
* I have not tried this on CMake 3.1, but have verified it works in CMake 3.3. The documentation for 3.1 does document this so it should work.
We've written a CMake module for detecting and enabling C++11 support which you can find here:
https://github.com/NitroShare/CXX11-CMake-Macros
It's still a work-in-progress, but we are using it for a number of Qt projects that target Windows/Linux/Mac. Currently only MSVC++, GCC, and Clang are supported.
Example:
include(CXX11)
check_for_cxx11_compiler(CXX11_COMPILER)
# If a C++11 compiler is available, then set the appropriate flags
if(CXX11_COMPILER)
enable_cxx11()
endif()
참고URL : https://stackoverflow.com/questions/10984442/how-to-detect-c11-support-of-a-compiler-with-cmake
'Nice programing' 카테고리의 다른 글
사용자 정의 함수에 도구 설명을 추가하는 방법 (0) | 2020.10.31 |
---|---|
푸시 알림을위한 장치 토큰 가져 오기 (0) | 2020.10.31 |
함수의 PHP 액세스 전역 변수 (0) | 2020.10.31 |
간단한 파이프로 소수점 2 자리로 제한 (0) | 2020.10.31 |
4 개의 그룹으로 배열 요소를 작업하는 루비 (0) | 2020.10.31 |