fix: BuildFedora.sh actually builds on Fedora (dnf, CMake 4.x, system-lib ABI mismatches) - #229
Open
bugparty wants to merge 8 commits into
Open
fix: BuildFedora.sh actually builds on Fedora (dnf, CMake 4.x, system-lib ABI mismatches)#229bugparty wants to merge 8 commits into
bugparty wants to merge 8 commits into
Conversation
….sh usage text BuildFedora.sh was a copy of the Debian/Ubuntu build script that never got ported: the -u dependency-install block still called apt with Debian package names, and the usage/help text still referenced BuildLinux.sh. Switched the dependency installation to dnf with the Fedora equivalent package names, and corrected the usage strings to reference BuildFedora.sh. Claude-Session: https://claude.ai/code/session_01GX1HqJrRdEWvoiwXkfrLQH
Beyond the apt->dnf and BuildLinux.sh->BuildFedora.sh renames, the deps build (-d) and app build (-s) steps didn't actually work on Fedora 44/CMake 4.x. Fixes, verified with a full clean `-u` -> `-d` -> `-b -s` run: - deps/CMakeLists.txt required CMake >= 3.2, and CMake 4.x refuses to configure anything below 3.5 at all. Bumped it, and pass CMAKE_POLICY_VERSION_MINIMUM=3.5 (as both a cmake arg and an env var, so it also applies to bundled deps' own nested try_compile() checks) to work around the same problem in third-party vendored CMakeLists.txt files (NLopt, wxWidgets, etc.) we can't edit directly. - Fedora's glew-devel and openvdb-devel ship only shared .so libs, no static .a, but SLIC3R_STATIC forces static linking of both. Added SLIC3R_STATIC_EXCLUDE_OPENVDB (mirroring the existing SLIC3R_STATIC_EXCLUDE_GLEW) and pass both from BuildFedora.sh so the app links the system shared libs instead. - deps/ unconditionally built its own GLFW, OpenVDB (+OpenEXR/Imath) and expat even when a usable system version exists, and being under the same shared destdir/include root as everything else, those headers silently shadow Fedora's system headers regardless of any CMake variable override -- causing ABI-mismatched undefined-symbol link errors (GLFW needs KDE's extra-cmake-modules for its Wayland backend; OpenVDB's ABI-versioned inline namespaces don't match Fedora's; and webkit2gtk needs a matching dynamic libexpat.so, not deps' static one). Added DEP_BUILD_OPENVDB/DEP_BUILD_EXPAT toggles (mirroring the existing DEP_BUILD_GLFW) and disabled all three from BuildFedora.sh. - wx-config hardcodes "-L.../lib" for its own deps (e.g. "-lzlibstatic"), but zlib's own CMakeLists follows GNUInstallDirs, which resolves to "lib64" on Fedora. Added lib64 to the linker search path. - Added the now-required Fedora devel packages to the -u dependency list: nasm, boost-static, webkit2gtk4.1-devel, mesa-compat-libOSMesa-devel, openvdb-devel, imath-devel, openexr-devel, NLopt-devel, glfw-devel. - The -s step's final `make -j4 QIDIStudio` was hardcoded regardless of core count; changed to $NCORES to match the -d step. Claude-Session: https://claude.ai/code/session_01GX1HqJrRdEWvoiwXkfrLQH
If a conda/miniforge environment is active (very common as a default shell setup), its bin/ directory sits ahead of the system toolchain on PATH. CMake's find_package(... CONFIG) search treats PATH entries as candidate install prefixes, so it can silently resolve a dependency (observed with zstd, pulled in transitively by Boost::iostreams) to an older/incompatible copy from the conda env instead of Fedora's own libzstd-devel -- and since CMake auto-adds found libraries' directories to the built binary's RPATH, that conda path gets baked into qidi-studio itself. This made the binary pick up conda's outdated libexpat.so.1 too (shared indirectly via the same RPATH entry) at runtime, regardless of the invoking shell's LD_LIBRARY_PATH or whether conda was still active when actually running the binary. Strip $CONDA_PREFIX from PATH at the top of the script so the Fedora system toolchain and libraries are used consistently throughout configure and build. Verified with another full clean -u/-d/-b -s run: the resulting binary's RUNPATH no longer references the conda environment. Claude-Session: https://claude.ai/code/session_01GX1HqJrRdEWvoiwXkfrLQH
bugparty
force-pushed
the
fix/build-fedora-sh-apt-dnf
branch
from
September 6, 2026 06:40
1f6bdad to
6cacd92
Compare
Assimp's contrib/zlib is an old vendored fork whose zutil.h still has
the classic `#if defined(MACOS) || defined(TARGET_OS_MAC)` branch that
redefines fdopen() to NULL. TARGET_OS_MAC is unconditionally 1 on all
Apple platforms (not just legacy Mac OS Classic, which this guard was
written for), so on macOS-15/Xcode 16 this macro corrupts the system
_stdio.h's fdopen() declaration and fails the CI build with "error:
expected identifier or '('".
Assimp.cmake was passing -DASSIMP_BUILD_ZLIB=ON, forcing it to compile
this broken vendored copy instead of the project's own already-fixed
zlib (deps/ZLIB/ZLIB.cmake). Every other dependency that needs zlib
(CURL, PNG, TIFF, wxWidgets, OpenEXR, Blosc, JPEG) already depends on
${ZLIB_PKG} and lets find_package(ZLIB) resolve it via the shared
CMAKE_PREFIX_PATH; Assimp was the one outlier still building its own.
Turned ASSIMP_BUILD_ZLIB off and added the same DEPENDS so Assimp
finds the shared zlib instead.
Claude-Session: https://claude.ai/code/session_013GV54EAeMeXrZuiGg6X2Ct
FFMPEG.cmake built its own `make ${_build_j}` invocation with
`_build_j` defaulting to a bare `-j` (unlimited parallel jobs) unless
CMAKE_BUILD_PARALLEL_LEVEL happened to be set in the environment. On
the macOS-15 GitHub Actions runner this exhausted the process table
mid-build ("/bin/sh: fork: Resource temporarily unavailable", "make:
*** [fftools/ffmpeg_demux.o] Error 128").
The rest of deps/CMakeLists.txt already computes a bounded NPROC
(ProcessorCount, overridable via CMAKE_BUILD_PARALLEL_LEVEL) and uses
it for every other dependency's build step. FFMPEG.cmake was
reimplementing the same env-var check on its own, but without the
ProcessorCount fallback, so its effective default parallelism was
unbounded. Reuse NPROC directly instead of duplicating the logic.
Claude-Session: https://claude.ai/code/session_013GV54EAeMeXrZuiGg6X2Ct
…UBLIC CI builds with -DQDT_RELEASE_TO_PUBLIC=0 (the proprietary QIDI/ cloud sync sources aren't in this checkout), but src/slic3r/CMakeLists.txt still listed QIDI/UserPresetSyncManager.cpp/.hpp unconditionally in SLIC3R_GUI_SOURCES, so add_library() failed with "Cannot find source file" once the deps build got far enough to reach the app's CMake configure step. Every actual use of UserPresetSyncManager in GUI_App.cpp/.hpp is already wrapped in #if QDT_RELEASE_TO_PUBLIC -- only the CMakeLists source list was unguarded. Upstream hit and fixed this exact issue in 911a3ea ("fix: build without QIDI proprietary assets"), which moved these two files into the existing `if(QDT_RELEASE_TO_PUBLIC)` guarded list alongside QIDINetwork.cpp/P2PManager.cpp. This branch predates that commit, so port just the src/slic3r/CMakeLists.txt hunk (the resulting file is byte-identical to upstream's fixed version). Claude-Session: https://claude.ai/code/session_013GV54EAeMeXrZuiGg6X2Ct
The Linux CI step tries to force QDT_RELEASE_TO_PUBLIC=0 by sed-patching
BuildLinux.sh for the literal string "-DQDT_INTERNAL_TESTING=0", but
BuildLinux.sh only ever writes that flag as -DQDT_INTERNAL_TESTING=${INTERNAL_TESTING}
(a variable, never the literal "0"), so the sed is a silent no-op and
QDT_RELEASE_TO_PUBLIC keeps its "1" default. CMake then configures the
QDT_RELEASE_TO_PUBLIC-guarded proprietary QIDI/ sources (QIDINetwork.cpp,
P2PManager.cpp, etc.), none of which exist in this checkout, and
add_library() fails with "Cannot find source file".
Upstream hit the same class of bug and fixed it in 911a3ea ("fix:
build without QIDI proprietary assets") by making version.inc
auto-detect missing QIDI/ sources and force QDT_RELEASE_TO_PUBLIC off
regardless of what was passed in, instead of relying on every build
script/CI step to thread the flag through correctly. Port that same
version.inc fallback here so all three CI platforms build correctly
even when their flag-passing is unreliable.
The macOS CI step brew-installs boost and injects it into CMAKE_PREFIX_PATH ahead of the project's own destdir ($DEPS/usr/local): "-DCMAKE_PREFIX_PATH=\"$CMAKE_PREFIX_PATH;$DEPS...". find_package(Boost) in CONFIG mode picks the first root satisfying the minimum version, so it resolved to Homebrew's Boost 1.92.0 instead of the project's own pinned Boost 1.84.0 (built from source by deps/Boost/Boost.cmake specifically so the app isn't at the mercy of whatever boost version the CI image happens to have). Something about that newer Boost's ABI doesn't match what libslic3r/libslic3r_gui was compiled against, and the final link fails with undefined symbols for several boost::filesystem::detail:: functions. BuildMac.sh's own default is "-DCMAKE_PREFIX_PATH=\"$DEPS/usr/local\"" (no Homebrew paths at all), so put $DEPS/usr/local back in front and keep the brew-installed libs only as a fallback after it, instead of ahead of it.
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.
Summary
BuildFedora.shwas a copy of the Debian/Ubuntu build script that never got ported to Fedora. Beyond the surface-levelapt->dnfandBuildLinux.sh->BuildFedora.shissues, the-d(deps) and-s(app) steps didn't actually produce a working build on Fedora 44 / CMake 4.x. This PR was verified end-to-end multiple times with a full cleansudo ./BuildFedora.sh -u->./BuildFedora.sh -d->./BuildFedora.sh -b -srun.-udependency-install step calledaptwith Debian package names; switched todnfwith Fedora package names.deps/CMakeLists.txtrequired CMake >= 3.2, and CMake 4.x refuses to configure anything below 3.5 at all. Bumped it, and passCMAKE_POLICY_VERSION_MINIMUM=3.5(both as a cmake arg and an env var, so it also covers bundled deps' own nestedtry_compile()checks) to work around the same problem in third-party vendoredCMakeLists.txtfiles (NLopt, wxWidgets, etc.) that can't be edited directly.glew-devel/openvdb-develship only shared.solibs, no static.a, butSLIC3R_STATICforces static linking of both. AddedSLIC3R_STATIC_EXCLUDE_OPENVDB(mirroring the existingSLIC3R_STATIC_EXCLUDE_GLEW) and pass both fromBuildFedora.sh.deps/unconditionally built its own GLFW, OpenVDB (+OpenEXR/Imath) and expat even when a usable system version exists. Since all deps share one install prefix/include root, those headers silently shadow Fedora's system headers regardless of any CMake variable override — causing ABI-mismatched undefined-symbol link errors (GLFW needs KDE'sextra-cmake-modulesfor its Wayland backend; OpenVDB's ABI-versioned inline namespaces don't match Fedora's; webkit2gtk needs a matching dynamiclibexpat.so, not deps' static one). AddedDEP_BUILD_OPENVDB/DEP_BUILD_EXPATtoggles (mirroring the existingDEP_BUILD_GLFW) and disabled all three fromBuildFedora.sh.wx-confighardcodes-L.../libfor its own deps (e.g.-lzlibstatic), but zlib's ownCMakeListsfollowsGNUInstallDirs, which resolves tolib64on Fedora. Addedlib64to the linker search path.bin/sits ahead of the system toolchain onPATH, and CMake'sfind_package(... CONFIG)treatsPATHentries as candidate install prefixes. This silently resolvedzstd(pulled in transitively byBoost::iostreams) to conda's older copy instead of Fedora'slibzstd-devel, and CMake baked that path into the built binary's RPATH — which then also shadowed the systemlibexpat.soat runtime via the same RPATH entry, regardless of whether conda was active when actually running the binary. Strip$CONDA_PREFIXfromPATHat the top of the script.nasm,boost-static,webkit2gtk4.1-devel,mesa-compat-libOSMesa-devel,openvdb-devel,imath-devel,openexr-devel,NLopt-devel,glfw-develto the-udependency list. (Note: Fedora'scereal-develis deliberately not installed — it exports a namespacedcereal::cerealtarget that doesn't match this codebase'starget_link_libraries(... cereal)calls, unlike the barecerealtarget the bundled deps build exports.)-sstep's finalmake -j4 QIDIStudiowas hardcoded regardless of core count; changed to$NCORESto match the-dstep.Test plan
sudo ./BuildFedora.sh -uinstalls cleanly on Fedora 44./BuildFedora.sh -dbuilds all dependencies from a cleandeps/build./BuildFedora.sh -b -sbuildsqidi-studiofrom a cleanbuild, end to end, no manual intervention (verified twice)qidi-studiobinary launches and runs the GUIhttps://claude.ai/code/session_01GX1HqJrRdEWvoiwXkfrLQH