Skip to content

Commit f68990e

Browse files
fangqclaude
andcommitted
[ci] static-link libstdc++/libgcc into MATLAB MEX, leave Octave dynamic
MATLAB R2024a ships a bundled libstdc++.so.6 that's older than the ubuntu-22.04 / windows-latest runner toolchains. A dynamically-linked MEX from those runners fails to load with: Invalid MEX-file ... siamex.mexa64: libstdc++.so.6: version `GLIBCXX_3.4.29' not found Fix: pass -static-libstdc++ -static-libgcc (Linux GCC) and /MT (MSVC) to the siamize_mex link line so the MEX brings its own C++ runtime. This is gated on SIAMIZE_STATIC_LINK (default ON, same flag the CLI binary already uses) so users can opt out if they need to. Important: this is MATLAB-only. The Octave MEX must stay dynamically linked against libstdc++. Statically embedding a second libstdc++ inside a MEX loaded by an Octave process that already has one dynamically loaded causes ABI conflicts (std::cout, type_info, exception state) and SIGABRT on first siamex() call. Verified locally: adding -static-libstdc++ to mkoctfile LDFLAGS made octave-cli core dump on siamex() entry; reverting restored normal operation and the 30/30 siamize.m unit tests still pass. MATLAB doesn't hit the same problem in practice because its bundled libstdc++ is genuinely too old -- the static MEX has no "real" stdc++ to fight with, only a stub that lacks the needed GLIBCXX symbols. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 19ecec7 commit f68990e

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,24 @@ if(SIAMIZE_BUILD_MATLAB_MEX)
307307
if(OpenMP_CXX_FOUND)
308308
target_link_libraries(siamize_mex OpenMP::OpenMP_CXX)
309309
endif()
310+
# Statically link the C++ runtime into the MEX. MATLAB ships its
311+
# own libstdc++.so.6 that's typically older than the host
312+
# toolchain's, so a dynamic MEX raises "GLIBCXX_x.y.z not found"
313+
# at MEX-load time. Statically linking libstdc++ + libgcc into
314+
# siamex.mexa64 (and using /MT on MSVC) sidesteps the version
315+
# negotiation entirely.
316+
if(SIAMIZE_STATIC_LINK)
317+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
318+
target_link_options(siamize_mex PRIVATE -static-libstdc++ -static-libgcc)
319+
elseif(MSVC)
320+
target_compile_options(siamize_mex PRIVATE
321+
$<$<CONFIG:Release>:/MT>
322+
$<$<CONFIG:Debug>:/MTd>
323+
$<$<CONFIG:RelWithDebInfo>:/MT>
324+
$<$<CONFIG:MinSizeRel>:/MT>
325+
)
326+
endif()
327+
endif()
310328
if(MSVC)
311329
target_compile_definitions(siamize_mex PRIVATE _CRT_SECURE_NO_WARNINGS NOMINMAX)
312330
target_compile_options(siamize_mex PRIVATE /wd4068 /wd4244 /wd4267)
@@ -365,6 +383,15 @@ if(SIAMIZE_BUILD_OCTAVE_MEX)
365383
# mkoctfile honors LDFLAGS env for link-stage flags; -L/-l args
366384
# on the command line get dropped silently.
367385
set(_oct_ld "-L${ORT_LIB_DIR} -lonnxruntime -Wl,-rpath,${ORT_LIB_DIR}")
386+
# Octave loads its MEX into a process that already has a
387+
# dynamically-loaded libstdc++. Statically embedding a second
388+
# copy of libstdc++ inside the MEX causes ABI conflicts at
389+
# load time (std::cout, type_info, exception handling) and
390+
# SIGABRT during siamex() entry. So we always link libstdc++
391+
# dynamically for the Octave MEX even with SIAMIZE_STATIC_LINK=ON.
392+
# (The MATLAB MEX is different -- MATLAB ships an older bundled
393+
# libstdc++.so.6 that lacks recent GLIBCXX_x.y.z symbols, so
394+
# there static-linking is the only thing that loads.)
368395
add_custom_command(
369396
OUTPUT ${_oct_out}
370397
COMMAND ${CMAKE_COMMAND} -E env

0 commit comments

Comments
 (0)