Skip to content

build(before-code-freeze): Export the stub's dynamic symbols when libpython is static - #451

Merged
mc-nv merged 2 commits into
r26.08from
mchornyi/TRI-1650/before-code-freeze-build-against-latest-upstream-container
Aug 12, 2026
Merged

build(before-code-freeze): Export the stub's dynamic symbols when libpython is static#451
mc-nv merged 2 commits into
r26.08from
mchornyi/TRI-1650/before-code-freeze-build-against-latest-upstream-container

Conversation

@mc-nv

@mc-nv mc-nv commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What does the PR do?

Set ENABLE_EXPORTS on triton-python-backend-stub when libpython resolves to a
static archive. The manylinux base builds CPython --disable-shared, so the
Py_* symbols live in the stub executable; the 77 lib-dynload/*.so modules link
no libpython and carry undefined Py_* (math alone: 63), so without the export
the stub links and starts, then fails on the first import math.

Checklist

  • PR title reflects the change and is of format <commit_type>: <Title>
  • Changes are described in the pull request.
  • Related issues are referenced.
  • Populated github labels field
  • Added test plan and verified test passes.
  • Verified that the PR passes existing CI.
  • Verified copyright is correct on all changed files.
  • Added succinct git squash message before merging.
  • All template sections are filled out.

Commit Type:

  • build
  • docs

Related PRs:

Where should the reviewer start?

The if(PYTHON_LIBRARY MATCHES "\\.a$") block in CMakeLists.txt.

Test plan:

Covered by the internal RHEL/manylinux pipeline for the 26.08 upstream bump.

  • CI Pipeline ID: 61271932

Caveats:

Gated on the resolved library being an archive, not on the platform, so the Debian
build (shared libpython) is unaffected. Uses PYTHON_LIBRARY, not
PYTHON_LIBRARIES: pybind11 arrives via FetchContent_MakeAvailable, which uses
add_subdirectory, so only the find_library cache entry crosses into this scope.

Background

Part of the 26.08 "build against latest upstream container" work: the base image
moved to cuda:13.4-devel-manylinux--26.08, which changed the default GCC
toolset, the Python layout and the bundled OpenSSL.

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • Resolves: TRI-1650
CI (internal): [#61271932](http://tritonserver.local/ci/pipelines/61271932)

mc-nv added 2 commits August 4, 2026 22:06
The manylinux base container builds CPython with --disable-shared, so on
that platform triton_python_backend_stub links libpython3.x.a and the
Py_* symbols live in the executable rather than a shared library. Python
C extension modules are dlopen'ed and deliberately leave Py_* undefined
-- every one of the 77 lib-dynload modules in the image does, math.so
alone with 63 undefined symbols and no libpython in DT_NEEDED -- so they
can only bind against the stub's dynamic symbol table. Without the
export the stub links and starts, then fails on the first `import math`.

Set ENABLE_EXPORTS, which makes CMake add the platform's flag
(-Wl,--export-dynamic on Linux, per Platform/Linux.cmake), matching how
CPython links its own interpreter.

Gate it on the resolved library being an archive rather than on the
platform. A shared libpython needs no export, so the Debian build is
unaffected, and the condition stays correct if a target moves between
the two linkage modes.

The condition reads PYTHON_LIBRARY, not PYTHON_LIBRARIES: pybind11
arrives through FetchContent_MakeAvailable, which uses add_subdirectory,
so only the cache entry find_library creates crosses back into this
scope. PYTHON_LIBRARIES is a plain variable in pybind11's directory and
is empty here, which would have made this a silent no-op.
The comment said RHEL_BUILD existed because pybind would otherwise pick
up Python 3.6 in the RHEL base container, so PYBIND11_PYTHON_VERSION was
set to force 3.12. That pin has been dropped from build.py -- pybind11
prefers the newest entry of its own Python_ADDITIONAL_VERSIONS list, and
the manylinux base container puts a single interpreter first on PATH.

RHEL_BUILD itself stays: it still selects the stub's link settings
further down. Only the justification was wrong.
@mc-nv

mc-nv commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

Updates the stub link configuration so executables embedding a static libpython export their dynamic symbols, allowing Python extension modules to resolve Py_* references.

  • Enables ENABLE_EXPORTS when PYTHON_LIBRARY resolves to a .a archive.
  • Documents why PYTHON_LIBRARY is used and clarifies current Python discovery behavior.
  • Updates the copyright year.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
CMakeLists.txt Conditionally exports symbols from the Python backend stub when linked against a static libpython archive.

Reviews (2): Last reviewed commit: "docs: Correct the stale RHEL_BUILD ratio..." | Re-trigger Greptile

@mc-nv mc-nv changed the title build: Export the stub's dynamic symbols when libpython is static build(before-code-freeze): Export the stub's dynamic symbols when libpython is static Aug 5, 2026
@mc-nv
mc-nv requested review from mattwittwer, whoisj and yinggeh August 5, 2026 23:30
@mc-nv
mc-nv marked this pull request as ready for review August 5, 2026 23:31
@mc-nv
mc-nv changed the base branch from main to r26.08 August 7, 2026 20:39
@mc-nv
mc-nv merged commit 96d6021 into r26.08 Aug 12, 2026
4 checks passed
mc-nv added a commit that referenced this pull request Sep 2, 2026
…python is static (#451) (#453)

* build: Export the stub's dynamic symbols when libpython is static

The manylinux base container builds CPython with --disable-shared, so on
that platform triton_python_backend_stub links libpython3.x.a and the
Py_* symbols live in the executable rather than a shared library. Python
C extension modules are dlopen'ed and deliberately leave Py_* undefined
-- every one of the 77 lib-dynload modules in the image does, math.so
alone with 63 undefined symbols and no libpython in DT_NEEDED -- so they
can only bind against the stub's dynamic symbol table. Without the
export the stub links and starts, then fails on the first `import math`.

Set ENABLE_EXPORTS, which makes CMake add the platform's flag
(-Wl,--export-dynamic on Linux, per Platform/Linux.cmake), matching how
CPython links its own interpreter.

Gate it on the resolved library being an archive rather than on the
platform. A shared libpython needs no export, so the Debian build is
unaffected, and the condition stays correct if a target moves between
the two linkage modes.

The condition reads PYTHON_LIBRARY, not PYTHON_LIBRARIES: pybind11
arrives through FetchContent_MakeAvailable, which uses add_subdirectory,
so only the cache entry find_library creates crosses back into this
scope. PYTHON_LIBRARIES is a plain variable in pybind11's directory and
is empty here, which would have made this a silent no-op.

* docs: Correct the stale RHEL_BUILD rationale

The comment said RHEL_BUILD existed because pybind would otherwise pick
up Python 3.6 in the RHEL base container, so PYBIND11_PYTHON_VERSION was
set to force 3.12. That pin has been dropped from build.py -- pybind11
prefers the newest entry of its own Python_ADDITIONAL_VERSIONS list, and
the manylinux base container puts a single interpreter first on PATH.

RHEL_BUILD itself stays: it still selects the stub's link settings
further down. Only the justification was wrong.

(cherry picked from commit 96d6021)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Build system or external dependencies (build: PRs) documentation Improvements or additions to documentation (docs: PRs)

Development

Successfully merging this pull request may close these issues.

2 participants