Skip to content

Commit 1d23aab

Browse files
authored
[Issue #4500] Fix resource bundle accessor issue for Clang sources (#5921)
motivation: I noticed an issue when trying to access a Clang package's resources when testing the target from the SwiftPM CLI. In short, the resource bundle is placed in the same place when building a Clang-only or Swift-only package, but the generated resource_bundle_accessor.m's logic tries to create an NSBundle for a path that DNE. The difference becomes clear when comparing the logic to the resource_bundle_accessor.swift that is generated from Swift-only packages with resources.
1 parent 41f6843 commit 1d23aab

File tree

8 files changed

+77
-2
lines changed

8 files changed

+77
-2
lines changed

Fixtures/Resources/Simple/Package.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ let package = Package(
1818
]
1919
),
2020

21+
.target(
22+
name: "ClangResource",
23+
resources: [
24+
.copy("foo.txt"),
25+
]
26+
),
27+
28+
.testTarget(
29+
name: "ClangResourceTests",
30+
dependencies: ["ClangResource"]
31+
),
32+
2133
.target(
2234
name: "CPPResource",
2335
resources: [
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#import <Foundation/Foundation.h>
2+
3+
#import "Package.h"
4+
5+
@implementation Package
6+
7+
+ (NSBundle *)resourceBundle {
8+
return SWIFTPM_MODULE_BUNDLE;
9+
}
10+
11+
@end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface Package : NSObject
4+
5+
+ (NSBundle *)resourceBundle;
6+
7+
@end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#import <XCTest/XCTest.h>
2+
3+
@import ClangResource;
4+
5+
@interface ClangResourceTests : XCTestCase
6+
@end
7+
8+
@implementation ClangResourceTests
9+
10+
- (void)testResourceBundleIsNonNil {
11+
XCTAssertNotNil([Package resourceBundle]);
12+
}
13+
14+
@end

Sources/Build/BuildPlan.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,13 @@ public final class ClangTargetBuildDescription {
503503
504504
NSBundle* \(target.c99name)_SWIFTPM_MODULE_BUNDLE() {
505505
NSURL *bundleURL = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:@"\(bundleBasename)"];
506-
return [NSBundle bundleWithURL:bundleURL];
506+
507+
NSBundle *preferredBundle = [NSBundle bundleWithURL:bundleURL];
508+
if (preferredBundle == nil) {
509+
return [NSBundle bundleWithPath:@"\(bundlePath.pathString)"];
510+
}
511+
512+
return preferredBundle;
507513
}
508514
"""
509515

Sources/SPMTestSupport/XCTAssertHelpers.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,25 @@ public func XCTAssertBuilds(
5656

5757
public func XCTAssertSwiftTest(
5858
_ path: AbsolutePath,
59+
configuration: Configuration = .Debug,
60+
extraArgs: [String] = [],
61+
Xcc: [String] = [],
62+
Xld: [String] = [],
63+
Xswiftc: [String] = [],
5964
env: EnvironmentVariables? = nil,
6065
file: StaticString = #file,
6166
line: UInt = #line
6267
) {
6368
XCTAssertNoThrow(
64-
try SwiftPMProduct.SwiftTest.execute([], packagePath: path, env: env),
69+
try executeSwiftTest(
70+
path,
71+
configuration: configuration,
72+
extraArgs: extraArgs,
73+
Xcc: Xcc,
74+
Xld: Xld,
75+
Xswiftc: Xswiftc,
76+
env: env
77+
),
6578
file: file,
6679
line: line
6780
)

Tests/FunctionalTests/ResourcesTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,15 @@ class ResourcesTests: XCTestCase {
102102
#endif
103103
}
104104
}
105+
106+
func testResourceBundleInClangPackageWhenRunningSwiftTest() throws {
107+
#if !os(macOS)
108+
// Running swift-test fixtures on linux is not yet possible.
109+
try XCTSkipIf(true, "test is only supported on macOS")
110+
#endif
111+
112+
try fixture(name: "Resources/Simple") { fixturePath in
113+
XCTAssertSwiftTest(fixturePath, extraArgs: ["--filter", "ClangResourceTests"])
114+
}
115+
}
105116
}

0 commit comments

Comments
 (0)