From b1fee77f66c59332d277b9ddb41ca06fe0880af4 Mon Sep 17 00:00:00 2001 From: "Paul J. Davis" Date: Thu, 10 Oct 2024 15:14:25 -0500 Subject: [PATCH] Add CMake option to bundle all static dependencies This PR adds a new bootstrap/cmake option for *nix operating systems that allows for creating a single unified static library that contains libtiledb and all the vcpkg installed dependencies. --- bootstrap | 4 ++++ scripts/bundle-libs.py | 37 +++++++++++++++++++++++++++++++++++++ tiledb/CMakeLists.txt | 25 +++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100755 scripts/bundle-libs.py diff --git a/bootstrap b/bootstrap index 5ae7321b8c7..1a1ca0dc93f 100755 --- a/bootstrap +++ b/bootstrap @@ -39,6 +39,7 @@ Configuration: ['"${default_dependency}"'] --linkage specify the linkage of tiledb. Defaults to shared. [static|shared] + --enable-static-bundle when building with static linkage, create a libtiledb_bundled.a --remove-deprecations build TileDB without any deprecated APIs --disable-werror disables use of -Werror during build --disable-cpp-api disables building of the TileDB C++ API @@ -109,6 +110,7 @@ tiledb_arrow_tests="OFF" tiledb_experimental_features="OFF" tiledb_build_webp="ON" tiledb_tests_aws_s3_config="OFF" +tiledb_static_bundle="OFF" enable_multiple="" while test $# != 0; do case "$1" in @@ -119,6 +121,7 @@ while test $# != 0; do --dependency=*) dir=`arg "$1"` dependency_dir="$dir";; --linkage=*) linkage=`arg "$1"`;; + --enable-static-bundle) tiledb_static_bundle="ON";; --force-build-all-deps) echo "Argument '--force-build-all-deps' has no effect and will be removed in a future version. Vcpkg builds all dependencies by default, please consult the guide in doc/dev/BUILD.md or vcpkg's documentation to see how to provide your own dependencies.";; --remove-deprecations) tiledb_remove_deprecations="ON";; --disable-werror) tiledb_werror="OFF";; @@ -247,6 +250,7 @@ ${cmake} -DCMAKE_BUILD_TYPE=${build_type} \ -DTILEDB_SANITIZER="${sanitizer}" \ -DTILEDB_EXPERIMENTAL_FEATURES=${tiledb_experimental_features} \ -DTILEDB_TESTS_AWS_S3_CONFIG=${tiledb_tests_aws_s3_config} \ + -DTILEDB_STATIC_BUNDLE=${tiledb_static_bundle} \ ${tiledb_disable_avx2} \ ${vcpkg_base_triplet} \ "${source_dir}" || die "failed to configure the project" diff --git a/scripts/bundle-libs.py b/scripts/bundle-libs.py new file mode 100755 index 00000000000..7ea8db6f61a --- /dev/null +++ b/scripts/bundle-libs.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import shlex +import os.path +import subprocess as sp + +VCPKG_DIR = "vcpkg_installed" + +def vcpkg_deps(): + if not os.path.isdir(VCPKG_DIR): + print("Unable to find `{VCPKG_DIR}` directory") + exit(2) + for entry in os.listdir(VCPKG_DIR): + libdir = os.path.join(VCPKG_DIR, entry, "lib") + print(libdir) + if not os.path.isdir(libdir): + continue + for entry in os.listdir(libdir): + if os.path.splitext(entry)[1] != ".a": + continue + yield os.path.join(libdir, entry) + + +def main(): + libs = ["tiledb/libtiledb.a"] + libs.extend(vcpkg_deps()) + for lib in libs: + if not os.path.isfile(lib): + print("Path failed: {}", lib) + exit(2) + + cmd = "armerge --output libtiledb_bundled.a " + " ".join(libs) + sp.check_call(cmd, shell=True) + + +if __name__ == "__main__": + main() diff --git a/tiledb/CMakeLists.txt b/tiledb/CMakeLists.txt index d018eccfdfc..ff8b73326b4 100644 --- a/tiledb/CMakeLists.txt +++ b/tiledb/CMakeLists.txt @@ -940,3 +940,28 @@ add_custom_target(install-tiledb COMMAND ${CMAKE_COMMAND} --build . --target install --config $ WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) + +# Create a static library that includes libtiledb and all of its dependencies +message(STATUS "CHECKING FOR STATIC BUNDLE") +if (NOT BUILD_SHARED_LIBS AND TILEDB_STATIC_BUNDLE) + # We check for the availability of armerge here rather than in the + # bundle-libs.py script. + find_program(ARMERGE armerge) + if (NOT ARMERGE) + message(FATAL_ERROR "Failed to find 'armerge' for building static bundle.") + endif() + + add_custom_target(static_bundle + ALL + COMMENT "Bundle tiledb and all static library dependencies into a single archive." + COMMAND "${CMAKE_SOURCE_DIR}/scripts/bundle-libs.py" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS tiledb + BYPRODUCTS libtiledb_bundled.a + ) + + install( + FILES ${PROJECT_BINARY_DIR}/libtiledb_bundled.a + DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif()