PROTON-1621: Reworked - C++11 example testing Revert and rework the previous solution which pushed too much C++ detail to the top level. Now each binding can export a small, set of selected extra flags for examples that are built in a repo. These flags are optional, the examples must be able to build without them when installed stand-alone. These flags are exported as CACHE INTERNAL cmake variables for visibility, there is no binding-specific cmake code outside the binding trees.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/85d7fb4c Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/85d7fb4c Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/85d7fb4c Branch: refs/heads/go1 Commit: 85d7fb4c2676b2dcff34388d6e108b799ae31e4f Parents: 434a2e7 Author: Alan Conway <acon...@redhat.com> Authored: Tue Oct 17 12:01:34 2017 +0100 Committer: Alan Conway <acon...@redhat.com> Committed: Tue Oct 17 12:01:34 2017 +0100 ---------------------------------------------------------------------- CMakeLists.txt | 2 - examples/CMakeLists.txt | 9 +++ proton-c/CMakeLists.txt | 10 +-- proton-c/bindings/cpp/CMakeLists.txt | 48 +++++++++++- proton-c/bindings/cpp/cpp.cmake | 118 +++++++----------------------- 5 files changed, 85 insertions(+), 102 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/85d7fb4c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index bab0ccf..b87f232 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,8 +192,6 @@ 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/85d7fb4c/examples/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index bed9f34..47b24db 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -17,6 +17,15 @@ # under the License. # +# NOTE: The examples and their build files are self-contained, and installed +# stand-alone independent of the library build tree. They must build and work in +# this mode. +# +# For self-test purposes, the library and binding CMake files can provide extra +# settings in <LANGUAGE>_EXAMPLE_* variables - for example to enable extra error +# checking or ensure compiler consistency with the library build. However, the +# examples must also build correctly stand-alone, with none of those variables set. + set (Proton_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set (ProtonCpp_DIR ${CMAKE_CURRENT_SOURCE_DIR}) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/85d7fb4c/proton-c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt index e2c7b3d..98d53c1 100644 --- a/proton-c/CMakeLists.txt +++ b/proton-c/CMakeLists.txt @@ -294,17 +294,13 @@ if (SANITIZE_FLAGS) endif() endif() -# Flags used to build examples for self-test. -# The examples must be self-contained and build even if these are not set. +# Flags for example self-test build, CACHE INTERNAL for visibility +set(C_EXAMPLE_FLAGS "${COMPILE_WARNING_FLAGS} ${CMAKE_C_FLAGS}" CACHE INTERNAL "") if (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_COMPILER_IS_GNUCC) # Ensure that examples build with c90, to deal with older c++03-as-c compilers. - set(C_EXAMPLE_FLAGS "-std=iso9899:1990 -pedantic") + set(C_EXAMPLE_FLAGS "${C_EXAMPLE_FLAGS} -std=iso9899:1990 -pedantic") endif() -# Set example flags in parent scope so example/CMakefile can read them. -set(C_EXAMPLE_FLAGS "${C_EXAMPLE_FLAGS} ${COMPILE_WARNING_FLAGS} ${CMAKE_C_FLAGS}" PARENT_SCOPE) -set(CXX_EXAMPLE_FLAGS "${CXX_WARNING_FLAGS} ${CMAKE_CXX_FLAGS}" PARENT_SCOPE) - if (MSVC) set(CMAKE_DEBUG_POSTFIX "d") add_definitions( http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/85d7fb4c/proton-c/bindings/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt index 7961018..bd5437e 100644 --- a/proton-c/bindings/cpp/CMakeLists.txt +++ b/proton-c/bindings/cpp/CMakeLists.txt @@ -17,8 +17,52 @@ # under the License. # -# NOTE: cpp.cmake is included at the top level so the examples can be built with -# the same version C++ compiler as the library. +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 () + +# Make these CACHE INTERNAL so they will be set for the C++ examples +set(CXX_EXAMPLE_FLAGS "${CXX_WARNING_FLAGS} ${CMAKE_CXX_FLAGS} ${CXX_STANDARD}" CACHE INTERNAL "") +set(CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD} CACHE INTERNAL "") +set(CMAKE_CXX_EXTENSIONS ${CMAKE_CXX_EXTENSIONS} CACHE INTERNAL "") include_directories( "${CMAKE_SOURCE_DIR}/proton-c/include" http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/85d7fb4c/proton-c/bindings/cpp/cpp.cmake ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/cpp.cmake b/proton-c/bindings/cpp/cpp.cmake index 447dbad..051781c 100644 --- a/proton-c/bindings/cpp/cpp.cmake +++ b/proton-c/bindings/cpp/cpp.cmake @@ -17,100 +17,36 @@ # under the License. # -include(CheckCXXCompilerFlag) -include(CheckCXXSourceCompiles) - # Check C++ capabilities. -# 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() - - 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) +include(CheckCXXSourceCompiles) - 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) - unset(CMAKE_REQUIRED_FLAGS) # Don't contaminate later C tests with C++ flags +macro (cxx_test prog name) + check_cxx_source_compiles("${prog}" HAS_${name}) + if (HAS_${name}) + add_definitions(-DPN_CPP_HAS_${name}=1) endif() endmacro() - -# 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 () +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) + unset(CMAKE_REQUIRED_FLAGS) # Don't contaminate later C tests with C++ flags +endif() --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org