Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for libc++abi #152

Merged
merged 1 commit into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ project(test_cxx_runtime)
add_executable(test_cxx_runtime typeinfo_test.cc)
add_executable(test_cxx_stdlib typeinfo_test.cc)
if (CXX_RUNTIME)
if (CXX_RUNTIME MATCHES ".*libc\\+\\+abi.*")
find_library(M_LIBRARY m)
if (M_LIBRARY)
target_link_libraries(test_cxx_runtime ${M_LIBRARY})
endif()
endif()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
target_link_libraries(test_cxx_runtime ${CXX_RUNTIME})
set_target_properties(test_cxx_runtime PROPERTIES
LINKER_LANGUAGE C)
Expand Down
3 changes: 3 additions & 0 deletions CMake/typeinfo_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class type_info2 : public std::type_info
virtual bool __do_catch(const type_info *thrown_type,
void **thrown_object,
unsigned outer) const { return true; }
virtual bool __do_upcast(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need this test anymore? I think we're now detecting the C++ runtime at run time, so we should work with any C++ runtime.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now work with every runtime, but we still need this test to find out whether there is a usable runtime or if we need to link the full stdlib.

Copy link
Member Author

@ngrewe ngrewe Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change here is needed to prevent a dependency on symbols from the GNU runtime, btw.

const __class_type_info *target,
void **thrown_object) const { return true; };
};
bool type_info2::__is_pointer_p() const { return true; }

Expand Down
28 changes: 24 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,11 @@ if (ENABLE_OBJCXX)
if (NOT CXX_RUNTIME)
test_cxx(supc++ false)
endif (NOT CXX_RUNTIME)
# libc++abi does not currently work, don't try it.
if (NOT CXX_RUNTIME)
# test_cxx(c++abi false)
list (FIND CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "c++" _libcxx_index)
if (${_libcxx_index} GREATER -1)
test_cxx(c++abi false)
endif()
endif (NOT CXX_RUNTIME)

# If we have a C++ ABI library, then we can produce a single libobjc that
Expand Down Expand Up @@ -325,6 +327,9 @@ if (ENABLE_OBJCXX)
MAIN_DEPENDENCY eh_trampoline.cc)
list(APPEND libobjc_ASM_SRCS eh_trampoline.s)
list(APPEND libobjc_CXX_SRCS objcxx_eh.cc)

# Find libm for linking, as some versions of libc++ don't link against it
find_library(M_LIBRARY m)
endif ()
endif (ENABLE_OBJCXX)

Expand Down Expand Up @@ -377,6 +382,11 @@ if (LIBGC)
target_link_libraries(objc ${LIBGC})
endif ()

# Explicitly link libm, as an implicit dependency of the C++ runtime
if (M_LIBRARY)
target_link_libraries(objc ${M_LIBRARY})
endif ()

# Make weak symbols work on OS X
if (APPLE)
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS
Expand Down Expand Up @@ -459,8 +469,18 @@ include (CPack)
if (BOEHM_GC)
set(PC_REQUIRES_PRIVATE_BOEHM_GC "Requires.private: bdw-gc")
endif ()
if (ENABLE_OBJCXX AND NOT CXXRT_IS_STDLIB)
set(PC_LIBS_PRIVATE "Libs.private: -l${CXX_RUNTIME}")
if (ENABLE_OBJCXX)
if (CXXRT_IS_STDLIB)
set(PC_LIBS_PRIVATE ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES})
else()
list(APPEND PC_LIBS_PRIVATE ${CXX_RUNTIME})
if (M_LIBRARY)
list(APPEND PC_LIBS_PRIVATE ${M_LIBRARY})
endif ()
endif()
list(REMOVE_DUPLICATES PC_LIBS_PRIVATE)
string(REPLACE ";" " -l" PC_LIBS_PRIVATE "${PC_LIBS_PRIVATE}")
set(PC_LIBS_PRIVATE "Libs.private: -l${PC_LIBS_PRIVATE}")
endif()

configure_file("libobjc.pc.in" "libobjc.pc" @ONLY)
Expand Down
23 changes: 20 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,36 @@ jobs:
matrix:
Debug:
BuildType: Debug
StdLib: libstdc++
CxxFlags: ""
Release:
BuildType: Release
StdLib: libstdc++
CxxFlags: ""
Debug-libc++:
BuildType: Debug
StdLib: libc++
CxxFlags: "-stdlib=libc++"
Release-libc++:
BuildType: Release
StdLib: libc++
CxxFlags: "-stdlib=libc++"
steps:
- checkout: self
submodules: true
- script: |
sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main"
sudo apt-get update
sudo apt-get install -y ninja-build
sudo apt-get install -y clang-8
sudo apt-get install -y ninja-build clang-8
if [ "$(StdLib)" = "libc++" ]; then
sudo apt-get install -qy libc++-8-dev libc++abi-8-dev
fi
displayName: Install Dependencies

- task: CMake@1
displayName: Generate Build Scripts
inputs:
cmakeArgs: '.. -GNinja -DCMAKE_BUILD_TYPE=$(BuildType) -DTESTS=ON -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_C_COMPILER=clang-8'
cmakeArgs: '.. -GNinja -DCMAKE_BUILD_TYPE=$(BuildType) -DTESTS=ON -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_FLAGS="$(CxxFlags)"'

- script: |
ninja
Expand All @@ -32,6 +48,7 @@ jobs:
- script: |
ctest -j 4 --output-on-failure -T test

displayName: 'Test'
workingDirectory: build
failOnStderr: false
- task: PublishTestResults@2
Expand Down
14 changes: 12 additions & 2 deletions objcxx_eh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,16 @@ namespace gnustep
unsigned outer) const;
};
}

static inline id dereference_thrown_object_pointer(void** obj) {
ngrewe marked this conversation as resolved.
Show resolved Hide resolved
/* libc++-abi does not have __is_pointer_p and won't do the double dereference
* required to get the object pointer. We need to do it ourselves if we have
* caught an exception with libc++'s exception class. */
if (cxx_exception_class == llvm_cxx_exception_class) {
return **(id**)obj;
}
return *(id*)obj;
}
};


Expand All @@ -316,7 +326,7 @@ bool gnustep::libobjc::__objc_class_type_info::__do_catch(const type_info *throw
|| (AppleCompatibleMode &&
dynamic_cast<const __objc_class_type_info*>(thrownType)))
{
thrown = *(id*)obj;
thrown = dereference_thrown_object_pointer(obj);
// nil only matches id catch handlers in Apple-compatible mode, or when thrown as an id
if (0 == thrown)
{
Expand All @@ -328,7 +338,7 @@ bool gnustep::libobjc::__objc_class_type_info::__do_catch(const type_info *throw
}
else if (dynamic_cast<const __objc_class_type_info*>(thrownType))
{
thrown = *(id*)obj;
thrown = dereference_thrown_object_pointer(obj);
found = isKindOfClass((Class)objc_getClass(thrownType->name()),
(Class)objc_getClass(name()));
}
Expand Down