@@ -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 , 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, 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
+ var includeFlags : [ 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 "..."`
@@ -45,32 +39,91 @@ extension Command {
45
39
includeFlag = " -iquote "
46
40
}
47
41
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
42
}
43
+ return args
44
+ }
45
+
46
+ var linkFlags : [ String ] {
47
+ var args : [ String ] = [ ]
48
+ for case let dep as ClangModule in dependencies {
49
+ args += [ " -l \( dep. c99name) " ]
50
+ }
51
+ return args
52
+ }
50
53
54
+ func optimizationFlags( conf: Configuration ) -> [ String ] {
51
55
switch conf {
52
56
case . Debug:
53
- args += [ " -g " , " -O0 " ]
57
+ return [ " -g " , " -O0 " ]
54
58
case . Release:
55
- args += [ " -O2 " ]
59
+ return [ " -O2 " ]
60
+ }
61
+ }
62
+ }
63
+
64
+ private extension Sources {
65
+ func compilePathsForBuildDir( wd: String ) -> [ ( filename: String , source: String , object: String , deps: String ) ] {
66
+ return relativePaths. map { source in
67
+ let path = Path . join ( root, source)
68
+ let object = Path . join ( wd, " \( source) .o " )
69
+ let deps = Path . join ( wd, " \( source) .d " )
70
+ return ( source, path, object, deps)
56
71
}
72
+ }
73
+ }
74
+
75
+ extension Command {
76
+ static func compile( clangModule module: ClangModule , configuration conf: Configuration , prefix: String ) -> ( [ Command ] , Command ) {
77
+
78
+ let wd = Path . join ( prefix, " \( module. c99name) .build " )
79
+ let mkdir = Command . createDirectory ( wd)
80
+
81
+ ///------------------------------ Compile -----------------------------------------
82
+ var compileCommands = [ Command] ( )
83
+ let dependencies = module. dependencies. map { $0. targetName }
84
+ let basicArgs = module. basicArgs + module. includeFlags + module. optimizationFlags ( conf)
85
+ for path in module. sources. compilePathsForBuildDir ( wd) {
86
+ var args = basicArgs
87
+ args += [ " -MMD " , " -MT " , " dependencies " , " -MF " , path. deps]
88
+ args += [ " -c " , path. source, " -o " , path. object]
89
+
90
+ let node = " < \( module. name) . \( path. filename) > "
91
+
92
+ let clang = ClangTool ( desc: " Compiling \( module. name) \( path. filename) " ,
93
+ inputs: dependencies + [ path. source, mkdir. node] ,
94
+ outputs: [ path. object, node] ,
95
+ args: args,
96
+ deps: path. deps)
97
+
98
+ let command = Command ( node: node, tool: clang)
99
+
100
+ compileCommands. append ( command)
101
+ }
102
+
103
+
104
+ ///FIXME: This probably doesn't belong here
105
+ ///------------------------------ Product -----------------------------------------
106
+
107
+ var args = module. basicArgs
108
+ args += module. optimizationFlags ( conf)
109
+ args += [ " -L \( prefix) " ]
110
+ args += module. linkFlags
111
+ args += module. sources. compilePathsForBuildDir ( wd) . map { $0. object}
57
112
58
- args += module. sources. paths
59
-
60
113
if module. type == . Library {
61
114
args += [ " -shared " ]
62
115
}
63
-
64
- args += [ " -o " , productPath]
65
116
66
- let clang = ShellTool (
67
- description: " Compiling \( module. name) " ,
68
- inputs: inputs,
69
- outputs: [ productPath, module. targetName] ,
70
- args: [ Toolchain . clang] + args)
117
+ let productPath = Path . join ( prefix, module. type == . Library ? " lib \( module. c99name) .so " : module. c99name)
118
+ args += [ " -o " , productPath]
71
119
120
+ let clang = ClangTool ( desc: " Linking \( module. name) " ,
121
+ inputs: dependencies + compileCommands. map { $0. node} + [ mkdir. node] ,
122
+ outputs: [ productPath, module. targetName] ,
123
+ args: args,
124
+ deps: nil )
72
125
let command = Command ( node: module. targetName, tool: clang)
73
126
74
- return ( command, mkdir)
127
+ return ( compileCommands + [ command] , mkdir)
75
128
}
76
129
}
0 commit comments