From b69bb37c8b4b6d11d12b0519a89fe6a2eb0aab32 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Fri, 4 Sep 2026 17:02:59 -0300 Subject: [PATCH] Merge vendored third-party dependencies as object libraries Signed-off-by: Juan Cruz Viotti --- cmake/FindCMarkGFM.cmake | 43 ++---------- cmake/FindLibDeflate.cmake | 43 ++---------- cmake/FindPCRE2.cmake | 101 ++++------------------------- cmake/common/targets/library.cmake | 8 +++ config.cmake.in | 9 --- 5 files changed, 31 insertions(+), 173 deletions(-) diff --git a/cmake/FindCMarkGFM.cmake b/cmake/FindCMarkGFM.cmake index 6d50b32b36..0155c9839d 100644 --- a/cmake/FindCMarkGFM.cmake +++ b/cmake/FindCMarkGFM.cmake @@ -79,7 +79,9 @@ if(NOT CMarkGFM_FOUND) "${CMARK_GFM_EXTENSIONS_DIR}/tagfilter.c" "${CMARK_GFM_EXTENSIONS_DIR}/tasklist.c") - add_library(cmark_gfm + # Merged into the library that uses it, so that no archive, no header and + # no CMake package of our own build of it reaches an installed consumer + add_library(cmark_gfm OBJECT ${CMARK_GFM_CORE_SOURCES} ${CMARK_GFM_EXTENSION_SOURCES}) sourcemeta_add_default_options(PRIVATE cmark_gfm) @@ -101,10 +103,12 @@ if(NOT CMarkGFM_FOUND) target_include_directories(cmark_gfm PUBLIC "$" "$" - "$" - "$") + "$") target_compile_definitions(cmark_gfm PRIVATE HAVE_CONFIG_H) + # Marking every entry point as visible would publish this library from the + # one it is merged into, where it can collide with a real installation of it + target_compile_definitions(cmark_gfm PUBLIC CMARK_GFM_STATIC_DEFINE) include(GenerateExportHeader) generate_export_header(cmark_gfm @@ -113,38 +117,5 @@ if(NOT CMarkGFM_FOUND) add_library(CMarkGFM::cmark_gfm ALIAS cmark_gfm) - set_target_properties(cmark_gfm - PROPERTIES - OUTPUT_NAME cmark_gfm - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - EXPORT_NAME cmark_gfm - WINDOWS_EXPORT_ALL_SYMBOLS OFF) - - if(SOURCEMETA_CORE_INSTALL) - include(GNUInstallDirs) - install(TARGETS cmark_gfm - EXPORT cmark_gfm - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - COMPONENT sourcemeta_core - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core - NAMELINK_COMPONENT sourcemeta_core_dev - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core_dev) - install(EXPORT cmark_gfm - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cmark_gfm" - NAMESPACE CMarkGFM:: - COMPONENT sourcemeta_core_dev) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmark_gfm-config.cmake - "include(\"\${CMAKE_CURRENT_LIST_DIR}/cmark_gfm.cmake\")\n" - "check_required_components(\"cmark_gfm\")\n") - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/cmark_gfm-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cmark_gfm" - COMPONENT sourcemeta_core_dev) - endif() - set(CMarkGFM_FOUND ON) endif() diff --git a/cmake/FindLibDeflate.cmake b/cmake/FindLibDeflate.cmake index 1b830bbbb8..c6ae748ff0 100644 --- a/cmake/FindLibDeflate.cmake +++ b/cmake/FindLibDeflate.cmake @@ -1,7 +1,6 @@ if(NOT LibDeflate_FOUND) set(LIBDEFLATE_DIR "${PROJECT_SOURCE_DIR}/vendor/libdeflate") set(LIBDEFLATE_LIB_DIR "${LIBDEFLATE_DIR}/lib") - set(LIBDEFLATE_PUBLIC_HEADER "${LIBDEFLATE_DIR}/libdeflate.h") set(LIBDEFLATE_SOURCES "${LIBDEFLATE_LIB_DIR}/utils.c" @@ -23,7 +22,9 @@ if(NOT LibDeflate_FOUND) "${LIBDEFLATE_LIB_DIR}/x86/cpu_features.c") endif() - add_library(libdeflate STATIC ${LIBDEFLATE_SOURCES}) + # Merged into the library that uses it, so that no archive, no header and + # no CMake package of our own build of it reaches an installed consumer + add_library(libdeflate OBJECT ${LIBDEFLATE_SOURCES}) sourcemeta_add_default_options(PRIVATE libdeflate) # Check if the assembler supports ARM dot-product (udot) instructions. @@ -99,8 +100,7 @@ if(NOT LibDeflate_FOUND) endif() target_include_directories(libdeflate PUBLIC - "$" - "$") + "$") target_include_directories(libdeflate PRIVATE "${LIBDEFLATE_LIB_DIR}") @@ -127,42 +127,7 @@ if(NOT LibDeflate_FOUND) target_compile_options(libdeflate PRIVATE /wd4267) endif() - set_target_properties(libdeflate - PROPERTIES - OUTPUT_NAME deflate - PUBLIC_HEADER "${LIBDEFLATE_PUBLIC_HEADER}" - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - EXPORT_NAME LibDeflate) - add_library(LibDeflate::LibDeflate ALIAS libdeflate) - if(SOURCEMETA_CORE_INSTALL) - include(GNUInstallDirs) - install(TARGETS libdeflate - EXPORT libdeflate - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT sourcemeta_core_dev - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - COMPONENT sourcemeta_core - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core - NAMELINK_COMPONENT sourcemeta_core_dev - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core_dev) - install(EXPORT libdeflate - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdeflate" - NAMESPACE LibDeflate:: - COMPONENT sourcemeta_core_dev) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/libdeflate-config.cmake - "include(\"\${CMAKE_CURRENT_LIST_DIR}/libdeflate.cmake\")\n" - "check_required_components(\"libdeflate\")\n") - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/libdeflate-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdeflate" - COMPONENT sourcemeta_core_dev) - endif() - set(LibDeflate_FOUND ON) endif() diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake index ad73b552da..1a834de0a5 100644 --- a/cmake/FindPCRE2.cmake +++ b/cmake/FindPCRE2.cmake @@ -32,11 +32,9 @@ if(NOT PCRE2_FOUND) set(PCRE2GREP_MAX_BUFSIZE 1048576) set(NEWLINE_DEFAULT 2) - if(WIN32 AND BUILD_SHARED_LIBS) - set(PCRE2_EXPORT "__declspec(dllexport)") - else() - set(PCRE2_EXPORT) - endif() + # This library is compiled into the one that uses it rather than shipped + # on its own, so its symbols must never leave the resulting binary + set(PCRE2_EXPORT) set(SUPPORT_PCRE2_8 1) set(SUPPORT_UNICODE 1) @@ -57,8 +55,6 @@ if(NOT PCRE2_FOUND) "${PCRE2_BINARY_DIR}/src/pcre2_chartables.c" COPYONLY) - set(PCRE2_PUBLIC_HEADER "${PCRE2_BINARY_DIR}/interface/pcre2.h") - set(PCRE2_SOURCES "${PCRE2_SOURCE_DIR}/pcre2_auto_possess.c" "${PCRE2_BINARY_DIR}/src/pcre2_chartables.c" @@ -92,43 +88,9 @@ if(NOT PCRE2_FOUND) "${PCRE2_SOURCE_DIR}/pcre2_valid_utf.c" "${PCRE2_SOURCE_DIR}/pcre2_xclass.c") - set(SLJIT_DIR "${PCRE2_DIR}/deps/sljit/sljit_src") - set(SLJIT_SOURCES "${SLJIT_DIR}/sljitLir.c") - - add_library(sljit STATIC ${SLJIT_SOURCES}) - sourcemeta_add_default_options(PRIVATE sljit) - - if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC) - target_compile_options(sljit PRIVATE -Wno-double-promotion) - target_compile_options(sljit PRIVATE -Wno-conditional-uninitialized) - target_compile_options(sljit PRIVATE -fstrict-flex-arrays=0) - endif() - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(sljit PRIVATE /sdl-) - target_compile_options(sljit PRIVATE /wd4701) - target_compile_options(sljit PRIVATE /wd4702) - target_compile_options(sljit PRIVATE /wd4127) - endif() - - target_include_directories(sljit PUBLIC - "$" - "$") - - target_compile_definitions(sljit PRIVATE SLJIT_CONFIG_AUTO=1) - - if(SOURCEMETA_OS_LINUX) - target_compile_definitions(sljit PRIVATE _GNU_SOURCE) - endif() - - set_target_properties(sljit - PROPERTIES - OUTPUT_NAME sljit - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - EXPORT_NAME sljit) - - add_library(pcre2 ${PCRE2_SOURCES}) + # Merged into the library that uses it, so that no archive, no header and + # no CMake package of our own build of it reaches an installed consumer + add_library(pcre2 OBJECT ${PCRE2_SOURCES}) sourcemeta_add_default_options(PRIVATE pcre2) if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC) @@ -158,63 +120,24 @@ if(NOT PCRE2_FOUND) "${PCRE2_SOURCE_DIR}") target_include_directories(pcre2 PUBLIC - "$" - "$") + "$") target_compile_definitions(pcre2 PRIVATE HAVE_CONFIG_H) target_compile_definitions(pcre2 PUBLIC PCRE2_CODE_UNIT_WIDTH=8) target_compile_definitions(pcre2 PRIVATE SUPPORT_PCRE2_8=1) target_compile_definitions(pcre2 PRIVATE SUPPORT_UNICODE=1) + # The just-in-time compiler brings its own code generator in as part of one + # of its translation units, so there is no second library to build for it target_compile_definitions(pcre2 PRIVATE SUPPORT_JIT=1) - - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(pcre2 PUBLIC PCRE2_STATIC=1) - endif() + # Declarations of an import from a shared library of our own build of this + # one, which no longer exists, would be unresolvable on Windows + target_compile_definitions(pcre2 PUBLIC PCRE2_STATIC=1) if(SOURCEMETA_OS_LINUX) target_compile_definitions(pcre2 PRIVATE _GNU_SOURCE) endif() - target_link_libraries(pcre2 PRIVATE sljit) - add_library(PCRE2::pcre2 ALIAS pcre2) - set_target_properties(pcre2 - PROPERTIES - OUTPUT_NAME pcre2 - PUBLIC_HEADER "${PCRE2_PUBLIC_HEADER}" - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - EXPORT_NAME pcre2 - WINDOWS_EXPORT_ALL_SYMBOLS OFF) - - if(SOURCEMETA_CORE_INSTALL) - include(GNUInstallDirs) - install(TARGETS sljit pcre2 - EXPORT pcre2 - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT sourcemeta_core_dev - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - COMPONENT sourcemeta_core - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core - NAMELINK_COMPONENT sourcemeta_core_dev - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core_dev) - sourcemeta_library_export_flatten(pcre2) - install(EXPORT pcre2 - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/pcre2" - NAMESPACE PCRE2:: - COMPONENT sourcemeta_core_dev) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pcre2-config.cmake - "include(\"\${CMAKE_CURRENT_LIST_DIR}/pcre2.cmake\")\n" - "check_required_components(\"pcre2\")\n") - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/pcre2-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/pcre2" - COMPONENT sourcemeta_core_dev) - endif() - set(PCRE2_FOUND ON) endif() diff --git a/cmake/common/targets/library.cmake b/cmake/common/targets/library.cmake index 94a8171772..a9fa7c38ed 100644 --- a/cmake/common/targets/library.cmake +++ b/cmake/common/targets/library.cmake @@ -146,8 +146,16 @@ function(sourcemeta_library_export_flatten TARGET_NAME) set(SOURCEMETA_LIBRARY_FLATTENED) foreach(entry IN LISTS SOURCEMETA_LIBRARY_INTERFACE) string(REGEX REPLACE "^\\$$" "\\1" unwrapped "${entry}") + set(dependency_type) + if(TARGET "${unwrapped}") + get_target_property(dependency_type "${unwrapped}" TYPE) + endif() if(unwrapped STREQUAL entry) list(APPEND SOURCEMETA_LIBRARY_FLATTENED "${entry}") + elseif(dependency_type STREQUAL "OBJECT_LIBRARY") + # The objects of such a dependency are already part of this library, + # so there is nothing left for an installed consumer to link against + list(APPEND SOURCEMETA_LIBRARY_FLATTENED "$") else() list(APPEND SOURCEMETA_LIBRARY_FLATTENED "$" diff --git a/config.cmake.in b/config.cmake.in index 335d496763..0605d95d97 100644 --- a/config.cmake.in +++ b/config.cmake.in @@ -89,7 +89,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_crypto.cmake") elseif(component STREQUAL "regex") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_regex.cmake") @@ -125,7 +124,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake") elseif(component STREQUAL "uritemplate") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake") @@ -142,7 +140,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) if(@SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL@) find_dependency(OpenSSL 3.0) endif() - find_dependency(LibDeflate CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") @@ -153,7 +150,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonl.cmake") elseif(component STREQUAL "jsonpointer") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") @@ -165,7 +161,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake") elseif(component STREQUAL "jsonpath") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") @@ -178,7 +173,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpath.cmake") elseif(component STREQUAL "jsonld") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") @@ -192,7 +186,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_langtag.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonld.cmake") elseif(component STREQUAL "yaml") - find_dependency(PCRE2 CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") @@ -312,7 +305,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) if(@SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL@) find_dependency(OpenSSL 3.0) endif() - find_dependency(LibDeflate CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") @@ -327,7 +319,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_css.cmake") elseif(component STREQUAL "markdown") - find_dependency(cmark_gfm CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_markdown.cmake") elseif(component STREQUAL "diff") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_text.cmake")