@@ -12,25 +12,19 @@ import PackageType
12
12
import Utility
13
13
import POSIX
14
14
15
- //FIXME: Incremental builds
16
-
17
- extension Command {
18
- static func compile( clangModule module: ClangModule , externalModules: Set < Module > , configuration conf: Configuration , prefix: String , CC: 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, module. type == . Library ? " lib \( module. c99name) .so " : module. c99name)
25
-
15
+ private extension ClangModule {
16
+ var basicArgs : [ String ] {
26
17
var args : [ String ] = [ ]
27
- #if os(Linux)
28
- args += [ " -fPIC " ]
29
- #endif
30
- args += [ " -fmodules " , " -fmodule-name= \( module. name) " ]
31
- args += [ " -L \( prefix) " ]
18
+ #if os(Linux)
19
+ args += [ " -fPIC " ]
20
+ #endif
21
+ args += [ " -fmodules " , " -fmodule-name= \( name) " ]
22
+ return args
23
+ }
32
24
33
- for case let dep as ClangModule in module. dependencies {
25
+ func includeFlagsWithExternalModules( externalModules: Set < Module > ) -> [ String ] {
26
+ var args : [ String ] = [ ]
27
+ for case let dep as ClangModule in dependencies {
34
28
let includeFlag : String
35
29
//add `-iquote` argument to the include directory of every target in the package in the
36
30
//transitive closure of the target being built allowing the use of `#include "..."`
@@ -39,32 +33,89 @@ extension Command {
39
33
40
34
includeFlag = externalModules. contains ( dep) ? " -I " : " -iquote "
41
35
args += [ includeFlag, dep. path]
42
- args += [ " -l \( dep. c99name) " ] //FIXME: giving path to other module's -fmodule-map-file is not linking that module
43
36
}
37
+ return args
38
+ }
39
+
40
+ var linkFlags : [ String ] {
41
+ var args : [ String ] = [ ]
42
+ for case let dep as ClangModule in dependencies {
43
+ args += [ " -l \( dep. c99name) " ]
44
+ }
45
+ return args
46
+ }
44
47
48
+ func optimizationFlags( conf: Configuration ) -> [ String ] {
45
49
switch conf {
46
50
case . Debug:
47
- args += [ " -g " , " -O0 " ]
51
+ return [ " -g " , " -O0 " ]
48
52
case . Release:
49
- args += [ " -O2 " ]
53
+ return [ " -O2 " ]
50
54
}
55
+ }
56
+ }
57
+
58
+ private extension Sources {
59
+ func compilePathsForBuildDir( wd: String ) -> [ ( filename: String , source: String , object: String , deps: String ) ] {
60
+ return relativePaths. map { source in
61
+ let path = Path . join ( root, source)
62
+ let object = Path . join ( wd, " \( source) .o " )
63
+ let deps = Path . join ( wd, " \( source) .d " )
64
+ return ( source, path, object, deps)
65
+ }
66
+ }
67
+ }
68
+
69
+ extension Command {
70
+ static func compile( clangModule module: ClangModule , externalModules: Set < Module > , configuration conf: Configuration , prefix: String , CC: String ) -> ( [ Command ] , Command ) {
71
+
72
+ let wd = Path . join ( prefix, " \( module. c99name) .build " )
73
+ let mkdir = Command . createDirectory ( wd)
74
+
75
+ ///------------------------------ Compile -----------------------------------------
76
+ var compileCommands = [ Command] ( )
77
+ let dependencies = module. dependencies. map { $0. targetName }
78
+ let basicArgs = module. basicArgs + module. includeFlagsWithExternalModules ( externalModules) + module. optimizationFlags ( conf)
79
+ for path in module. sources. compilePathsForBuildDir ( wd) {
80
+ var args = basicArgs
81
+ args += [ " -MD " , " -MT " , " dependencies " , " -MF " , path. deps]
82
+ args += [ " -c " , path. source, " -o " , path. object]
83
+
84
+ let clang = ClangTool ( desc: " Compiling \( module. name) \( path. filename) " ,
85
+ inputs: dependencies + [ path. source, mkdir. node] ,
86
+ outputs: [ path. object] ,
87
+ args: [ CC] + args,
88
+ deps: path. deps)
89
+
90
+ let command = Command ( node: path. object, tool: clang)
91
+
92
+ compileCommands. append ( command)
93
+ }
94
+
95
+
96
+ ///FIXME: This probably doesn't belong here
97
+ ///------------------------------ Product -----------------------------------------
98
+
99
+ var args = module. basicArgs
100
+ args += module. optimizationFlags ( conf)
101
+ args += [ " -L \( prefix) " ]
102
+ args += module. linkFlags
103
+ args += module. sources. compilePathsForBuildDir ( wd) . map { $0. object}
51
104
52
- args += module. sources. paths
53
-
54
105
if module. type == . Library {
55
106
args += [ " -shared " ]
56
107
}
57
-
58
- args += [ " -o " , productPath]
59
108
60
- let clang = ShellTool (
61
- description: " Compiling \( module. name) " ,
62
- inputs: inputs,
63
- outputs: [ productPath, module. targetName] ,
64
- args: [ CC] + args)
65
-
66
- let command = Command ( node: module. targetName, tool: clang)
109
+ let productPath = Path . join ( prefix, module. type == . Library ? " lib \( module. c99name) .so " : module. c99name)
110
+ args += [ " -o " , productPath]
111
+
112
+ let shell = ShellTool ( description: " Linking \( module. name) " ,
113
+ inputs: dependencies + compileCommands. map { $0. node} + [ mkdir. node] ,
114
+ outputs: [ productPath, module. targetName] ,
115
+ args: [ CC] + args)
116
+
117
+ let command = Command ( node: module. targetName, tool: shell)
67
118
68
- return ( command, mkdir)
119
+ return ( compileCommands + [ command] , mkdir)
69
120
}
70
121
}
0 commit comments