Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions cmake/FindMimalloc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,18 @@ if(NOT Mimalloc_FOUND)
add_library(mimalloc ${MIMALLOC_SOURCES})
sourcemeta_add_default_options(PRIVATE mimalloc)

# Link the resolved thread library rather than the imported target, as the
# latter obliges every consumer of the exported package to run FindThreads,
# whose try_compile cannot run inside build systems that read the export by
# tracing CMake instead of calling it. The imported target also carries a
# compile option on the platforms whose threads need one, which we set here
find_package(Threads REQUIRED)
target_link_libraries(mimalloc PRIVATE Threads::Threads)
if(THREADS_HAVE_PTHREAD_ARG)
target_compile_options(mimalloc PRIVATE -pthread)
endif()
if(CMAKE_THREAD_LIBS_INIT)
target_link_libraries(mimalloc PRIVATE "${CMAKE_THREAD_LIBS_INIT}")

@augmentcode augmentcode Bot Sep 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMAKE_THREAD_LIBS_INIT only represents the link item; it drops Threads::Threads' compile usage requirement (notably -pthread when that is how FindThreads succeeds). On platforms using that flag, mimalloc is now compiled without the thread feature macro/compile option even though it uses pthread APIs.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
endif()

target_include_directories(mimalloc PUBLIC
"$<BUILD_INTERFACE:${MIMALLOC_DIR}/include>"
Expand Down Expand Up @@ -145,8 +155,6 @@ if(NOT Mimalloc_FOUND)
COMPONENT sourcemeta_core_dev)

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/mimalloc-config.cmake
"include(CMakeFindDependencyMacro)\n"
"find_dependency(Threads)\n"
"include(\"\${CMAKE_CURRENT_LIST_DIR}/mimalloc.cmake\")\n"
"check_required_components(\"mimalloc\")\n")
install(FILES
Expand Down
1 change: 1 addition & 0 deletions cmake/FindPCRE2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ if(NOT PCRE2_FOUND)
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::
Expand Down
32 changes: 32 additions & 0 deletions cmake/common/targets/library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,32 @@ function(sourcemeta_library)
endif()
endfunction()

# A static library records its private dependencies as $<LINK_ONLY:...> in the
# exported link interface. Build systems that read the export without evaluating
# generator expressions drop those entries and lose the transitive link closure,
# so unwrap them for the installed interface. The build interface keeps the
# wrapper, so that consumers within this project do not start inheriting the
# usage requirements that a private dependency is not meant to hand them
function(sourcemeta_library_export_flatten TARGET_NAME)
get_target_property(SOURCEMETA_LIBRARY_INTERFACE
${TARGET_NAME} INTERFACE_LINK_LIBRARIES)
if(SOURCEMETA_LIBRARY_INTERFACE)
set(SOURCEMETA_LIBRARY_FLATTENED)
foreach(entry IN LISTS SOURCEMETA_LIBRARY_INTERFACE)
string(REGEX REPLACE "^\\$<LINK_ONLY:(.*)>$" "\\1" unwrapped "${entry}")
if(unwrapped STREQUAL entry)
list(APPEND SOURCEMETA_LIBRARY_FLATTENED "${entry}")
else()
list(APPEND SOURCEMETA_LIBRARY_FLATTENED
"$<BUILD_INTERFACE:${entry}>"
"$<INSTALL_INTERFACE:${unwrapped}>")
endif()
endforeach()
set_property(TARGET ${TARGET_NAME}
PROPERTY INTERFACE_LINK_LIBRARIES ${SOURCEMETA_LIBRARY_FLATTENED})
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
endif()
endfunction()

function(sourcemeta_library_install)
cmake_parse_arguments(SOURCEMETA_LIBRARY "" "NAMESPACE;PROJECT;NAME;VARIANT" "" ${ARGN})

Expand Down Expand Up @@ -173,6 +199,12 @@ function(sourcemeta_library_install)
NAMELINK_COMPONENT ${COMPONENT_NAME}_dev
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
COMPONENT ${COMPONENT_NAME}_dev)
# Deferred, as callers link their dependencies after installing the target.
# The target name is expanded into the deferred call, as its arguments are
# not evaluated until the call runs, by which point the variable is gone
cmake_language(EVAL CODE
"cmake_language(DEFER CALL sourcemeta_library_export_flatten ${TARGET_NAME})")

install(EXPORT ${TARGET_NAME}
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${SOURCEMETA_LIBRARY_PROJECT}"
NAMESPACE ${NAMESPACE_PREFIX}
Expand Down
Loading