Skip to content

Commit c47c6b8

Browse files
committed
Update modulemap generation logic, add more tests
these are the updated cases for generating modulemaps: 1. Look for include/foo/foo.h, if so, use umbrella header and error if there are any other dirs or headers outside of there 2. Look for include/foo.h, if so, use umbrella header and error if there are any other dirs outside of there 3. All other cases, just use umbrella dir and don't bother to diagnose anything else
1 parent 0b8e728 commit c47c6b8

File tree

8 files changed

+49
-41
lines changed

8 files changed

+49
-41
lines changed

Fixtures/ClangModules/ModuleMapGenerationCases/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import PackageDescription
33
let package = Package(
44
name: "ModuleMapGenerationCases",
55
targets: [
6-
Target(name: "Baz", dependencies: ["FlatInclude", "UmbrellaHeader", "UmbellaModuleNameInclude"])]
6+
Target(name: "Baz", dependencies: ["FlatInclude", "UmbrellaHeader", "UmbellaModuleNameInclude", "UmbrellaHeaderFlat"])]
77
)
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import UmbellaModuleNameInclude
22
import FlatInclude
33
import UmbrellaHeader
4+
import UmbrellaHeaderFlat
45

56
let _ = foo()
67
let _ = bar()
7-
let _ = jaz()
8+
let _ = jaz()
9+
let _ = umbrellaHeaderFlat()

Fixtures/ClangModules/ModuleMapGenerationCases/Sources/FlatInclude/FlatInclude.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "include/FlatInclude.h"
1+
#include "include/FlatIncludeHeader.h"
22

33
int bar() {
44
int a = 6;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "include/UmbrellaHeaderFlat.h"
2+
3+
int umbrellaHeaderFlat() {
4+
int a = 5;
5+
int b = a;
6+
a = b;
7+
return a;
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int umbrellaHeaderFlat();

Sources/Build/Command.link().swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ extension Command {
8181
let main = Path.join(testDirectory, "LinuxMain.swift")
8282
args.append(main)
8383
for module in product.modules {
84-
args += module.Xcc
84+
args += module.XccFlags(prefix)
8585
}
8686
args.append("-emit-executable")
8787
args += ["-I", prefix]

Sources/Build/misc.swift

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -71,44 +71,45 @@ extension ClangModule {
7171

7272
let files = walked.filter{$0.isFile && $0.hasSuffix(".h")}
7373
let dirs = walked.filter{$0.isDirectory}
74-
75-
///There are three possible cases for which we will generate modulemaps:
76-
///Flat includes dir with only header files, in that case we generate
77-
/// `umbrella "path/to/includes/"`
78-
///Module name dir is the only dir in includes, in that case we generate
79-
/// `umbrella header "path/to/includes/modulename/modulename.h"` if there is a `modulename.h`
80-
///inside that directory, otherwise we generate
81-
/// `umbrella "path/to/includes/modulename"`
82-
83-
if dirs.isEmpty {
84-
guard !files.isEmpty else { throw ModuleMapError.UnsupportedIncludeLayoutForModule(name) }
85-
try createModuleMap(inDir: wd, type: .FlatHeaderLayout)
74+
75+
///We generate modulemap for a C module `foo` if:
76+
///* `umbrella header "path/to/include/foo/foo.h"` exists and `foo` is the only
77+
/// directory under include directory
78+
///* `umbrella header "path/to/include/foo.h"` exists and include contains no other
79+
/// directory
80+
///* `umbrella "path/to/include"` in all other cases
81+
82+
let umbrellaHeaderFlat = Path.join(includeDir, "\(c99name).h")
83+
if umbrellaHeaderFlat.isFile {
84+
guard dirs.isEmpty else { throw ModuleMapError.UnsupportedIncludeLayoutForModule(name) }
85+
try createModuleMap(inDir: wd, type: .Header(umbrellaHeaderFlat))
8686
return
8787
}
88-
89-
guard let moduleHeaderDir = dirs.first where moduleHeaderDir.basename == c99name && files.isEmpty else {
90-
throw ModuleMapError.UnsupportedIncludeLayoutForModule(name)
88+
diagnoseInvalidUmbrellaHeader(includeDir)
89+
90+
let umbrellaHeader = Path.join(includeDir, c99name, "\(c99name).h")
91+
if umbrellaHeader.isFile {
92+
guard dirs.count == 1 && files.isEmpty else { throw ModuleMapError.UnsupportedIncludeLayoutForModule(name) }
93+
try createModuleMap(inDir: wd, type: .Header(umbrellaHeader))
94+
return
9195
}
92-
93-
let umbrellaHeader = Path.join(moduleHeaderDir, "\(c99name).h")
94-
95-
///warn user if in case module name and c99name are different and there a `name.h` umbrella header
96-
let invalidUmbrellaHeader = Path.join(moduleHeaderDir, "\(name).h")
96+
diagnoseInvalidUmbrellaHeader(Path.join(includeDir, c99name))
97+
98+
try createModuleMap(inDir: wd, type: .Directory(includeDir))
99+
}
100+
101+
///warn user if in case module name and c99name are different and there a `name.h` umbrella header
102+
private func diagnoseInvalidUmbrellaHeader(path: String) {
103+
let umbrellaHeader = Path.join(path, "\(c99name).h")
104+
let invalidUmbrellaHeader = Path.join(path, "\(name).h")
97105
if c99name != name && invalidUmbrellaHeader.isFile {
98106
print("warning: \(invalidUmbrellaHeader) should be renamed to \(umbrellaHeader) to be used as an umbrella header")
99107
}
100-
101-
if umbrellaHeader.isFile {
102-
try createModuleMap(inDir: wd, type: .HeaderFile)
103-
} else {
104-
try createModuleMap(inDir: wd, type: .ModuleNameDir)
105-
}
106108
}
107-
109+
108110
private enum UmbrellaType {
109-
case FlatHeaderLayout
110-
case ModuleNameDir
111-
case HeaderFile
111+
case Header(String)
112+
case Directory(String)
112113
}
113114

114115
private func createModuleMap(inDir wd: String, type: UmbrellaType) throws {
@@ -119,14 +120,10 @@ extension ClangModule {
119120

120121
var output = "module \(c99name) {\n"
121122
switch type {
122-
case .FlatHeaderLayout:
123-
output += " umbrella \"\(path)\"\n"
124-
case .ModuleNameDir:
125-
let path = Path.join(self.path, c99name)
123+
case .Header(let header):
124+
output += " umbrella header \"\(header)\"\n"
125+
case .Directory(let path):
126126
output += " umbrella \"\(path)\"\n"
127-
case .HeaderFile:
128-
let path = Path.join(self.path, c99name, "\(c99name).h")
129-
output += " umbrella header \"\(path)\"\n"
130127
}
131128
output += " link \"\(c99name)\"\n"
132129
output += " export *\n"

0 commit comments

Comments
 (0)