Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-14728] SwiftPM/Driver on Windows fails to link C-based targets #4415

Open
kabiroberai opened this issue Jun 5, 2021 · 6 comments
Open

Comments

@kabiroberai
Copy link
Contributor

Previous ID SR-14728
Radar rdar://problem/79292673
Original Reporter @kabiroberai
Type Bug

Attachment: Download

Environment

OS: Windows 10 Pro (20H2)

Toolchain: compnerd.org Swift version 5.5-dev (LLVM 76b16fe31111aa0, Swift 5eb25f1662051fd)

Additional Detail from JIRA
Votes 0
Component/s Package Manager
Labels Bug, Android, Driver, Linux, Windows
Assignee None
Priority Medium

md5: a5cefba8ea42e9bae4dfc9028530df2a

Issue Description:

When using SPM on Windows to build a `.dynamic` library which only contains C targets, the linker fails with the following error:

lld-link: error: undefined symbol: __declspec(dllimport) swift_addNewDSOImage
>>> referenced by C:\Library\Developer\Platforms\Windows.platform\Developer\SDKs\Windows.sdk\usr\lib\swift\windows\x86_64\swiftrt.obj:(void 
__cdecl swift_image_constructor(void))
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Running `swift build -Xswiftc -v` reveals what seems to be the issue:

"C:\\Library\\Developer\\Toolchains\\unknown-Asserts-development.xctoolchain\\usr\\bin\\lld-link" "-out:C:\\Users\\kabir\\Desktop\\Code\\WinBug\\.build\\x86_64-unknown-windows-msvc\\debug\\WinBug.dll" -dll <...> "C:\\Library\\Developer\\Platforms\\Windows.platform\\Developer\\SDKs\\Windows.sdk\\usr\\lib\\swift\\windows\\x86_64\\swiftrt.obj" "C:\\Users\\kabir\\Desktop\\Code\\WinBug\\.build\\x86_64-unknown-windows-msvc\\debug\\WinBug.build\\WinBug.c.o"

i.e. the Swift driver appears to be linking swiftrt.obj but not swiftCore.lib (since swift-autolink-extract sees no need for swiftCore.lib because it's a pure C target). Using the driver by itself (instead of through swift build) also produces this issue.

I'm not too familiar with the Swift codebase but an initial search seems to indicate that the issue is caused due to swiftrt.obj being unconditionally linked at lib/Driver/WindowsToolChains.cpp#L134. Running `swift build -Xswiftc -lswiftCore` causes it to link successfully – though I suspect that not linking swiftrt.obj in C-only targets might be the preferred solution.

I've attached a minimal project demonstrating the issue; running `swift build` succeeds on both macOS and Linux, but fails on Windows.

@typesanitizer
Copy link

cc @compnerd

@compnerd
Copy link
Collaborator

CC: @abertelrud

This is caused by using swiftc as the linker driver for the C library. We should invoke clang as the linker driver rather than swiftc for a pure C library, and {{clang+++}} for a C+ library. This should also be something that occurs on elvish targets as we use the registrar there as well for dealing with runtime class registrarion.

@typesanitizer
Copy link

@swift-ci create

@compnerd
Copy link
Collaborator

Just adding this for people who stumble upon the issue. I don't have a solution for this in mind, but do have a temporary workaround that users can use:

-Xlinker %SDKROOT%\usr\lib\swift\windows\x86_64\swiftCore.lib

This is a rather unsatisfactory workaround as it causes a preserved over-linkage to the swift runtime which will cause an extra module constructor to be invoked.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 4, 2022
dabrahams added a commit to dabrahams/citron that referenced this issue Dec 29, 2023
@dabrahams
Copy link
Contributor

For stumblers again, a perhaps less-sketchy workaround is to put the C code in a library and invoke it from a trivial Swift main. HTH!

@MaxDesiatov MaxDesiatov changed the title [SR-14728] SPM/Driver on Windows fails to link C-based targets [SR-14728] SwiftPM/Driver on Windows fails to link C-based targets Dec 29, 2023
dabrahams added a commit to dabrahams/citron that referenced this issue Dec 29, 2023
@dabrahams
Copy link
Contributor

For stumblers again, a perhaps less-sketchy workaround is to put the C code in a library and invoke it from a trivial Swift main. HTH!

And if you want it to work with Xcode; that's slightly too trivial; you need to use @main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants