Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions builtins/lhc4codec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.
# All rights reserved.
#
# For the licensing terms see $ROOTSYS/LICENSE.
# For the list of contributors see $ROOTSYS/README/CREDITS.

# Build lhc4codec as part of ROOT. Upstream:
# https://gitlab.cern.ch/apeters/lhc4codec.git
#
# If LHC4CODEC_SOURCE_DIR is set, that checkout is built via add_subdirectory
# (offline / development). Otherwise the source is fetched with ExternalProject
# (clad-style git clone; requires network and GitLab credentials).

include(ExternalProject)

# **PLEASE UPDATE ALSO THE FOLLOWING LINE WHEN UPDATING THE VERSION**
# 16 Sep 2026, https://gitlab.cern.ch/apeters/lhc4codec.git @ 922d272 (packaging/CI, bzip3 pin)
set(ROOT_LHC4CODEC_VERSION 2.3.0)
set(ROOT_LHC4CODEC_GIT_REPOSITORY "https://gitlab.cern.ch/apeters/lhc4codec.git")
set(ROOT_LHC4CODEC_GIT_TAG "922d2729da39cb393c4f109d393ffbaca3424a57")

set(_lhc4codec_build_args
-DLHC4CODEC_BUILD_CLI=OFF
-DLHC4CODEC_BUILD_TESTS=OFF
-DLHC4CODEC_METAL=OFF
-DLHC4CODEC_HIP=OFF
-DLHC4CODEC_NATIVE=OFF
-DLHC4CODEC_LTO=OFF
-DLHC4CODEC_ZSTD=AUTO
-DLHC4CODEC_LZMA=AUTO
-DLHC4CODEC_BZIP3=BUNDLED
-DCMAKE_CXX_STANDARD=20
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
)

if(LHC4CODEC_SOURCE_DIR)
if(NOT EXISTS "${LHC4CODEC_SOURCE_DIR}/CMakeLists.txt")
message(FATAL_ERROR "LHC4CODEC_SOURCE_DIR=\"${LHC4CODEC_SOURCE_DIR}\" does not contain a CMake project")
endif()

message(STATUS "Building builtin lhc4codec from ${LHC4CODEC_SOURCE_DIR}")

set(LHC4CODEC_BUILD_CLI OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_METAL OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_HIP OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_NATIVE OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_LTO OFF CACHE BOOL "" FORCE)
set(LHC4CODEC_ZSTD AUTO CACHE STRING "" FORCE)
set(LHC4CODEC_LZMA AUTO CACHE STRING "" FORCE)
set(LHC4CODEC_BZIP3 BUNDLED CACHE STRING "" FORCE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_subdirectory(${LHC4CODEC_SOURCE_DIR} ${CMAKE_BINARY_DIR}/builtins/lhc4codec-build EXCLUDE_FROM_ALL)

set(LHC4CODEC_INCLUDE_DIRS ${LHC4CODEC_SOURCE_DIR}/include)
set(LHC4CODEC_LIBRARIES lhc4codec_static)

if(NOT TARGET LHC4CODEC::LHC4CODEC)
add_library(LHC4CODEC::LHC4CODEC ALIAS lhc4codec_static)
endif()
else()
message(STATUS "Downloading and building lhc4codec ${ROOT_LHC4CODEC_VERSION} from "
"${ROOT_LHC4CODEC_GIT_REPOSITORY} (${ROOT_LHC4CODEC_GIT_TAG})")

set(ROOT_LHC4CODEC_PREFIX ${CMAKE_BINARY_DIR}/builtins/lhc4codec-prefix)
set(ROOT_LHC4CODEC_SOURCE_DIR ${ROOT_LHC4CODEC_PREFIX}/src/BUILTIN_LHC4CODEC)
set(ROOT_LHC4CODEC_BUILD_DIR ${ROOT_LHC4CODEC_PREFIX}/src/BUILTIN_LHC4CODEC-build)
# Staged headers live outside the git tree so the path exists at configure time
# (CMake validates INTERFACE_INCLUDE_DIRECTORIES on imported targets).
set(ROOT_LHC4CODEC_INCLUDE_DIR ${ROOT_LHC4CODEC_PREFIX}/include)
set(ROOT_LHC4CODEC_LIBRARY
${ROOT_LHC4CODEC_BUILD_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lhc4codec${CMAKE_STATIC_LIBRARY_SUFFIX})
set(ROOT_LHC4CODEC_BZIP3_LIBRARY
${ROOT_LHC4CODEC_BUILD_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lhc4_bzip3_bundled${CMAKE_STATIC_LIBRARY_SUFFIX})
file(MAKE_DIRECTORY ${ROOT_LHC4CODEC_INCLUDE_DIR})

if(MSVC)
set(_lhc4codec_build_type Release)
if(winrtdebug)
set(_lhc4codec_build_type Debug)
endif()
if(NOT CMAKE_GENERATOR MATCHES Ninja)
set(_lhc4codec_build_flags --config ${_lhc4codec_build_type})
endif()
set(_lhc4codec_extra_cmake_args
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
-DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG})
else()
set(_lhc4codec_build_type Release)
set(_lhc4codec_build_flags "")
set(_lhc4codec_extra_cmake_args "")
endif()

ExternalProject_Add(
BUILTIN_LHC4CODEC
GIT_REPOSITORY ${ROOT_LHC4CODEC_GIT_REPOSITORY}
GIT_TAG ${ROOT_LHC4CODEC_GIT_TAG}
GIT_SUBMODULES third_party/bzip3
PREFIX ${ROOT_LHC4CODEC_PREFIX}
UPDATE_COMMAND ""
CMAKE_ARGS -G ${CMAKE_GENERATOR}
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=${_lhc4codec_build_type}
${_lhc4codec_build_args}
${_lhc4codec_extra_cmake_args}
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> ${_lhc4codec_build_flags}
--target lhc4codec_static lhc4_bzip3_bundled
INSTALL_COMMAND ""
LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 LOG_OUTPUT_ON_FAILURE 1
BUILD_BYPRODUCTS ${ROOT_LHC4CODEC_LIBRARY} ${ROOT_LHC4CODEC_BZIP3_LIBRARY}
TIMEOUT 600
)

# Copy public headers after the git clone, before the nested configure/build.
ExternalProject_Add_Step(BUILTIN_LHC4CODEC stage-headers
COMMAND ${CMAKE_COMMAND} -E rm -rf ${ROOT_LHC4CODEC_INCLUDE_DIR}/lhc4codec
COMMAND ${CMAKE_COMMAND} -E copy_directory
<SOURCE_DIR>/include/lhc4codec
${ROOT_LHC4CODEC_INCLUDE_DIR}/lhc4codec
DEPENDEES download
DEPENDERS configure
)

add_library(LHC4CODEC::LHC4CODEC IMPORTED STATIC GLOBAL)
add_dependencies(LHC4CODEC::LHC4CODEC BUILTIN_LHC4CODEC)
set_target_properties(LHC4CODEC::LHC4CODEC PROPERTIES
IMPORTED_LOCATION ${ROOT_LHC4CODEC_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${ROOT_LHC4CODEC_INCLUDE_DIR}
INTERFACE_LINK_LIBRARIES ${ROOT_LHC4CODEC_BZIP3_LIBRARY}
)

set(LHC4CODEC_INCLUDE_DIRS ${ROOT_LHC4CODEC_INCLUDE_DIR})
set(LHC4CODEC_LIBRARIES ${ROOT_LHC4CODEC_LIBRARY})
endif()

set(LHC4CODEC_FOUND TRUE)
set(LHC4CODEC_VERSION ${ROOT_LHC4CODEC_VERSION})

set(LHC4CODEC_INCLUDE_DIRS ${LHC4CODEC_INCLUDE_DIRS} PARENT_SCOPE)
set(LHC4CODEC_LIBRARIES ${LHC4CODEC_LIBRARIES} PARENT_SCOPE)
set(LHC4CODEC_FOUND ${LHC4CODEC_FOUND} PARENT_SCOPE)
set(LHC4CODEC_VERSION ${LHC4CODEC_VERSION} PARENT_SCOPE)
124 changes: 124 additions & 0 deletions cmake/modules/FindLHC4CODEC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.
# All rights reserved.
#
# For the licensing terms see $ROOTSYS/LICENSE.
# For the list of contributors see $ROOTSYS/README/CREDITS.

#.rst:
# FindLHC4CODEC
# -------------
#
# Find the lhc4codec library header and define variables.
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines :prop_tgt:`IMPORTED` target ``LHC4CODEC::LHC4CODEC``,
# if lhc4codec has been found.
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This module defines the following variables:
#
# ::
#
# LHC4CODEC_FOUND - True if lhc4codec is found.
# LHC4CODEC_INCLUDE_DIRS - Where to find lhc4codec/lhc4codec_c.h
# LHC4CODEC_LIBRARIES - The lhc4codec library path
# LHC4CODEC_VERSION - The lhc4codec version string, if available
# LHC4CODEC_INSTALL_HELP - How to install a missing package (always set)

# Prebuilt packages: https://gitlab.cern.ch/apeters/lhc4codec-bin
set(LHC4CODEC_INSTALL_HELP [=[
lhc4codec was not found (need lhc4codec/lhc4codec_c.h and liblhc4codec).

Install a prebuilt package from https://gitlab.cern.ch/apeters/lhc4codec-bin :

# AlmaLinux 9 / 10 (x86_64)
sudo curl -fsSL -o /etc/yum.repos.d/lhc4codec.repo \
https://gitlab.cern.ch/apeters/lhc4codec-bin/-/raw/master/lhc4codec-el9.repo # or -el10
sudo dnf install lhc4codec lhc4codec-devel

# macOS, Apple silicon (macOS 13+)
brew tap apeters/lhc4codec https://gitlab.cern.ch/apeters/lhc4codec-bin.git
brew install apeters/lhc4codec/lhc4codec

Or point CMake at an existing prefix: -DLHC4CODEC_ROOT=/path/to/prefix
Or let ROOT clone and build it: -Dbuiltin_lhc4codec=ON
(fetches https://gitlab.cern.ch/apeters/lhc4codec.git)
]=])

set(_lhc4codec_hints)
if(LHC4CODEC_ROOT)
list(APPEND _lhc4codec_hints "${LHC4CODEC_ROOT}")
endif()
if(DEFINED ENV{LHC4CODEC_ROOT})
list(APPEND _lhc4codec_hints "$ENV{LHC4CODEC_ROOT}")
endif()

if(APPLE)
# Homebrew: arm64 default is /opt/homebrew, Intel is /usr/local.
list(APPEND _lhc4codec_hints /opt/homebrew /usr/local)
find_program(_lhc4codec_brew brew)
if(_lhc4codec_brew)
execute_process(COMMAND "${_lhc4codec_brew}" --prefix lhc4codec
OUTPUT_VARIABLE _lhc4codec_brew_formula
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(_lhc4codec_brew_formula)
list(APPEND _lhc4codec_hints "${_lhc4codec_brew_formula}")
endif()
execute_process(COMMAND "${_lhc4codec_brew}" --prefix
OUTPUT_VARIABLE _lhc4codec_brew_prefix
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(_lhc4codec_brew_prefix)
list(APPEND _lhc4codec_hints "${_lhc4codec_brew_prefix}")
endif()
endif()
unset(_lhc4codec_brew CACHE)
endif()

find_path(LHC4CODEC_INCLUDE_DIR lhc4codec/lhc4codec_c.h
HINTS ${_lhc4codec_hints}
PATH_SUFFIXES include
)

find_library(LHC4CODEC_LIBRARY
NAMES lhc4codec lhc4codec_static
HINTS ${_lhc4codec_hints}
PATH_SUFFIXES lib lib64
)

if(LHC4CODEC_INCLUDE_DIR AND EXISTS "${LHC4CODEC_INCLUDE_DIR}/lhc4codec/lhc4codec_c.h")
file(READ "${LHC4CODEC_INCLUDE_DIR}/lhc4codec/lhc4codec_c.h" _lhc4codec_header)
string(REGEX MATCH "#define LHC4CODEC_VERSION \"([^\"]+)\"" _lhc4codec_version_match "${_lhc4codec_header}")
if(CMAKE_MATCH_1)
set(LHC4CODEC_VERSION "${CMAKE_MATCH_1}")
endif()
unset(_lhc4codec_header)
unset(_lhc4codec_version_match)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LHC4CODEC
REQUIRED_VARS LHC4CODEC_LIBRARY LHC4CODEC_INCLUDE_DIR
VERSION_VAR LHC4CODEC_VERSION
)

if(LHC4CODEC_FOUND)
set(LHC4CODEC_INCLUDE_DIRS "${LHC4CODEC_INCLUDE_DIR}")
set(LHC4CODEC_LIBRARIES "${LHC4CODEC_LIBRARY}")

if(NOT TARGET LHC4CODEC::LHC4CODEC)
add_library(LHC4CODEC::LHC4CODEC UNKNOWN IMPORTED)
set_target_properties(LHC4CODEC::LHC4CODEC PROPERTIES
IMPORTED_LOCATION "${LHC4CODEC_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${LHC4CODEC_INCLUDE_DIRS}")
endif()
endif()

unset(_lhc4codec_hints)
unset(_lhc4codec_brew_formula)
unset(_lhc4codec_brew_prefix)
2 changes: 2 additions & 0 deletions cmake/modules/RootBuildOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ ROOT_BUILD_OPTION(builtin_glu OFF "Build libtess-GLU from an internal source tar
ROOT_BUILD_OPTION(builtin_gsl OFF "Build GSL from an automatically downloaded source tarball (requires network) [GPL]")
ROOT_BUILD_OPTION(builtin_gtest OFF "Build googletest from an automatically downloaded source tarball (requires network)")
ROOT_BUILD_OPTION(builtin_jpeg OFF "Build libjpeg from an automatically downloaded source tarball (requires network)")
ROOT_BUILD_OPTION(builtin_lhc4codec OFF "Build bundled copy of lhc4codec (git clone or LHC4CODEC_SOURCE_DIR)")
ROOT_BUILD_OPTION(builtin_llvm ON "Build bundled copy of LLVM (advanced option)")
MARK_AS_ADVANCED(builtin_llvm)
ROOT_BUILD_OPTION(builtin_lz4 OFF "Build lz4 from an automatically downloaded source tarball (requires network)")
Expand Down Expand Up @@ -123,6 +124,7 @@ ROOT_BUILD_OPTION(coverage OFF "Enable compile flags for coverage testing")
ROOT_BUILD_OPTION(cuda OFF "Enable support for CUDA (requires CUDA toolkit >= 7.5)")
ROOT_BUILD_OPTION(curl ON "Enable support for HTTP(S) through libcurl")
ROOT_BUILD_OPTION(daos OFF "Enable RNTuple support for Intel DAOS")
ROOT_BUILD_OPTION(lhc4codec OFF "Enable LHC4 compression for RNTuple/TFile (requires lhc4codec library)")
ROOT_BUILD_OPTION(dataframe ON "Enable ROOT RDataFrame")
ROOT_BUILD_OPTION(davix ON "Enable support for Davix (HTTP/WebDAV access)")
ROOT_BUILD_OPTION(dcache OFF "Enable support for dCache (requires libdcap from DESY)")
Expand Down
5 changes: 5 additions & 0 deletions cmake/modules/RootConfiguration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ if(clad)
else()
set(hasclad undef)
endif()
if(lhc4codec)
set(haslhc4codec define)
else()
set(haslhc4codec undef)
endif()
if(cocoa)
set(hascocoa define)
else()
Expand Down
25 changes: 25 additions & 0 deletions cmake/modules/SearchInstalledSoftware.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,31 @@ if(builtin_lz4)
add_subdirectory(builtins/lz4)
endif()

#---Check for LHC4CODEC--------------------------------------------------------------
set(LHC4CODEC_SOURCE_DIR "" CACHE PATH
"Optional path to an lhc4codec checkout; if empty and builtin_lhc4codec=ON, the source is git-cloned")

if(lhc4codec)
if(builtin_lhc4codec)
list(APPEND ROOT_BUILTINS LHC4CODEC)
add_subdirectory(builtins/lhc4codec)
else()
find_package(LHC4CODEC QUIET)
if(NOT LHC4CODEC_FOUND)
if(NOT LHC4CODEC_INSTALL_HELP)
set(LHC4CODEC_INSTALL_HELP
"lhc4codec was not found. Install lhc4codec-devel / brew tap apeters/lhc4codec, set -DLHC4CODEC_ROOT, or use -Dbuiltin_lhc4codec=ON.")
endif()
message(FATAL_ERROR "${LHC4CODEC_INSTALL_HELP}")
endif()
if(LHC4CODEC_VERSION)
message(STATUS "Found LHC4CODEC: ${LHC4CODEC_LIBRARIES} (version ${LHC4CODEC_VERSION})")
else()
message(STATUS "Found LHC4CODEC: ${LHC4CODEC_LIBRARIES}")
endif()
endif()
endif()

#---Check for X11 which is mandatory lib on Unix--------------------------------------
if(x11)
message(STATUS "Looking for X11")
Expand Down
2 changes: 2 additions & 0 deletions config/RConfigure.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@

#@hasgeom@ R__HAS_GEOM /**/

#@haslhc4codec@ R__HAS_LHC4CODEC /**/

#endif
3 changes: 3 additions & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ add_subdirectory(zip)
add_subdirectory(lzma)
add_subdirectory(lz4)
add_subdirectory(zstd)
if(lhc4codec)
add_subdirectory(lhc4codec)
endif()

add_subdirectory(macosx)
add_subdirectory(unix)
Expand Down
26 changes: 26 additions & 0 deletions core/lhc4codec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
############################################################################
# CMakeLists.txt file for building ROOT core/lhc4codec package
############################################################################

add_library(ROOTLHC4Zip OBJECT src/ZipLHC4.cxx)
set_target_properties(ROOTLHC4Zip PROPERTIES
CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF
POSITION_INDEPENDENT_CODE ON)
target_link_libraries(ROOTLHC4Zip PRIVATE LHC4CODEC::LHC4CODEC)
target_include_directories(ROOTLHC4Zip
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
)

target_sources(Core PRIVATE $<TARGET_OBJECTS:ROOTLHC4Zip>)

target_link_libraries(Core PRIVATE LHC4CODEC::LHC4CODEC)

# Bundled bzip3 is a separate static lib in the lhc4codec build; propagate it when
# built via add_subdirectory (ExternalProject uses INTERFACE_LINK_LIBRARIES).
if(TARGET lhc4_bzip3_bundled)
target_link_libraries(Core PRIVATE lhc4_bzip3_bundled)
endif()

target_include_directories(Core PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>)

ROOT_INSTALL_HEADERS()
Loading