This is an automated email from the ASF dual-hosted git repository.

ColinLeeo pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git


The following commit(s) were added to refs/heads/develop by this push:
     new 7ca2e79fb Support static libtsfile builds (#894)
7ca2e79fb is described below

commit 7ca2e79fbdd9a36ef9dde5e522b7c23020536aeb
Author: Colin Lee <[email protected]>
AuthorDate: Tue Aug 4 14:50:59 2026 +0800

    Support static libtsfile builds (#894)
---
 cpp/CMakeLists.txt          | 11 ++++++++---
 cpp/README.md               | 24 +++++++++++++++++++++++-
 cpp/build.sh                | 10 ++++++++++
 cpp/pom.xml                 |  2 ++
 cpp/src/CMakeLists.txt      | 37 +++++++++++++++++++++++++------------
 cpp/src/utils/util_define.h |  9 +++++----
 cpp/test/CMakeLists.txt     |  2 +-
 7 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index efdc5ecfb..440c6cbfb 100755
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -31,6 +31,9 @@ if (POLICY CMP0079)
 endif ()
 set(TsFile_CPP_VERSION 2.3.2.dev)
 
+option(TSFILE_BUILD_SHARED "Build libtsfile as a shared library" ON)
+message("cmake using: TSFILE_BUILD_SHARED=${TSFILE_BUILD_SHARED}")
+
 if (MSVC)
     # MSVC does not provide a /std:c++11 flag; C++11 is its implicit baseline.
     # The lowest explicitly settable standard is /std:c++14. Without this flag,
@@ -39,9 +42,11 @@ if (MSVC)
     set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} /W3 /utf-8 /EHsc /bigobj 
/Zc:__cplusplus /std:c++14")
     add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS 
-D_CRT_NONSTDC_NO_WARNINGS
                     -D_SCL_SECURE_NO_WARNINGS 
-D_WINSOCK_DEPRECATED_NO_WARNINGS)
-    # Export all symbols of the tsfile shared library automatically so that
-    # consumers do not need __declspec(dllexport) annotations.
-    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+    if (TSFILE_BUILD_SHARED)
+        # Export all symbols of the tsfile shared library automatically so that
+        # consumers do not need __declspec(dllexport) annotations.
+        set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+    endif ()
 else ()
     set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall")
 endif ()
