From 1bb4602af2194e1ce699f68de5056d7652db8e80 Mon Sep 17 00:00:00 2001 From: Sameer Sheorey Date: Sun, 29 Sep 2024 00:52:04 -0700 Subject: [PATCH] Use RPATH instead of RUNPATH to load libc++abi.so directly in Python. No need to find and load explicitly. Use libc++11 to build in Ubuntu 22.04. Warn if newer version is used. TODO: Solution for Ubuntu 24.04 --- 3rdparty/find_dependencies.cmake | 8 ++++++++ cpp/pybind/CMakeLists.txt | 3 +++ python/open3d/__init__.py | 8 -------- util/install_deps_ubuntu.sh | 11 +++++++++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/3rdparty/find_dependencies.cmake b/3rdparty/find_dependencies.cmake index 77b7085df69..8d4cf9284ee 100644 --- a/3rdparty/find_dependencies.cmake +++ b/3rdparty/find_dependencies.cmake @@ -1338,6 +1338,7 @@ if(BUILD_GUI) if (CPP_LIBRARY AND CPPABI_LIBRARY) set(CLANG_LIBDIR ${llvm_lib_dir}) message(STATUS "CLANG_LIBDIR found in ubuntu-default: ${CLANG_LIBDIR}") + set(LIBCPP_VERSION ${llvm_ver}) break() endif() endforeach() @@ -1363,6 +1364,8 @@ if(BUILD_GUI) llvm-7/lib ) get_filename_component(CLANG_LIBDIR ${CPPABI_LIBRARY} DIRECTORY) + string(REGEX MATCH "llvm-([0-9]+)/lib" _ ${CLANG_LIBDIR}) + set(LIBCPP_VERSION ${CMAKE_MATCH_1}) endif() # Find clang libraries at the exact path ${CLANG_LIBDIR}. @@ -1378,6 +1381,11 @@ if(BUILD_GUI) target_link_libraries(3rdparty_filament INTERFACE -lstdc++ ${CPP_LIBRARY} ${CPPABI_LIBRARY}) message(STATUS "Filament C++ libraries: ${CPP_LIBRARY} ${CPPABI_LIBRARY}") + if (LIBCPP_VERSION GREATER 11) + message(WARNING "libc++ (LLVM) version ${LIBCPP_VERSION} > 11 includes libunwind that " + "interferes with the system libunwind.so.8 and may crash Python code when exceptions " + "are used. Please consider using libc++ v11.") + endif() endif() if (APPLE) find_library(CORE_VIDEO CoreVideo) diff --git a/cpp/pybind/CMakeLists.txt b/cpp/pybind/CMakeLists.txt index e7a534a3eb3..c79bbd96719 100644 --- a/cpp/pybind/CMakeLists.txt +++ b/cpp/pybind/CMakeLists.txt @@ -80,6 +80,9 @@ set(PYTHON_COMPILED_MODULE_DIR if (APPLE) set_target_properties(pybind PROPERTIES BUILD_RPATH "@loader_path;@loader_path/..") elseif (UNIX) + # Use RPATH instead of RUNPATH in pybind so that needed libc++.so can find child dependant libc++abi.so in RPATH + # https://stackoverflow.com/questions/69662319/managing-secondary-dependencies-of-shared-libraries + target_link_options(pybind PRIVATE "LINKER:--disable-new-dtags") set_target_properties(pybind PROPERTIES BUILD_RPATH "$ORIGIN;$ORIGIN/..") endif() set_target_properties(pybind PROPERTIES diff --git a/python/open3d/__init__.py b/python/open3d/__init__.py index 141bf426c50..f7354b2a90c 100644 --- a/python/open3d/__init__.py +++ b/python/open3d/__init__.py @@ -45,14 +45,6 @@ def load_cdll(path): if sys.platform == "win32": # Unix: Use rpath to find libraries _win32_dll_dir = os.add_dll_directory(str(Path(__file__).parent)) -if _build_config["BUILD_GUI"] and not (find_library("c++abi") or - find_library("c++")): - try: # Preload libc++.so and libc++abi.so (required by filament) - load_cdll(str(next((Path(__file__).parent).glob("*c++abi.*")))) - load_cdll(str(next((Path(__file__).parent).glob("*c++.*")))) - except StopIteration: # Not found: check system paths while loading - pass - __DEVICE_API__ = "cpu" if _build_config["BUILD_CUDA_MODULE"]: # Load CPU pybind dll gracefully without introducing new python variable. diff --git a/util/install_deps_ubuntu.sh b/util/install_deps_ubuntu.sh index 3e359a1a6e7..f5cd661ab58 100755 --- a/util/install_deps_ubuntu.sh +++ b/util/install_deps_ubuntu.sh @@ -40,12 +40,19 @@ eval $( echo DISTRIB_RELEASE="$DISTRIB_RELEASE" ) if [ "$DISTRIB_ID" == "Ubuntu" -a "$DISTRIB_RELEASE" == "20.04" ]; then - # Ubuntu 20.04's clang/libc++-dev/libc++abi-dev are version 8, 10 or 12. - # To avoid dependence on libunwind, we don't want to use versions later than 10. + # To avoid dependence on libunwind, we don't want to use clang / libc++ versions later than 11. + # Ubuntu 20.04's has versions 8, 10 or 12 while Ubuntu 22.04 has versions 11 and later. deps=("${deps[@]/clang/clang-10}") deps=("${deps[@]/libc++-dev/libc++-10-dev}") deps=("${deps[@]/libc++abi-dev/libc++abi-10-dev}") fi +if [ "$DISTRIB_ID" == "Ubuntu" -a "$DISTRIB_RELEASE" == "22.04" ]; then + # To avoid dependence on libunwind, we don't want to use clang / libc++ versions later than 11. + # Ubuntu 20.04's has versions 8, 10 or 12 while Ubuntu 22.04 has versions 11 and later. + deps=("${deps[@]/clang/clang-11}") + deps=("${deps[@]/libc++-dev/libc++-11-dev}") + deps=("${deps[@]/libc++abi-dev/libc++abi-11-dev}") +fi # Special case for ARM64 if [ "$(uname -m)" == "aarch64" ]; then