aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-16 09:19:30 +0000
committer_ov4 <ov4@ov4.org>2026-10-16 09:19:30 +0000
commitb6f0bf2df0f6baadc345a9d146599197a5b46e9f (patch)
treece8954ede317117262244306e7d7444536de0b3a
parentce584238e66a32f93c1af4d16bfe4a1928e25b88 (diff)
fix(build): statically link MinGW XML manifest dependencies
Replace LLVMWindowsManifest's XML import library with static XML, iconv and zlib archives. Check the Windows compiler's PE imports before the restricted-PATH package smoke test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-rw-r--r--.github/workflows/nightly-build.yml21
-rw-r--r--AGENTS/ARCH.md4
-rw-r--r--cmake/NativeCompiler.cmake15
-rw-r--r--doc/build.md2
4 files changed, 42 insertions, 0 deletions
diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
index 773f8ca..62b8d49 100644
--- a/.github/workflows/nightly-build.yml
+++ b/.github/workflows/nightly-build.yml
@@ -217,6 +217,7 @@ jobs:
mingw-w64-x86_64-python
mingw-w64-x86_64-libffi
mingw-w64-x86_64-libxml2
+ mingw-w64-x86_64-libiconv
mingw-w64-x86_64-zlib
mingw-w64-x86_64-zstd
@@ -239,6 +240,26 @@ jobs:
-DCMAKE_PREFIX_PATH="$(cygpath -m /mingw64)"
cmake --build build --target release --parallel 4
+ - name: Check Windows runtime dependencies
+ shell: msys2 {0}
+ run: |
+ llvm-readobj --coff-imports build/cpsc.exe > build/windows-imports.txt
+ imports=$(sed -n 's/^ Name: //p' build/windows-imports.txt | tr -d '\r')
+ test -n "$imports"
+ windows_root=$(cygpath -u "$SYSTEMROOT")
+ while IFS= read -r library; do
+ echo "Runtime dependency: $library"
+ case "${library,,}" in
+ api-ms-win-*.dll|ext-ms-win-*.dll) ;;
+ *)
+ if [[ ! -f "$windows_root/System32/$library" ]]; then
+ echo "Unexpected runtime dependency: $library" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ done <<< "$imports"
+
- name: Smoke test the packaged compiler
shell: pwsh
run: |
diff --git a/AGENTS/ARCH.md b/AGENTS/ARCH.md
index 002d62e..a73e086 100644
--- a/AGENTS/ARCH.md
+++ b/AGENTS/ARCH.md
@@ -131,6 +131,10 @@ macOS links with `-dead_strip_dylibs` to omit unused dylibs inherited
from LLVM's support interface, including Homebrew's Z3. Keep the nightly package's
non-system dependency check; required dylibs are not removed by this option.
Windows EMBEDDED is untested.
+On MinGW, `LLVMWindowsManifest` explicitly uses static libxml2, iconv and zlib
+plus the system bcrypt library. XML definitions are loaded with `--whole-archive`
+to satisfy dllimport references in the prebuilt LLVM archive. `-static` alone
+does not replace an imported target's explicit `.dll.a` path.
`NativeCompiler` clones the module, sets the host triple/DataLayout and emits a PIC
object. Clang Driver constructs one platform linker job, which is dispatched to
diff --git a/cmake/NativeCompiler.cmake b/cmake/NativeCompiler.cmake
index 35c7f41..bd536f4 100644
--- a/cmake/NativeCompiler.cmake
+++ b/cmake/NativeCompiler.cmake
@@ -74,6 +74,21 @@ target_sources(cpsc PRIVATE tools/driver/NativeCompiler.cc)
target_include_directories(cpsc PRIVATE ${CLANG_INCLUDE_DIRS} ${LLD_INCLUDE_DIRS}
"${CMAKE_BINARY_DIR}/native-runtime")
target_link_libraries(cpsc PRIVATE clangDriver ${cpsc_linker_libraries})
+if(MINGW AND TARGET LibXml2::LibXml2)
+ # LLD's COFF manifest support reaches libxml2 through LLVMWindowsManifest.
+ # An explicit .dll.a in that interface bypasses the driver's -static flag.
+ cpsc_find_dependency(LIBRARY CPSC_STATIC_xml2 REQUIRED NAMES libxml2.a)
+ cpsc_find_dependency(LIBRARY CPSC_STATIC_iconv REQUIRED NAMES libiconv.a)
+ add_library(CPSCStaticXML2 INTERFACE)
+ # The prebuilt LLVM archive uses dllimport references. Load XML definitions
+ # before LLD resolves those references to local symbols.
+ target_link_libraries(CPSCStaticXML2 INTERFACE
+ -Wl,--whole-archive "${CPSC_STATIC_xml2}" -Wl,--no-whole-archive
+ "${CPSC_STATIC_iconv}" "${CPSC_STATIC_z}" bcrypt)
+ get_target_property(cpsc_manifest_libs LLVMWindowsManifest INTERFACE_LINK_LIBRARIES)
+ list(TRANSFORM cpsc_manifest_libs REPLACE "^LibXml2::LibXml2$" CPSCStaticXML2)
+ set_property(TARGET LLVMWindowsManifest PROPERTY INTERFACE_LINK_LIBRARIES "${cpsc_manifest_libs}")
+endif()
# Distribution Clang/LLD archives can still name the shared LLVM umbrella
# library in their imported interfaces. Resolve those edges to static archives.
add_library(CPSCStaticLLVM INTERFACE)
diff --git a/doc/build.md b/doc/build.md
index 17f2741..dce9d7c 100644
--- a/doc/build.md
+++ b/doc/build.md
@@ -129,6 +129,8 @@ version; check that it is 23. Windows builds have only been reviewed statically.
The `clang-tools-extra` package is required because MSYS2's `ClangTargets.cmake` checks the extra-tool archives, including `libclangApplyReplacements.a`, when loading the Clang development package, even though cpsc does not invoke those tools.
+LLD's Windows manifest support also uses libxml2. cpsc explicitly selects `libxml2.a` and its static iconv/zlib dependencies; the package's default `libxml2.dll.a` import library would retain a DLL dependency even with `-static`. The XML archive is loaded in full so LLD can resolve the prebuilt LLVM archive's `dllimport` references to local definitions. Nightly checks the compiler's PE import table for non-system DLLs before running the package with a restricted PATH.
+
### macOS (Homebrew)
Install the Xcode Command Line Tools for the macOS SDK, make and package