Skip to content

Commit df26dac

Browse files
committed
Merge `static products'
2 parents 9f62a2b + 65ebb86 commit df26dac

17 files changed

+569
-476
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class Foo {
2+
var bar: Int = 0
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import PackageDescription
2+
3+
let package = Package(name: "Foo")
4+
5+
let archive = Product(name: "Bar", type: .Library(.Static), modules: "Foo")
6+
7+
products.append(archive)

Sources/Build/Buildable.swift

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import PackageType
12+
13+
protocol Buildable {
14+
var targetName: String { get }
15+
var isTest: Bool { get }
16+
}
17+
18+
extension Module: Buildable {
19+
var isTest: Bool {
20+
return self is TestModule
21+
}
22+
23+
var Xcc: [String] {
24+
return recursiveDependencies.flatMap { module -> [String] in
25+
if let module = module as? CModule {
26+
return ["-Xcc", "-fmodule-map-file=\(module.moduleMapPath)"]
27+
} else {
28+
return []
29+
}
30+
}
31+
}
32+
33+
var targetName: String {
34+
return "<\(name).module>"
35+
}
36+
}
37+
38+
extension Product: Buildable {
39+
var isTest: Bool {
40+
if case .Test = type {
41+
return true
42+
}
43+
return false
44+
}
45+
46+
var targetName: String {
47+
switch type {
48+
case .Library(.Dynamic):
49+
return "<\(name).dylib>"
50+
case .Test:
51+
return "<\(name).test>"
52+
case .Library(.Static):
53+
return "<\(name).a>"
54+
case .Executable:
55+
return "<\(name).exe>"
56+
}
57+
}
58+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import PackageType
12+
import Utility
13+
import POSIX
14+
15+
//FIXME: Incremental builds
16+
17+
extension Command {
18+
static func compile(clangModule module: ClangModule, configuration conf: Configuration, prefix: String) -> (Command, Command) {
19+
20+
let wd = Path.join(prefix, "\(module.c99name).build")
21+
let mkdir = Command.createDirectory(wd)
22+
23+
let inputs = module.dependencies.map{ $0.targetName } + module.sources.paths + [mkdir.node]
24+
let productPath = Path.join(prefix, "lib\(module.c99name).so")
25+
26+
var args: [String] = []
27+
#if os(Linux)
28+
args += ["-fPIC"]
29+
#endif
30+
args += ["-fmodules", "-fmodule-name=\(module.name)"]
31+
args += ["-L\(prefix)"]
32+
33+
for case let dep as ClangModule in module.dependencies {
34+
let includeFlag: String
35+
//add `-iquote` argument to the include directory of every target in the package in the
36+
//transitive closure of the target being built allowing the use of `#include "..."`
37+
//add `-I` argument to the include directory of every target outside the package in the
38+
//transitive closure of the target being built allowing the use of `#include <...>`
39+
//FIXME: To detect external deps we're checking if their path's parent.parent directory
40+
//is `Packages` as external deps will get copied to `Packages` dir. There should be a
41+
//better way to do this.
42+
if dep.path.parentDirectory.parentDirectory.basename == "Packages" {
43+
includeFlag = "-I"
44+
} else {
45+
includeFlag = "-iquote"
46+
}
47+
args += [includeFlag, dep.path]
48+
args += ["-l\(dep.c99name)"] //FIXME: giving path to other module's -fmodule-map-file is not linking that module
49+
}
50+
51+
switch conf {
52+
case .Debug:
53+
args += ["-g", "-O0"]
54+
case .Release:
55+
args += ["-O2"]
56+
}
57+
58+
args += module.sources.paths
59+
args += ["-shared", "-o", productPath]
60+
61+
let clang = ShellTool(
62+
description: "Compiling \(module.name)",
63+
inputs: inputs,
64+
outputs: [productPath, module.targetName],
65+
args: [Toolchain.clang] + args)
66+
67+
let command = Command(node: module.targetName, tool: clang)
68+
69+
return (command, mkdir)
70+
}
71+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import PackageType
12+
import Utility
13+
14+
extension Command {
15+
static func compile(swiftModule module: SwiftModule, configuration conf: Configuration, prefix: String, otherArgs: [String]) throws -> (Command, [Command]) {
16+
17+
let otherArgs = otherArgs + module.Xcc
18+
19+
func cmd(tool: ToolProtocol) -> Command {
20+
return Command(node: module.targetName, tool: tool)
21+
}
22+
23+
switch conf {
24+
case .Debug:
25+
var args = ["-j8","-Onone","-g","-D","SWIFT_PACKAGE", "-enable-testing"]
26+
27+
#if os(OSX)
28+
if let platformPath = Toolchain.platformPath {
29+
let path = Path.join(platformPath, "Developer/Library/Frameworks")
30+
args += ["-F", path]
31+
} else {
32+
throw Error.InvalidPlatformPath
33+
}
34+
#endif
35+
let tool = SwiftcTool(module: module, prefix: prefix, otherArgs: args + otherArgs)
36+
let mkdirs = Set(tool.objects.map{ $0.parentDirectory }).map(Command.createDirectory)
37+
return (cmd(tool), mkdirs)
38+
39+
case .Release:
40+
let inputs = module.dependencies.map{ $0.targetName } + module.sources.paths
41+
var args = ["-c", "-emit-module", "-D", "SWIFT_PACKAGE", "-O", "-whole-module-optimization", "-I", prefix] + otherArgs
42+
let productPath = Path.join(prefix, "\(module.c99name).o")
43+
44+
if module.type == .Library {
45+
args += ["-parse-as-library"]
46+
}
47+
48+
let tool = ShellTool(
49+
description: "Compiling \(module.name)",
50+
inputs: inputs,
51+
outputs: [productPath, module.targetName],
52+
args: [Toolchain.swiftc, "-o", productPath] + args + module.sources.paths + otherArgs)
53+
54+
return (cmd(tool), [])
55+
}
56+
}
57+
}

