Bundled static curl and BoringSSL archive grouping is ineffective in Linux source link
Checklist
- Clean upstream checkout at the exact reported revision.
- Reached the shared-library link and preserved the failing import.
- Captured the generated link order and compared only the concrete-archive
LINK_GROUP:RESCANcorrection.
Environment
Ubuntu 26.04.1 LTS, x86_64
Linux 7.0.0-31-generic
Python 3.12.13
CMake 4.2.3; Ninja 1.13.2; GCC 15.2.0
Open3D 1a9eb990f9a20936c30c428568c602bdef760744
Clean checkout status before configure: emptyExact reproduction
cmake -S . -B build-link -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \
-DBUILD_GUI=ON -DBUILD_WEBRTC=OFF -DBUILD_CUDA_MODULE=OFF \
-DUSE_SYSTEM_CURL=OFF -DUSE_SYSTEM_OPENSSL=OFF \
-DPython3_EXECUTABLE=/path/to/python
set -o pipefail
cmake --build build-link --target pip-package --parallel 24 --verbose 2>&1 \
| tee build-original.log
status=${PIPESTATUS[0]}
printf '\nExit status: %s\n' "$status" | tee -a build-original.logSeparately recorded prerequisites
The first generated graph was blocked by #7555's prebuilt-Filament variant (lib/*.a declared versus lib/x86_64/*.a imported and installed). I corrected the archive-directory declaration in both Filament external-project files before testing this link issue. GCC 15 also required the unrelated host workaround -DCMAKE_CXX_FLAGS=-include cstdint. Neither changes curl/BoringSSL order or semantics.
Original generated link order
The shared-library link completed, but CMake placed an empty group immediately after liblzf while the concrete bundled archives appeared later ungrouped:
... libOpen3D_3rdparty_liblzf.a -Wl,-\( -Wl,-\) ...
... boringssl/src/ext_boringssl/lib/libssl.a
boringssl/src/ext_boringssl/lib/libcrypto.a
curl/lib/libcurl.a ...The full generated command is reproducible without relying on shell history:
ninja -C build-link -t commands lib/Release/libOpen3D.so.0.19.0 | tail -n 1Because this is a shared link, GNU ld permitted unresolved references. The resulting library was:
aaa45a944532fa3128df9eec8c3dd03e11793b2024f9311ec8889acce469477f libOpen3D.so.0.19.0nm -D --undefined-only showed strong bundled-curl TLS references including BIO_free, EVP_PKEY_free, SSL_CTX_new, and X509_INFO_free. Importing the generated package produced the target failure:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/open3d-audit-7556-build/lib/python_package/open3d/__init__.py", line 79, in <module>
from open3d.pybind import (
ImportError: /tmp/open3d-audit-7556-build/lib/python_package/open3d/libOpen3D.so.0.19: undefined symbol: X509_INFO_free
Exit status: 1libcrypto.a defines X509_INFO_free; the archive was simply scanned before the later libcurl.a introduced the reference.
Isolated concrete-archive control
The control grouped the concrete archive paths on the build interface:
set(_curl_openssl_archives
"${CURL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${CURL_LIBRARIES}${CMAKE_STATIC_LIBRARY_SUFFIX}")
foreach(_library IN LISTS BORINGSSL_LIBRARIES)
list(APPEND _curl_openssl_archives
"${BORINGSSL_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${_library}${CMAKE_STATIC_LIBRARY_SUFFIX}")
endforeach()
set(_curl_iface_libs
"$<BUILD_INTERFACE:$<LINK_GROUP:RESCAN,${_curl_openssl_archives}>>")
set_property(TARGET 3rdparty_curl PROPERTY INTERFACE_LINK_LIBRARIES
"${_curl_iface_libs}")The regenerated final command contains the actual archives inside one rescan group (order is curl, ssl, crypto):
... -Wl,--start-group
curl/lib/libcurl.a
boringssl/src/ext_boringssl/lib/libssl.a
boringssl/src/ext_boringssl/lib/libcrypto.a
-Wl,--end-group ...The separate MKL archive group remains intact. pip-package completes with exit status 0. The control library and wheel are:
d75d25012b9c3592c624675eae9c0e9dc06302dfce1b6010a86bcaf217bc7e3c libOpen3D.so.0.19.0
b79867388b29b9abc24ef1b7c5e854e4a159fd605e3ee8761965f7c8fe931d7d open3d_cpu-0.19.0+1a9eb99-cp312-cp312-manylinux_2_43_x86_64.whlThe only remaining OPENSSL_* entries in nm -D --undefined-only are the three expected weak memory hooks. Import now succeeds:
0.19.0+1a9eb99
Exit status: 0Result
Confirmed. Grouping INTERFACE targets produced an empty group and left the actual bundled curl/BoringSSL archives subject to one-pass ordering. Applying LINK_GROUP:RESCAN to the concrete archive paths emits a real group, removes the strong TLS undefined symbols, and makes the generated Python package importable.
Source: isl-org/Open3D