fix(python): statically link and hide bundled HiGHS to avoid symbol clash with highspy (#5246)#5248
Open
aryan5v wants to merge 3 commits into
Open
fix(python): statically link and hide bundled HiGHS to avoid symbol clash with highspy (#5246)#5248aryan5v wants to merge 3 commits into
aryan5v wants to merge 3 commits into
Conversation
…lash with highspy (google#5246)
…#5246) When HiGHS is statically linked on Linux, need_unix_highs_lib is false but the copy command still used BUILD_HIGHS for its IF guard, producing an empty `cmake -E copy` that fails python_package. Gate copy on the need_*_highs_lib conditions instead.
Mizux
reviewed
Jul 8, 2026
Mizux
reviewed
Jul 8, 2026
need_unix_highs_lib already requires a shared HiGHS target, so the extra is_highs_shared wrapper around TARGET_SONAME_FILE is unnecessary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5246.
Problem
Any Python process that imports both
ortoolsandhighspy(>= 1.15.1) crashes on solver creation:Reproducer (released wheel):
This breaks all
cvxpy+or-toolsusers, since cvxpy eagerly co-imports solver backends. It is not HiGHS-specific at the call site — the wholelibortools.sofails to load, so GLOP/PDLP/etc. all fail too.Root cause
On Linux the wheel ships HiGHS as a separate shared library (
libhighs.so, inortools/.libs/), andlibortools.socarries undefined HiGHS references resolved at load time. OR-Tools bundles HiGHS v1.12.0;highspybundles v1.15.1, which renamed/removedsetLocalOptionValue. Both copies export HiGHS symbols with default ELF visibility into the global dynamic scope. Whenhighspyis imported first, its symbols occupy global scope; loadinglibortools.soafterward interposes its HiGHS references onto highspy's incompatible copy, where the symbol no longer exists →undefined symbolatdlopentime.auditwheel repairrenames bundled.sofiles but does not mangle symbols, so it does not prevent the collision.macOS (two-level namespace) and Windows (explicit
OR_EXPORT) are unaffected, so every change is guardedif(UNIX AND NOT APPLE).Fix
Statically link the bundled HiGHS into
libortools.soand localize its symbols, Linux-only:cmake/dependencies/CMakeLists.txt— build the FetchContent HiGHS withBUILD_SHARED_LIBS=OFF(saved/restored around the fetch) so it produceslibhighs.a, folded intolibortools.so. HiGHS references become internally resolved — no longer undefined, so there is nothing for another HiGHS copy to interpose onto.cmake/cpp.cmake— addtarget_link_options(ortools PRIVATE "LINKER:--exclude-libs,libhighs.a")so the statically-linked HiGHS symbols becomeSTB_LOCALinlibortools.so's dynamic symbol table (not exported, not interposable). Targeted at the HiGHS archive specifically to avoid over-hiding abseil/protobuf/OR-Tools public symbols.cmake/python.cmake,cmake/java.cmake,cmake/dotnet.cmake— a static library has no SONAME, so thelibhighs.socopy-into-package step is skipped when HiGHS is static (via anis_highs_sharedtype check); the copy command collapses to a no-op.This is immune to import order and to whatever HiGHS version another package bundles.
Scope
Validation (Linux, x86_64, Python 3.12)
Built the unmodified branch and ran the reproducer against the locally-built wheel:
build/lib/libhighs.a, nolibhighs.so*).nm -Dshows no exportedsetLocalOptionValue;readelf -dshows noNEEDEDentry for HiGHS;setLocalOptionValueis present only as a localtsymbol..libs/contains nolibhighs.highspy==1.15.1now pass; GLOP, PDLP, and HIGHS all solve.CI note:
.github/workflows/amd64_linux_cmake_python.ymlexercises the changed Linux wheel build path.