You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tsfile.apache.org by co...@apache.org on 2026/09/17 07:36:34 UTC
(tsfile) 19/22: fix(cmake): preserve static SDK ANTLR compatibility bounds
This is an automated email from the ASF dual-hosted git repository.
ColinLeeo pushed a commit to branch feat/native-package-artifacts
in repository https://gitbox.apache.org/repos/asf/tsfile.git
commit 4b9b613a90c817771ffc0c1f05fa4f4ed0ba9fbd
Author: ColinLee <sh...@163.com>
AuthorDate: Thu Sep 10 22:35:05 2026 +0800
fix(cmake): preserve static SDK ANTLR compatibility bounds
---
cpp/cmake/TsFileStaticDependencies.cmake | 26 ++++-
packaging/tests/test_native_install.py | 163 +++++++++++++++++++++++++++++++
2 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/cpp/cmake/TsFileStaticDependencies.cmake b/cpp/cmake/TsFileStaticDependencies.cmake
index a4942ca77..8233487f3 100644
--- a/cpp/cmake/TsFileStaticDependencies.cmake
+++ b/cpp/cmake/TsFileStaticDependencies.cmake
@@ -50,9 +50,33 @@ function(tsfile_install_static_dependency NAME SOURCE SYSTEM_TARGET FIND_CODE)
endfunction()
set(TSFILE_STATIC_DEPENDENCY_CODE "")
+# Keep the build-side compatibility interval when a static consumer rediscovers
+# ANTLR4. Explicit comparisons also support CMake 3.11 and packages that report
+# ANTLR_VERSION instead of antlr4-runtime_VERSION.
+string(CONFIGURE [=[
+find_package(utf8cpp CONFIG QUIET)
+find_package(antlr4-runtime CONFIG QUIET)
+set(_TSFILE_ANTLR4_VERSION "${antlr4-runtime_VERSION}")
+if ("${_TSFILE_ANTLR4_VERSION}" STREQUAL "" AND DEFINED ANTLR_VERSION)
+ set(_TSFILE_ANTLR4_VERSION "${ANTLR_VERSION}")
+endif ()
+if (NOT antlr4-runtime_FOUND OR
+ "${_TSFILE_ANTLR4_VERSION}" STREQUAL "" OR
+ _TSFILE_ANTLR4_VERSION VERSION_LESS "@TSFILE_ANTLR4_MIN_VERSION@" OR
+ NOT _TSFILE_ANTLR4_VERSION VERSION_LESS "@TSFILE_ANTLR4_NEXT_INCOMPATIBLE_VERSION@" OR
+ NOT TARGET @TSFILE_ANTLR4_SYSTEM_TARGET@)
+ set(TsFile_FOUND FALSE)
+ set(TsFile_NOT_FOUND_MESSAGE
+ "Static TsFile requires a compatible system ANTLR4 >=@TSFILE_ANTLR4_MIN_VERSION@ and <@TSFILE_ANTLR4_NEXT_INCOMPATIBLE_VERSION@ with target @TSFILE_ANTLR4_SYSTEM_TARGET@; reported version '${_TSFILE_ANTLR4_VERSION}'.")
+ unset(_TSFILE_ANTLR4_VERSION)
+ return()
+endif ()
+unset(_TSFILE_ANTLR4_VERSION)
+]=] _TSFILE_FIND_STATIC_ANTLR4 @ONLY)
tsfile_install_static_dependency(ANTLR4 "${TSFILE_ANTLR4_SOURCE}"
"${TSFILE_ANTLR4_SYSTEM_TARGET}"
- "find_package(utf8cpp CONFIG QUIET)\nfind_dependency(antlr4-runtime CONFIG)")
+ "${_TSFILE_FIND_STATIC_ANTLR4}")
+unset(_TSFILE_FIND_STATIC_ANTLR4)
if (ENABLE_ANTLR4 AND TSFILE_ANTLR4_SOURCE STREQUAL "BUNDLED")
if (WIN32)
string(APPEND TSFILE_STATIC_DEPENDENCY_CODE
diff --git a/packaging/tests/test_native_install.py b/packaging/tests/test_native_install.py
index ea0574834..76128fcf9 100644
--- a/packaging/tests/test_native_install.py
+++ b/packaging/tests/test_native_install.py
@@ -20,6 +20,7 @@
import os
import re
import shlex
+import shutil
import subprocess
import tempfile
import textwrap
@@ -30,6 +31,168 @@ ROOT = Path(__file__).resolve().parents[2]
FIXTURES = ROOT / "cpp/cmake/tests/projects"
+class StaticANTLRPackageTest(unittest.TestCase):
+ """Exercise installed metadata without compiling the ANTLR runtime."""
+
+ def test_installed_system_antlr_requires_compatible_runtime(self):
+ with tempfile.TemporaryDirectory(prefix="tsfile-antlr-config-") as temporary:
+ directory = Path(temporary)
+ producer = directory / "producer"
+ (producer / "cmake").mkdir(parents=True)
+ shutil.copyfile(
+ ROOT / "cpp/cmake/TsFileStaticDependencies.cmake.in",
+ producer / "cmake/TsFileStaticDependencies.cmake.in",
+ )
+ (producer / "CMakeLists.txt").write_text(textwrap.dedent("""\
+ cmake_minimum_required(VERSION 3.11)
+ project(StaticANTLRPackage NONE)
+ include(CMakePackageConfigHelpers)
+ include("${TSFILE_CMAKE_DIR}/DependencySource.cmake")
+ include("${TSFILE_CMAKE_DIR}/ANTLR4Dependency.cmake")
+ set(CMAKE_INSTALL_LIBDIR lib)
+ set(ENABLE_ANTLR4 ON)
+ set(ENABLE_THREADS OFF)
+ set(TSFILE_BUILD_SHARED OFF)
+ add_library(tsfile INTERFACE)
+ add_library(TsFile::ANTLR4 INTERFACE IMPORTED)
+ include("${TSFILE_CMAKE_DIR}/TsFileStaticDependencies.cmake")
+ configure_package_config_file(
+ "${TSFILE_CMAKE_DIR}/TsFileConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfig.cmake"
+ INSTALL_DESTINATION lib/cmake/TsFile)
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TsFileConfig.cmake"
+ DESTINATION lib/cmake/TsFile)
+ install(TARGETS tsfile EXPORT TsFileTargets)
+ install(EXPORT TsFileTargets NAMESPACE TsFile::
+ DESTINATION lib/cmake/TsFile)
+ """))
+ consumer = directory / "consumer"
+ consumer.mkdir()
+ (consumer / "CMakeLists.txt").write_text(textwrap.dedent("""\
+ cmake_minimum_required(VERSION 3.11)
+ project(StaticANTLRConsumer NONE)
+ find_package(TsFile CONFIG REQUIRED)
+ get_target_property(runtime TsFile::Static_ANTLR4
+ INTERFACE_LINK_LIBRARIES)
+ if (NOT runtime STREQUAL EXPECTED_TARGET OR NOT TARGET ${runtime})
+ message(FATAL_ERROR "Static TsFile lost its system target")
+ endif ()
+ if (NOT TARGET utf8cpp)
+ message(FATAL_ERROR "Static TsFile lost utf8cpp compatibility")
+ endif ()
+ """))
+
+ def configure(source, build, *options):
+ return subprocess.run(
+ [
+ "cmake",
+ "-S",
+ str(source),
+ "-B",
+ str(build),
+ "-DCMAKE_FIND_USE_PACKAGE_REGISTRY=FALSE",
+ "-DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=FALSE",
+ "-DCMAKE_FIND_USE_CMAKE_SYSTEM_PATH=FALSE",
+ "-DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=FALSE",
+ f"-DCMAKE_MAKE_PROGRAM={shutil.which('make')}",
+ "-G",
+ "Unix Makefiles",
+ *options,
+ ],
+ text=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
+
+ def package(prefix, version, target, version_field):
+ prefix.mkdir(parents=True)
+ (prefix / "utf8cppConfig.cmake").write_text(
+ "add_library(utf8cpp INTERFACE IMPORTED)\n"
+ )
+ if version == "missing-package":
+ return
+ content = ""
+ if version is not None:
+ content += f'set({version_field} "{version}")\n'
+ if target is not None:
+ content += (
+ f"add_library({target} INTERFACE IMPORTED)\n"
+ f"set_property(TARGET {target} PROPERTY "
+ "INTERFACE_LINK_LIBRARIES utf8cpp)\n"
+ )
+ (prefix / "antlr4-runtime-config.cmake").write_text(content)
+
+ targets = (
+ "antlr4_static",
+ "antlr4-runtime::antlr4_static",
+ "antlr4_shared",
+ "antlr4-runtime::antlr4_shared",
+ )
+ for index, target in enumerate(targets):
+ build = directory / f"producer-build-{index}"
+ stage = directory / f"stage-{index}"
+ build_package = directory / f"build-package-{index}"
+ package(build_package, "4.9.3", target, "ANTLR_VERSION")
+ result = configure(
+ producer,
+ build,
+ f"-DTSFILE_CMAKE_DIR={ROOT / 'cpp/cmake'}",
+ "-DTSFILE_DEPENDENCY_SOURCE=SYSTEM",
+ f"-DCMAKE_PREFIX_PATH={build_package}",
+ f"-DCMAKE_INSTALL_PREFIX={stage}",
+ )
+ self.assertEqual(result.returncode, 0, result.stdout)
+ result = subprocess.run(
+ ["cmake", "--install", str(build)],
+ text=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
+ self.assertEqual(result.returncode, 0, result.stdout)
+ relocated = directory / f"relocated-{index}"
+ stage.rename(relocated)
+ cases = (
+ ("4.9.3", target, True),
+ ("4.12.0", target, True),
+ ("4.13.0", target, False),
+ ("4.13.2", target, False),
+ ("4.9.2", target, False),
+ (None, target, False),
+ ("4.9.3", None, False),
+ ("missing-package", None, False),
+ )
+ for field in ("antlr4-runtime_VERSION", "ANTLR_VERSION"):
+ for case, (version, consumer_target, succeeds) in enumerate(cases):
+ with self.subTest(
+ target=target,
+ field=field,
+ version=version,
+ consumer_target=consumer_target,
+ ):
+ suffix = f"{index}-{field}-{case}"
+ runtime = directory / f"runtime-{suffix}"
+ package(runtime, version, consumer_target, field)
+ result = configure(
+ consumer,
+ directory / f"consumer-{suffix}",
+ f"-DCMAKE_PREFIX_PATH={relocated};{runtime}",
+ f"-DEXPECTED_TARGET={target}",
+ )
+ if succeeds:
+ self.assertEqual(result.returncode, 0, result.stdout)
+ else:
+ self.assertNotEqual(
+ result.returncode,
+ 0,
+ f"Installed static TsFile accepted {version}:\n"
+ + result.stdout,
+ )
+ diagnostic = " ".join(result.stdout.split())
+ self.assertIn("compatible system ANTLR4", diagnostic)
+ self.assertIn(">=4.9.3", diagnostic)
+ self.assertIn("<4.13.0", diagnostic)
+
+
@unittest.skipUnless(
os.environ.get("TSFILE_RUN_INSTALL_TESTS") == "1", "opt-in native builds"
)