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
14 changes: 14 additions & 0 deletions Fixtures/PIFBuilder/CCPackage/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// swift-tools-version: 6.2

import PackageDescription

let package = Package(
name: "CCPackage",
products: [
.library(name: "CCTarget", type: .static, targets: ["CCTarget"]),
],
targets: [
.target(name: "CCTarget", ),
.executableTarget(name: "executable", dependencies: ["CCTarget"]),
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

#include <string>
2 changes: 2 additions & 0 deletions Fixtures/PIFBuilder/CCPackage/Sources/CCTarget/test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

#include <test.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book

@main
struct Executable {
static func main() {
print("Hello, world!")
}
}
2 changes: 1 addition & 1 deletion Fixtures/PIFBuilder/UnknownPlatforms/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let package = Package(
name: "UnknownPlatforms",
swiftSettings: [
.define("FOO", .when(platforms: [.custom("DoesNotExist")])),
.define("BAR", .when(platforms: [.linux])),
.define("BAR", .when(platforms: [.linux])),
.define("BAZ", .when(platforms: [.macOS])),
],
),
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftBuildSupport/PackagePIFBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,6 @@ public final class PackagePIFBuilder {
// We currently deliberately do not support Swift ObjC interface headers.
settings[.SWIFT_INSTALL_OBJC_HEADER] = "NO"
settings[.SWIFT_OBJC_INTERFACE_HEADER_NAME] = ""
settings[.OTHER_LDRFLAGS] = []
Copy link
Contributor

Choose a reason for hiding this comment

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

This is set because OTHER_LDRFLAGS defaults to OTHER_LDFLAGS, and this might've been on purpose if we wanted to set linker flags without those applying to ld -r invocations (e.g. when producing mh_objects).

Let's double check whether we actually mean to remove this, and if not, document via a code comment why it's empty.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like the original purpose was to avoid trying to link frameworks when producing object files as part of ld -r.


// Packages use the SwiftPM workspace's cache directory as a compiler working directory to maximize module
// sharing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,14 +484,16 @@ extension PackagePIFProjectBuilder {
if enableDuplicateLinkageCulling {
impartedSettings[.LD_WARN_DUPLICATE_LIBRARIES] = "NO"
}
impartedSettings[.OTHER_LDFLAGS] = (sourceModule.isCxx ? ["-lc++"] : []) + ["$(inherited)"]
impartedSettings[.OTHER_LDRFLAGS] = []
log(
.debug,
indent: 1,
"Added '\(impartedSettings[.OTHER_LDFLAGS]!)' to imparted OTHER_LDFLAGS"
)

if sourceModule.isCxx {
for platform in ProjectModel.BuildSettings.Platform.allCases {
// darwin & freebsd
if [.macOS, .macCatalyst, .iOS, .watchOS, .tvOS, .xrOS, .driverKit, .freebsd].contains(platform) {
settings[.OTHER_LDFLAGS, platform] = ["-lc++", "$(inherited)"]
} else if [.android, .linux, .wasi, .openbsd].contains(platform) {
settings[.OTHER_LDFLAGS, platform] = ["-lstdc++", "$(inherited)"]
}
}
}
// This should be only for dynamic targets, but that isn't possible today.
// Improvement is tracked by rdar://77403529 (Only impart `PackageFrameworks` search paths to clients of dynamic
// package targets and products).
Expand Down Expand Up @@ -816,7 +818,6 @@ extension PackagePIFProjectBuilder {
impartedSettings[.OTHER_CFLAGS] = ["-fmodule-map-file=\(systemLibrary.modulemapFileAbsolutePath)"] +
pkgConfig.cFlags.prepending("$(inherited)")
impartedSettings[.OTHER_LDFLAGS] = pkgConfig.libs.prepending("$(inherited)")
impartedSettings[.OTHER_LDRFLAGS] = []
impartedSettings[.OTHER_SWIFT_FLAGS] = ["-Xcc"] + impartedSettings[.OTHER_CFLAGS]!
log(.debug, indent: 1, "Added '\(systemLibrary.path.pathString)' to imparted HEADER_SEARCH_PATHS")

Expand Down
35 changes: 35 additions & 0 deletions Tests/SwiftBuildSupportTests/PIFBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ extension SwiftBuildSupport.PIF.Workspace {
}

extension SwiftBuildSupport.PIF.Project {
fileprivate func target(id: String) throws -> ProjectModel.BaseTarget {
let matchingTargets: [ProjectModel.BaseTarget] = underlying.targets.filter {
return $0.common.id.value == String(id)
}
if matchingTargets.isEmpty {
throw StringError("No target named \(id) in PIF project")
} else if matchingTargets.count > 1 {
throw StringError("Multiple target named \(id) in PIF project")
} else {
return matchingTargets[0]
}
}

fileprivate func target(named name: String) throws -> ProjectModel.BaseTarget {
let matchingTargets = underlying.targets.filter {
$0.common.name == name
Expand Down Expand Up @@ -135,6 +148,28 @@ struct PIFBuilderTests {
}
}

@Test func platformCCLibrary() async throws {
try await withGeneratedPIF(fromFixture: "PIFBuilder/CCPackage") { pif, observabilitySystem in
let releaseConfig = try pif.workspace
.project(named: "CCPackage")
.target(id: "PACKAGE-TARGET:CCTarget")
.buildConfig(named: "Release")

for platform in ProjectModel.BuildSettings.Platform.allCases {
let ld_flags = releaseConfig.settings[.OTHER_LDFLAGS, platform]
if [.macOS, .macCatalyst, .iOS, .watchOS, .tvOS, .xrOS, .driverKit, .freebsd].contains(platform) {
#expect(ld_flags == ["-lc++", "$(inherited)"], "for platform \(platform)")
} else if [.android, .linux, .wasi, .openbsd].contains(platform) {
#expect(ld_flags == ["-lstdc++", "$(inherited)"], "for platform \(platform)")
} else if [.windows, ._iOSDevice].contains(platform) {
#expect(ld_flags == nil, "for platform \(platform)")
} else {
Issue.record("Unexpected platform \(platform)")
}
}
}
}

@Test func pluginWithBinaryTargetDependency() async throws {
try await withGeneratedPIF(fromFixture: "Miscellaneous/Plugins/BinaryTargetExePlugin") { pif, observabilitySystem in
// Verify that PIF generation succeeds for a package with a plugin that depends on a binary target
Expand Down