diff --git a/cpp/README.md b/cpp/README.md
index 639aa38f7..918eff68f 100644
--- a/cpp/README.md
+++ b/cpp/README.md
@@ -132,7 +132,29 @@ mvn clean verify -P with-cpp -Dcpp.toolchain=mingw
 mvn clean verify -P with-cpp -Dcpp.toolchain=msvc
 ```
 
-Then you can find the shared library at `./cpp/target/build/lib`.
+By default, the shared library is written to `./cpp/target/build/lib`.
+
+To build `libtsfile` as a static library instead, disable
+`TSFILE_BUILD_SHARED` through Maven:
+
+```bash
+mvn clean verify -P with-cpp -Dtsfile.build.shared=OFF
+```
+
+The static library is written to the same directory (`libtsfile.a` on
+Linux/macOS and `tsfile.lib` on Windows). When consuming the installed archive
+directly on MSVC rather than linking the CMake `tsfile` target, define
+`TSFILE_STATIC` for the consumer so public headers do not use DLL import
+decorations.
+
+For a direct CMake build, use:
+
+```bash
+cmake -S cpp -B cpp/build/static \
+  -DTSFILE_BUILD_SHARED=OFF \
+  -DBUILD_TEST=OFF
+cmake --build cpp/build/static --target tsfile
+```
 
 Before you submit your code to GitHub, please ensure that the compilation is 
correct.
 
diff --git a/cpp/build.sh b/cpp/build.sh
index f51c4eded..3cc100c13 100644
--- a/cpp/build.sh
+++ b/cpp/build.sh
@@ -20,6 +20,7 @@
 # build_type=MinSizeRel
 build_type=Release
 build_test=0
+build_shared=ON
 build_bench=0
 do_install=0
 use_cpp11=1
@@ -52,6 +53,9 @@ Options:
   -t=<type>, -t <type>   Build type: Debug, Release, RelWithDebInfo, 
MinSizeRel.
   -a=<ON|OFF>            Enable or disable AddressSanitizer.
   -c=<ON|OFF>            Enable or disable code coverage.
+  --build-shared=<ON|OFF>
+                         Build libtsfile as a shared library (default: ON).
+  --build-static         Build libtsfile as a static library.
   --enable-antlr4=<ON|OFF>
   --disable-antlr4
   --enable-snappy=<ON|OFF>
@@ -70,6 +74,7 @@ function print_config()
 {
   echo "build_type=$build_type"
   echo "build_test=$build_test"
+  echo "build_shared=$build_shared"
   echo "do_install=$do_install"
   echo "use_cpp11=$use_cpp11"
   echo "enable_cov=$enable_cov"
@@ -113,6 +118,10 @@ parse_options()
     -c)
       shift
       enable_cov=$(get_key_value "$1");;
+    --build-shared=*)
+      build_shared=$(get_key_value "$1");;
+    --build-static)
+      build_shared=OFF;;
     --enable-antlr4=*)
       enable_antlr4=$(get_key_value "$1");;
     --enable-snappy=*)
@@ -190,6 +199,7 @@ cmake ../../                           \
   -DZLIB=$zlib_project_dir/install     \
   -DLZ4LIB=$lz4lib_project_dir         \
   -DBUILD_TEST=$build_test             \
+  -DTSFILE_BUILD_SHARED=$build_shared  \
   -DCMAKE_BUILD_TYPE=$build_type       \
   -DUSE_CPP11=$use_cpp11               \
   -DENABLE_COV=$enable_cov             \
diff --git a/cpp/pom.xml b/cpp/pom.xml
index c4ea285d4..9b47ce0a7 100644
--- a/cpp/pom.xml
+++ b/cpp/pom.xml
@@ -35,6 +35,7 @@
         <build.type>Release</build.type>
         <enable.asan>OFF</enable.asan>
         <build.test>ON</build.test>
+        <tsfile.build.shared>ON</tsfile.build.shared>
         <enable.snappy>ON</enable.snappy>
         <enable.lz4>ON</enable.lz4>
         <enable.lzokay>ON</enable.lzokay>
@@ -82,6 +83,7 @@
                                 
<option>-DCMAKE_BUILD_TYPE=${build.type}</option>
                                 <option>-DENABLE_ASAN=${enable.asan}</option>
                                 <option>-DBUILD_TEST=${build.test}</option>
+                                
<option>-DTSFILE_BUILD_SHARED=${tsfile.build.shared}</option>
                                 
<option>-DENABLE_ANTLR4=${enable.antlr4}</option>
                                 
<option>-DENABLE_SNAPPY=${enable.snappy}</option>
                                 <option>-DENABLE_LZ4=${enable.lz4}</option>
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index 895c1ddba..41d2cde12 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -101,10 +101,14 @@ endif()
 
 include_directories(${PROJECT_INCLUDE_DIR})
 
-# Mark every translation unit that is compiled into the tsfile library so that
-# TSFILE_API (see utils/util_define.h) resolves to an export-side (empty)
-# decoration here, and to __declspec(dllimport) for external consumers.
-add_definitions(-DTSFILE_BUILDING)
+# Configure TSFILE_API (see utils/util_define.h) for every translation unit
+# compiled into the tsfile library. Shared builds export data symbols, while
+# static builds do not use DLL import/export decorations.
+if (TSFILE_BUILD_SHARED)
+    add_definitions(-DTSFILE_BUILDING)
+else()
+    add_definitions(-DTSFILE_STATIC)
+endif()
 
 if (ENABLE_ANTLR4)
     add_subdirectory(parser)
@@ -150,7 +154,14 @@ target_link_libraries(common_obj ${COMPRESSION_LIBS})
 target_link_libraries(read_obj ${COMPRESSION_LIBS})
 target_link_libraries(write_obj ${COMPRESSION_LIBS})
 
-add_library(tsfile SHARED)
+if (TSFILE_BUILD_SHARED)
+    add_library(tsfile SHARED)
+else()
+    add_library(tsfile STATIC)
+    # Consumers of the CMake target must see TSFILE_API without DLL import
+    # decoration when linking the static library on MSVC.
+    target_compile_definitions(tsfile INTERFACE TSFILE_STATIC)
+endif()
 
 if (${COV_ENABLED})
     message("Enable code cov...")
@@ -177,14 +188,16 @@ endif()
 
 add_dependencies(tsfile utils_obj encoding_obj)
 
-set(LIBTSFILE_PROJECT_VERSION ${TsFile_CPP_VERSION})
-set(LIBTSFILE_SO_VERSION ${TsFile_CPP_VERSION})
-set_target_properties(tsfile PROPERTIES VERSION ${LIBTSFILE_PROJECT_VERSION})
-set_target_properties(tsfile PROPERTIES SOVERSION ${LIBTSFILE_SO_VERSION})
+if (TSFILE_BUILD_SHARED)
+    set(LIBTSFILE_PROJECT_VERSION ${TsFile_CPP_VERSION})
+    set(LIBTSFILE_SO_VERSION ${TsFile_CPP_VERSION})
+    set_target_properties(tsfile PROPERTIES VERSION 
${LIBTSFILE_PROJECT_VERSION})
+    set_target_properties(tsfile PROPERTIES SOVERSION ${LIBTSFILE_SO_VERSION})
+endif()
 
-# On Windows a SHARED library produces a .dll (RUNTIME) plus an import .lib
-# (ARCHIVE); on Unix it produces a .so (LIBRARY). Cover all three so the
-# install step works for every platform.
+# 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}
diff --git a/cpp/src/utils/util_define.h b/cpp/src/utils/util_define.h
index ee96616f1..564581a11 100644
--- a/cpp/src/utils/util_define.h
+++ b/cpp/src/utils/util_define.h
@@ -64,17 +64,18 @@ typedef int mode_t;
 #endif
 #endif  // _WIN32
 
-/* ======== shared-library symbol visibility ========
+/* ======== library symbol visibility ========
  *
  * Functions are exported from tsfile.dll automatically via
  * CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS, but global DATA symbols (plain variables,
  * static class members) are not reliably auto-exported, and a consumer must
  * see __declspec(dllimport) to reference them across the DLL boundary. Mark
  * such symbols with TSFILE_API: it expands to dllexport while building the
- * library (TSFILE_BUILDING is defined for its own translation units),
- * dllimport for external consumers, and nothing on non-MSVC toolchains.
+ * shared library (TSFILE_BUILDING is defined for its own translation units),
+ * dllimport for shared-library consumers, and nothing for static builds or
+ * non-MSVC toolchains.
  */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(TSFILE_STATIC)
 #if defined(TSFILE_BUILDING)
 #define TSFILE_API __declspec(dllexport)
 #else
diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt
index 066e5accb..7fc9041b1 100644
--- a/cpp/test/CMakeLists.txt
+++ b/cpp/test/CMakeLists.txt
@@ -258,7 +258,7 @@ set_target_properties(TsFile_Test PROPERTIES 
RUNTIME_OUTPUT_DIRECTORY ${LIB_TSFI
 # On Windows, copy tsfile DLL next to the test exe so it can load at runtime
 # (and when gtest_discover_tests runs the exe). Use TARGET_FILE so the path
 # is correct for the current build config (e.g. Release).
-if (WIN32)
+if (WIN32 AND TSFILE_BUILD_SHARED)
     add_custom_command(TARGET TsFile_Test POST_BUILD
             COMMAND ${CMAKE_COMMAND} -E copy_if_different
             $<TARGET_FILE:tsfile>

Reply via email to