isl-org / isl-org/Open3D

Bundled static curl and BoringSSL archive grouping is ineffective in Linux source link

Open
#7,556 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
14k
Forks
2.6k
Avg merge
5d 18h
Merged PRs (30d)
6

Description

### Checklist

- [x] Clean upstream checkout at the exact reported revision.
- [x] Reached the shared-library link and preserved the failing import.
- [x] Captured the generated link order and compared only the concrete-archive `LINK_GROUP:RESCAN` correction.

### Environment

```text
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: empty
```

### Exact reproduction

```bash
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.log
```

### Separately 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:

```text
... 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:

```bash
ninja -C build-link -t commands lib/Release/libOpen3D.so.0.19.0 | tail -n 1
```

Because this is a shared link, GNU ld permitted unresolved references. The resulting library was:

```text
aaa45a944532fa3128df9eec8c3dd03e11793b2024f9311ec8889acce469477f libOpen3D.so.0.19.0
```

`nm -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:

```text
Traceback (most recent call last):
File "", line 1, in
File "/tmp/open3d-audit-7556-build/lib/python_package/open3d/__init__.py", line 79, in
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: 1
```

`libcrypto.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:

```cmake
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
"$>")
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):

```text
... -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:

```text
d75d25012b9c3592c624675eae9c0e9dc06302dfce1b6010a86bcaf217bc7e3c libOpen3D.so.0.19.0
b79867388b29b9abc24ef1b7c5e854e4a159fd605e3ee8761965f7c8fe931d7d open3d_cpu-0.19.0+1a9eb99-cp312-cp312-manylinux_2_43_x86_64.whl
```

The only remaining `OPENSSL_*` entries in `nm -D --undefined-only` are the three expected weak memory hooks. Import now succeeds:

```text
0.19.0+1a9eb99
Exit status: 0
```

### Result

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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the CMake definition of target 3rdparty_curl and inspect the generated libOpen3D.so link command with ninja -C build-link -t commands. Verify that the concrete curl and BoringSSL archives are emitted in one RESCAN group, then build the pip-package target and confirm importing the generated package succeeds without the strong TLS undefined symbols.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, linux, python
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.