Skip to content
Open
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
69 changes: 69 additions & 0 deletions mingw-w64-delay-load-support/DelayLoad.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# CMake module to support delay loading of optional DLLs and separating optdepends in MSYS2.
#
# SPDX-FileCopyrightText: 2026 Mikhail Titov <mlt@gmx.us>
# SPDX-License-Identifier: BSD-3-Clause

function(target_delay_load TARGET REGEX)
set(DELAY_LIBS) # reset for each target
if(ARGN)
set(PROP ${ARGN})
else()
set(PROP LINK_LIBRARIES)
endif()
message(STATUS "Processing ${TARGET} for deps in ${PROP} matching ${REGEX}")
get_target_property(CURRENT_LIBS ${TARGET} ${PROP})
if (NOT CURRENT_LIBS)
message(VERBOSE " No ${PROP} libraries found for target ${TARGET}")
return()
endif()
foreach(lib IN LISTS CURRENT_LIBS)
if(TARGET ${lib})
message(VERBOSE " keeping target ${lib} as is for target ${TARGET}")
list(APPEND DELAY_LIBS "${lib}")
get_target_property(real "${lib}" ALIASED_TARGET)
if(real)
set(lib "${real}")
endif()
target_delay_load(${lib} "${REGEX}" INTERFACE_LINK_LIBRARIES) # transient dependencies
target_delay_load(${lib} "${REGEX}" IMPORTED_IMPLIB_RELEASE)
else() # plain libs
get_filename_component(libname "${lib}" NAME_WE) # chop .dll.a
if("${libname}" MATCHES "${REGEX}" AND NOT "${libname}" MATCHES "-delay$")
message(" found ${libname} for target ${TARGET}")
execute_process(
COMMAND dlltool -I "${lib}"
OUTPUT_VARIABLE dllname
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
list(APPEND DELAY_LIBS "${lib}")
list(APPEND DELAY_OPTS "LINKER:/delayload:${dllname}")
else()
set(dllpath "$ENV{MINGW_PREFIX}/bin/${dllname}")
execute_process(
COMMAND gendef - "${dllpath}"
OUTPUT_FILE "${PROJECT_BINARY_DIR}/${libname}.def"
ERROR_QUIET
)
execute_process(
COMMAND dlltool -k -d "${libname}.def" -y "${libname}-delay.a"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
)
list(APPEND DELAY_LIBS "${PROJECT_BINARY_DIR}/${libname}-delay.a")
endif()
message(VERBOSE "Delay load libs: ${DELAY_LIBS}")
else()
message(VERBOSE " keeping ${libname} as is for target ${TARGET}")
list(APPEND DELAY_LIBS "${lib}")
endif()
endif()
endforeach()
message(VERBOSE "Final delay load libs for ${TARGET}: ${DELAY_LIBS}")
if(NOT ARGN) # top level target the function was called for originally
list(APPEND DELAY_LIBS "$ENV{MINGW_PREFIX}/lib/dl_reaper.o;delayimp;ntdll")
list(REMOVE_DUPLICATES DELAY_OPTS)
target_link_options(${TARGET} PRIVATE ${DELAY_OPTS})
endif()
set_property(TARGET ${TARGET} PROPERTY ${PROP} "${DELAY_LIBS}")
return(PROPAGATE DELAY_OPTS)
endfunction()
27 changes: 27 additions & 0 deletions mingw-w64-delay-load-support/PKGBUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Contributor: Mikhail Titov <mlt@gmx.us>

_realname=delay-load-support
pkgbase=mingw-w64-${_realname}
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}")
pkgver=0.1.0
pkgrel=1
pkgdesc="delay load helpers for packaging, not for end users"
arch=('any')
mingw_arch=('mingw64', 'ucrt64' 'clang64' 'clangarm64')
license=('spdx:BSD-3-Clause')
depends=( $([[ ${MSYSTEM} == CLANG* ]] || echo "${MINGW_PACKAGE_PREFIX}-tools") )
makedepends=("${MINGW_PACKAGE_PREFIX}-cc")
source=('DelayLoad.cmake'
'dl_reaper.c')
sha256sums=('336957446db47b764a2c7f23f76577691b4973a34f528cc6225da821296192e8'
'774608ace1423bb58ee62410f743ca1f871518a85da963f5da7aefc1b92248a3')

