From 936b7b2d43e23a5a208f2a5c14429bcf7f6c8a3f Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 14 Jun 2026 15:35:31 +0200 Subject: [PATCH 1/2] [CMake] Add missing build dependency for builtin zstd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit builtins/zstd defined the imported ZSTD::ZSTD target but never tied it to the BUILTIN_ZSTD ExternalProject that actually produces libzstd.a. As a result a parallel or targeted build (e.g. building only the Core target) could try to link the archive before it exists. Add the dependency edge, consistent with what builtins/zlib already does for BUILTIN_ZLIB. 🤖 Done with the help of [Claude Code](https://claude.com/claude-code) (Claude Opus 4.8) --- builtins/zstd/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builtins/zstd/CMakeLists.txt b/builtins/zstd/CMakeLists.txt index b2cd2076a7a87..8297a3cb4469d 100644 --- a/builtins/zstd/CMakeLists.txt +++ b/builtins/zstd/CMakeLists.txt @@ -62,6 +62,10 @@ set_target_properties(ZSTD::ZSTD PROPERTIES IMPORTED_LOCATION ${ROOT_ZSTD_LIBRARY} INTERFACE_INCLUDE_DIRECTORIES ${ZSTD_INCLUDE_DIR} ) +# Make consumers of ZSTD::ZSTD wait for the ExternalProject that actually builds +# the library, otherwise a parallel or targeted build can try to link the not-yet +# existing libzstd archive (consistent with builtins/zlib's add_dependencies). +add_dependencies(ZSTD::ZSTD BUILTIN_ZSTD) # Set the canonical output of find_package according to # https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#standard-variable-names From 3a71c657a9afceaa562e9678a421a3d4891d6b0a Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 14 Jun 2026 15:31:00 +0200 Subject: [PATCH 2/2] [CMake] Don't override find_package() for builtins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ROOT redefined the global find_package() command to no-op for its builtins, so that sub-projects added later (notably the bundled LLVM) and transitive find modules (e.g. FindPNG -> find_package(ZLIB)) would reuse ROOT's builtin imported targets instead of re-discovering a system copy. This relied on undocumented CMake behaviour and recursed infinitely under tools that override find_package() themselves, such as vcpkg (#8633). The override only ever did real work for ZLIB and zstd: every other name in ROOT_BUILTINS was unnecessary (no find_package() consumer downstream). Both are now handled directly, so the override and the ROOT_BUILTINS list can be removed: * ZLIB (used by core/zip's find_package(ZLIB REQUIRED) and the transitive FindPNG -> find_package(ZLIB) of the asimage build): builtins/zlib pre-seeds the singular cache variables ZLIB_LIBRARY and ZLIB_INCLUDE_DIR that FindZLIB.cmake checks, so find_package() short-circuits to the builtin and keeps the ZLIB::ZLIB target. This also avoids the "FORCE specified without CACHE" error from select_library_configurations() that a real FindPNG -> FindZLIB chain would otherwise hit. * zstd (used only by the bundled LLVM): interpreter/CMakeLists.txt sets LLVM_ENABLE_ZSTD=OFF (and LLVM_ENABLE_ZLIB=OFF) for builtin builds, so LLVM never searches for the system copy. We can't point LLVM at the builtins instead, as it probes them with a configure-time compile/link check that the not-yet-built ExternalProject can't pass anyway. This makes ROOT compatible with vcpkg and other dependency providers without changing behaviour: in builtin builds LLVM is still built without zlib/zstd, and a system build is unaffected since find_package() is no longer shadowed. Closes #8633. 🤖 Done with the help of [Claude Code](https://claude.com/claude-code) (Claude Opus 4.8) --- builtins/zlib/CMakeLists.txt | 10 +++++++++ cmake/modules/SearchInstalledSoftware.cmake | 25 --------------------- interpreter/CMakeLists.txt | 12 ++++++++++ 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/builtins/zlib/CMakeLists.txt b/builtins/zlib/CMakeLists.txt index 85e69387c88af..4370710a63687 100644 --- a/builtins/zlib/CMakeLists.txt +++ b/builtins/zlib/CMakeLists.txt @@ -74,3 +74,13 @@ set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR} PARENT_SCOPE) set(ZLIB_LIBRARIES ${ROOT_ZLIB_LIBRARY} PARENT_SCOPE) set(ZLIB_FOUND TRUE PARENT_SCOPE) set(ZLIB_VERSION ${ROOT_ZLIB_VERSION} PARENT_SCOPE) + +# Pre-seed the singular variables FindZLIB.cmake consumes (its REQUIRED_VARS: +# ZLIB_INCLUDE_DIR via find_path(), ZLIB_LIBRARY via its if(NOT ZLIB_LIBRARY) +# guard), so a real find_package(ZLIB) short-circuits the system search and +# reuses the builtin ZLIB::ZLIB target above. Setting this variable in the +# PARENT_SCOPE is sufficient, because that's SearchInstalledSoftware.cmake +# where also the other find_package(ZLIB) calls happen (indirectly via +# FindPNG). So a CACHE entry is not required. +set(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIR} PARENT_SCOPE) +set(ZLIB_LIBRARY ${ROOT_ZLIB_LIBRARY} PARENT_SCOPE) diff --git a/cmake/modules/SearchInstalledSoftware.cmake b/cmake/modules/SearchInstalledSoftware.cmake index f50178edc7e66..d98155c531f68 100644 --- a/cmake/modules/SearchInstalledSoftware.cmake +++ b/cmake/modules/SearchInstalledSoftware.cmake @@ -137,14 +137,6 @@ if(NOT "${MISSING_PACKAGES}" STREQUAL "") message(FATAL_ERROR "The following packages need to be installed or enabled to build ROOT: ${MISSING_PACKAGES}") endif() -#--- Redefine find_package for LLVM to pick up ROOT's builtins ---------------------- -# TODO: Make this only local to LLVM? -macro(find_package) - if(NOT "${ARGV0}" IN_LIST ROOT_BUILTINS) # ROOT_BUILTINS are the variable names, not the same as ROOT_BUILTIN_TARGETS used for move-header dependency - _find_package(${ARGV}) - endif() -endmacro() - #---On MacOSX, try to find frameworks after standard libraries or headers------------ set(CMAKE_FIND_FRAMEWORK LAST) @@ -160,7 +152,6 @@ endif() #---Check for Zlib ------------------------------------------------------------------ if(builtin_zlib) - list(APPEND ROOT_BUILTINS ZLIB) add_subdirectory(builtins/zlib) else() # If not built-in, check if this is zlib-ng @@ -216,7 +207,6 @@ if(NOT builtin_nlohmannjson) endif() if(builtin_nlohmannjson) - list(APPEND ROOT_BUILTINS BUILTIN_NLOHMANN) add_subdirectory(builtins/nlohmann) endif() @@ -259,7 +249,6 @@ endif() #---Check for Freetype--------------------------------------------------------------- ROOT_FIND_REQUIRED_DEP(Freetype builtin_freetype) # needed for asimage, but also outside of it (for "graf" target) if(builtin_freetype) - list(APPEND ROOT_BUILTINS BUILTIN_FREETYPE) add_subdirectory(builtins/freetype) elseif(NOT Freetype_VERSION AND FREETYPE_VERSION_STRING) # on mac brew installed freetype version_string is returned @@ -299,18 +288,15 @@ endif() if(builtin_pcre) add_subdirectory(builtins/pcre) - list(APPEND ROOT_BUILTINS BUILTIN_PCRE) endif() #---Check for LZMA------------------------------------------------------------------- if(builtin_lzma) - list(APPEND ROOT_BUILTINS LZMA) add_subdirectory(builtins/lzma) endif() #---Check for xxHash----------------------------------------------------------------- if(builtin_xxhash) - list(APPEND ROOT_BUILTINS xxHash) add_subdirectory(builtins/xxhash) endif() @@ -320,14 +306,11 @@ if(ZSTD_FOUND AND ZSTD_VERSION VERSION_LESS 1.0.0) endif() if(builtin_zstd) - list(APPEND ROOT_BUILTINS zstd) - list(APPEND ROOT_BUILTINS ZSTD) add_subdirectory(builtins/zstd) endif() #---Check for LZ4-------------------------------------------------------------------- if(builtin_lz4) - list(APPEND ROOT_BUILTINS LZ4) add_subdirectory(builtins/lz4) endif() @@ -482,7 +465,6 @@ if(opengl) ROOT_FIND_REQUIRED_DEP(gl2ps builtin_gl2ps) if (builtin_gl2ps) add_subdirectory(builtins/gl2ps) - list(APPEND ROOT_BUILTINS BUILTIN_GL2PS) endif() elseif(builtin_gl2ps) message(SEND_ERROR "gl2ps features enabled with \"builtin_gl2ps=ON\" require \"opengl=ON\"") @@ -550,7 +532,6 @@ if(builtin_openssl) set(builtin_openssl OFF CACHE BOOL "Disabled because there is no internet connection" FORCE) set(ssl OFF CACHE BOOL "Disabled because there is no internet connection" FORCE) else() - list(APPEND ROOT_BUILTINS OpenSSL) add_subdirectory(builtins/openssl) endif() endif() @@ -619,7 +600,6 @@ if(fftw3) endif() endif() if(builtin_fftw3) - list(APPEND ROOT_BUILTINS BUILTIN_FFTW3) add_subdirectory(builtins/fftw3) set(fftw3 ON CACHE BOOL "Enabled because builtin_fftw3 requested (${fftw3_description})" FORCE) endif() @@ -713,7 +693,6 @@ if(builtin_xrootd) if(NOT ssl AND NOT builtin_openssl) message(FATAL_ERROR "Building XRootD ('builtin_xrootd'=On) requires ssl support ('ssl' or 'builtin_openssl').") endif() - list(APPEND ROOT_BUILTINS BUILTIN_XROOTD) add_subdirectory(builtins/xrootd) set(xrootd ON CACHE BOOL "Enabled because builtin_xrootd requested (${xrootd_description})" FORCE) endif() @@ -780,7 +759,6 @@ if(opengl) ROOT_FIND_REQUIRED_DEP(FTGL builtin_ftgl) if (builtin_ftgl) add_subdirectory(builtins/ftgl) - list(APPEND ROOT_BUILTINS BUILTIN_FTGL) endif() elseif(builtin_ftgl) message(SEND_ERROR "FTGL features enabled with \"builtin_ftgl=ON\" require \"opengl=ON\"") @@ -940,7 +918,6 @@ if(builtin_tbb) endif() if(builtin_tbb) - list(APPEND ROOT_BUILTINS BUILTIN_TBB) add_subdirectory(builtins/tbb) endif() @@ -969,7 +946,6 @@ if(vdt OR builtin_vdt) endif() endif() if(builtin_vdt) - list(APPEND ROOT_BUILTINS VDT) add_subdirectory(builtins/vdt) endif() endif() @@ -1129,7 +1105,6 @@ if(mathmore OR builtin_gsl OR (tmva-cpu AND use_gsl_cblas)) endif() endif() else() - list(APPEND ROOT_BUILTINS BUILTIN_GSL) add_subdirectory(builtins/gsl) set(mathmore ON CACHE BOOL "Enabled because builtin_gsl requested (${mathmore_description})" FORCE) endif() diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt index 0885d6e74a66b..4d012a667b870 100644 --- a/interpreter/CMakeLists.txt +++ b/interpreter/CMakeLists.txt @@ -21,6 +21,18 @@ set(LLVM_ENABLE_FFI OFF CACHE BOOL "") set(LLVM_ENABLE_OCAMLDOC OFF CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") set(LLVM_ENABLE_WARNINGS OFF CACHE BOOL "") + +# When ROOT provides zlib/zstd as builtins, disable them in the bundled LLVM so it +# cannot discover and link the *system* copy (mixing two versions in one process). +# We cannot point LLVM at the builtins instead: it probes them with a configure-time +# compile/link check, but the builtin libraries are only produced later by their +# ExternalProject, so the check would always fail. +if(builtin_zlib) + set(LLVM_ENABLE_ZLIB OFF CACHE STRING "Disabled because ROOT uses builtin zlib" FORCE) +endif() +if(builtin_zstd) + set(LLVM_ENABLE_ZSTD OFF CACHE STRING "Disabled because ROOT uses builtin zstd" FORCE) +endif() set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")