Skip to content

Commit

Permalink
Repair the Windows SwiftPM build (#5068)
Browse files Browse the repository at this point in the history
* Repair the Windows SwiftPM build

* Update XCTSkip message
  • Loading branch information
jmschonfeld authored Aug 16, 2024
1 parent e0f1615 commit a39f398
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 106 deletions.
70 changes: 59 additions & 11 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ let platformsWithThreads: [Platform] = [
.linux,
.windows,
]
var dispatchIncludeFlags: [CSetting]

var dispatchIncludeFlags: [CSetting] = []
if let environmentPath = Context.environment["DISPATCH_INCLUDE_PATH"] {
dispatchIncludeFlags = [.unsafeFlags([
dispatchIncludeFlags.append(.unsafeFlags([
"-I\(environmentPath)",
"-I\(environmentPath)/Block"
])]
]))
} else {
dispatchIncludeFlags = [
dispatchIncludeFlags.append(
.unsafeFlags([
"-I/usr/lib/swift",
"-I/usr/lib/swift/Block"
], .when(platforms: [.linux, .android]))
]
)
if let sdkRoot = Context.environment["SDKROOT"] {
dispatchIncludeFlags.append(.unsafeFlags([
"-I\(sdkRoot)usr\\include",
Expand All @@ -35,10 +36,55 @@ if let environmentPath = Context.environment["DISPATCH_INCLUDE_PATH"] {
}
}

var libxmlIncludeFlags: [CSetting] = []
if let environmentPath = Context.environment["LIBXML_INCLUDE_PATH"] {
libxmlIncludeFlags = [
.unsafeFlags([
"-I\(environmentPath)"
]),
.define("LIBXML_STATIC")
]
}

var curlIncludeFlags: [CSetting] = []
if let environmentPath = Context.environment["CURL_INCLUDE_PATH"] {
curlIncludeFlags = [
.unsafeFlags([
"-I\(environmentPath)"
]),
.define("CURL_STATICLIB")
]
}

var curlLinkFlags: [LinkerSetting] = [
.linkedLibrary("libcurl.lib", .when(platforms: [.windows])),
.linkedLibrary("zlibstatic.lib", .when(platforms: [.windows]))
]
if let environmentPath = Context.environment["CURL_LIBRARY_PATH"] {
curlLinkFlags.append(.unsafeFlags([
"-L\(environmentPath)"
]))
}
if let environmentPath = Context.environment["ZLIB_LIBRARY_PATH"] {
curlLinkFlags.append(.unsafeFlags([
"-L\(environmentPath)"
]))
}

var libxmlLinkFlags: [LinkerSetting] = [
.linkedLibrary("libxml2s.lib", .when(platforms: [.windows]))
]
if let environmentPath = Context.environment["LIBXML2_LIBRARY_PATH"] {
libxmlLinkFlags.append(.unsafeFlags([
"-L\(environmentPath)"
]))
}

let coreFoundationBuildSettings: [CSetting] = [
.headerSearchPath("internalInclude"),
.define("DEBUG", .when(configuration: .debug)),
.define("CF_BUILDING_CF"),
.define("CF_WINDOWS_EXECUTABLE_INITIALIZER", .when(platforms: [.windows])), // Ensure __CFInitialize is run even when statically linked into an executable
.define("DEPLOYMENT_ENABLE_LIBDISPATCH", .when(platforms: platformsWithThreads)),
.define("DEPLOYMENT_RUNTIME_SWIFT"),
.define("HAVE_STRUCT_TIMESPEC"),
Expand Down Expand Up @@ -216,25 +262,27 @@ let package = Package(
name: "_CFXMLInterface",
dependencies: [
"CoreFoundation",
"Clibxml2",
.target(name: "Clibxml2", condition: .when(platforms: [.linux])),
],
path: "Sources/_CFXMLInterface",
exclude: [
"CMakeLists.txt"
],
cSettings: interfaceBuildSettings
cSettings: interfaceBuildSettings + libxmlIncludeFlags,
linkerSettings: libxmlLinkFlags
),
.target(
name: "_CFURLSessionInterface",
dependencies: [
"CoreFoundation",
"Clibcurl",
.target(name: "Clibcurl", condition: .when(platforms: [.linux])),
],
path: "Sources/_CFURLSessionInterface",
exclude: [
"CMakeLists.txt"
],
cSettings: interfaceBuildSettings
cSettings: interfaceBuildSettings + curlIncludeFlags,
linkerSettings: curlLinkFlags
),
.systemLibrary(
name: "Clibxml2",
Expand Down Expand Up @@ -292,8 +340,8 @@ let package = Package(
"Foundation",
"FoundationXML",
"FoundationNetworking",
.targetItem(name: "XCTest", condition: .when(platforms: [.linux])),
"xdgTestHelper"
"XCTest",
.target(name: "xdgTestHelper", condition: .when(platforms: [.linux]))
],
resources: [
.copy("Foundation/Resources")
Expand Down
10 changes: 10 additions & 0 deletions Sources/CoreFoundation/CFRuntime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,16 @@ static CFBundleRef RegisterCoreFoundationBundle(void) {
#define DLL_THREAD_DETACH 3
#define DLL_PROCESS_DETACH 0

#if CF_WINDOWS_EXECUTABLE_INITIALIZER
static void __CFWindowsExecutableInitializer(void) __attribute__ ((constructor)) __attribute__ ((used));

void __CFWindowsExecutableInitializer(void) {
static CFBundleRef cfBundle = NULL;
__CFInitialize();
cfBundle = RegisterCoreFoundationBundle();
}
#endif

int DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved ) {
static CFBundleRef cfBundle = NULL;
if (dwReason == DLL_PROCESS_ATTACH) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/_CFURLSessionInterface/CFURLSessionInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
///
//===----------------------------------------------------------------------===//

#include "CFURLSessionInterface.h"
#include "CFInternal.h"
#include "CFURLSessionInterface.h"
#include "CFString.h"
#include <curl/curl.h>

Expand Down
10 changes: 9 additions & 1 deletion Tests/Foundation/TestBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,16 @@ internal func testBundleName() -> String {
return testBundle().infoDictionary!["CFBundleName"] as! String
}

internal func xdgTestHelperURL() -> URL {
internal func xdgTestHelperURL() throws -> URL {
#if os(Windows)
// Adding the xdgTestHelper as a dependency of TestFoundation causes its object files (including the main function) to be linked into the test runner executable as well
// While this works on Linux due to special linker functionality, this doesn't work on Windows and results in a collision between the two main symbols
// SwiftPM also cannot support depending on this executable (to ensure it is built) without also linking its objects into the test runner
// For those reasons, using the xdgTestHelper on Windows is currently unsupported and tests that rely on it must be skipped
throw XCTSkip("xdgTestHelper is not supported during testing on Windows (test executables are not supported by SwiftPM on Windows)")
#else
testBundle().bundleURL.deletingLastPathComponent().appendingPathComponent("xdgTestHelper")
#endif
}


Expand Down
2 changes: 1 addition & 1 deletion Tests/Foundation/TestFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ class TestFileManager : XCTestCase {
environment[entry.key] = entry.value
}

let helper = xdgTestHelperURL()
let helper = try xdgTestHelperURL()
let (stdout, _) = try runTask([ helper.path, "--nspathfor", method, identifier ],
environment: environment)

Expand Down
2 changes: 1 addition & 1 deletion Tests/Foundation/TestHTTPCookieStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ class TestHTTPCookieStorage: XCTestCase {

// Test by setting the environmental variable
let task = Process()
task.executableURL = xdgTestHelperURL()
task.executableURL = try xdgTestHelperURL()
task.arguments = ["--xdgcheck"]
var environment = ProcessInfo.processInfo.environment
let testPath = NSHomeDirectory() + "/TestXDG"
Expand Down
Loading

0 comments on commit a39f398

Please sign in to comment.