-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cross compilation support (configurable destinations)
- Loading branch information
Showing
24 changed files
with
320 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import Foundation | ||
import Basic | ||
import PackageModel | ||
|
||
enum HostDestinationError: Swift.Error { | ||
/// Couldn't find the Xcode installation. | ||
case invalidInstallation(problem: String) | ||
} | ||
|
||
extension HostDestinationError: CustomStringConvertible { | ||
var description: String { | ||
switch self { | ||
case .invalidInstallation(let problem): | ||
return problem | ||
} | ||
} | ||
} | ||
|
||
enum DestinationFileError: Swift.Error { | ||
/// Wrong version. | ||
case destinationFileVersionMismatch(problem: String) | ||
} | ||
|
||
extension DestinationFileError: CustomStringConvertible { | ||
var description: String { | ||
switch self { | ||
case .destinationFileVersionMismatch(let problem): | ||
return problem | ||
} | ||
} | ||
} | ||
|
||
public struct Destination { | ||
public let target: String | ||
|
||
public let sdk: AbsolutePath | ||
|
||
public let toolchain: AbsolutePath | ||
|
||
public let dynamicLibraryExtension: String | ||
|
||
public let extraCCFlags: [String] | ||
|
||
public let extraSwiftCFlags: [String] | ||
|
||
public let extraCPPFlags: [String] | ||
|
||
public static func hostDestination() throws -> Destination { | ||
#if os(macOS) | ||
let sdkPath = try Process.checkNonZeroExit(args: "xcrun", "--sdk", "macosx", "--show-sdk-path").chomp() | ||
guard !sdkPath.isEmpty else { | ||
throw HostDestinationError.invalidInstallation(problem: "could not find default SDK") | ||
} | ||
|
||
let platformPath = try Process.checkNonZeroExit(args: "xcrun", "--sdk", sdkPath, "--show-sdk-platform-path").chomp() | ||
guard !platformPath.isEmpty else { | ||
throw HostDestinationError.invalidInstallation(problem: "could not find SDK platform path for SDK \(sdkPath)") | ||
} | ||
|
||
let sdkPlatformFrameworksPath = AbsolutePath(platformPath).appending(components: "Developer", "Library", "Frameworks") | ||
|
||
let devDirPath = try Process.checkNonZeroExit(args: "xcode-select", "-p").chomp() | ||
let sysFWPath = AbsolutePath(sdkPath).appending(component: "System") | ||
.appending(component: "Library") | ||
.appending(component: "Frameworks").asString | ||
let tcPath = AbsolutePath(devDirPath).appending(component: "Toolchains") | ||
.appending(component: "XcodeDefault.xctoolchain") | ||
return Destination(target: "x86_64-apple-macosx10.10", | ||
sdk: AbsolutePath(sdkPath), | ||
toolchain: tcPath, | ||
dynamicLibraryExtension: "dylib", | ||
extraCCFlags: ["-F", sdkPlatformFrameworksPath.asString], | ||
extraSwiftCFlags: ["-F", sysFWPath, | ||
"-F", sdkPlatformFrameworksPath.asString, | ||
"-target", "x86_64-apple-macosx10.10", | ||
"-sdk", sdkPath], | ||
extraCPPFlags: ["-lc++"]) | ||
#elseif os(Linux) | ||
return Destination(target: "linux-unknown-x86_64", | ||
sdk: AbsolutePath("/"), | ||
toolchain: AbsolutePath(CommandLine.arguments[0], | ||
relativeTo: currentWorkingDirectory) | ||
.parentDirectory.parentDirectory.parentDirectory, | ||
dynamicLibraryExtension: "so", | ||
extraCCFlags: ["-fPIC"], | ||
extraSwiftCFlags: [], | ||
extraCPPFlags: ["-lstdc++"]) | ||
#else | ||
fatalError("unsupported OS, sorry") | ||
#endif | ||
} | ||
|
||
public static func loadFromDescription(path: AbsolutePath, | ||
fileSystem: FileSystem = localFileSystem) throws -> Destination { | ||
let json = try JSON(bytes: try fileSystem.readFileContents(path)) | ||
return try Destination.init(json: json) | ||
} | ||
|
||
public func outputFile(name: String, type: PackageModel.ProductType) -> RelativePath { | ||
switch type { | ||
case .executable: | ||
return RelativePath(name) | ||
case .library(.static): | ||
return RelativePath("lib\(name).a") | ||
case .library(.dynamic): | ||
return RelativePath("lib\(name).\(self.dynamicLibraryExtension)") | ||
case .library(.automatic): | ||
return RelativePath("please fix me, this file name shouldn't be used") | ||
case .test: | ||
let base = "\(name).xctest" | ||
#if os(macOS) | ||
return RelativePath("\(base)/Contents/MacOS/\(name)") | ||
#else | ||
return RelativePath(base) | ||
#endif | ||
} | ||
} | ||
|
||
#if os(macOS) | ||
public func sdkPlatformFrameworkPath() -> AbsolutePath? { | ||
if let platformPath = try? Process.checkNonZeroExit(args: "xcrun", | ||
"--sdk", self.sdk.asString, | ||
"--show-sdk-platform-path").chomp() | ||
, !platformPath.isEmpty { | ||
return AbsolutePath(platformPath).appending(components: "Developer", "Library", "Frameworks") | ||
} else { | ||
return nil | ||
} | ||
} | ||
#endif | ||
} | ||
|
||
extension Destination: JSONMappable { | ||
public init(json: JSON) throws { | ||
if !((json.get("version")).map ({ $0 == "1" }) ?? false) { | ||
throw DestinationFileError.destinationFileVersionMismatch(problem: "expected version 1") | ||
} | ||
self.init(target: try json.get("target"), | ||
sdk: AbsolutePath(try json.get("sdk")), | ||
toolchain: AbsolutePath(try json.get("toolchain")), | ||
dynamicLibraryExtension: try json.get("dynamic-library-extension"), | ||
extraCCFlags: try json.get("extra-cc-flags"), | ||
extraSwiftCFlags: try json.get("extra-swiftc-flags"), | ||
extraCPPFlags: try json.get("extra-cpp-flags")) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.