Skip to content
Open
Changes from 1 commit
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
12 changes: 10 additions & 2 deletions Sources/FoundationNetworking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,16 @@ 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>")
if(WIN32)

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.

Elsewhere we use if(CMAKE_SYSTEM_NAME STREQUAL "Windows") to conditionalize when building for Windows. How does if(WIN32) behave differently (if at all) / should we use the other format used elsewhere instead?

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.

Updated in 0243902 to use CMAKE_SYSTEM_NAME STREQUAL "Windows", matching the condition style used elsewhere in this project.

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.

To clarify - I'm not 100% certain whether that is the correct syntax but rather I was asking why you chose WIN32 and whether there is a difference with the CMAKE_SYSTEM_NAME check

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.

Good question - I checked this directly with CMake 4.3.2. WIN32 was true for Windows, WindowsStore, WindowsPhone and WindowsCE while CMAKE_SYSTEM_NAME STREQUAL "Windows" selects only desktop Windows.

I originally used WIN32 as conventional shorthand, not because this change needed the broader Windows family. There is no benefit to that breadth here, so the narrower check matching the project's existing style is preferable. That is why I updated it.

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