Skip to content

[swiftpm] Update to latest master #28

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

Merged
merged 2 commits into from
Dec 3, 2018
Merged
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
4 changes: 2 additions & 2 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ let package = Package(
.target(
name: "SKSwiftPMWorkspace",
dependencies: ["SwiftPM", "SKCore"]),
.testTarget(
name: "SKSwiftPMWorkspaceTests",
dependencies: ["SKSwiftPMWorkspace", "SKTestSupport"]),

// Csourcekitd: C modules wrapper for sourcekitd.
.target(
Expand Down
24 changes: 15 additions & 9 deletions Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public final class SwiftPMWorkspace {
// FIXME: duplicating code from UserToolchain setup in swiftpm.
var sdkpath: AbsolutePath? = nil
var platformPath: AbsolutePath? = nil
let target: Triple = Triple.hostTriple
if case .darwin? = Platform.currentPlatform {
if let path = try? Process.checkNonZeroExit(args: "/usr/bin/xcrun", "--show-sdk-path", "--sdk", "macosx") {
sdkpath = try? AbsolutePath(validating: path.spm_chomp())
Expand All @@ -84,8 +83,8 @@ public final class SwiftPMWorkspace {
}
}

var extraSwiftFlags = ["-target", target.tripleString]
var extraClangFlags = ["-arch", target.arch.rawValue]
var extraSwiftFlags: [String] = []
var extraClangFlags: [String] = []
if let sdkpath = sdkpath {
extraSwiftFlags += [
"-sdk", sdkpath.asString
Expand Down Expand Up @@ -344,16 +343,23 @@ extension ToolchainRegistry {

/// A toolchain appropriate for using to load swiftpm manifests.
fileprivate var swiftpmHost: SwiftPMToolchain? {
guard let base = self.default, base.swiftc != nil else {
return nil
var swiftc: AbsolutePath? = self.default?.swiftc
var clang: AbsolutePath? = self.default?.clang
if swiftc == nil {
swiftc = toolchains.first(where: { $0.swiftc != nil })?.swiftc
}
if clang == nil {
clang = toolchains.first(where: { $0.clang != nil })?.clang
}

guard let clang = base.clang ?? toolchains.first(where: { $0.clang != nil })?.clang else { return nil }
if swiftc == nil || clang == nil {
return nil
}

return SwiftPMToolchain(
swiftCompiler: base.swiftc!,
clangCompiler: clang,
libDir: base.swiftc!.parentDirectory.parentDirectory.appending(components: "lib", "swift", "pm"),
swiftCompiler: swiftc!,
clangCompiler: clang!,
libDir: swiftc!.parentDirectory.parentDirectory.appending(components: "lib", "swift", "pm"),
sdkRoot: nil,
extraCCFlags: [],
extraSwiftCFlags: [],
Expand Down
29 changes: 29 additions & 0 deletions Sources/SKTestSupport/FileSystem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Basic

extension FileSystem {

/// Creates files from a dictionary of path to contents.
///
/// - parameters:
/// - root: The root directory that the paths are relative to.
/// - files: Dictionary from path (relative to root) to contents.
public func createFiles(root: AbsolutePath = .root, files: [String: ByteString]) throws {
for (path, contents) in files {
let path = AbsolutePath(path, relativeTo: root)
try createDirectory(path.parentDirectory, recursive: true)
try writeFileContents(path, bytes: contents)
}
}
}
2 changes: 2 additions & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import LanguageServerProtocolJSONRPCTests
import LanguageServerProtocolTests
import SKCoreTests
import SKSupportTests
import SKSwiftPMWorkspaceTests
import SourceKitTests

var tests = [XCTestCaseEntry]()
tests += LanguageServerProtocolJSONRPCTests.__allTests()
tests += LanguageServerProtocolTests.__allTests()
tests += SKCoreTests.__allTests()
tests += SKSupportTests.__allTests()
tests += SKSwiftPMWorkspaceTests.__allTests()
tests += SourceKitTests.__allTests()

XCTMain(tests)
222 changes: 222 additions & 0 deletions Tests/SKSwiftPMWorkspaceTests/SwiftPMWorkspaceTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SKSwiftPMWorkspace
import SKCore
import PackageModel
import Basic
import SKTestSupport
import XCTest

final class SwiftPMWorkspaceTests: XCTestCase {
func testBasicSwiftArgs() {
// FIXME: should be possible to use InMemoryFileSystem.
let fs = localFileSystem
let tempDir = try! TemporaryDirectory(removeTreeOnDeinit: true)
try! fs.createFiles(root: tempDir.path, files: [
"pkg/Sources/lib/a.swift": "",
"pkg/Package.swift": """
// swift-tools-version:4.2
import PackageDescription
let package = Package(name: "a", products: [], dependencies: [],
targets: [.target(name: "lib", dependencies: [])])
"""
])
let packageRoot = tempDir.path.appending(component: "pkg")
let tr = ToolchainRegistry.shared
let ws = try! SwiftPMWorkspace(
workspacePath: packageRoot,
toolchainRegistry: tr,
fileSystem: fs)!

let aswift = packageRoot.appending(components: "Sources", "lib", "a.swift")

XCTAssertEqual(ws.buildPath, packageRoot.appending(components: ".build", "debug"))
XCTAssertNotNil(ws.indexStorePath)
let arguments = ws.settings(for: aswift.asURL, language: .swift)!.compilerArguments

check(
"-module-name", "lib", "-incremental", "-emit-dependencies",
"-emit-module", "-emit-module-path", arguments: arguments)
check("-parse-as-library", "-c", arguments: arguments)

check("-target", arguments: arguments) // Only one!
#if os(macOS)
check("-target", "x86_64-apple-macosx10.10", arguments: arguments)
check("-sdk", arguments: arguments)
check("-F", arguments: arguments)
#else
check("-target", "x86_64-unknown-linux", arguments: arguments)
#endif

check("-I", packageRoot.appending(components: ".build", "debug").asString, arguments: arguments)

check(aswift.asString, arguments: arguments)
}

func testMultiFileSwift() {
// FIXME: should be possible to use InMemoryFileSystem.
let fs = localFileSystem
let tempDir = try! TemporaryDirectory(removeTreeOnDeinit: true)
try! fs.createFiles(root: tempDir.path, files: [
"pkg/Sources/lib/a.swift": "",
"pkg/Sources/lib/b.swift": "",
"pkg/Package.swift": """
// swift-tools-version:4.2
import PackageDescription
let package = Package(name: "a", products: [], dependencies: [],
targets: [.target(name: "lib", dependencies: [])])
"""
])
let packageRoot = tempDir.path.appending(component: "pkg")
let tr = ToolchainRegistry.shared
let ws = try! SwiftPMWorkspace(
workspacePath: packageRoot,
toolchainRegistry: tr,
fileSystem: fs)!

let aswift = packageRoot.appending(components: "Sources", "lib", "a.swift")
let bswift = packageRoot.appending(components: "Sources", "lib", "b.swift")

let argumentsA = ws.settings(for: aswift.asURL, language: .swift)!.compilerArguments
check(aswift.asString, arguments: argumentsA)
check(bswift.asString, arguments: argumentsA)
let argumentsB = ws.settings(for: aswift.asURL, language: .swift)!.compilerArguments
check(aswift.asString, arguments: argumentsB)
check(bswift.asString, arguments: argumentsB)
}

func testMultiTargetSwift() {
// FIXME: should be possible to use InMemoryFileSystem.
let fs = localFileSystem
let tempDir = try! TemporaryDirectory(removeTreeOnDeinit: true)
try! fs.createFiles(root: tempDir.path, files: [
"pkg/Sources/libA/a.swift": "",
"pkg/Sources/libB/b.swift": "",
"pkg/Sources/libC/include/libC.h": "",
"pkg/Sources/libC/libC.c": "",
"pkg/Package.swift": """
// swift-tools-version:4.2
import PackageDescription
let package = Package(name: "a", products: [], dependencies: [],
targets: [
.target(name: "libA", dependencies: ["libB", "libC"]),
.target(name: "libB", dependencies: []),
.target(name: "libC", dependencies: []),
])
"""
])
let packageRoot = tempDir.path.appending(component: "pkg")
let tr = ToolchainRegistry.shared
let ws = try! SwiftPMWorkspace(
workspacePath: packageRoot,
toolchainRegistry: tr,
fileSystem: fs)!

let aswift = packageRoot.appending(components: "Sources", "libA", "a.swift")
let bswift = packageRoot.appending(components: "Sources", "libB", "b.swift")
let arguments = ws.settings(for: aswift.asURL, language: .swift)!.compilerArguments
check(aswift.asString, arguments: arguments)
checkNot(bswift.asString, arguments: arguments)
check("-I", packageRoot.appending(components: "Sources", "libC", "include").asString, arguments: arguments)

let argumentsB = ws.settings(for: bswift.asURL, language: .swift)!.compilerArguments
check(bswift.asString, arguments: argumentsB)
checkNot(aswift.asString, arguments: argumentsB)
checkNot("-I", packageRoot.appending(components: "Sources", "libC", "include").asString, arguments: argumentsB)
}

func testBasicCXXArgs() {
// FIXME: should be possible to use InMemoryFileSystem.
let fs = localFileSystem
let tempDir = try! TemporaryDirectory(removeTreeOnDeinit: true)
try! fs.createFiles(root: tempDir.path, files: [
"pkg/Sources/lib/a.cpp": "",
"pkg/Sources/lib/b.cpp": "",
"pkg/Sources/lib/include/a.h": "",
"pkg/Package.swift": """
// swift-tools-version:4.2
import PackageDescription
let package = Package(name: "a", products: [], dependencies: [],
targets: [.target(name: "lib", dependencies: [])],
cxxLanguageStandard: .cxx14)
"""
])
let packageRoot = tempDir.path.appending(component: "pkg")
let tr = ToolchainRegistry.shared
let ws = try! SwiftPMWorkspace(
workspacePath: packageRoot,
toolchainRegistry: tr,
fileSystem: fs)!

let acxx = packageRoot.appending(components: "Sources", "lib", "a.cpp")
let bcxx = packageRoot.appending(components: "Sources", "lib", "b.cpp")
let build = packageRoot.appending(components: ".build", "debug")

XCTAssertEqual(ws.buildPath, build)
XCTAssertNotNil(ws.indexStorePath)
let arguments = ws.settings(for: acxx.asURL, language: .cpp)!.compilerArguments

check("-MD", "-MT", "dependencies",
"-MF", build.appending(components: "lib.build", "a.cpp.d").asString,
arguments: arguments)
check("-std=c++14", arguments: arguments)

checkNot("-arch", arguments: arguments)
check("-target", arguments: arguments) // Only one!
#if os(macOS)
check("-target", "x86_64-apple-macosx10.10", arguments: arguments)
check("-isysroot", arguments: arguments)
check("-F", arguments: arguments)
#else
check("-target", "x86_64-unknown-linux", arguments: arguments)
#endif

check("-I", packageRoot.appending(components: "Sources", "lib", "include").asString, arguments: arguments)
checkNot("-I", build.asString, arguments: arguments)
check("-c", acxx.asString, arguments: arguments)
checkNot(bcxx.asString, arguments: arguments)
check("-o", build.appending(components: "lib.build", "a.cpp.o").asString, arguments: arguments)
}
}

private func checkNot(
_ pattern: String...,
arguments: [String],
file: StaticString = #file,
line: UInt = #line)
{
if let index = arguments.firstIndex(of: pattern) {
XCTFail(
"not-pattern \(pattern) unexpectedly found at \(index) in arguments \(arguments)",
file: file, line: line)
return
}
}

private func check(
_ pattern: String...,
arguments: [String],
file: StaticString = #file,
line: UInt = #line)
{
guard let index = arguments.firstIndex(of: pattern) else {
XCTFail("pattern \(pattern) not found in arguments \(arguments)", file: file, line: line)
return
}

if let index2 = arguments[(index+1)...].firstIndex(of: pattern) {
XCTFail(
"pattern \(pattern) found twice (\(index), \(index2)) in \(arguments)",
file: file, line: line)
}
}
21 changes: 21 additions & 0 deletions Tests/SKSwiftPMWorkspaceTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#if !canImport(ObjectiveC)
import XCTest

extension SwiftPMWorkspaceTests {
// DO NOT MODIFY: This is autogenerated, use:
// `swift test --generate-linuxmain`
// to regenerate.
static let __allTests__SwiftPMWorkspaceTests = [
("testBasicCXXArgs", testBasicCXXArgs),
("testBasicSwiftArgs", testBasicSwiftArgs),
("testMultiFileSwift", testMultiFileSwift),
("testMultiTargetSwift", testMultiTargetSwift),
]
}

public func __allTests() -> [XCTestCaseEntry] {
return [
testCase(SwiftPMWorkspaceTests.__allTests__SwiftPMWorkspaceTests),
]
}
#endif