PROTON-1621: Enable C++11 example testing for C++11 build environments Run the C++ compilier feature checking from the top level Cmake file so examples and the C++ binding are built consistently.
NOTE: This does not address the problem of building examples with partially capable compilers (MSVC < 13), only compilers that advertize full C++11 support. Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/6b2e7dcd Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/6b2e7dcd Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/6b2e7dcd Branch: refs/heads/go1 Commit: 6b2e7dcdbee49947f2fdcfa2a8f5950a9b87fbd3 Parents: 38019a6 Author: Alan Conway <acon...@redhat.com> Authored: Fri Oct 13 18:10:04 2017 +0100 Committer: Alan Conway <acon...@redhat.com> Committed: Fri Oct 13 18:51:37 2017 +0100 ---------------------------------------------------------------------- CMakeLists.txt | 2 + .../cpp/multithreaded_client_flow_control.cpp | 3 +- proton-c/bindings/cpp/CMakeLists.txt | 43 +------ proton-c/bindings/cpp/cpp.cmake | 116 ++++++++++++++----- 4 files changed, 96 insertions(+), 68 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6b2e7dcd/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index b87f232..bab0ccf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,6 +192,8 @@ macro(set_search_path result) file(TO_NATIVE_PATH "${${result}}" ${result}) # native slash separators endmacro() +# Include C++ compiler definition needed by bindings/cpp and examples/cpp +include(${CMAKE_CURRENT_SOURCE_DIR}/proton-c/bindings/cpp/cpp.cmake) add_subdirectory(proton-c) add_subdirectory(examples) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6b2e7dcd/examples/cpp/multithreaded_client_flow_control.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/multithreaded_client_flow_control.cpp b/examples/cpp/multithreaded_client_flow_control.cpp index 3f7e2b4..427b9c8 100644 --- a/examples/cpp/multithreaded_client_flow_control.cpp +++ b/examples/cpp/multithreaded_client_flow_control.cpp @@ -261,7 +261,8 @@ int main(int argc, const char **argv) { int count = n_messages * n_threads; // Total messages to be received, multiple receiver threads will decrement this. - std::atomic_int remaining(count); + std::atomic_int remaining; + remaining.store(count); // Run the proton container proton::container container; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6b2e7dcd/proton-c/bindings/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt index 859e364..33cbfa8 100644 --- a/proton-c/bindings/cpp/CMakeLists.txt +++ b/proton-c/bindings/cpp/CMakeLists.txt @@ -17,47 +17,8 @@ # under the License. # -set (BUILD_CPP_03 OFF CACHE BOOL "Compile the C++ binding as C++03 even when C++11 is available") - -# This effectively checks for cmake version 3.1 or later -if (DEFINED CMAKE_CXX_COMPILE_FEATURES) - if (BUILD_CPP_03) - set(STD 98) - else () - set(STD 11) - endif () - set(CMAKE_CXX_STANDARD ${STD}) - set(CMAKE_CXX_EXTENSIONS OFF) -# AStitcher 20170804: Disabled for present - work on this when Windows C++ works -# cmake_minimum_required(VERSION 3.1) -# include(WriteCompilerDetectionHeader) -# write_compiler_detection_header( -# FILE cpp_features.h -# PREFIX PN -# COMPILERS GNU Clang MSVC SunPro -# FEATURES ${CMAKE_CXX_COMPILE_FEATURES} -# ALLOW_UNKNOWN_COMPILERS) - if (MSVC) # Compiler feature checks only needed for Visual Studio in this case - include(cpp.cmake) - endif() -else () - if (BUILD_CPP_03) - set(CXX_STANDARD "-std=c++98") - else () - include(CheckCXXCompilerFlag) - # These flags work with GCC/Clang/SunPro compilers - check_cxx_compiler_flag("-std=c++11" ACCEPTS_CXX11) - check_cxx_compiler_flag("-std=c++0x" ACCEPTS_CXX0X) - if (ACCEPTS_CXX11) - set(CXX_STANDARD "-std=c++11") - elseif(ACCEPTS_CXX0X) - set(CXX_STANDARD "-std=c++0x") - include(cpp.cmake) # Compiler checks needed for C++0x as not all C++11 may be supported - else() - include(cpp.cmake) # Compiler checks needed as we have no idea whats going on here! - endif() - endif() -endif () +# NOTE: cpp.cmake is included at the top level so the examples can be built with +# the same version C++ compiler as the library. include_directories( "${CMAKE_SOURCE_DIR}/proton-c/include" http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6b2e7dcd/proton-c/bindings/cpp/cpp.cmake ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/cpp.cmake b/proton-c/bindings/cpp/cpp.cmake index e49ec9a..2c8f296 100644 --- a/proton-c/bindings/cpp/cpp.cmake +++ b/proton-c/bindings/cpp/cpp.cmake @@ -17,35 +17,99 @@ # under the License. # +include(CheckCXXCompilerFlag) +include(CheckCXXSourceCompiles) + # Check C++ capabilities. -include(CheckCXXSourceCompiles) +# NOTE: The checks here are for the C++ compiler used to build the proton *library* +# +# A developer using the library will get the checks done by internal/config.hpp +# which may not be the same, for example you can use a c++03 compiler to build +# applications that are linked with a library built with c++11. + + +set (BUILD_CPP_03 OFF CACHE BOOL "Compile the C++ binding as C++03 even when C++11 is available") + +# Manual feature checks for older CMake versions + +macro(cxx_compile_checks) + + macro (cxx_test prog name) + check_cxx_source_compiles("${prog}" HAS_${name}) + if (HAS_${name}) + add_definitions(-DPN_CPP_HAS_${name}=1) + endif() + endmacro() -macro (cxx_test prog name) - check_cxx_source_compiles("${prog}" HAS_${name}) - if (HAS_${name}) - add_definitions(-DPN_CPP_HAS_${name}=1) + check_cxx_source_compiles("#if defined(__cplusplus) && __cplusplus >= 201103\nint main(int, char**) { return 0; }\n#endif" CPP11) + + # Don't need to check individual flags if compiler claims to be C++11 or later as they will be set automatically + if (NOT CPP11) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} ${CXX_WARNING_FLAGS}") + cxx_test("long long ll; int main(int, char**) { return 0; }" LONG_LONG_TYPE) + cxx_test("int* x = nullptr; int main(int, char**) { return 0; }" NULLPTR) + cxx_test("#include <string>\nvoid blah(std::string&&) {} int main(int, char**) { blah(\"hello\"); return 0; }" RVALUE_REFERENCES) + cxx_test("class x {explicit operator int(); }; int main(int, char**) { return 0; }" EXPLICIT_CONVERSIONS) + cxx_test("class x {x()=default; }; int main(int, char**) { return 0; }" DEFAULTED_FUNCTIONS) + cxx_test("class x {x(x&&)=default; }; int main(int, char**) { return 0; }" DEFAULTED_MOVE_INITIALIZERS) + cxx_test("class x {x()=delete; }; int main(int, char**) { return 0; }" DELETED_FUNCTIONS) + cxx_test("struct x {x() {}}; int main(int, char**) { static thread_local x foo; return 0; }" THREAD_LOCAL) + cxx_test("int main(int, char**) { int a=[](){return 42;}(); return a; }" LAMBDAS) + cxx_test("template <class... X> void x(X... a) {} int main(int, char**) { x(1); x(43, \"\"); return 0; }" VARIADIC_TEMPLATES) + + cxx_test("#include <random>\nint main(int, char**) { return 0; }" HEADER_RANDOM) + cxx_test("#include <memory>\nstd::unique_ptr<int> u; int main(int, char**) { return 0; }" STD_UNIQUE_PTR) + cxx_test("#include <thread>\nstd::thread t; int main(int, char**) { return 0; }" STD_THREAD) + cxx_test("#include <mutex>\nstd::mutex m; int main(int, char**) { return 0; }" STD_MUTEX) + cxx_test("#include <atomic>\nstd::atomic<int> a; int main(int, char**) { return 0; }" STD_ATOMIC) endif() endmacro() -check_cxx_source_compiles("#if defined(__cplusplus) && __cplusplus >= 201103\nint main(int, char**) { return 0; }\n#endif" CPP11) -# Don't need to check individual flags if compiler claims to be C++11 or later as they will be set automatically -if (NOT CPP11) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} ${CXX_WARNING_FLAGS}") - cxx_test("long long ll; int main(int, char**) { return 0; }" LONG_LONG_TYPE) - cxx_test("int* x = nullptr; int main(int, char**) { return 0; }" NULLPTR) - cxx_test("#include <string>\nvoid blah(std::string&&) {} int main(int, char**) { blah(\"hello\"); return 0; }" RVALUE_REFERENCES) - cxx_test("class x {explicit operator int(); }; int main(int, char**) { return 0; }" EXPLICIT_CONVERSIONS) - cxx_test("class x {x()=default; }; int main(int, char**) { return 0; }" DEFAULTED_FUNCTIONS) - cxx_test("class x {x(x&&)=default; }; int main(int, char**) { return 0; }" DEFAULTED_MOVE_INITIALIZERS) - cxx_test("class x {x()=delete; }; int main(int, char**) { return 0; }" DELETED_FUNCTIONS) - cxx_test("struct x {x() {}}; int main(int, char**) { static thread_local x foo; return 0; }" THREAD_LOCAL) - cxx_test("int main(int, char**) { int a=[](){return 42;}(); return a; }" LAMBDAS) - cxx_test("template <class... X> void x(X... a) {} int main(int, char**) { x(1); x(43, \"\"); return 0; }" VARIADIC_TEMPLATES) - - cxx_test("#include <random>\nint main(int, char**) { return 0; }" HEADER_RANDOM) - cxx_test("#include <memory>\nstd::unique_ptr<int> u; int main(int, char**) { return 0; }" STD_UNIQUE_PTR) - cxx_test("#include <thread>\nstd::thread t; int main(int, char**) { return 0; }" STD_THREAD) - cxx_test("#include <mutex>\nstd::mutex m; int main(int, char**) { return 0; }" STD_MUTEX) - cxx_test("#include <atomic>\nstd::atomic<int> a; int main(int, char**) { return 0; }" STD_ATOMIC) -endif() + +# Check for cmake C++ feature support (version 3.1 or later) +if (DEFINED CMAKE_CXX_COMPILE_FEATURES) + if (BUILD_CPP_03) + set(STD 98) + else () + set(STD 11) + list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_11 INDEX) + if (NOT ${INDEX} EQUAL -1) + set(HAS_CPP11 True) + endif() + endif () + + # Note: this will "degrade" to the highest available standard <= ${STD} + set(CMAKE_CXX_STANDARD ${STD}) + set(CMAKE_CXX_EXTENSIONS OFF) + # AStitcher 20170804: Disabled for present - work on this when Windows C++ works + # cmake_minimum_required(VERSION 3.1) + # include(WriteCompilerDetectionHeader) + # write_compiler_detection_header( + # FILE cpp_features.h + # PREFIX PN + # COMPILERS GNU Clang MSVC SunPro + # FEATURES ${CMAKE_CXX_COMPILE_FEATURES} + # ALLOW_UNKNOWN_COMPILERS) + if (MSVC) # Compiler feature checks only needed for Visual Studio in this case + cxx_compile_checks() + endif() + +else (DEFINED CMAKE_CXX_COMPILE_FEATURES) + + if (BUILD_CPP_03) + set(CXX_STANDARD "-std=c++98") + else () + # These flags work with GCC/Clang/SunPro compilers + check_cxx_compiler_flag("-std=c++11" ACCEPTS_CXX11) + check_cxx_compiler_flag("-std=c++0x" ACCEPTS_CXX0X) + if (ACCEPTS_CXX11) + set(CXX_STANDARD "-std=c++11") + elseif(ACCEPTS_CXX0X) + set(CXX_STANDARD "-std=c++0x") + cxx_compile_checks() # Compiler checks needed for C++0x as not all C++11 may be supported + else() + cxx_compile_checks() # Compiler checks needed as we have no idea whats going on here! + endif() + endif() +endif () --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org