Skip to content

Commit

Permalink
Brute Force Check of ACE Required C++ Std in CMake
Browse files Browse the repository at this point in the history
Since OpenDDS#4487, CMake requires
knowledge of the minimum C++ standard of ACE. Before it used the ACE
version to assume it, but the required standard changed in ACE to C++17.
To support this correctly in CMake, we could do a version check, but
master has currently the same version as the last ACE7 release.

This changes it to try to compile against `ace/Global_Macros.h` like how
we currently check the compiler default. This will allow us to get any
standard ACE requires as long it's a standard we're aware of. We will
not need this after OpenDDS#4578,
because CMake can directly tell us what ACE/TAO requires.

This change still doesn't cover a case like ACE/TAO 7.1.4, where ACE/TAO
was compiled with something other the compiler default or the minimum
standard of ACE. CMake can't detect that, so that requires manually
setting the standard in either CMake and/or the ACE/TAO build so they
match.
  • Loading branch information
iguessthislldo committed May 2, 2024
1 parent 62ad206 commit 4485a1e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
2 changes: 2 additions & 0 deletions cmake/ace_cppstd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include <ace/Global_Macros.h>
int main() {}
84 changes: 63 additions & 21 deletions cmake/init.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ function(_opendds_cxx_std_to_year out_var cxx_std)
set(${out_var} ${year} PARENT_SCOPE)
endfunction()

function(_opendds_cplusplus_to_year out_var cplusplus)
math(EXPR year "${cplusplus} / 100")
set(${out_var} ${year} PARENT_SCOPE)
endfunction()

function(_opendds_cxx_std_from_year out_var year)
if(year STREQUAL 1998)
set(std 98)
Expand All @@ -167,14 +172,15 @@ 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
set(cplusplus_values 201103 201402 201703 202002 202302)
foreach(cplusplus IN LISTS cplusplus_values)
try_compile(compiled
"${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")
if(compiled)
_opendds_cplusplus_to_year(default_cxx_std_year ${cplusplus})
else()
break()
endif()
Expand Down Expand Up @@ -207,10 +213,8 @@ function(_opendds_set_cxx_std)
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(ace_info "ACE ${OPENDDS_ACE_VERSION}")
set(compiler_info "compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
set(existing_cxx11 FALSE)
if(OPENDDS_CXX11 OR (DEFINED _opendds_default_features_no_cxx11 AND
_opendds_default_features_no_cxx11 STREQUAL "0"))
Expand All @@ -220,12 +224,55 @@ function(_opendds_set_cxx_std)
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)
if(OPENDDS_ACE_VERSION VERSION_LESS "7.0.0")
# What ACE 6 requires depends on the no_cxx11 feature
set(ace_info "${ace_info} (cxx11=${existing_cxx11})")
if(existing_cxx11 OR can_build_cxx11)
set(ace_min_cxx_std_year 2011)
else()
set(ace_min_cxx_std_year 1998)
endif()
else()
set(ace_min_cxx_std_year 1998)
# What ACE 7+ requires depends on a check in ace/Global_Macros.h. We must
# compile against that header using each standard we know of until it
# compiles.
set(dir "${CMAKE_CURRENT_BINARY_DIR}/opendds_test_ace_cppstd")
set(includes "${ACE_INCLUDE_DIRS}")
if(NOT EXISTS "${ACE_INCLUDE_DIRS}/ace/config.h")
if(NOT ACE_IS_BEING_BUILT)
message(FATAL_ERROR "ACE doesn't have a config.h.")
endif()
# Won't compile without a config.h, so make a fake one.
set(include_dir "${dir}/include")
list(APPEND includes "${include_dir}")
set(ace_dir "${include_dir}/ace")
file(MAKE_DIRECTORY "${ace_dir}")
file(WRITE "${ace_dir}/config.h" "#include <ace/${_OPENDDS_ACE_CONFIG_FILE}>\n")
endif()
foreach(try_cplusplus IN LISTS cplusplus_values)
_opendds_cplusplus_to_year(try_year ${try_cplusplus})
_opendds_cxx_std_from_year(try_std ${try_year})
message("CMAKE_CXX_STANDARD=${try_std}")
try_compile(compiled
"${dir}/${try_cplusplus}"
SOURCES "${CMAKE_CURRENT_LIST_DIR}/ace_cppstd.cpp"
CMAKE_FLAGS
"-DCMAKE_CXX_STANDARD=${try_std}"
"-DINCLUDE_DIRECTORIES=${includes}"
OUTPUT_VARIABLE build_output
)
if(compiled)
set(ace_min_cxx_std_year ${try_year})
break()
endif()
endforeach()
if(NOT DEFINED ace_min_cxx_std_year)
message(FATAL_ERROR
" Can't figure out required C++ standard for ${ace_info}\n"
" Tried up to C++ ${try_year} on ${compiler_info}, last output:\n"
" \n"
" ${build_output}")
endif()
endif()

if(OPENDDS_CMAKE_VERBOSE)
Expand All @@ -239,17 +286,12 @@ function(_opendds_set_cxx_std)

# 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}")
set(msg "${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 "
message(FATAL_ERROR "${msg}, 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 "
message(STATUS "${compiler_info} would use ${cxx_std_year}, but ${msg}. Raising "
"requirment to that.")
set(cxx_std_year ${ace_min_cxx_std_year})
endif()
Expand Down
1 change: 1 addition & 0 deletions dds/DdsDcps.mpc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ project(OpenDDS_Dcps): core, coverage_optional, \
" @$(MKDIR) $(cmake_dir_install_dest)"
" cp $(DDS_ROOT)/cmake/*.cmake $(cmake_dir_install_dest)"
" cp $(DDS_ROOT)/cmake/cplusplus.cpp $(cmake_dir_install_dest)"
" cp $(DDS_ROOT)/cmake/ace_cppstd.cpp $(cmake_dir_install_dest)"
" cp $(DDS_ROOT)/cmake/export.h.in $(cmake_dir_install_dest)"
" echo '' >> $(cmake_config_install_dest)"
" echo '# From make install' >> $(cmake_config_install_dest)"
Expand Down
5 changes: 5 additions & 0 deletions docs/news.d/cmake-ace-tao-cpp-std.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.. news-prs: 4618
.. news-start-section: Platform Support and Dependencies
- Fix cases where the CMake support fails when using the ACE/TAO master branch because it now requires C++17.
.. news-end-section. news-end-section

0 comments on commit 4485a1e

Please sign in to comment.