Sources/Build/Command.link().swift

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import func POSIX.mkdir
12+
import PackageType
13+
import Utility
14+
15+
16+
//FIXME messy :/
17+
18+
19+
extension Command {
20+
static func link(product: Product, configuration conf: Configuration, prefix: String, otherArgs: [String]) throws -> Command {
21+
22+
let objects: [String]
23+
switch conf {
24+
case .Release:
25+
objects = product.buildables.map{ Path.join(prefix, "\($0.c99name).o") }
26+
case .Debug:
27+
objects = product.buildables.flatMap{ return SwiftcTool(module: $0, prefix: prefix, otherArgs: []).objects }
28+
}
29+
30+
let outpath = Path.join(prefix, product.outname)
31+
32+
var args: [String]
33+
switch product.type {
34+
case .Library(.Dynamic), .Executable, .Test:
35+
args = [Toolchain.swiftc] + otherArgs
36+
37+
if conf == .Debug {
38+
args += ["-g"]
39+
}
40+
args += ["-L\(prefix)"]
41+
args += ["-o", outpath]
42+
43+
case .Library(.Static):
44+
//FIXME proper static archive llbuild tool
45+
//NOTE HACK this works because llbuild runs it with via a shell
46+
//FIXME this is coincidental, do properly
47+
args = ["rm", "-f", outpath, "&&", "ar", "cr"]
48+
}
49+
50+
let inputs = product.modules.flatMap { module -> [String] in
51+
switch conf {
52+
case .Debug:
53+
let tool = SwiftcTool(module: module, prefix: prefix, otherArgs: [])
54+
// must return tool’s outputs and inputs as shell nodes don't calculate more than that
55+
return tool.inputs + tool.outputs
56+
case .Release:
57+
return objects
58+
}
59+
}
60+
61+
switch product.type {
62+
case .Library(.Static):
63+
args.append(outpath)
64+
case .Test:
65+
#if os(OSX)
66+
args += ["-Xlinker", "-bundle"]
67+
68+
if let platformPath = Toolchain.platformPath {
69+
let path = Path.join(platformPath, "Developer/Library/Frameworks")
70+
args += ["-F", path]
71+
} else {
72+
throw Error.InvalidPlatformPath
73+
}
74+
75+
// TODO should be llbuild rules∫
76+
if conf == .Debug {
77+
try mkdir(outpath.parentDirectory)
78+
try fopen(outpath.parentDirectory.parentDirectory, "Info.plist", mode: .Write) { fp in
79+
try fputs(product.Info.plist, fp)
80+
}
81+
}
82+
#else
83+
// HACK: To get a path to LinuxMain.swift, we just grab the
84+
// parent directory of the first test module we can find.
85+
let firstTestModule = product.modules.flatMap{ $0 as? TestModule }.first!
86+
let testDirectory = firstTestModule.sources.root.parentDirectory
87+
let main = Path.join(testDirectory, "LinuxMain.swift")
88+
args.append(main)
89+
for module in product.modules {
90+
args += module.Xcc
91+
}
92+
args.append("-emit-executable")
93+
args += ["-I", prefix]
94+
#endif
95+
case .Library(.Dynamic):
96+
args.append("-emit-library")
97+
case .Executable:
98+
args.append("-emit-executable")
99+
}
100+
101+
args += objects
102+
103+
if case .Library(.Static) = product.type {
104+
//HACK we need to be executed passed-through to the shell
105+
// otherwise we cannot do the rm -f first
106+
//FIXME make a proper static archive tool for llbuild
107+
args = [args.joined(separator: " ")] //TODO escape!
108+
}
109+
110+
let shell = ShellTool(
111+
description: "Linking \(outpath.prettyPath)",
112+
inputs: inputs,
113+
outputs: [product.targetName, outpath],
114+
args: args)
115+
116+
return Command(node: product.targetName, tool: shell)
117+
}
118+
}
119+
120+
extension Product {
121+
private var buildables: [SwiftModule] {
122+
return recursiveDependencies(modules.map{$0}).flatMap{ $0 as? SwiftModule }
123+
}
124+
}

Sources/Build/Command.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 - 2016 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
struct Command {
12+
let node: String
13+
let tool: ToolProtocol
14+
15+
static func createDirectory(path: String) -> Command {
16+
return Command(node: path, tool: MkdirTool(path: path))
17+
}
18+
}

Sources/Build/IncrementalNode.swift

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)