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
15 changes: 13 additions & 2 deletions Sources/FoundationNetworking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,19 @@ target_link_libraries(FoundationNetworking
if(NOT BUILD_SHARED_LIBS)
target_compile_options(FoundationNetworking PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend _CFURLSessionInterface>")
target_compile_options(FoundationNetworking PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend curl>")

# The Windows SDK's curl uses Schannel, zlib, and Brotli. The static Linux
# SDK's curl uses OpenSSL and zlib, which BUILD_FULLY_STATIC supplies below.
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_options(FoundationNetworking PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend libcurl>"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't understand why the name changes here. It worked as curl there? That said the rename is likely better as the name is supposed to be the actual name on disk.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The CMake path emitted an autolink for curl, which requests curl.lib, while the Windows static SDK packages the archive as libcurl.lib. A minimal FoundationNetworking executable therefore failed with LNK1104. The package manifest already names libcurl.lib, so this makes the CMake build match the working SwiftPM configuration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Right, but I mean, how has this been working? I suppose that this fix is for outside the CMake build as the curl target in CMake already points to the static library.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, exactly. This change is for consumers of the installed static SDK that are outside the CMake target graph. In the in-tree build _CFURLSessionInterface links CURL::libcurl so final CMake targets resolve the imported target to the static archive and its link interface.

An external swiftc consumer cannot see that CMake target. It only sees the -public-autolink-library metadata embedded in the installed Swift module. On Windows those entries become /DEFAULTLIB:<name>.lib, so the names must match the SDK’s packaged files and the static curl dependencies must be listed explicitly. These directives are emitted only under NOT BUILD_SHARED_LIBS which is why the installed static-SDK reproducer exposed the problem

"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend zlibstatic>"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend brotlicommon>"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend brotlidec>")
else()
target_compile_options(FoundationNetworking PRIVATE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why doesn't Linux need the extra auto linked libraries as well? The dependencies should be the same between Linux/Windows so I wouldn't expect anything to be windows specific here (except for maybe the name of the library if windows uses a different prefix for example)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The Windows SDK builds and packages a static curl archive with zlib and Brotli enabled, but those archive dependencies are not encoded in its autolink metadata. Linux normally resolves the shared curl target and its dynamic dependencies; the existing BUILD_FULLY_STATIC path separately handles its static link additions. This Windows list also mirrors the existing Windows-only linker settings in Package.swift.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Linux normally resolves the shared curl target and its dynamic dependencies

I don't think this is true - the static Linux SDK includes a libcurl.a, a libz.a, etc. The static Linux SDK should not be dynamically linking curl.

This Windows list also mirrors the existing Windows-only linker settings in Package.swift.

I don't think the Package.swift file is relevant here because it does not build static libraries - it dynamically links in the dependencies

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I don't think this is true - the static Linux SDK includes a libcurl.a, a libz.a, etc. The static Linux SDK should not be dynamically linking curl.

You are right about the underlying mechanism and my earlier comment conflated archive naming with linkage mode. On Unix, curl is the correct -l name for either libcurl.so or libcurl.a. The selected linkage mode determines which file is used. The relevant question here is which transitive archives the static curl build actually needs.

I checked the published Swift 6.3.3 Static Linux SDK and the latest main snapshot from 2026-07-11 for both x86_64 and aarch64. In all four configurations:

  • libcurl.a references OpenSSL and zlib
  • libcurl.a has no unresolved Brotli* symbols
  • The SDK ships libcurl.a, libssl.a, libcrypto.a, and `libz.a
  • It does not ship libbrotlicommon.a or libbrotlidec.a
  • swift-sdk.json and toolset.json inject no dependency linker flags
  • A minimal FoundationNetworking executable links successfully

The generated autolink file contains -lcrypto, -lssl, -lcurl and -lz confirming that Linux's dependencies are supplied by the existing BUILD_FULLY_STATIC block. Brotli is absent because both published Linux curl archives were built without Brotli support.

Windows uses a different curl configuration: Schannel, zlib and Brotli. Its observed unresolved symbols are exactly the zlib and Brotli set. Therefore the platform-specific lists are intentional: Windows needs libcurl, zlibstatic, brotlicommon and brotlidec while Linux correctly retains curl plus the existing crypto, ssl and z autolinks.


I don't think the Package.swift file is relevant here because it does not build static libraries - it dynamically links in the dependencies

I agree that Package.swift does not establish the CMake or Linux behavior. Its narrower relevance is that its Windows _CFURLSessionInterface configuration defines CURL_STATICLIB and uses those same four Windows archive names.

The cross-repository full static SDK build @compnerd requested remains the final integration check. My @swift-ci request has not produced a visible run, so someone with CI access still needs to trigger it - I am happy to validate the result!

"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend curl>")
endif()
target_compile_options(FoundationNetworking PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend $<$<PLATFORM_ID:Windows>:${CMAKE_STATIC_LIBRARY_PREFIX_Swift}>swiftSynchronization>")

Expand Down
9 changes: 7 additions & 2 deletions Sources/FoundationXML/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ target_link_libraries(FoundationXML
if(NOT BUILD_SHARED_LIBS)
target_compile_options(FoundationXML PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend _CFXMLInterface>")
target_compile_options(FoundationXML PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend xml2>")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_options(FoundationXML PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend libxml2s>")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think that this might be xml2s and not libxml2s

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I rechecked the installed SDK and the emitted directive. Both the x86_64 and ARM64 slices of the pinned WindowsExperimental SDK contain libxml2s.lib. Neither contains xml2s.lib or xml2.lib

The autolink argument is literal on Windows apart from the .lib suffix. The previous xml2 entry emitted /DEFAULTLIB:xml2.lib while libxml2s emits /DEFAULTLIB:libxml2s.lib. With that directive the static XMLParser reproducer links and prints true. Package.swift also names libxml2s.lib for Windows although the packaged SDK and functional link test are the decisive checks.

Are you seeing xml2s.lib in a different build-tree or SDK artifact? Could you please point me to it? Thanks!

else()
target_compile_options(FoundationXML PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend xml2>")
endif()
target_compile_options(FoundationXML PRIVATE
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -public-autolink-library -Xfrontend $<$<PLATFORM_ID:Windows>:${CMAKE_STATIC_LIBRARY_PREFIX_Swift}>swiftSynchronization>")

Expand Down