build() {
$CC $CFLAGS -c ../dl_reaper.c
}

package() {
mkdir -p "${pkgdir}${MINGW_PREFIX}/lib" "${pkgdir}${MINGW_PREFIX}/share/cmake/Modules"
install -Dm644 "${srcdir}/dl_reaper.o" "${pkgdir}${MINGW_PREFIX}/lib/"
install -Dm644 "${srcdir}/DelayLoad.cmake" "${pkgdir}${MINGW_PREFIX}/share/cmake/Modules/"
}
38 changes: 38 additions & 0 deletions mingw-w64-delay-load-support/dl_reaper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2026 Mikhail Titov <mlt@gmx.us>
* SPDX-License-Identifier: BSD-3-Clause
*/

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <delayimp.h>
#include <winternl.h>

NTSYSAPI NTSTATUS NTAPI NtRaiseHardError(
NTSTATUS ErrorStatus,
ULONG NumberOfParameters,
ULONG UnicodeStringParameterMask,
PULONG_PTR Parameters,
ULONG ValidResponseOptions,
PULONG Response
);

#define PREFIX L"(optional) "
#define PREFIX_LEN sizeof(PREFIX)/sizeof(wchar_t) - 1

wchar_t wDllName[PREFIX_LEN + MAX_PATH] = PREFIX;

FARPROC WINAPI DelayLoadFailureHook(unsigned dliNotify, PDelayLoadInfo pdli) {
ULONG response;
UNICODE_STRING usDllName;

SetErrorMode(0);
MultiByteToWideChar(CP_ACP, 0, pdli->szDll, -1, wDllName + PREFIX_LEN, MAX_PATH);
RtlInitUnicodeString(&usDllName, wDllName);
NtRaiseHardError(STATUS_DLL_NOT_FOUND, 1, 1, (PULONG_PTR)&(PUNICODE_STRING){ &usDllName }, 1, &response);

TerminateProcess(GetCurrentProcess(), STATUS_DLL_NOT_FOUND);
return 0;
}

PfnDliHook __pfnDliFailureHook2 = DelayLoadFailureHook;
22 changes: 22 additions & 0 deletions mingw-w64-mongo-c-driver/004-delay-load-deps.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--- src/src/libmongoc/CMakeLists.txt.orig 2026-03-03 09:18:30.000000000 -0600
+++ src/src/libmongoc/CMakeLists.txt 2026-03-12 01:14:57.595993100 -0500
@@ -873,6 +873,8 @@
endif()
set_target_properties (mongoc_shared PROPERTIES CMAKE_CXX_VISIBILITY_PRESET hidden)
target_link_libraries (mongoc_shared PRIVATE ${LIBRARIES} PUBLIC bson::shared mongo::detail::c_dependencies)
+ include(DelayLoad)
+ target_delay_load(mongoc_shared "snappy|libz|zstd|utf8")
target_include_directories (mongoc_shared PRIVATE ${ZLIB_INCLUDE_DIRS})
target_include_directories (mongoc_shared PRIVATE ${UTF8PROC_INCLUDE_DIRS})
target_include_directories (mongoc_shared PRIVATE ${LIBMONGOCRYPT_INCLUDE_DIRECTORIES})
--- src/build/cmake/GeneratePkgConfig.cmake.orig 2026-03-03 09:18:30.000000000 -0600
+++ src/build/cmake/GeneratePkgConfig.cmake 2026-03-12 10:52:03.255389100 -0500
@@ -284,7 +284,7 @@
# Otherwise, link to the dynamic library namelink
-L\${libdir} -l$<TARGET_PROPERTY:OUTPUT_NAME>>
$<GENEX_EVAL:$<TARGET_PROPERTY:pkg_config_LIBS>>
- $<REMOVE_DUPLICATES:$<TARGET_PROPERTY:INTERFACE_LINK_OPTIONS>>
+ $<REMOVE_DUPLICATES:$<FILTER:$<TARGET_PROPERTY:INTERFACE_LINK_OPTIONS>,EXCLUDE,^LINKER:/delayload:>>
)

