Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect C++11 support of a compiler with CMake

Tags:

c++

c++11

cmake

Is there a way to let CMake detect automatically if a compiler supports C++11 or not?

As it would be nice to inform the users during the CMake run that the code will not compile as the compiler does not support C++11. At the moment I set the C++11 flags. However, if a compiler does not support it the user gets compile errors instead of an error during the CMake run.

Perfect would be something that works like find_package(). However, I have not found any module or function which provides the functionality needed.

Additional it would be nice to have the feature to detect if the compiler needs the flags std=c++0x or std=c++11.

Is there something available or do I need to develop this on my own?

Below is some code I use so far, however it works only with GNU'c GCC compilers. It would be nice if there would be a more general solution.

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) 
like image 596
tune2fs Avatar asked Jun 11 '12 16:06

tune2fs


People also ask

Does my compiler support C ++ 11?

To see if your compiler has C++11 support, run it with just the --version option to get a print out of the version number. Do this for whichever compiler(s) you wish to use with Rosetta. Acceptable versions: GCC/g++: Version 4.8 or later.

How does CMake find C compiler?

1. Inspecting the Default Compiler. When CMake is invoked to read a configuration file, temporary files are generated, including a cache and a CMakeFiles directory containing information specific to the environment. CMake uses this information to select the most appropriate compiler for the project.

How does CMake identify compiler?

CMake does check for the compiler ids by compiling special C/C++ files. So no need to manually include from Module/Compiler or Module/Platform . This will be automatically done by CMake based on its compiler and platform checks. CMake: In which Order are Files parsed (Cache, Toolchain, …)?

Which C++ compiler does CMake use?

Usually under Linux, one uses CMake to generate a GNU make file which then uses gcc or g++ to compile the source file and to create the executable. A CMake project is composed of source files and of one or several CMakeLists.


1 Answers

If you have CMake version 3.1.0 or later you can detect what C++ features your C++ compiler supports

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() 

But normally you don't need to use the CMake variable CMAKE_CXX_COMPILE_FEATURES in your CMake scripts. Instead there are two ways of how to tell CMake under which C++ standard your C++ files should be compiled, either by specifying the C++ standard explicitly or by specifying the required C++ features and let CMake induce the C++ standard. CMake will make sure the C++ compiler is invoked with the correct command line flags (e.g. -std=c++11).

1. Specifying the C++ standard explicitly

You could specify the C++ standard explicitly, by setting the CMake properties CXX_STANDARD and CXX_STANDARD_REQUIRED for your CMake target.

$ 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. Specifying the required C++ features and let CMake induce the C++ standard

You could use the CMake command target_compile_features to specify the C++ features that are made use of in your CMake target. From this list CMake will induce the C++ standard to be used. The CMake global property CMAKE_CXX_KNOWN_FEATURES lists the C++ features you can choose from.

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() 

For example, this C++ program with the filename main.cc makes use of the C++11 features: 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; } 

This CMakeLists.txt file would build it

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}) 
like image 73
Erik Sjölund Avatar answered Sep 19 '22 14:09

Erik Sjölund