Skip to content

Commit ff84d87

Browse files
committed
Generate module maps in build dir
1 parent 1866db0 commit ff84d87

File tree

5 files changed

+56
-27
lines changed

5 files changed

+56
-27
lines changed

Sources/Build/Buildable.swift

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,43 @@
99
*/
1010

1111
import PackageType
12+
import struct Utility.Path
1213

1314
protocol Buildable {
1415
var targetName: String { get }
1516
var isTest: Bool { get }
1617
}
1718

19+
extension CModule {
20+
func workingDirectory(prefix: String) -> String {
21+
return Path.join(prefix, "\(c99name).build")
22+
}
23+
}
24+
1825
extension Module: Buildable {
1926
var isTest: Bool {
2027
return self is TestModule
2128
}
2229

23-
var Xcc: [String] {
30+
func XccFlagsForPrefix(prefix: String) -> [String] {
2431
return recursiveDependencies.flatMap { module -> [String] in
25-
if let module = module as? CModule {
32+
if let module = module as? ClangModule {
33+
var moduleMap: String? = nil
34+
35+
if module.moduleMapPath.isFile {
36+
moduleMap = module.moduleMapPath
37+
}
38+
39+
let genModuleMap = Path.join(module.workingDirectory(prefix), module.moduleMap)
40+
if genModuleMap.isFile {
41+
moduleMap = genModuleMap
42+
}
43+
//No module map found, return with no args
44+
if let moduleMap = moduleMap {
45+
return ["-Xcc", "-fmodule-map-file=\(moduleMap)"]
46+
}
47+
return []
48+
} else if let module = module as? CModule {
2649
return ["-Xcc", "-fmodule-map-file=\(module.moduleMapPath)"]
2750
} else {
2851
return []

Sources/Build/Command.compile(ClangModule).swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ import POSIX
1515
//FIXME: Incremental builds
1616

1717
extension Command {
18-
static func compile(clangModule module: ClangModule, externalModules: Set<Module>, configuration conf: Configuration, prefix: String) -> (Command, Command) {
19-
20-
let wd = Path.join(prefix, "\(module.c99name).build")
18+
static func compile(clangModule module: ClangModule, externalModules: Set<Module>, configuration conf: Configuration, prefix: String) throws -> (Command, Command) {
19+
20+
let wd = module.workingDirectory(prefix)
21+
22+
if module.type == .Library {
23+
try module.generateModuleMap(inDir: wd)
24+
}
25+
2126
let mkdir = Command.createDirectory(wd)
2227

2328
let inputs = module.dependencies.map{ $0.targetName } + module.sources.paths + [mkdir.node]

Sources/Build/Command.compile(SwiftModule).swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Utility
1414
extension Command {
1515
static func compile(swiftModule module: SwiftModule, configuration conf: Configuration, prefix: String, otherArgs: [String]) throws -> (Command, [Command]) {
1616

17-
let otherArgs = otherArgs + module.Xcc
17+
let otherArgs = otherArgs + module.XccFlagsForPrefix(prefix)
1818

1919
func cmd(tool: ToolProtocol) -> Command {
2020
return Command(node: module.targetName, tool: tool)

Sources/Build/describe().swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
4040
targets.append(compile, for: module)
4141

4242
case let module as ClangModule:
43-
if module.type == .Library {
44-
try module.generateModuleMap()
45-
}
46-
47-
let (compile, mkdir) = Command.compile(clangModule: module, externalModules: externalModules, configuration: conf, prefix: prefix)
43+
let (compile, mkdir) = try Command.compile(clangModule: module, externalModules: externalModules, configuration: conf, prefix: prefix)
4844
commands.append(compile)
4945
commands.append(mkdir)
5046
targets.main.cmds.append(compile)

Sources/Build/misc.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ func platformArgs() -> [String] {
3030
}
3131

3232
extension CModule {
33+
34+
var moduleMap: String {
35+
return "module.modulemap"
36+
}
37+
3338
var moduleMapPath: String {
34-
return Path.join(path, "module.modulemap")
39+
return Path.join(path, moduleMap)
3540
}
3641
}
3742

@@ -41,7 +46,7 @@ extension ClangModule {
4146
case UnsupportedIncludeLayoutForModule(String)
4247
}
4348

44-
public func generateModuleMap() throws {
49+
public func generateModuleMap(inDir wd: String) throws {
4550

4651
//Return if module map is already present
4752
guard !moduleMapPath.isFile else {
@@ -50,13 +55,9 @@ extension ClangModule {
5055

5156
let includeDir = path
5257

53-
//Generate empty module map if include dir is not present
58+
//Warn and return if no include directory
5459
guard includeDir.isDirectory else {
55-
print("warning: No include directory, generating empty module map")
56-
try POSIX.mkdir(includeDir)
57-
try fopen(moduleMapPath, mode: .Write) { fp in
58-
try fputs("\n", fp)
59-
}
60+
print("warning: No include directory found, a library can not be imported without any public headers.")
6061
return
6162
}
6263

@@ -67,7 +68,7 @@ extension ClangModule {
6768

6869
if dirs.isEmpty {
6970
guard !files.isEmpty else { throw ModuleMapError.UnsupportedIncludeLayoutForModule(name) }
70-
try createModuleMap(.FlatHeaderLayout)
71+
try createModuleMap(inDir: wd, type: .FlatHeaderLayout)
7172
return
7273
}
7374

@@ -77,9 +78,9 @@ extension ClangModule {
7778

7879
let umbrellaHeader = Path.join(moduleHeaderDir, "\(name).h")
7980
if umbrellaHeader.isFile {
80-
try createModuleMap(.HeaderFile)
81+
try createModuleMap(inDir: wd, type: .HeaderFile)
8182
} else {
82-
try createModuleMap(.ModuleNameDir)
83+
try createModuleMap(inDir: wd, type: .ModuleNameDir)
8384
}
8485
}
8586

@@ -89,20 +90,24 @@ extension ClangModule {
8990
case HeaderFile
9091
}
9192

92-
private func createModuleMap(type: UmbrellaType) throws {
93-
let moduleMap = try fopen(moduleMapPath, mode: .Write)
93+
private func createModuleMap(inDir wd: String, type: UmbrellaType) throws {
94+
try POSIX.mkdir(wd)
95+
let moduleMapFile = Path.join(wd, self.moduleMap)
96+
let moduleMap = try fopen(moduleMapFile, mode: .Write)
9497
defer { fclose(moduleMap) }
9598

9699
try fputs("module \(name) {\n", moduleMap)
97100
try fputs(" umbrella ", moduleMap)
98101

99102
switch type {
100103
case .FlatHeaderLayout:
101-
try fputs("\".\"\n", moduleMap)
104+
try fputs("\"\(path)\"\n", moduleMap)
102105
case .ModuleNameDir:
103-
try fputs("\"\(name)\"\n", moduleMap)
106+
let path = Path.join(self.path, name)
107+
try fputs("\"\(path)\"\n", moduleMap)
104108
case .HeaderFile:
105-
try fputs("header \"\(name)/\(name).h\"\n", moduleMap)
109+
let path = Path.join(self.path, name, "\(name).h")
110+
try fputs("header \"\(path)\"\n", moduleMap)
106111

107112
}
108113

0 commit comments

Comments
 (0)