From dc9b8313a4af686254ea93f622ecf74e533f2ea0 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Tue, 26 Dec 2017 17:21:48 +0000 Subject: [PATCH] Rework C++ library detection. macOS ships with libc++abi, which doesn't provide the hooks required for interop, so this was causing all of the tests to fail to link in the Travis macOS test. We're now correctly detecting that it won't work on macOS and disabling those tests. --- CMake/CMakeLists.txt | 8 +++-- CMake/typeinfo_test.cc | 3 +- CMakeLists.txt | 70 ++++++++++++++++++++++++++++++------------ Test/CMakeLists.txt | 2 ++ 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt index 899bb0e..9cbdd09 100644 --- a/CMake/CMakeLists.txt +++ b/CMake/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8) add_executable(test_cxx_runtime typeinfo_test.cc) set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") -target_link_libraries(test_cxx_runtime ${CXX_RUNTIME}) -set_target_properties(test_cxx_runtime PROPERTIES - LINKER_LANGUAGE C) +if (CXX_RUNTIME) + target_link_libraries(test_cxx_runtime ${CXX_RUNTIME}) + set_target_properties(test_cxx_runtime PROPERTIES + LINKER_LANGUAGE C) +endif() diff --git a/CMake/typeinfo_test.cc b/CMake/typeinfo_test.cc index b0b7b77..e11629a 100644 --- a/CMake/typeinfo_test.cc +++ b/CMake/typeinfo_test.cc @@ -57,5 +57,6 @@ bool type_info2::__is_pointer_p() const { return true; } int main() { - return 0; + type_info2 s; + return s.__is_pointer_p(); } diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a0e15c..2d0d463 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ set(libobjc_HDRS objc/slot.h ) -set(libobjc_CXX_SRCS objcxx_eh.cc) +set(libobjcxx_CXX_SRCS objcxx_eh.cc) # For release builds, we disable spamming the terminal with warnings about # selector type mismatches @@ -162,18 +162,43 @@ set_source_files_properties( # C++ Runtime interaction # + +function(test_cxx CXX_RUNTIME_NAME IS_STDLIB) + set(CXX_RUNTIME_NAME "${CMAKE_SHARED_LIBRARY_PREFIX}${CXX_RUNTIME_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}") + message(STATUS "Testing ${CXX_RUNTIME_NAME} as the C++ runtime library") + find_library(CXX_RUNTIME NAMES libsupc++.so) + if (CXX_RUNTIME) + message(STATUS "Testing ${CXX_RUNTIME} as the C++ runtime library") + try_compile(USERUNTIME + "${CMAKE_BINARY_DIR}/CMake" + "${CMAKE_SOURCE_DIR}/CMake" + test_cxx_runtime + CMAKE_FLAGS "-DCXX_RUNTIME=${CXX_RUNTIME} -DTEST_LINKER_LANGUAGE=C") + if (${USERUNTIME}) + set(CXX_RUNTIME ${CXX_RUNTIME} PARENT_SCOPE) + endif() + endif() +endfunction() + set(ENABLE_OBJCXX true CACHE BOOL "Enable support for Objective-C++") -set(FORCE_LIBOBJCXX false CACHE BOOL - "Force building a separate Objective-C++ runtime library") + +set(CXXRT_IS_STDLIB false) + +add_library(objc SHARED ${libobjc_C_SRCS} ${libobjc_ASM_SRCS} ${libobjc_OBJC_SRCS}) + if (ENABLE_OBJCXX) + message(STATUS "Testing C++ interop") # Try to find libcxxrt.so. We can link to this to provide the C++ ABI # layer, if it exists. - find_library(CXX_RUNTIME NAMES libcxxrt.so) + test_cxx(cxxrt false) # If it doesn't, then look for GNU libsupc++.so instead (either works, # they're ABI compatible). if (NOT CXX_RUNTIME) - find_library(CXX_RUNTIME NAMES libsupc++.so) + test_cxx(supc++ false) + endif (NOT CXX_RUNTIME) + if (NOT CXX_RUNTIME) + test_cxx(c++abi false) endif (NOT CXX_RUNTIME) # If we have a C++ ABI library, then we can produce a single libobjc that @@ -181,26 +206,34 @@ if (ENABLE_OBJCXX) # a separate libobjcxx. if (CXX_RUNTIME) message(STATUS "Using ${CXX_RUNTIME} as the C++ runtime library") - try_compile( USERUNTIME + else() + message(STATUS "Testing C++ standard library") + try_compile(USERUNTIME "${CMAKE_BINARY_DIR}/CMake" "${CMAKE_SOURCE_DIR}/CMake" - test_cxx_runtime - CMAKE_FLAGS "-DCXX_RUNTIME=${CXX_RUNTIME}") - message(STATUS "Is runtime useable? ${USERUNTIME}") - if (NOT ${USERUNTIME}) + test_cxx_runtime) + if (${USERUNTIME}) message(STATUS "libobjc will depend on C++ standard library") - else () - # We don't want to link the STL implementation (e.g. libstdc++) if - # we have a separate C++ runtime. - set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") - target_link_libraries(objc ${CXX_RUNTIME}) - endif () - else () - message(STATUS "libobjc will depend on C++ standard library") + set(CXXRT_IS_STDLIB true) + else() + message(STATUS "No useable C++ runtime found") + set(ENABLE_OBJCXX false) + endif() endif () endif (ENABLE_OBJCXX) +if (ENABLE_OBJCXX) + if (NOT CXXRT_IS_STDLIB) + # We don't want to link the STL implementation (e.g. libstdc++) if + # we have a separate C++ runtime. + set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") + target_link_libraries(objc ${CXX_RUNTIME}) + endif() + set(libobjc_CXX_SRCS ${libobjcxx_CXX_SRCS}) + target_sources(objc ${libobjcxx_CXX_SRCS}) +endif() + # Currently, we actually need pthreads, but we should use the platform's native # threading implementation (we do for everything except thread-local storage) @@ -210,7 +243,6 @@ set(objc_LINK_FLAGS "${objc_LINK_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") -add_library(objc SHARED ${libobjc_C_SRCS} ${libobjc_ASM_SRCS} ${libobjc_OBJC_SRCS} ${libobjc_CXX_SRCS}) set_target_properties(objc PROPERTIES LINKER_LANGUAGE C diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 79a75cd..7db5183 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -70,5 +70,7 @@ endforeach() # Tests that are more than a single file. addtest_flags(CXXExceptions "-O0" "CXXException.m;CXXException.cc;Test.m") addtest_flags(CXXExceptions_optimised "-O3" "CXXException.m;CXXException.cc;Test.m") +if (ENABLE_OBJCXX) addtest_flags(ObjCXXEHInterop "-O0" "ObjCXXEHInterop.mm;ObjCXXEHInterop.m;Test.m") addtest_flags(ObjCXXEHInterop_optimised "-O3" "ObjCXXEHInterop.mm;ObjCXXEHInterop.m;Test.m") +endif()