-
Notifications
You must be signed in to change notification settings - Fork 35
Set OtherLDFlags for dynamic framework type #206
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
base: main
Are you sure you want to change the base?
Conversation
I used swift-atomics for test on cd10ffc, but I found Scipio fails with
void this_is_c_function(); #include "ClangModule.h"
void this_is_c_function() {
} import ClangModule
@usableFromInline
struct Sample {
@usableFromInline
static func sample() {
this_is_c_function()
}
} Please see 6bf01ab for the concrete example. |
We can check which libraries created xcframeworks depends on with
I think we need to make |
SummaryCause of IssueThe linker cannot link Clang modules for ChangesPIFGenerator.swift
DynamicFrameworkTests.swift
IntegrationTests.swift
UsableFromInlinePackage, DynamicFrameworkOtherLDFlagsTestPackage
|
@S-Shimotori Sorry for waiting you. It's ready to review. Could you rebase the current main? |
I have to fix this PR because it still depends on SwiftPM, not PIFKit. Could you review my idea and give me some advice? What I should do to merge PIFKit logic into this PRRetrieve dependenciesWhen
|
guard let resolvedTarget = descriptionPackage.graph.allModules.first(where: { $0.c99name == c99Name }) else { |
PIFCompiler
passed descriptionPackage: DescriptionPackage
to PIFGenerator
, but it was deleted with #183.
What to do with PIFKit
- Pass
ResolvedModule
toPIFGenerator.init(...)
- Pass
c99Name
toPIFGenerator.init(...)
- Maybe
buildProduct.target.c99name
in createXCFramework(buildProduct:outputDirectory:overwrite:) ?
- Maybe
Configure build settings
When PIFGenerator
depended on SwiftPM
Scipio used PIF.BuildSettings
as a container.
PIF.BuildSettings
has consists of some dictionaries for platform-specific settings.
c.f. swift-package-manager/Sources/XCBuildSupport/PIF.swift at 29e562052de0305417c9bd71d8a7c64bee2759fb · swiftlang/swift-package-manager
What to do with PIFKit
PIFKit.BuildConfiguration
's buildSettings is a simple dictionary.
- Option 1: Scipio doesn't consider
PackageCondition
nor set platform-specific values there. - Option 2:
PIFGenerator
configures them somehow to handlePackageCondition
s.
Do you have any ideas? If we choose the latter option, how should I update updateBuildConfiguration(_:)
?
@S-Shimotori I'm sorry for the long wait. As you mentioned, we should configure settings considering the Platform Filter, but PIFKit currently does not have that interface. As far as I understand, the new ResolvedModule also has an interface to retrieve the PlatformFilter. With these, I believe we can reproduce the original implementation. What do you think? |
case .mergeable: | ||
settings[.OTHER_LDFLAGS, default: ["$(inherited)"]] | ||
.append("-Wl,-make_mergeable") | ||
case .dynamic: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to take the same path for mergeable as well.
private let fixturePath = URL(fileURLWithPath: #filePath) | ||
.deletingLastPathComponent() | ||
.appendingPathComponent("Resources") | ||
.appendingPathComponent("Fixtures") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nits] Please use the modern API
private let fixturePath = URL(fileURLWithPath: #filePath) | |
.deletingLastPathComponent() | |
.appendingPathComponent("Resources") | |
.appendingPathComponent("Fixtures") | |
private let fixturePath = URL(filePath: #filePath) | |
.deletingLastPathComponent() | |
.appending(components: "Resources", "Fixtures") |
case .mergeable: | ||
configuration.buildSettings["OTHER_LDFLAGS"] | ||
.append("-Wl,-make_mergeable") | ||
case .dynamic: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These flag settings will be required also for mergeable
let outputDir = fileManager.temporaryDirectory | ||
.appendingPathComponent("Scipio") | ||
.appendingPathComponent(packageName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let outputDir = fileManager.temporaryDirectory | |
.appendingPathComponent("Scipio") | |
.appendingPathComponent(packageName) | |
let outputDir = fileManager.temporaryDirectory | |
.appending(components: "Scipio", packageName) |
.appendingPathComponent(packageName) | ||
|
||
defer { | ||
print("remove output directory: \(outputDir.path)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed?
verbose: false | ||
) | ||
) | ||
let packageDir = fixturePath.appendingPathComponent(packageName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let packageDir = fixturePath.appendingPathComponent(packageName) | |
let packageDir = fixturePath.appending(component: packageName) |
dependencies: [String: Set<Destination>], | ||
outputDir: URL | ||
) async throws { | ||
let xcFrameworkPath = outputDir.appendingPathComponent(framework.xcFrameworkName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let xcFrameworkPath = outputDir.appendingPathComponent(framework.xcFrameworkName) | |
let xcFrameworkPath = outputDir.appending(component: framework.xcFrameworkName) |
let binaryPath = xcFrameworkPath | ||
.appendingPathComponent(arch.rawValue) | ||
.appendingPathComponent("\(framework.name).framework") | ||
.appendingPathComponent(framework.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let binaryPath = xcFrameworkPath | |
.appendingPathComponent(arch.rawValue) | |
.appendingPathComponent("\(framework.name).framework") | |
.appendingPathComponent(framework.name) | |
let binaryPath = xcFrameworkPath | |
.appending(components: arch.rawValue, "\(framework.name).framework", framework.name) |
Changes:
|
private let fileManager: FileManager = .default | ||
|
||
@Test( | ||
arguments: [FrameworkType.dynamic, .mergeable] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Closes #116
This is a draft that containsFIXME
and doesn't have required tests.I created this PR to disclose codes given by ikesyo san. I will close this issue if anyone can implement completely.
Issue
According to #116, current Scipio cannot create dynamic frameworks for these libraries:
The linker needs dependencies with
-framework
flag.Idea
PIFGenerator
-framework
toOTHER_LDFLAGS
when frameworkType=dynamicTests
I think these tests are required but I'm sorry couldn't create them by myself yet.
Scipio/Tests/ScipioKitTests/IntegrationTests.swift
Line 38 in dd8e118
"Atomics": .init(frameworkType: .mergeable)
I tried to create a package that contains a simple internal target, but current Scipio can create XCFramework without-framework
. Maybe we should prepare a special target (e.g. Clang module?)[2025-05-01] It seems that the linker requires
-framework
for@usableFromInline
and Clang module.PIFLibraryTargetModifier
internal for checkingOTHER_LDFLAGS
.I think "OtherLDFlagsTestPackage" is not a good name but I need to decide what tests we need before giving name.