From 0edf0cfdecd207d43de23dd8548eaf706cdfeb28 Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 20 Aug 2026 15:54:16 +0800 Subject: [PATCH 1/3] feat(cpp): add native installation packages --- .github/workflows/cpp-packaging.yml | 130 +++++++++++++ cpp/CMakeLists.txt | 171 +++++++++++++++++- cpp/README.md | 9 +- cpp/cmake/ANTLR4Dependency.cmake | 6 +- cpp/cmake/TsFileConfig.cmake.in | 29 +++ cpp/cmake/TsFilePublicHeaders.cmake | 47 +++++ cpp/cmake/libtsfile.pc.in | 31 ++++ cpp/cmake/tests/ANTLR4DependencyTest.cmake | 2 +- .../projects/ANTLR4Dependency/CMakeLists.txt | 2 +- .../projects/InstalledConsumer/CMakeLists.txt | 42 +++++ .../tests/projects/InstalledConsumer/main.cc | 24 +++ .../projects/PkgConfigConsumer/CMakeLists.txt | 32 ++++ .../tests/projects/PkgConfigConsumer/main.c | 21 +++ .../tests/projects/PkgConfigConsumer/main.cc | 21 +++ cpp/src/CMakeLists.txt | 118 ++++++++++-- cpp/third_party/CMakeLists.txt | 23 +++ cpp/third_party/README.md | 2 +- cpp/tools/CMakeLists.txt | 17 +- packaging/README.md | 92 ++++++++++ packaging/homebrew/tsfile.rb | 71 ++++++++ 20 files changed, 868 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/cpp-packaging.yml create mode 100644 cpp/cmake/TsFileConfig.cmake.in create mode 100644 cpp/cmake/TsFilePublicHeaders.cmake create mode 100644 cpp/cmake/libtsfile.pc.in create mode 100644 cpp/cmake/tests/projects/InstalledConsumer/CMakeLists.txt create mode 100644 cpp/cmake/tests/projects/InstalledConsumer/main.cc create mode 100644 cpp/cmake/tests/projects/PkgConfigConsumer/CMakeLists.txt create mode 100644 cpp/cmake/tests/projects/PkgConfigConsumer/main.c create mode 100644 cpp/cmake/tests/projects/PkgConfigConsumer/main.cc create mode 100644 packaging/README.md create mode 100644 packaging/homebrew/tsfile.rb diff --git a/.github/workflows/cpp-packaging.yml b/.github/workflows/cpp-packaging.yml new file mode 100644 index 000000000..ef5a457c2 --- /dev/null +++ b/.github/workflows/cpp-packaging.yml @@ -0,0 +1,130 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: Cpp-Packaging + +on: + push: + branches: + - develop + - rc/** + paths: + - '.github/workflows/cpp-packaging.yml' + - 'cpp/**' + - 'packaging/**' + - 'LICENSE' + - 'NOTICE' + pull_request: + branches: + - develop + - rc/** + paths: + - '.github/workflows/cpp-packaging.yml' + - 'cpp/**' + - 'packaging/**' + - 'LICENSE' + - 'NOTICE' + workflow_dispatch: + +permissions: + contents: read + +jobs: + deb: + name: Debian package + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Install packaging tools + run: | + sudo apt-get update + sudo apt-get install -y build-essential cmake ninja-build pkg-config dpkg-dev + + - name: Configure and build + run: | + cmake -S cpp -B build/deb -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TEST=OFF \ + -DBUILD_TOOLS=ON \ + -DTSFILE_ENABLE_CPACK=ON \ + -DTSFILE_DEPENDENCY_SOURCE=AUTO \ + -DTSFILE_ENABLE_NATIVE_ARCH=OFF + cmake --build build/deb --parallel + cmake --install build/deb + + - name: Build and inspect DEB packages + run: | + cpack --config build/deb/CPackConfig.cmake -G DEB + ls -lh ./*.deb + for package in ./*.deb; do + dpkg-deb --info "$package" + dpkg-deb --contents "$package" | grep -E '(/libtsfile|/tsfile-cli|TsFileConfig|libtsfile.pc)' || true + done + + - name: Upload DEB packages + uses: actions/upload-artifact@v4 + with: + name: tsfile-deb + path: '*.deb' + if-no-files-found: error + + rpm: + name: Fedora package + runs-on: ubuntu-24.04 + container: fedora:latest + timeout-minutes: 30 + steps: + - name: Install build and packaging tools + run: | + dnf install -y \ + cmake gcc-c++ make ninja-build pkgconf-pkg-config rpm-build \ + git curl tar xz unzip gzip + + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Configure and build + run: | + cmake -S cpp -B build/rpm -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TEST=OFF \ + -DBUILD_TOOLS=ON \ + -DTSFILE_ENABLE_CPACK=ON \ + -DTSFILE_DEPENDENCY_SOURCE=AUTO \ + -DTSFILE_ENABLE_NATIVE_ARCH=OFF + cmake --build build/rpm --parallel + cmake --install build/rpm + + - name: Build and inspect RPM packages + run: | + cpack --config build/rpm/CPackConfig.cmake -G RPM + ls -lh ./*.rpm + for package in ./*.rpm; do + rpm -qip "$package" + rpm -qlp "$package" | grep -E '(/libtsfile|/tsfile-cli|TsFileConfig|libtsfile.pc)' || true + done + + - name: Upload RPM packages + uses: actions/upload-artifact@v4 + with: + name: tsfile-rpm + path: '*.rpm' + if-no-files-found: error diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 7ff07a786..9da9a2d8c 100755 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -34,6 +34,25 @@ if (POLICY CMP0074) endif () set(TsFile_CPP_VERSION 2.3.2.dev) +include(GNUInstallDirs) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/TsFilePublicHeaders.cmake) + +# The package version identifies the source release. Development suffixes are +# intentionally removed from generated package metadata and never enter the +# SONAME. +string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" TSFILE_PACKAGE_VERSION + "${TsFile_CPP_VERSION}") +if ("${TSFILE_PACKAGE_VERSION}" STREQUAL "") + message(FATAL_ERROR + "TsFile_CPP_VERSION must start with a semantic version: " + "${TsFile_CPP_VERSION}") +endif () +set(TSFILE_ABI_VERSION "1" CACHE STRING + "TsFile shared-library ABI epoch (changes only on ABI breaks)") +if (NOT TSFILE_ABI_VERSION MATCHES "^[0-9]+$") + message(FATAL_ERROR "TSFILE_ABI_VERSION must be a positive integer") +endif () + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DependencySource.cmake) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -64,10 +83,18 @@ endif () message("cmake using: USE_CPP11=${USE_CPP11}") # MSVC has no /std:c++11; CMake maps this to the closest supported standard # (C++14 default on MSVC), which compiles the C++11 codebase fine. -set(CMAKE_CXX_STANDARD 11) +set(TSFILE_CXX_STANDARD "11" CACHE STRING + "C++ language standard used to build TsFile (11, 14, or 17)") +set_property(CACHE TSFILE_CXX_STANDARD PROPERTY STRINGS 11 14 17) +if (NOT TSFILE_CXX_STANDARD MATCHES "^(11|14|17)$") + message(FATAL_ERROR + "TSFILE_CXX_STANDARD must be one of 11, 14, or 17") +endif () +set(CMAKE_CXX_STANDARD ${TSFILE_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED OFF) if (NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -std=c++${TSFILE_CXX_STANDARD}") endif () if (DEFINED ENV{CXX}) @@ -333,7 +360,8 @@ if (MSVC) # C++17 extensions), so we pin it explicitly for reproducibility. set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} /W3 /utf-8 /EHsc /bigobj /Zc:__cplusplus /std:c++14") else () - set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall -std=c++11") + set(CMAKE_CXX_FLAGS + "$ENV{CXXFLAGS} -Wall -std=c++${TSFILE_CXX_STANDARD}") endif () add_subdirectory(third_party) @@ -406,3 +434,140 @@ endif () unset(_TSFILE_PROJECT_DEPENDENCIES) add_subdirectory(examples) + +# Install the compatibility header closure from the generated staging tree. The +# staging tree is populated by the existing copy_* targets and contains only +# headers selected by the reviewed closure manifest. The closure is retained +# for source compatibility; it is not the final public API boundary. +foreach (header_dir IN LISTS TSFILE_PUBLIC_HEADER_CLOSURE) + install(DIRECTORY "${LIBRARY_INCLUDE_DIR}/${header_dir}/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tsfile/${header_dir}" + COMPONENT development + FILES_MATCHING PATTERN "*.h") +endforeach() +if (ENABLE_SIMD AND TSFILE_SIMDE_INCLUDE_ROOT) + install(DIRECTORY "${TSFILE_SIMDE_INCLUDE_ROOT}/simde/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/simde" + COMPONENT development + FILES_MATCHING PATTERN "*.h") +endif () +if (ENABLE_ANTLR4 AND TSFILE_ANTLR4_INCLUDE_ROOT) + install(DIRECTORY "${TSFILE_ANTLR4_INCLUDE_ROOT}/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT development + FILES_MATCHING PATTERN "*.h") +endif () +if (ENABLE_ANTLR4 AND TSFILE_UTF8CPP_INCLUDE_ROOT) + install(DIRECTORY "${TSFILE_UTF8CPP_INCLUDE_ROOT}/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT development + FILES_MATCHING PATTERN "*.h") +endif () + +set(TSFILE_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE") +set(TSFILE_NOTICE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../NOTICE") +if (EXISTS "${TSFILE_LICENSE_FILE}") + install(FILES "${TSFILE_LICENSE_FILE}" + DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/tsfile" + COMPONENT runtime) +endif() +if (EXISTS "${TSFILE_NOTICE_FILE}") + install(FILES "${TSFILE_NOTICE_FILE}" + DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/tsfile" + COMPONENT runtime) +endif() + +include(CMakePackageConfigHelpers) +set(TSFILE_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/TsFile") +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/TsFileConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfig.cmake" + INSTALL_DESTINATION "${TSFILE_CMAKE_INSTALL_DIR}") +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfigVersion.cmake" + VERSION "${TSFILE_PACKAGE_VERSION}" + COMPATIBILITY SameMajorVersion) +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfigVersion.cmake" + DESTINATION "${TSFILE_CMAKE_INSTALL_DIR}" + COMPONENT development) + +set(TSFILE_PKGCONFIG_CFLAGS "") +foreach (_TSFILE_PUBLIC_FEATURE + ENABLE_ANTLR4 + ENABLE_MEM_STAT + ENABLE_SNAPPY + ENABLE_LZ4 + ENABLE_LZOKAY + ENABLE_ZLIB + ENABLE_GZIP + ENABLE_ZSTD + ENABLE_LZMA2 + ENABLE_THREADS + ENABLE_SIMD) + if (${_TSFILE_PUBLIC_FEATURE}) + string(APPEND TSFILE_PKGCONFIG_CFLAGS + " -D${_TSFILE_PUBLIC_FEATURE}") + endif () +endforeach () +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/libtsfile.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/libtsfile.pc" + @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libtsfile.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + COMPONENT development) +unset(_TSFILE_PUBLIC_FEATURE) + +# CPack is an opt-in local/package-builder integration. Native release jobs +# can configure the project with TSFILE_DEPENDENCY_SOURCE=SYSTEM when the +# target image provides every compatible dependency; AUTO remains the +# reproducible fallback for distribution images with older packages. +option(TSFILE_ENABLE_CPACK + "Enable CPack DEB/RPM package metadata generation" OFF) +if (TSFILE_ENABLE_CPACK) + set(CPACK_PACKAGE_NAME "tsfile") + set(CPACK_PACKAGE_VENDOR "Apache Software Foundation") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache TsFile C++ library") + set(CPACK_PACKAGE_DESCRIPTION + "Columnar storage library and command-line tools for time series data") + set(CPACK_PACKAGE_HOMEPAGE_URL "https://tsfile.apache.org/") + set(CPACK_PACKAGE_CONTACT "dev@tsfile.apache.org") + set(CPACK_RESOURCE_FILE_LICENSE "${TSFILE_LICENSE_FILE}") + set(CPACK_PACKAGE_VERSION "${TSFILE_PACKAGE_VERSION}") + string(REPLACE "." ";" _TSFILE_PACKAGE_VERSION_PARTS + "${TSFILE_PACKAGE_VERSION}") + list(GET _TSFILE_PACKAGE_VERSION_PARTS 0 CPACK_PACKAGE_VERSION_MAJOR) + list(GET _TSFILE_PACKAGE_VERSION_PARTS 1 CPACK_PACKAGE_VERSION_MINOR) + list(GET _TSFILE_PACKAGE_VERSION_PARTS 2 CPACK_PACKAGE_VERSION_PATCH) + + set(CPACK_COMPONENTS_ALL runtime development tools) + set(CPACK_COMPONENT_DEVELOPMENT_DEPENDS runtime) + set(CPACK_COMPONENT_TOOLS_DEPENDS runtime) + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "tsfile") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "tsfile-dev") + set(CPACK_DEBIAN_TOOLS_PACKAGE_NAME "tsfile-tools") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS + "tsfile (= ${TSFILE_PACKAGE_VERSION})") + set(CPACK_DEBIAN_TOOLS_PACKAGE_DEPENDS + "tsfile (= ${TSFILE_PACKAGE_VERSION})") + + set(CPACK_RPM_COMPONENT_INSTALL ON) + set(CPACK_RPM_PACKAGE_LICENSE "Apache-2.0") + set(CPACK_RPM_PACKAGE_RELEASE "1") + set(CPACK_RPM_PACKAGE_AUTOREQPROV ON) + set(CPACK_RPM_RUNTIME_PACKAGE_NAME "tsfile") + set(CPACK_RPM_DEVELOPMENT_PACKAGE_NAME "tsfile-devel") + set(CPACK_RPM_TOOLS_PACKAGE_NAME "tsfile-tools") + set(CPACK_RPM_DEVELOPMENT_PACKAGE_REQUIRES + "tsfile = ${TSFILE_PACKAGE_VERSION}-1") + set(CPACK_RPM_TOOLS_PACKAGE_REQUIRES + "tsfile = ${TSFILE_PACKAGE_VERSION}-1") + + include(CPack) + unset(_TSFILE_PACKAGE_VERSION_PARTS) +endif () diff --git a/cpp/README.md b/cpp/README.md index 6341287e4..d14cf6ad6 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -80,6 +80,13 @@ TsFile C++ now supports: - **macOS**: Clang - **Windows**: MSVC 2017+ and MinGW +### Installation and Packages + +The C++ install layout supports CMake consumers, pkg-config, a relocatable +TGZ archive, native Linux DEB/RPM packages, and Homebrew on macOS. See +[`packaging/README.md`](../packaging/README.md) for build commands and the +platform-specific release rules. + All code must compile without errors on all supported platforms before submission. We welcome any bug reports. You can open an issue with a title starting with [CPP] to describe the bug, like: https://github.com/apache/tsfile/issues/94 @@ -170,7 +177,7 @@ dependencies are resolved: ANTLR4, Snappy, LZ4, lzokay, SIMDe, zlib, Zstandard, and liblzma are currently resolved through this policy. A compatible system ANTLR4 must be version 4.9.3 -or newer and earlier than 5.0.0, and provide an `antlr4_static` or +or newer and earlier than 4.10.0, and provide an `antlr4_static` or `antlr4_shared` target. A compatible system Snappy must be version 1.2.1 or newer in the 1.x release series and provide the `Snappy::snappy` CMake target. A compatible system LZ4 must be version 1.9.4 or newer in the 1.x release diff --git a/cpp/cmake/ANTLR4Dependency.cmake b/cpp/cmake/ANTLR4Dependency.cmake index 3d772c25c..b92483e51 100644 --- a/cpp/cmake/ANTLR4Dependency.cmake +++ b/cpp/cmake/ANTLR4Dependency.cmake @@ -19,7 +19,11 @@ under the License. set(TSFILE_ANTLR4_MIN_VERSION "4.9.3") set(TSFILE_ANTLR4_BUNDLED_VERSION "4.9.3") -set(TSFILE_ANTLR4_NEXT_INCOMPATIBLE_VERSION "5.0.0") +# The generated parser in this repository follows the 4.9 runtime API. ANTLR +# 4.10 introduced breaking C++ runtime changes (and raised its language floor +# to C++17), so newer system runtimes must use the verified bundled fallback +# until the parser is regenerated and reviewed. +set(TSFILE_ANTLR4_NEXT_INCOMPATIBLE_VERSION "4.10.0") set(TSFILE_ANTLR4_SYSTEM_INCLUDE_DIR "") set(_TSFILE_SYSTEM_ANTLR4_FOUND FALSE) diff --git a/cpp/cmake/TsFileConfig.cmake.in b/cpp/cmake/TsFileConfig.cmake.in new file mode 100644 index 000000000..eea711a9e --- /dev/null +++ b/cpp/cmake/TsFileConfig.cmake.in @@ -0,0 +1,29 @@ +#[[ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +]] + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +if (@ENABLE_THREADS@) + find_dependency(Threads) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/TsFileTargets.cmake") + +check_required_components(TsFile) diff --git a/cpp/cmake/TsFilePublicHeaders.cmake b/cpp/cmake/TsFilePublicHeaders.cmake new file mode 100644 index 000000000..a517d3a9c --- /dev/null +++ b/cpp/cmake/TsFilePublicHeaders.cmake @@ -0,0 +1,47 @@ +#[[ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +]] + +# Public entry points are intentionally listed separately from the transitive +# header closure. The current public headers include implementation-level +# declarations, so the closure is installed until those dependencies can be +# hidden behind a stable facade. Adding a new public entry point requires an +# explicit review of this list. +set(TSFILE_PUBLIC_ENTRYPOINT_HEADERS + cwrapper/tsfile_cwrapper.h + cwrapper/tsfile_cwrapper_expression.h + reader/tsfile_reader.h + writer/tsfile_writer.h + writer/tsfile_table_writer.h + writer/tsfile_tree_writer.h) + +# These directories form the reviewed transitive closure of the entry points +# above. This is an installation compatibility closure, not a promise that +# every header is a stable public API. Compression, encoding, parser, and +# utility headers are implementation dependencies today, but are required for +# consumers to parse the installed public declarations. +set(TSFILE_PUBLIC_HEADER_CLOSURE + common + compress + cwrapper + encoding + file + parser + reader + utils + writer) diff --git a/cpp/cmake/libtsfile.pc.in b/cpp/cmake/libtsfile.pc.in new file mode 100644 index 000000000..ff820d0d8 --- /dev/null +++ b/cpp/cmake/libtsfile.pc.in @@ -0,0 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The .pc file is installed below ${prefix}/@CMAKE_INSTALL_LIBDIR@/pkgconfig. +# Deriving the prefix from its own location keeps DESTDIR and relocations +# working without embedding the build-time install prefix. +prefix=${pcfiledir}/../.. +exec_prefix=${prefix} +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: libtsfile +Description: Apache TsFile C++ library +Version: @TSFILE_PACKAGE_VERSION@ +URL: https://tsfile.apache.org/ +Libs: -L${libdir} -ltsfile +Cflags: -I${includedir} -I${includedir}/tsfile@TSFILE_PKGCONFIG_CFLAGS@ diff --git a/cpp/cmake/tests/ANTLR4DependencyTest.cmake b/cpp/cmake/tests/ANTLR4DependencyTest.cmake index 2fc981712..e6f1f5565 100644 --- a/cpp/cmake/tests/ANTLR4DependencyTest.cmake +++ b/cpp/cmake/tests/ANTLR4DependencyTest.cmake @@ -84,7 +84,7 @@ endfunction() _tsfile_write_fake_antlr4("${_TSFILE_COMPATIBLE_ROOT}" 4.9.3 antlr4_static) _tsfile_write_fake_antlr4("${_TSFILE_TOO_OLD_ROOT}" 4.9.2 antlr4_static) -_tsfile_write_fake_antlr4("${_TSFILE_INCOMPATIBLE_ROOT}" 5.0.0 antlr4_shared) +_tsfile_write_fake_antlr4("${_TSFILE_INCOMPATIBLE_ROOT}" 4.10.0 antlr4_shared) file(MAKE_DIRECTORY "${_TSFILE_MISSING_ROOT}") _tsfile_run_antlr4_case(system-compatible SYSTEM SYSTEM TRUE diff --git a/cpp/cmake/tests/projects/ANTLR4Dependency/CMakeLists.txt b/cpp/cmake/tests/projects/ANTLR4Dependency/CMakeLists.txt index 61901e38a..551373afe 100644 --- a/cpp/cmake/tests/projects/ANTLR4Dependency/CMakeLists.txt +++ b/cpp/cmake/tests/projects/ANTLR4Dependency/CMakeLists.txt @@ -18,7 +18,7 @@ under the License. ]] cmake_minimum_required(VERSION 3.11) -project(TsFileANTLR4DependencyTest NONE) +project(TsFileANTLR4DependencyTest LANGUAGES CXX) get_filename_component(_TSFILE_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE) diff --git a/cpp/cmake/tests/projects/InstalledConsumer/CMakeLists.txt b/cpp/cmake/tests/projects/InstalledConsumer/CMakeLists.txt new file mode 100644 index 000000000..bf0f83e34 --- /dev/null +++ b/cpp/cmake/tests/projects/InstalledConsumer/CMakeLists.txt @@ -0,0 +1,42 @@ +#[[ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +]] +cmake_minimum_required(VERSION 3.11) +project(TsFileInstalledConsumer LANGUAGES CXX) + +find_package(TsFile CONFIG REQUIRED) + +get_target_property(_TSFILE_INCLUDE_DIRS TsFile::tsfile + INTERFACE_INCLUDE_DIRECTORIES) +if (NOT _TSFILE_INCLUDE_DIRS MATCHES "/include") + message(FATAL_ERROR "TsFile target does not expose the installed include root") +endif () +if (_TSFILE_INCLUDE_DIRS MATCHES "cpp/src|build/") + message(FATAL_ERROR "TsFile target leaks a source or build include path: ${_TSFILE_INCLUDE_DIRS}") +endif () + +get_target_property(_TSFILE_LINK_LIBRARIES TsFile::tsfile + INTERFACE_LINK_LIBRARIES) +if (_TSFILE_LINK_LIBRARIES MATCHES "(^|;)[^;]*_obj($|;)|cpp/src|build/") + message(FATAL_ERROR + "TsFile target leaks private build link requirements: " + "${_TSFILE_LINK_LIBRARIES}") +endif () + +add_executable(tsfile_installed_consumer main.cc) +target_link_libraries(tsfile_installed_consumer PRIVATE TsFile::tsfile) diff --git a/cpp/cmake/tests/projects/InstalledConsumer/main.cc b/cpp/cmake/tests/projects/InstalledConsumer/main.cc new file mode 100644 index 000000000..8d242f678 --- /dev/null +++ b/cpp/cmake/tests/projects/InstalledConsumer/main.cc @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include +#include +#include +#include + +int main() { return TS_DATATYPE_INT32 == 1 ? 0 : 1; } diff --git a/cpp/cmake/tests/projects/PkgConfigConsumer/CMakeLists.txt b/cpp/cmake/tests/projects/PkgConfigConsumer/CMakeLists.txt new file mode 100644 index 000000000..1aaabc396 --- /dev/null +++ b/cpp/cmake/tests/projects/PkgConfigConsumer/CMakeLists.txt @@ -0,0 +1,32 @@ +#[[ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +]] +cmake_minimum_required(VERSION 3.11) +project(TsFilePkgConfigConsumer LANGUAGES C CXX) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(TsFile REQUIRED IMPORTED_TARGET libtsfile) +if (NOT TsFile_INCLUDEDIR MATCHES "/include$") + message(FATAL_ERROR "pkg-config did not report the installed include root: ${TsFile_INCLUDEDIR}") +endif () + +add_executable(tsfile_pkgconfig_consumer main.c) +target_link_libraries(tsfile_pkgconfig_consumer PRIVATE PkgConfig::TsFile) + +add_executable(tsfile_pkgconfig_cpp_consumer main.cc) +target_link_libraries(tsfile_pkgconfig_cpp_consumer PRIVATE PkgConfig::TsFile) diff --git a/cpp/cmake/tests/projects/PkgConfigConsumer/main.c b/cpp/cmake/tests/projects/PkgConfigConsumer/main.c new file mode 100644 index 000000000..f32e5a550 --- /dev/null +++ b/cpp/cmake/tests/projects/PkgConfigConsumer/main.c @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include + +int main(void) { return TS_DATATYPE_INT32 == 1 ? 0 : 1; } diff --git a/cpp/cmake/tests/projects/PkgConfigConsumer/main.cc b/cpp/cmake/tests/projects/PkgConfigConsumer/main.cc new file mode 100644 index 000000000..be94b8543 --- /dev/null +++ b/cpp/cmake/tests/projects/PkgConfigConsumer/main.cc @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include + +int main() { return 0; } diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 4e34031ed..e6b60d69c 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -78,6 +78,18 @@ add_subdirectory(reader) add_subdirectory(utils) add_subdirectory(writer) +# Object libraries need the directory-level project dependencies on older +# CMake versions, but those dependencies are implementation details of the +# shared library and must not become exported consumer requirements. Keep the +# platform thread target in the directory scope for its public link interface, +# then link codecs explicitly as PRIVATE below. +get_property(_TSFILE_SRC_LINK_LIBRARIES DIRECTORY PROPERTY LINK_LIBRARIES) +if (ENABLE_THREADS) + set_property(DIRECTORY PROPERTY LINK_LIBRARIES Threads::Threads) +else () + set_property(DIRECTORY PROPERTY LINK_LIBRARIES "") +endif () + set(_TSFILE_OBJECT_TARGETS common_obj compress_obj @@ -123,35 +135,115 @@ if (${COV_ENABLED}) else() set(COV_LINK_LIB -lgcov) endif() - if (CMAKE_VERSION VERSION_LESS "3.12") - target_link_libraries(tsfile ${COV_LINK_LIB}) - else() - target_link_libraries(tsfile ${_TSFILE_OBJECT_TARGETS} ${COV_LINK_LIB}) - endif() + target_link_libraries(tsfile PRIVATE ${COV_LINK_LIB}) else() message("Disable code cov...") - if (NOT CMAKE_VERSION VERSION_LESS "3.12") - target_link_libraries(tsfile ${_TSFILE_OBJECT_TARGETS}) - endif() endif() +# Linking object libraries directly makes static-library exports depend on +# private, non-exported object targets. Add their object files as sources +# instead; this works on the CMake 3.11 baseline and keeps the install target +# self-contained for both shared and static builds. +foreach (_TSFILE_OBJECT_TARGET IN LISTS _TSFILE_OBJECT_TARGETS) + target_sources(tsfile PRIVATE + $) +endforeach () + +if (NOT "${_TSFILE_PROJECT_DEPENDENCIES}" STREQUAL "") + target_link_libraries(tsfile PRIVATE ${_TSFILE_PROJECT_DEPENDENCIES}) +endif () + unset(_TSFILE_OBJECT_SOURCES) unset(_TSFILE_OBJECT_TARGET) unset(_TSFILE_OBJECT_TARGETS) add_dependencies(tsfile utils_obj encoding_obj) +set_property(DIRECTORY PROPERTY LINK_LIBRARIES + "${_TSFILE_SRC_LINK_LIBRARIES}") +unset(_TSFILE_SRC_LINK_LIBRARIES) + if (TSFILE_BUILD_SHARED) - set(LIBTSFILE_PROJECT_VERSION ${TsFile_CPP_VERSION}) - set(LIBTSFILE_SO_VERSION ${TsFile_CPP_VERSION}) + # Keep development suffixes out of the install name and SONAME. The ABI + # epoch changes only for incompatible binary interface changes. + set(LIBTSFILE_PROJECT_VERSION ${TSFILE_PACKAGE_VERSION}) + set(LIBTSFILE_SO_VERSION ${TSFILE_ABI_VERSION}) set_target_properties(tsfile PROPERTIES VERSION ${LIBTSFILE_PROJECT_VERSION}) set_target_properties(tsfile PROPERTIES SOVERSION ${LIBTSFILE_SO_VERSION}) endif() +add_library(TsFile::tsfile ALIAS tsfile) + +target_include_directories(tsfile PUBLIC + $ + $ + $ + $) +if (ENABLE_SIMD AND TSFILE_SIMDE_INCLUDE_ROOT) + # Public TsFile headers include SIMDe directly. Copy the resolved header + # tree into the install prefix so consumers do not need the build host's + # system or dependency-cache paths. + target_include_directories(tsfile PUBLIC + $ + $) +endif () +if (ENABLE_ANTLR4 AND TSFILE_ANTLR4_INCLUDE_ROOT) + target_include_directories(tsfile PUBLIC + $ + $) +endif () +if (ENABLE_ANTLR4 AND TSFILE_UTF8CPP_INCLUDE_ROOT) + target_include_directories(tsfile PUBLIC + $ + $) +endif () +target_compile_features(tsfile PUBLIC cxx_std_11) +set(_TSFILE_PUBLIC_FEATURE_DEFINITIONS "") +foreach (_TSFILE_PUBLIC_FEATURE + ENABLE_ANTLR4 + ENABLE_MEM_STAT + ENABLE_SNAPPY + ENABLE_LZ4 + ENABLE_LZOKAY + ENABLE_ZLIB + ENABLE_GZIP + ENABLE_ZSTD + ENABLE_LZMA2 + ENABLE_THREADS + ENABLE_SIMD) + if (${_TSFILE_PUBLIC_FEATURE}) + list(APPEND _TSFILE_PUBLIC_FEATURE_DEFINITIONS + ${_TSFILE_PUBLIC_FEATURE}) + endif () +endforeach () +if (NOT "${_TSFILE_PUBLIC_FEATURE_DEFINITIONS}" STREQUAL "") + target_compile_definitions(tsfile INTERFACE + ${_TSFILE_PUBLIC_FEATURE_DEFINITIONS}) +endif () +unset(_TSFILE_PUBLIC_FEATURE) +unset(_TSFILE_PUBLIC_FEATURE_DEFINITIONS) + +if (TSFILE_BUILD_SHARED) + # A shared library already resolves its private codec and object-library + # dependencies at link time. Do not export those build-only targets as + # consumer link requirements; they are not installed with the package. + set_property(TARGET tsfile PROPERTY INTERFACE_LINK_LIBRARIES "") +endif () + # A shared library is a RUNTIME plus an import ARCHIVE on Windows and a LIBRARY # on Unix. A static library is an ARCHIVE on every platform. Cover all three so # the install step works for either library type. install(TARGETS tsfile - RUNTIME DESTINATION ${LIBRARY_OUTPUT_PATH} - LIBRARY DESTINATION ${LIBRARY_OUTPUT_PATH} - ARCHIVE DESTINATION ${LIBRARY_OUTPUT_PATH}) + EXPORT TsFileTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT runtime + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT development) + +install(EXPORT TsFileTargets + FILE TsFileTargets.cmake + NAMESPACE TsFile:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TsFile + COMPONENT development) diff --git a/cpp/third_party/CMakeLists.txt b/cpp/third_party/CMakeLists.txt index f7a8851b5..203b93c34 100755 --- a/cpp/third_party/CMakeLists.txt +++ b/cpp/third_party/CMakeLists.txt @@ -35,6 +35,12 @@ if (ENABLE_ANTLR4) "${TSFILE_UTF8CPP_SOURCE_DIR}/source") add_library(tsfile_antlr4_bundled STATIC ${_TSFILE_ANTLR4_SOURCES}) + set(TSFILE_ANTLR4_INCLUDE_ROOT + "${TSFILE_ANTLR4_SOURCE_DIR}/runtime/Cpp/runtime/src" + CACHE INTERNAL "Resolved ANTLR4 include root" FORCE) + set(TSFILE_UTF8CPP_INCLUDE_ROOT + "${TSFILE_UTF8CPP_SOURCE_DIR}/source" + CACHE INTERNAL "Resolved utf8cpp include root" FORCE) set_target_properties(tsfile_antlr4_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON CXX_STANDARD 11) @@ -93,6 +99,17 @@ if (ENABLE_ANTLR4) target_link_libraries(tsfile_antlr4 INTERFACE tsfile_antlr4_bundled) else () + set(TSFILE_ANTLR4_INCLUDE_ROOT + "${TSFILE_ANTLR4_SYSTEM_INCLUDE_DIR}" + CACHE INTERNAL "Resolved ANTLR4 include root" FORCE) + if (TARGET utf8cpp) + get_target_property(_TSFILE_UTF8CPP_INCLUDE_ROOT utf8cpp + INTERFACE_INCLUDE_DIRECTORIES) + set(TSFILE_UTF8CPP_INCLUDE_ROOT + "${_TSFILE_UTF8CPP_INCLUDE_ROOT}" + CACHE INTERNAL "Resolved utf8cpp include root" FORCE) + unset(_TSFILE_UTF8CPP_INCLUDE_ROOT) + endif () target_link_libraries(tsfile_antlr4 INTERFACE ${TSFILE_ANTLR4_SYSTEM_TARGET}) if (TSFILE_ANTLR4_SYSTEM_INCLUDE_DIR) @@ -449,9 +466,15 @@ if (ENABLE_SIMD) add_library(tsfile_simde INTERFACE) if (TSFILE_SIMDE_SOURCE STREQUAL "BUNDLED") + set(TSFILE_SIMDE_INCLUDE_ROOT "${TSFILE_SIMDE_SOURCE_DIR}" + CACHE INTERNAL "Resolved SIMDe include root" FORCE) target_include_directories(tsfile_simde INTERFACE "${TSFILE_SIMDE_SOURCE_DIR}") else () + get_target_property(TSFILE_SIMDE_INCLUDE_ROOT simde::simde + INTERFACE_INCLUDE_DIRECTORIES) + set(TSFILE_SIMDE_INCLUDE_ROOT "${TSFILE_SIMDE_INCLUDE_ROOT}" + CACHE INTERNAL "Resolved SIMDe include root" FORCE) target_link_libraries(tsfile_simde INTERFACE simde::simde) endif () add_library(TsFile::SIMDe ALIAS tsfile_simde) diff --git a/cpp/third_party/README.md b/cpp/third_party/README.md index 6b782d8b5..ec860c0a0 100644 --- a/cpp/third_party/README.md +++ b/cpp/third_party/README.md @@ -86,7 +86,7 @@ dependency before compiling and linking TsFile. `Vocabulary.cpp`, `ATN.cpp`, `LL1Analyzer.cpp`, `LL1Analyzer.h`, `LexerATNSimulator.cpp`, `LexerATNSimulator.h`, `IntervalSet.cpp`, `Any.h`, and `CPPUtils.cpp`. utf8cpp is not modified. -- Resolution: `SYSTEM` accepts ANTLR4 4.9.3 or newer and earlier than 5.0.0 +- Resolution: `SYSTEM` accepts ANTLR4 4.9.3 or newer and earlier than 4.10.0 through an `antlr4_static` or `antlr4_shared` target; `BUNDLED` downloads or reuses both verified archives; and `AUTO` prefers a compatible system package before falling back to the verified archives. diff --git a/cpp/tools/CMakeLists.txt b/cpp/tools/CMakeLists.txt index 4448feab2..138e792ee 100644 --- a/cpp/tools/CMakeLists.txt +++ b/cpp/tools/CMakeLists.txt @@ -46,4 +46,19 @@ set_target_properties(tsfile_cli PROPERTIES OUTPUT_NAME tsfile-cli RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) -install(TARGETS tsfile_cli RUNTIME DESTINATION bin) +# Keep the installed CLI self-contained with the sibling lib directory. This +# is relative to the executable location and therefore remains valid when the +# installation prefix is relocated. +if (APPLE) + set_target_properties(tsfile_cli PROPERTIES + INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR}" + BUILD_WITH_INSTALL_RPATH TRUE) +elseif (UNIX) + set_target_properties(tsfile_cli PROPERTIES + INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}" + BUILD_WITH_INSTALL_RPATH TRUE) +endif () + +install(TARGETS tsfile_cli + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT tools) diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 000000000..ff77cf46b --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,92 @@ + + +# TsFile C++ Packages + +The C++ installation contract is shared by all package formats. It installs +the library, the current compatibility header closure, `TsFileConfig.cmake`, +pkg-config metadata, the CLI, and Apache license files below one prefix. + +The header closure mirrors the include relationships used by the current C++ +implementation. It is intentionally broader than the long-term stable public +API; a separate API cleanup will narrow it in a future version. + +## Portable archive + +Build a relocatable source archive on any host with CMake and CPack: + +```bash +cmake -S cpp -B cpp/build/package \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TEST=OFF \ + -DBUILD_TOOLS=ON \ + -DTSFILE_ENABLE_CPACK=ON \ + -DTSFILE_DEPENDENCY_SOURCE=AUTO +cmake --build cpp/build/package --parallel +cmake --install cpp/build/package +cpack --config cpp/build/package/CPackConfig.cmake -G TGZ +``` + +The resulting `tsfile--.tar.gz` contains a standard +prefix layout and can be unpacked at `/usr/local`, a user directory, or a +relocated application prefix. + +## Native Linux packages + +DEB and RPM packages must be built in the target distribution environment so +CPack can run the native dependency scanner (`dpkg-shlibdeps` or +`rpmbuild`). On Debian/Ubuntu use `-G DEB`; on Fedora/RHEL use `-G RPM`: + +```bash +cmake -S cpp -B cpp/build/package \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TEST=OFF \ + -DBUILD_TOOLS=ON \ + -DTSFILE_ENABLE_CPACK=ON \ + -DTSFILE_DEPENDENCY_SOURCE=AUTO +cmake --build cpp/build/package --parallel +cmake --install cpp/build/package +cpack --config cpp/build/package/CPackConfig.cmake -G DEB +# or: cpack --config cpp/build/package/CPackConfig.cmake -G RPM +``` + +`SYSTEM` can be used instead of `AUTO` when the build image provides every +compatible dependency, including ANTLR4 4.9.x. `AUTO` is the reproducible +release default and uses the verified source fallback for unavailable or +incompatible distro versions. + +The repository workflow `Cpp-Packaging` builds and uploads native DEB and RPM +artifacts on packaging-related changes. The DEB job runs on Ubuntu and the RPM +job runs in Fedora, so each package is generated with its native dependency +metadata tool. + +## macOS + +Homebrew is the native macOS distribution path. The formula is +`packaging/homebrew/tsfile.rb`; it builds the same CMake install layout and +tests both a C++ consumer and `tsfile-cli --version` after installation. + +```bash +brew install ./packaging/homebrew/tsfile.rb +``` + +The stable formula URL and checksum must be updated to the ASF source archive +when the first release containing this packaging work is published. diff --git a/packaging/homebrew/tsfile.rb b/packaging/homebrew/tsfile.rb new file mode 100644 index 000000000..3e96f3dca --- /dev/null +++ b/packaging/homebrew/tsfile.rb @@ -0,0 +1,71 @@ +# typed: strict +# frozen_string_literal: true + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Formula for the Apache TsFile C++ library. +class Tsfile < Formula + desc "Columnar storage library for time series data" + homepage "https://tsfile.apache.org/" + # Replace this development snapshot with the ASF source archive and its + # release checksum when the first native TsFile release is published. + url "https://github.com/apache/tsfile/archive/d4c3c94690cf9af819bc26bec7114a0de7900359.tar.gz" + version "2.3.2" + sha256 "369cf43742601fe6107b299647d2c01f705bfc9ff111402d7b5ddb9b50f40f16" + license "Apache-2.0" + head "https://github.com/apache/tsfile.git", branch: "develop" + + depends_on "cmake" => :build + depends_on "lz4" + depends_on "simde" + depends_on "snappy" + depends_on "utf8cpp" + depends_on "zstd" + + uses_from_macos "zlib" + + def install + args = %W[ + -DBUILD_TEST=OFF + -DBUILD_TOOLS=ON + -DENABLE_LZMA2=OFF + -DTSFILE_DEPENDENCY_SOURCE=AUTO + -DTSFILE_ENABLE_NATIVE_ARCH=OFF + -DCMAKE_INSTALL_RPATH=#{rpath} + ] + + system "cmake", "-S", "cpp", "-B", "build", *args, *std_cmake_args + system "cmake", "--build", "build" + system "cmake", "--install", "build" + end + + test do + (testpath / "test.cpp").write <<~CPP + #include + + int main() { + return TS_DATATYPE_INT32 == 1 ? 0 : 1; + } + CPP + + system ENV.cxx, "-std=c++11", "test.cpp", "-I#{include}", "-L#{lib}", + "-Wl,-rpath,#{lib}", "-ltsfile", "-o", "test" + system "./test" + system bin / "tsfile-cli", "--version" + end +end From 067ebd4c40b614dbdbddc73a8080c62fda51295e Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 20 Aug 2026 17:14:33 +0800 Subject: [PATCH 2/3] fix(ci): remove redundant install step before cpack --- .github/workflows/cpp-packaging.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/cpp-packaging.yml b/.github/workflows/cpp-packaging.yml index ef5a457c2..197cd7b18 100644 --- a/.github/workflows/cpp-packaging.yml +++ b/.github/workflows/cpp-packaging.yml @@ -68,7 +68,6 @@ jobs: -DTSFILE_DEPENDENCY_SOURCE=AUTO \ -DTSFILE_ENABLE_NATIVE_ARCH=OFF cmake --build build/deb --parallel - cmake --install build/deb - name: Build and inspect DEB packages run: | @@ -111,7 +110,6 @@ jobs: -DTSFILE_DEPENDENCY_SOURCE=AUTO \ -DTSFILE_ENABLE_NATIVE_ARCH=OFF cmake --build build/rpm --parallel - cmake --install build/rpm - name: Build and inspect RPM packages run: | From 914a23d8f306dfe6fe66098bdc9f1abd26dd957b Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 20 Aug 2026 17:31:10 +0800 Subject: [PATCH 3/3] fix(ci): install uuid headers for bundled ANTLR4 --- .github/workflows/cpp-packaging.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cpp-packaging.yml b/.github/workflows/cpp-packaging.yml index 197cd7b18..54fa92211 100644 --- a/.github/workflows/cpp-packaging.yml +++ b/.github/workflows/cpp-packaging.yml @@ -56,7 +56,7 @@ jobs: - name: Install packaging tools run: | sudo apt-get update - sudo apt-get install -y build-essential cmake ninja-build pkg-config dpkg-dev + sudo apt-get install -y build-essential cmake ninja-build pkg-config dpkg-dev uuid-dev - name: Configure and build run: | @@ -95,7 +95,7 @@ jobs: run: | dnf install -y \ cmake gcc-c++ make ninja-build pkgconf-pkg-config rpm-build \ - git curl tar xz unzip gzip + git curl tar xz unzip gzip libuuid-devel - name: Checkout repository uses: actions/checkout@v7