1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
# This module sets the variable "ITK_PRIVATE_DYNAMIC_CAST".
#
# This modules performs a try compile and execution to determine if
# the compiler and standard C++ run-time library supports
# dynamic_cast-ing of a private (hidden) Run-Time-Type-Information
# (RTTI). This can happen when private symbols (of instantiated
# templates) are duplicated in different libraries or executables.
#
function(_itkCheckPrivateDynamicCast)
set(VARIABLE "ITK_PRIVATE_DYNAMIC_CAST")
if(MSVC)
set("${VARIABLE}"
1
CACHE INTERNAL "MSVC is know to support dynamic_cast of private symbols." FORCE)
return()
endif()
set(test_project_dir "${PROJECT_BINARY_DIR}/CMakeTmp/${VARIABLE}")
file(
WRITE "${test_project_dir}/base.h"
"
struct __attribute__ ((visibility (\"default\"))) base
{
virtual ~base() = 0;
};
template <typename T> struct derived : public base{ ~derived() {};};
base* create(void) __attribute__ ((visibility (\"default\")));
")
file(
WRITE "${test_project_dir}/base.cxx"
"
#include \"base.h\"
base::~base() {}
base* create(void) { return new derived<int>(); }
")
file(
WRITE "${test_project_dir}/main.cxx"
"
#include \"base.h\"
int main(void)
{
return bool(dynamic_cast<derived<int>*>(create()))?0:1;
}")
# we cannot use a "try_run" here because of the complexity of the
# test project with shared libraries, and visibility flags. The run is
# accomplished with a custom command as a post build step for the
# compilation of the executable.
file(
WRITE "${test_project_dir}/CMakeLists.txt"
"
cmake_minimum_required(VERSION 3.16.3 FATAL_ERROR)
foreach(p
## Only policies introduced after the cmake_minimum_required
## version need to explicitly be set to NEW.
CMP0070 #3.10.0 Define ``file(GENERATE)`` behavior for relative paths.
CMP0071 #3.10.0 Let ``AUTOMOC`` and ``AUTOUIC`` process ``GENERATED`` files.
)
if(POLICY ${p})
cmake_policy(SET ${p} NEW)
endif()
endforeach()
project(support_private_dynamic_cast CXX)
add_library(base SHARED \"base.cxx\")
set_target_properties(base PROPERTIES CXX_VISIBILITY_PRESET hidden)
add_executable(test_cast \"main.cxx\")
target_link_libraries(test_cast PRIVATE base)
add_custom_command(TARGET test_cast POST_BUILD COMMAND $<TARGET_FILE:test_cast>)
")
try_compile(
${VARIABLE} "${test_project_dir}"
"${test_project_dir}" support_private_dynamic_cast
CMAKE_FLAGS "-DCMAKE_MACOSX_RPATH=OFF"
OUTPUT_VARIABLE output)
if(${VARIABLE})
message(STATUS "Performing Test ${VARIABLE} - Success")
else()
message(STATUS "Performing Test ${VARIABLE} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Test ${VARIABLE} failed with the following output:\n" "${OUTPUT}\n")
endif()
endfunction()
_itkcheckprivatedynamiccast()
|