# XXX: Could we define a genex that can transform the INTERFACE_LINK_LIBRARIES to a list of
28 changes: 19 additions & 9 deletions mingw-w64-mongo-c-driver/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _realname=mongo-c-driver
pkgbase=mingw-w64-${_realname}
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}")
pkgver=2.2.3
pkgrel=1
pkgrel=2
pkgdesc="libbson and libmongoc, the libraries constituting the MongoDB C Driver (mingw-w64)"
arch=('any')
mingw_arch=('mingw64' 'ucrt64' 'clang64' 'clangarm64')
Expand All @@ -17,26 +17,33 @@ msys2_references=(
'cpe: cpe:2.3:a:mongodb:c_driver'
'gentoo: dev-libs/mongo-c-driver'
)
depends=("${MINGW_PACKAGE_PREFIX}-zlib"
"${MINGW_PACKAGE_PREFIX}-zstd"
"${MINGW_PACKAGE_PREFIX}-snappy"
"${MINGW_PACKAGE_PREFIX}-libutf8proc"
"${MINGW_PACKAGE_PREFIX}-cc-libs")
depends=("${MINGW_PACKAGE_PREFIX}-cc-libs")
optdepends=("${MINGW_PACKAGE_PREFIX}-zlib: Enable zlib compression support"
"${MINGW_PACKAGE_PREFIX}-zstd: Enable zstd compression support"
"${MINGW_PACKAGE_PREFIX}-snappy: Enable Snappy compression support"
"${MINGW_PACKAGE_PREFIX}-libutf8proc: Needed for SCRAM-SHA-256 authentication with non-ASCII passwords")
makedepends=("${MINGW_PACKAGE_PREFIX}-cc"
"${MINGW_PACKAGE_PREFIX}-cmake"
"${MINGW_PACKAGE_PREFIX}-ninja"
"${MINGW_PACKAGE_PREFIX}-python-sphinx")
"${MINGW_PACKAGE_PREFIX}-delay-load-support"
"${MINGW_PACKAGE_PREFIX}-python-sphinx"
"${MINGW_PACKAGE_PREFIX}-zlib"
"${MINGW_PACKAGE_PREFIX}-zstd"
"${MINGW_PACKAGE_PREFIX}-snappy"
"${MINGW_PACKAGE_PREFIX}-libutf8proc")
# source=("mongo-c-driver-${pkgver}.tar.gz::https://github.com/mongodb/mongo-c-driver/archive/refs/tags/${pkgver}.tar.gz")
# curl -s https://pgp.mongodb.com/c-driver.asc | gpg --import
# validpgpkeys=('6DB55D8223FF44E49DCB981344E76C0565ABC463') # MongoDB C Driver Release Signing Key <packaging@mongodb.com>
source=("${msys2_repository_url}/releases/download/${pkgver}/${_realname}-${pkgver}.tar.gz" #{,.asc}
'001-implib-suffix.patch'
'002-pkgconf-require-deps.patch'
'003-pkgconf-winsock-and-noinc.patch')
'003-pkgconf-winsock-and-noinc.patch'
'004-delay-load-deps.patch')
sha256sums=('031b23793a0e0b5eacce0004d9de03c084f6d258f596d374c7a005726dc0206b'
'3e00cd9d754e719d0c19867158ed5286ffa56de6b81f796f885cec1e3f8e1d70'
'83a78751d0a89cd908213977f9adf0f20c67ff132a67ed0ec50570ddd5965277'
'617f8df280d363557174eb098185af2bb048a59693ae0064070e8568b8fd4eb8')
'617f8df280d363557174eb098185af2bb048a59693ae0064070e8568b8fd4eb8'
'ca1ca420c5cbd10f4e2b3d582a47ac2ed78a2b801f42ba87f7a6d022654a05ae')

prepare() {
cd "${srcdir}/${_realname}-${pkgver}"
Expand All @@ -47,6 +54,9 @@ prepare() {
patch -Np1 -i "${srcdir}/001-implib-suffix.patch"
patch -Np1 -i "${srcdir}/002-pkgconf-require-deps.patch"
patch -Np1 -i "${srcdir}/003-pkgconf-winsock-and-noinc.patch"
patch -Np1 -i "${srcdir}/004-delay-load-deps.patch"

cp -a "${srcdir}/DelayLoad.cmake" "src/libmongoc/DelayLoad.cmake"
}

build() {
Expand Down
Loading