From 9b522e3ce900c258e5fa992b31d4430b730b6248 Mon Sep 17 00:00:00 2001 From: Fred Hornsey Date: Thu, 22 Feb 2024 20:32:01 -0600 Subject: [PATCH] Allow Compiling with CMake and C++03 This continues the work started in https://github.com/OpenDDS/OpenDDS/pull/4481 and tries to correctly handle C++ standards in all CMake support. Previously the CMake support was agnostic towards C++ standards, but this meant that building with CMake didn't have a way of differentiating C++ standards. Now we can detect C++ standard support and should be able to build ACE accordingly. Also: - Added `OPENDDS_CXX_STD_YEAR` CMake variable for easy checking of C++ standard support. - In addition to passing `CMAKE_CXX_STANDARD` to the ACE/TAO MPC build, it will also now pass `CMAKE_CXX_COMPILER`. - Removed need for `cmake/detect_ace.pl` - Some of the changes originally in https://github.com/OpenDDS/OpenDDS/pull/4374 - MPC location message will now say when it wasn't set. - Split adding of tests between different directories. --- CMakeLists.txt | 47 +--- cmake/build_ace_tao.cmake | 4 + cmake/configure_ace_tao.pl | 10 + cmake/cplusplus.cpp | 4 + cmake/detect_ace.pl | 140 ------------ cmake/import_common.cmake | 5 +- cmake/init.cmake | 330 ++++++++++++++++++++--------- cmake/opendds_build_helpers.cmake | 10 +- dds/DCPS/unique_ptr.h | 13 +- tests/CMakeLists.txt | 51 +++++ tests/DCPS/CMakeLists.txt | 8 + tests/DCPS/Compiler/CMakeLists.txt | 10 + 12 files changed, 334 insertions(+), 298 deletions(-) create mode 100644 cmake/cplusplus.cpp delete mode 100755 cmake/detect_ace.pl create mode 100644 tests/CMakeLists.txt create mode 100644 tests/DCPS/CMakeLists.txt create mode 100644 tests/DCPS/Compiler/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 6856dec55e8..4530c2f658f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ if(OPENDDS_XERCES3) endif() if(OPENDDS_SECURITY) add_subdirectory(dds/DCPS/security) - if(OPENDDS_BUILT_IN_TOPICS) + if(OPENDDS_BUILT_IN_TOPICS AND NOT OPENDDS_CXX_STD_YEAR LESS 2011) add_subdirectory(tools/dds/rtpsrelaylib) add_subdirectory(tools/rtpsrelay) endif() @@ -137,48 +137,5 @@ if(OPENDDS_BUILD_EXAMPLES OR OPENDDS_BUILD_TESTS) add_subdirectory(DevGuideExamples/DCPS/Messenger) endif() if(OPENDDS_BUILD_TESTS) - find_package(GTest QUIET PATHS "${OPENDDS_GTEST}") - if(NOT GTest_FOUND) - set(gtestsm "${OPENDDS_SOURCE_DIR}/tests/googletest") - if(EXISTS "${gtestsm}/CMakeLists.txt") - message("GTest not found, using submodule") - set(fetch_args SOURCE_DIR "${gtestsm}") - else() - message("GTest not found, using clone") - set(fetch_args - GIT_REPOSITORY "https://github.com/OpenDDS/googletest" - GIT_TAG "v1.8.x" - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - endif() - FetchContent_Declare(googletest ${fetch_args}) - # Prevent overriding the parent project's compiler/linker - # settings on Windows - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(googletest) - endif() - if(TARGET GTest::gtest) - get_target_property(google_test_bin_dir GTest::gtest BINARY_DIR) - set(_OPENDDS_GOOGLE_TEST_DIR "${google_test_bin_dir}" CACHE INTERNAL "") - elseif(TARGET gtest) - get_target_property(google_test_bin_dir gtest BINARY_DIR) - set(_OPENDDS_GOOGLE_TEST_DIR "${google_test_bin_dir}" CACHE INTERNAL "") - endif() - - add_subdirectory(tests/cmake/ace_tao_only) - if(OPENDDS_OWNERSHIP_PROFILE) - add_subdirectory(tests/cmake/Messenger) - endif() - add_subdirectory(tests/cmake/idl_compiler_tests) - add_subdirectory(tests/DCPS/Compiler/optional) - add_subdirectory(tests/cmake/include_subdir) - add_subdirectory(tests/DCPS/Compiler/char_literals) - add_subdirectory(tests/DCPS/HelloWorld) - # TODO: This test always builds shared libraries and linker complains about - # ACE/TAO libs lacking -fPIC when ACE is static. - if(OPENDDS_OWNERSHIP_PROFILE AND NOT OPENDDS_STATIC) - add_subdirectory(tests/cmake/generated_global) - endif() + add_subdirectory(tests) endif() diff --git a/cmake/build_ace_tao.cmake b/cmake/build_ace_tao.cmake index 9472e718688..66523f57c8f 100644 --- a/cmake/build_ace_tao.cmake +++ b/cmake/build_ace_tao.cmake @@ -20,6 +20,10 @@ find_package(Perl REQUIRED) if(OPENDDS_STATIC) list(APPEND _OPENDDS_CONFIGURE_ACE_TAO_ARGS --static=1) endif() +list(APPEND _OPENDDS_CONFIGURE_ACE_TAO_ARGS + --compiler "${CMAKE_CXX_COMPILER}" + --std "${OPENDDS_CXX_STD}" +) execute_process( COMMAND "${PERL_EXECUTABLE}" "${_OPENDDS_CMAKE_DIR}/configure_ace_tao.pl" diff --git a/cmake/configure_ace_tao.pl b/cmake/configure_ace_tao.pl index 0add2d4e216..5d6274d04e6 100755 --- a/cmake/configure_ace_tao.pl +++ b/cmake/configure_ace_tao.pl @@ -24,6 +24,8 @@ workspace-file platform-macros-file static + compiler + std /; my %is_value_required = map {$_ => 1} @required_values; my %values = (); @@ -100,6 +102,14 @@ sub read_file { my $platform_macros_path = "$values{ace}/include/makeinclude/platform_macros.GNU"; open(my $platform_macros_file, '>', $platform_macros_path) or die("Failed to open $platform_macros_path: $!"); + if ($values{compiler}) { + for my $var ('CC', 'CXX', 'LD') { + print $platform_macros_file ("$var = $values{compiler}\n"); + } + } + if ($values{std}) { + print $platform_macros_file ("CCFLAGS += -std=c++$values{std}\n"); + } if ($values{'macro-line'}) { for my $line (@{$values{'macro-line'}}) { print $platform_macros_file ("$line\n"); diff --git a/cmake/cplusplus.cpp b/cmake/cplusplus.cpp new file mode 100644 index 00000000000..373d339b3c1 --- /dev/null +++ b/cmake/cplusplus.cpp @@ -0,0 +1,4 @@ +#if __cplusplus < OPENDDS_TEST_CPLUSPLUS +# error "Less then requested value" +#endif +int main() {} diff --git a/cmake/detect_ace.pl b/cmake/detect_ace.pl deleted file mode 100755 index 7be0465b63b..00000000000 --- a/cmake/detect_ace.pl +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -my $ace_root = shift(); - -sub whack_to_slash { - my $s = shift; - $s =~ s|\\|/|g; - return $s; -} - -sub to_cmake_scalar { - my $val = shift; - return 'ON' if "$val" eq '1'; - return 'OFF' if "$val" eq '0'; - return '"' . whack_to_slash($val) . '"'; -} - -sub to_cmake_list { - my @list = @{$_[0]}; - return '"' . join(';', map {whack_to_slash($_)} @list) . '"'; -} - -sub to_cmake_value { - my $value = shift(); - - my $ref_type = ref($value); - if ($ref_type eq 'ARRAY') { - return to_cmake_list($value); - } - elsif ($ref_type eq '') { - return to_cmake_scalar($value); - } - else { - die "ERROR: to_cmake_value invalid value type, stopped"; - } -} - -my %features; -my $file = "$ace_root/bin/MakeProjectCreator/config/default.features"; -if (-f $file) { - open(my $fh, '<', $file) or die "ERROR: Could not open $file: $!"; - while (my $row = <$fh>) { - chomp $row; - $row =~ s/\/\/.*//; - $row =~ s/^\s+//; - $row =~ s/\s+$//; - next if $row eq ''; - my ($key, $value) = split(/\s*=\s*/, $row); - $features{$key} = $value; - } -} - -for my $f (@ARGV) { - my ($key, $value) = split(/=/, $f); - $value = "1" unless defined $value; - $features{$key} = $value; -} - -my @configs = ( - { - name => 'CXX11', - feature => 'no_cxx11', - inverted => 1, - }, - { - name => 'WCHAR', - feature => 'uses_wchar', - }, - { - name => 'IPV6', - feature => 'ipv6', - }, - { - name => 'SAFETY_PROFILE', - feature => 'no_opendds_safety_profile', - inverted => 1, - }, - { - name => 'VERSIONED_NAMESPACE', - feature => 'versioned_namespace', - }, - { - name => 'SUPPRESS_ANYS', - feature => 'dds_suppress_anys', - default => 1, - }, - { - name => 'COVERAGE', - feature => 'dds_non_coverage', - inverted => 1, - }, - { - name => 'TAO_CORBA_E_COMPACT', - feature => 'corba_e_compact', - }, - { - name => 'TAO_CORBA_E_MICRO', - feature => 'corba_e_micro', - }, - { - name => 'TAO_MINIMUM_CORBA', - feature => 'minimum_corba', - }, - { - name => 'TAO_IIOP', - feature => 'tao_no_iiop', - inverted => 1, - default => 1, - }, - { - name => 'TAO_GEN_OSTREAM', - feature => 'gen_ostream', - }, - { - name => 'TAO_OPTIMIZE_COLLOCATED_INVOCATIONS', - feature => 'optimize_collocated_invocations', - default => 1, - }, -); - -my @cmake_values; -for my $config (@configs) { - my $name = $config->{name}; - $name = uc("OPENDDS_$name"); - $name =~ s/-/_/g; - my $inverted = $config->{inverted} // 0; - my $default = $config->{default} // 0; - my $enabled; - if (exists($features{$config->{feature}})) { - $enabled = $features{$config->{feature}} eq "1" ? !$inverted : $inverted; - } - else { - $enabled = $default; - } - push(@cmake_values, "$name=" . to_cmake_value($enabled)); -} -print(join(';', @cmake_values), "\n"); diff --git a/cmake/import_common.cmake b/cmake/import_common.cmake index 874fbbb9bcb..65d6a6c172b 100644 --- a/cmake/import_common.cmake +++ b/cmake/import_common.cmake @@ -352,6 +352,7 @@ function(_opendds_import_group_targets group libs exes) if(NOT TARGET ${target} AND ${var_prefix}_LIBRARY_FOUND) add_library(${target} ${OPENDDS_LIBRARY_TYPE} IMPORTED GLOBAL) + _opendds_cxx_std(${target} INTERFACE) set_target_properties(${target} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${include_dirs}" @@ -360,10 +361,6 @@ function(_opendds_import_group_targets group libs exes) INTERFACE_COMPILE_OPTIONS "${${var_prefix}_COMPILE_OPTIONS}" ) - if(NOT CMAKE_VERSION VERSION_LESS "3.11.0" AND OPENDDS_CXX_STD) - target_compile_features(${target} INTERFACE "cxx_std_${OPENDDS_CXX_STD}") - endif() - set(mpc_ext_proj_var "${group_prefix}_MPC_EXTERNAL_PROJECT") if(DEFINED "${mpc_ext_proj_var}") add_dependencies(${target} "${${mpc_ext_proj_var}}") diff --git a/cmake/init.cmake b/cmake/init.cmake index ddf6d102884..a4004f5017d 100644 --- a/cmake/init.cmake +++ b/cmake/init.cmake @@ -17,17 +17,16 @@ include("${CMAKE_CURRENT_LIST_DIR}/opendds_version.cmake") function(_opendds_detect_ace) if(OPENDDS_CMAKE_VERBOSE) + set(path "${OPENDDS_ACE}/bin/MakeProjectCreator/config/default.features") + if(NOT EXISTS "${path}") + message(STATUS "${path} does not exist, assuming defaults") + return() + endif() message(STATUS "Getting features from ACE at ${OPENDDS_ACE}") list(APPEND CMAKE_MESSAGE_INDENT " ") endif() - find_package(Perl REQUIRED) - execute_process( - COMMAND ${PERL_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/detect_ace.pl" "${OPENDDS_ACE}" - OUTPUT_VARIABLE config_text - COMMAND_ERROR_IS_FATAL ANY - ) - + file(STRINGS "${path}" config_text) foreach(name_value ${config_text}) if(name_value MATCHES "([^=]+)=([^\n]+)") set(name "${CMAKE_MATCH_1}") @@ -35,13 +34,16 @@ function(_opendds_detect_ace) if(OPENDDS_CMAKE_VERBOSE) message(STATUS "${name}=${value}") endif() - set("${name}" "${value}" CACHE BOOL "") + set("_opendds_default_features_${name}" "${value}" PARENT_SCOPE) endif() endforeach() endfunction() include("${CMAKE_CURRENT_LIST_DIR}/config.cmake" OPTIONAL RESULT_VARIABLE OPENDDS_CONFIG_CMAKE) -if(NOT OPENDDS_USE_PREFIX_PATH) +if(OPENDDS_USE_PREFIX_PATH) + set(_OPENDDS_ROOT "${CMAKE_CURRENT_LIST_DIR}/../../..") +else() + set(_OPENDDS_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") if(DEFINED OPENDDS_ACE) if(NOT EXISTS "${OPENDDS_ACE}") message(SEND_ERROR "OPENDDS_ACE (${OPENDDS_ACE}) does not exist") @@ -72,6 +74,195 @@ endif() if(NOT OPENDDS_CONFIG_CMAKE AND NOT ACE_IS_BEING_BUILT) _opendds_detect_ace() endif() +get_filename_component(_OPENDDS_ROOT "${_OPENDDS_ROOT}" ABSOLUTE) + +if(NOT DEFINED OPENDDS_INSTALL_LIB) + set(OPENDDS_INSTALL_LIB "lib") +endif() + +file(TO_CMAKE_PATH "${OPENDDS_ACE}" OPENDDS_ACE) +if(OPENDDS_MPC) + file(TO_CMAKE_PATH "${OPENDDS_MPC}" OPENDDS_MPC) +endif() +file(TO_CMAKE_PATH "${OPENDDS_TAO}" OPENDDS_TAO) + +if(NOT DEFINED DDS_ROOT) + if(OPENDDS_USE_PREFIX_PATH) + set(DDS_ROOT "${_OPENDDS_ROOT}/share/dds") + set(OPENDDS_INCLUDE_DIRS "${_OPENDDS_ROOT}/include") + + else() + set(DDS_ROOT "${_OPENDDS_ROOT}") + set(OPENDDS_INCLUDE_DIRS "${_OPENDDS_ROOT}") + endif() + + if(NOT OPENDDS_IS_BEING_BUILT) + set(OPENDDS_BIN_DIR "${_OPENDDS_ROOT}/bin") + set(OPENDDS_LIB_DIR "${_OPENDDS_ROOT}/${OPENDDS_INSTALL_LIB}") + endif() +endif() + +if(NOT DEFINED ACE_ROOT) + if(OPENDDS_USE_PREFIX_PATH) + set(ACE_ROOT "${_OPENDDS_ROOT}/share/ace") + set(ACE_INCLUDE_DIRS "${_OPENDDS_ROOT}/include") + set(ACE_LIB_DIR "${_OPENDDS_ROOT}/${OPENDDS_INSTALL_LIB}") + + elseif(OPENDDS_ACE) + set(ACE_ROOT "${OPENDDS_ACE}") + set(ACE_INCLUDE_DIRS "${ACE_ROOT}") + set(ACE_LIB_DIR "${ACE_ROOT}/lib") + endif() + + set(ACE_BIN_DIR "${ACE_ROOT}/bin") +endif() +_opendds_get_version(OPENDDS_ACE_VERSION ACE "${ACE_ROOT}") + +if(NOT DEFINED TAO_ROOT) + if(OPENDDS_USE_PREFIX_PATH) + set(TAO_ROOT "${_OPENDDS_ROOT}/share/tao") + set(TAO_INCLUDE_DIR "${_OPENDDS_ROOT}/include") + + elseif(OPENDDS_TAO) + set(TAO_ROOT "${OPENDDS_TAO}") + set(TAO_INCLUDE_DIR "${OPENDDS_TAO}") + endif() + + set(TAO_BIN_DIR "${ACE_BIN_DIR}") + set(TAO_LIB_DIR "${ACE_LIB_DIR}") + set(TAO_INCLUDE_DIRS + "${TAO_INCLUDE_DIR}" + "${TAO_INCLUDE_DIR}/orbsvcs" + ) +endif() +_opendds_get_version(OPENDDS_TAO_VERSION TAO "${TAO_ROOT}") + +message(STATUS "Using OpenDDS ${OPENDDS_VERSION} at ${DDS_ROOT}") +if(DEFINED OPENDDS_MPC) + message(STATUS "Using MPC at ${OPENDDS_MPC}") +else() + message(STATUS "Not using MPC (not needed)") +endif() +message(STATUS "Using ACE ${OPENDDS_ACE_VERSION} at ${ACE_ROOT}") +message(STATUS "Using TAO ${OPENDDS_TAO_VERSION} at ${TAO_ROOT}") + +function(_opendds_cxx_std_to_year out_var cxx_std) + if(cxx_std STREQUAL 98) + set(year 1998) + else() + math(EXPR year "2000 + ${cxx_std}") + endif() + set(${out_var} ${year} PARENT_SCOPE) +endfunction() + +function(_opendds_cxx_std_from_year out_var year) + if(year STREQUAL 1998) + set(std 98) + else() + math(EXPR std "${year} - 2000") + endif() + set(${out_var} ${std} PARENT_SCOPE) +endfunction() + +function(_opendds_set_cxx_std) + # Get the latest known default compiler C++ standard + set(default_cxx_std_year 1998) + foreach(cplusplus 201103 201402 201703 202002 202302) + try_compile(at_least + "${CMAKE_CURRENT_BINARY_DIR}/opendds_test_cplusplus_${cplusplus}" + SOURCES "${CMAKE_CURRENT_LIST_DIR}/cplusplus.cpp" + COMPILE_DEFINITIONS "-DOPENDDS_TEST_CPLUSPLUS=${cplusplus}L" + ) + if(at_least) + math(EXPR default_cxx_std_year "${cplusplus} / 100") + else() + break() + endif() + endforeach() + + # Get the max C++ standard supported by the compiler + set(max_cxx_std_year ${default_cxx_std_year}) + if(NOT CMAKE_VERSION VERSION_LESS "3.8.0") + foreach(feature IN LISTS CMAKE_CXX_COMPILE_FEATURES) + if(feature MATCHES "^cxx_std_(.*)$") + _opendds_cxx_std_to_year(supported_year "${CMAKE_MATCH_1}") + if(supported_year GREATER max_cxx_std_year) + set(max_cxx_std_year "${supported_year}") + endif() + endif() + endforeach() + endif() + + # Get the min C++ standard that might be used + set(explicit TRUE) + if(DEFINED OPENDDS_CXX_STD) + # User is overriding the standard for OpenDDS specifically + _opendds_cxx_std_to_year(cxx_std_year ${OPENDDS_CXX_STD}) + elseif(DEFINED CMAKE_CXX_STANDARD) + # User is overriding the standard globally + _opendds_cxx_std_to_year(cxx_std_year ${CMAKE_CXX_STANDARD}) + else() + set(explicit FALSE) + set(cxx_std_year ${default_cxx_std_year}) + endif() + + # Get the C++ standard ACE requires + set(ace7 FALSE) + if(NOT OPENDDS_ACE_VERSION VERSION_LESS "7.0.0") + set(ace7 TRUE) + endif() + set(existing_cxx11 FALSE) + if(OPENDDS_CXX11 OR (DEFINED _opendds_default_features_no_cxx11 AND + _opendds_default_features_no_cxx11 STREQUAL "0")) + set(existing_cxx11 TRUE) + endif() + set(can_build_cxx11 FALSE) + if(ACE_IS_BEING_BUILT AND NOT cxx_std_year LESS 2011) + set(can_build_cxx11 TRUE) + endif() + if(ace7) + set(ace_min_cxx_std_year 2014) + elseif(existing_cxx11 OR can_build_cxx11) + set(ace_min_cxx_std_year 2011) + else() + set(ace_min_cxx_std_year 1998) + endif() + + message("default_cxx_std_year: ${default_cxx_std_year}") + message("max_cxx_std_year: ${max_cxx_std_year}") + message("cxx_std_year: ${cxx_std_year}") + message("existing_cxx11: ${existing_cxx11}") + message("can_build_cxx11: ${can_build_cxx11}") + message("ace_min_cxx_std_year: ${ace_min_cxx_std_year}") + + # See if ACE requires a later standard + if(cxx_std_year LESS ace_min_cxx_std_year) + set(compiler_info "compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") + set(ace_info "ACE ${OPENDDS_ACE_VERSION}") + if(NOT ace7) + set(ace_info " ${ace_info} (cxx11=${existing_cxx11})") + endif() + set(ace_info "${ace_info} requires at least C++ ${ace_min_cxx_std_year}") + if(NOT explicit AND max_cxx_std_year LESS ace_min_cxx_std_year) + message(FATAL_ERROR "${ace_info}, but ${compiler_info} only supports up to " + "C++ ${max_cxx_std_year}.") + endif() + message(STATUS "${compiler_info} would use ${cxx_std_year}, but ${ace_info}. Raising " + "requirment to that.") + set(cxx_std_year ${ace_min_cxx_std_year}) + endif() + + _opendds_cxx_std_from_year(cxx_std ${cxx_std_year}) + set(OPENDDS_CXX_STD ${cxx_std} CACHE STRING + "Minimum required C++ standard (same values as CMAKE_CXX_STANDARD)" FORCE) + set(OPENDDS_CXX_STD_YEAR ${cxx_std_year} CACHE STRING + "Minimum required C++ standard year (do not set mannually)" FORCE) +endfunction() + +if(NOT DEFINED OPENDDS_CXX_STD_YEAR) + _opendds_set_cxx_std() +endif() +message(STATUS "OPENDDS_CXX_STD: ${OPENDDS_CXX_STD}") set(_OPENDDS_ALL_FEATURES) set(_OPENDDS_FEATURE_VARS) @@ -89,7 +280,6 @@ function(_opendds_feature name default_value) string(TOLOWER "${name}" lowercase_name) list(APPEND _OPENDDS_ALL_FEATURES "${lowercase_name}") set(name "OPENDDS_${name}") - set("${name}" "${default_value}" CACHE "${arg_TYPE}" "${arg_DOC}") list(APPEND _OPENDDS_FEATURE_VARS "${name}") if(arg_MPC OR arg_MPC_INVERTED) if(NOT DEFINED arg_MPC_NAME) @@ -102,6 +292,20 @@ function(_opendds_feature name default_value) set(mpc_true 1) set(mpc_false 0) endif() + endif() + + set(mpc_var "_opendds_default_features_${arg_MPC_NAME}") + if(DEFINED ${mpc_var}) + set(mpc_val "${${mpc_var}}") + if(mpc_val STREQUAL mpc_true) + set(default_value TRUE) + else() + set(default_value FALSE) + endif() + endif() + set("${name}" "${default_value}" CACHE "${arg_TYPE}" "${arg_DOC}") + + if(arg_MPC OR arg_MPC_INVERTED) if(${${name}}) set(mpc_feature "${arg_MPC_NAME}=${mpc_true}") else() @@ -130,11 +334,15 @@ _opendds_feature(CONTENT_FILTERED_TOPIC ${OPENDDS_CONTENT_SUBSCRIPTION} DOC "Allows using ContentFilteredTopic") _opendds_feature(MULTI_TOPIC ${OPENDDS_CONTENT_SUBSCRIPTION} DOC "Allows using MultiTopic") _opendds_feature(QUERY_CONDITION ${OPENDDS_CONTENT_SUBSCRIPTION} DOC "Allows using QueryCondition") -_opendds_feature(SUPPRESS_ANYS ON DOC "Default for opendds_target_sources(SUPPRESS_ANYS)") +_opendds_feature(SUPPRESS_ANYS ON MPC_NAME dds_suppress_anys + DOC "Default for opendds_target_sources(SUPPRESS_ANYS)") _opendds_feature(SECURITY OFF DOC "Build with RTPS Security support") -_opendds_feature(SAFETY_PROFILE OFF DOC "Build using Safety Profile (Not for CMake-built OpenDDS)") +_opendds_feature(SAFETY_PROFILE OFF MPC_INVERTED MPC_NAME no_opendds_safety_profile + DOC "Build using Safety Profile (Not for CMake-built OpenDDS)") +_opendds_feature(COVERAGE OFF MPC_INVERTED MPC_NAME dds_non_coverage) # ACE Features +_opendds_feature(VERSIONED_NAMESPACE OFF MPC DOC "Namespaces include versions") if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "Debug") _opendds_feature(DEBUG ON MPC DOC "(Not for CMake-built OpenDDS)") _opendds_feature(OPTIMIZE OFF MPC DOC "(Not for CMake-built OpenDDS)") @@ -151,16 +359,18 @@ endif() _opendds_feature(XERCES3 "${OPENDDS_SECURITY}" MPC TYPE PATH DOC "Build with Xerces XML parser, needed for security and QoS XML Handler") _opendds_feature(IPV6 OFF MPC DOC "Build with IPv6 support") +if(OPENDDS_CXX_STD_YEAR LESS 2011) + set(_opendds_cxx11_default OFF) +else() + set(_opendds_cxx11_default ON) +endif() +_opendds_feature(CXX11 "${_opendds_cxx11_default}" MPC_INVERTED MPC_NAME no_cxx11 + DOC "Build assumes C++11 support") # TAO Features _opendds_feature(TAO_IIOP ON MPC_INVERTED MPC_NAME tao_no_iiop) _opendds_feature(TAO_OPTIMIZE_COLLOCATED_INVOCATIONS ON MPC) -# Make Sure CMake can use the Paths -file(TO_CMAKE_PATH "${OPENDDS_ACE}" OPENDDS_ACE) -file(TO_CMAKE_PATH "${OPENDDS_MPC}" OPENDDS_MPC) -file(TO_CMAKE_PATH "${OPENDDS_TAO}" OPENDDS_TAO) - option(OPENDDS_CMAKE_VERBOSE "Print verbose output when loading the OpenDDS Config Package" OFF) if("all" IN_LIST OPENDDS_CMAKE_VERBOSE) set(OPENDDS_CMAKE_VERBOSE @@ -173,7 +383,8 @@ option(OPENDDS_DEFAULT_NESTED "Require topic types to be declared explicitly" ON option(OPENDDS_FILENAME_ONLY_INCLUDES "No directory info in generated #includes." OFF) set(OPENDDS_DEFAULT_SCOPE "PRIVATE" CACHE STRING "Default scope for opendds_target_sources") set_property(CACHE OPENDDS_DEFAULT_SCOPE PROPERTY STRINGS "PUBLIC" "PRIVATE" "INTERFACE") -option(OPENDDS_ALWAYS_GENERATE_LIB_EXPORT_HEADER "Always generate an export header for libraries" OFF) +option(OPENDDS_ALWAYS_GENERATE_LIB_EXPORT_HEADER + "Always generate an export header for libraries" OFF) # This is off because it's not compatible with a possible existing usage of # target_link_libraries that doesn't specify a scope: # "All uses of target_link_libraries with a target must be either all-keyword @@ -184,7 +395,8 @@ option(OPENDDS_AUTO_LINK_DCPS # This is off by default because it could cause "Cannot find source file" # errors on `TypeSupport.idl` files generated in a another directory. # TODO: Make this default ON in v4.0 -option(OPENDDS_USE_CORRECT_INCLUDE_SCOPE "Include using SCOPE specified in opendds_target_sources" OFF) +option(OPENDDS_USE_CORRECT_INCLUDE_SCOPE + "Include using SCOPE specified in opendds_target_sources" OFF) macro(_opendds_save_cache name type value) list(APPEND _opendds_save_cache_vars ${name}) @@ -237,83 +449,11 @@ function(_opendds_path_list path_list_var) set("${path_list_var}" "${path_list}" PARENT_SCOPE) endfunction() -if(NOT DEFINED OPENDDS_INSTALL_LIB) - set(OPENDDS_INSTALL_LIB "lib") -endif() - -if(OPENDDS_USE_PREFIX_PATH) - set(_OPENDDS_ROOT "${CMAKE_CURRENT_LIST_DIR}/../../..") -else() - set(_OPENDDS_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") -endif() -get_filename_component(_OPENDDS_ROOT "${_OPENDDS_ROOT}" ABSOLUTE) - -if(NOT DEFINED DDS_ROOT) - if(OPENDDS_USE_PREFIX_PATH) - set(DDS_ROOT "${_OPENDDS_ROOT}/share/dds") - set(OPENDDS_INCLUDE_DIRS "${_OPENDDS_ROOT}/include") - - else() - set(DDS_ROOT "${_OPENDDS_ROOT}") - set(OPENDDS_INCLUDE_DIRS "${_OPENDDS_ROOT}") - endif() - - if(NOT OPENDDS_IS_BEING_BUILT) - set(OPENDDS_BIN_DIR "${_OPENDDS_ROOT}/bin") - set(OPENDDS_LIB_DIR "${_OPENDDS_ROOT}/${OPENDDS_INSTALL_LIB}") +function(_opendds_cxx_std target scope) + if(OPENDDS_CXX_STD AND NOT (scope STREQUAL INTERFACE AND CMAKE_VERSION VERSION_LESS "3.11.0")) + target_compile_features(${target} ${scope} "cxx_std_${OPENDDS_CXX_STD}") endif() -endif() - -if(NOT DEFINED ACE_ROOT) - if(OPENDDS_USE_PREFIX_PATH) - set(ACE_ROOT "${_OPENDDS_ROOT}/share/ace") - set(ACE_INCLUDE_DIRS "${_OPENDDS_ROOT}/include") - set(ACE_LIB_DIR "${_OPENDDS_ROOT}/${OPENDDS_INSTALL_LIB}") - - elseif(OPENDDS_ACE) - set(ACE_ROOT "${OPENDDS_ACE}") - set(ACE_INCLUDE_DIRS "${ACE_ROOT}") - set(ACE_LIB_DIR "${ACE_ROOT}/lib") - endif() - - set(ACE_BIN_DIR "${ACE_ROOT}/bin") -endif() -_opendds_get_version(OPENDDS_ACE_VERSION ACE "${ACE_ROOT}") -if(NOT DEFINED OPENDDS_CXX_STD) - if(NOT OPENDDS_ACE_VERSION VERSION_LESS "7.0.0") - set(OPENDDS_CXX_STD 14) - elseif(OPENDDS_CXX11) - set(OPENDDS_CXX_STD 11) - else() - set(OPENDDS_CXX_STD 98) - endif() -endif() - -if(NOT DEFINED TAO_ROOT) - if(OPENDDS_USE_PREFIX_PATH) - set(TAO_ROOT "${_OPENDDS_ROOT}/share/tao") - set(TAO_INCLUDE_DIR "${_OPENDDS_ROOT}/include") - - elseif(OPENDDS_TAO) - set(TAO_ROOT "${OPENDDS_TAO}") - set(TAO_INCLUDE_DIR "${OPENDDS_TAO}") - endif() - - set(TAO_BIN_DIR "${ACE_BIN_DIR}") - set(TAO_LIB_DIR "${ACE_LIB_DIR}") - set(TAO_INCLUDE_DIRS - "${TAO_INCLUDE_DIR}" - "${TAO_INCLUDE_DIR}/orbsvcs" - ) -endif() -_opendds_get_version(OPENDDS_TAO_VERSION TAO "${TAO_ROOT}") - -message(STATUS "Using OpenDDS ${OPENDDS_VERSION} at ${DDS_ROOT}") -if(DEFINED OPENDDS_MPC) - message(STATUS "Using MPC at ${OPENDDS_MPC}") -endif() -message(STATUS "Using ACE ${OPENDDS_ACE_VERSION} at ${ACE_ROOT}") -message(STATUS "Using TAO ${OPENDDS_TAO_VERSION} at ${TAO_ROOT}") +endfunction() if(OPENDDS_STATIC) set(OPENDDS_LIBRARY_TYPE STATIC) diff --git a/cmake/opendds_build_helpers.cmake b/cmake/opendds_build_helpers.cmake index dd9333423af..a5e57f79e39 100644 --- a/cmake/opendds_build_helpers.cmake +++ b/cmake/opendds_build_helpers.cmake @@ -28,10 +28,7 @@ function(_opendds_library target) "${no_value_options}" "${single_value_options}" "${multi_value_options}" ${ARGN}) _opendds_alias(${target}) - - if(OPENDDS_CXX_STD) - target_compile_features(${target} PUBLIC "cxx_std_${OPENDDS_CXX_STD}") - endif() + _opendds_cxx_std(${target} PUBLIC) # Put library in BINARY_DIR/lib set_target_properties(${target} PROPERTIES @@ -86,12 +83,9 @@ function(_opendds_executable target) "${no_value_options}" "${single_value_options}" "${multi_value_options}" ${ARGN}) _opendds_alias(${target}) + _opendds_cxx_std(${target} PRIVATE) set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OPENDDS_BIN_DIR}") - if(OPENDDS_CXX_STD) - target_compile_features(${target} PRIVATE "cxx_std_${OPENDDS_CXX_STD}") - endif() - if(NOT arg_NO_INSTALL) install(TARGETS ${target} EXPORT opendds_targets diff --git a/dds/DCPS/unique_ptr.h b/dds/DCPS/unique_ptr.h index 230997bdf65..ea2e4a905c1 100644 --- a/dds/DCPS/unique_ptr.h +++ b/dds/DCPS/unique_ptr.h @@ -1,14 +1,15 @@ #ifndef OPENDDS_DCPS_UNIQUE_PTR_H #define OPENDDS_DCPS_UNIQUE_PTR_H -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "Definitions.h" +#include -#include "dds/Versioned_Namespace.h" +#include -#include "ace/config-lite.h" +#ifndef ACE_LACKS_PRAGMA_ONCE +# pragma once +#endif #ifdef ACE_HAS_CPP11 # define OPENDDS_HAS_STD_UNIQUE_PTR @@ -343,4 +344,4 @@ typename unique_ptr::rv_reference move(container_supported_unique_ptr& ptr } // namespace OpenDDS OPENDDS_END_VERSIONED_NAMESPACE_DECL -#endif /* end of include guard: UNIQUE_PTR_H_18C6F30C */ +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000000..f23c39d9469 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.3...3.27) +project(opendds_tests) +enable_testing() + +find_package(OpenDDS REQUIRED) + +find_package(GTest QUIET PATHS "${OPENDDS_GTEST}") +if(NOT GTest_FOUND) + set(gtestsm "${OPENDDS_SOURCE_DIR}/tests/googletest") + if(EXISTS "${gtestsm}/CMakeLists.txt") + message("GTest not found, using submodule") + set(fetch_args SOURCE_DIR "${gtestsm}") + else() + message("GTest not found, using clone") + set(fetch_args + GIT_REPOSITORY "https://github.com/OpenDDS/googletest" + GIT_TAG "v1.8.x" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + endif() + FetchContent_Declare(googletest ${fetch_args}) + # Prevent overriding the parent project's compiler/linker + # settings on Windows + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) +endif() +if(TARGET GTest::gtest) + get_target_property(google_test_bin_dir GTest::gtest BINARY_DIR) + set(_OPENDDS_GOOGLE_TEST_DIR "${google_test_bin_dir}" CACHE INTERNAL "") +elseif(TARGET gtest) + get_target_property(google_test_bin_dir gtest BINARY_DIR) + set(_OPENDDS_GOOGLE_TEST_DIR "${google_test_bin_dir}" CACHE INTERNAL "") +endif() + +# TODO: Replace with: +# add_subdirectory(cmake) +add_subdirectory(cmake/ace_tao_only) +if(OPENDDS_OWNERSHIP_PROFILE) + add_subdirectory(cmake/Messenger) +endif() +add_subdirectory(cmake/idl_compiler_tests) +add_subdirectory(cmake/include_subdir) +# TODO: This test always builds shared libraries and linker complains about +# ACE/TAO libs lacking -fPIC when ACE is static. +if(OPENDDS_OWNERSHIP_PROFILE AND NOT OPENDDS_STATIC) + add_subdirectory(cmake/generated_global) +endif() + +add_subdirectory(DCPS) diff --git a/tests/DCPS/CMakeLists.txt b/tests/DCPS/CMakeLists.txt new file mode 100644 index 00000000000..1ed89081532 --- /dev/null +++ b/tests/DCPS/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.3...3.27) +project(opendds_tests_dcps) +enable_testing() + +find_package(OpenDDS REQUIRED) + +add_subdirectory(Compiler) +add_subdirectory(HelloWorld) diff --git a/tests/DCPS/Compiler/CMakeLists.txt b/tests/DCPS/Compiler/CMakeLists.txt new file mode 100644 index 00000000000..b2ef8ccd1b3 --- /dev/null +++ b/tests/DCPS/Compiler/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.3...3.27) +project(opendds_tests_dcps_compiler) +enable_testing() + +find_package(OpenDDS REQUIRED) + +if(NOT OPENDDS_CXX_STD_YEAR LESS 2011) + add_subdirectory(optional) + add_subdirectory(char_literals) +endif()