@@ -127,7 +127,11 @@ public final class SwiftModuleBuildDescription {
127
127
128
128
var modulesPath : AbsolutePath {
129
129
let suffix = self . buildParameters. suffix
130
- return self . buildParameters. buildPath. appending ( component: " Modules \( suffix) " )
130
+ var path = self . buildParameters. buildPath. appending ( component: " Modules \( suffix) " )
131
+ if self . windowsTargetType == . exporting {
132
+ path = path. appending ( " exporting " )
133
+ }
134
+ return path
131
135
}
132
136
133
137
/// The path to the swiftmodule file after compilation.
@@ -264,6 +268,18 @@ public final class SwiftModuleBuildDescription {
264
268
/// Whether to disable sandboxing (e.g. for macros).
265
269
private let shouldDisableSandbox : Bool
266
270
271
+ /// For Windows we default to static objects and create copies for objects
272
+ /// That export symbols. This will allow consumers to select which one they want.
273
+ public enum WindowsTargetType {
274
+ case `static`
275
+ case exporting
276
+ }
277
+ /// The target type. Leave nil for non-Windows behavior.
278
+ public let windowsTargetType : WindowsTargetType ?
279
+
280
+ /// The corresponding target symbols exporting (not -static)
281
+ public private( set) var windowsExportTarget : SwiftModuleBuildDescription ? = nil
282
+
267
283
/// Create a new target description with target and build parameters.
268
284
init (
269
285
package : ResolvedPackage ,
@@ -319,6 +335,14 @@ public final class SwiftModuleBuildDescription {
319
335
observabilityScope: observabilityScope
320
336
)
321
337
338
+ if buildParameters. triple. isWindows ( ) {
339
+ // Default to static and add another target for DLLs
340
+ self . windowsTargetType = . static
341
+ self . windowsExportTarget = . init( windowsExportFor: self )
342
+ } else {
343
+ self . windowsTargetType = nil
344
+ }
345
+
322
346
if self . shouldEmitObjCCompatibilityHeader {
323
347
self . moduleMap = try self . generateModuleMap ( )
324
348
}
@@ -340,6 +364,31 @@ public final class SwiftModuleBuildDescription {
340
364
try self . generateTestObservation ( )
341
365
}
342
366
367
+ /// Private init to set up exporting version of this module
368
+ private init ( windowsExportFor parent: SwiftModuleBuildDescription ) {
369
+ self . windowsTargetType = . exporting
370
+ self . windowsExportTarget = nil
371
+ self . tempsPath = parent. tempsPath. appending ( " exporting " )
372
+
373
+ // The rest of these are just copied from the parent
374
+ self . package = parent. package
375
+ self . target = parent. target
376
+ self . swiftTarget = parent. swiftTarget
377
+ self . toolsVersion = parent. toolsVersion
378
+ self . buildParameters = parent. buildParameters
379
+ self . macroBuildParameters = parent. macroBuildParameters
380
+ self . derivedSources = parent. derivedSources
381
+ self . pluginDerivedSources = parent. pluginDerivedSources
382
+ self . pluginDerivedResources = parent. pluginDerivedResources
383
+ self . testTargetRole = parent. testTargetRole
384
+ self . fileSystem = parent. fileSystem
385
+ self . buildToolPluginInvocationResults = parent. buildToolPluginInvocationResults
386
+ self . prebuildCommandResults = parent. prebuildCommandResults
387
+ self . observabilityScope = parent. observabilityScope
388
+ self . shouldGenerateTestObservation = parent. shouldGenerateTestObservation
389
+ self . shouldDisableSandbox = parent. shouldDisableSandbox
390
+ }
391
+
343
392
private func generateTestObservation( ) throws {
344
393
guard target. type == . test else {
345
394
return
@@ -519,6 +568,18 @@ public final class SwiftModuleBuildDescription {
519
568
args += [ " -parse-as-library " ]
520
569
}
521
570
571
+ switch self . windowsTargetType {
572
+ case . static:
573
+ // Static on Windows
574
+ args += [ " -static " ]
575
+ case . exporting:
576
+ // Add the static versions to the include path
577
+ // FIXME: need to be much more deliberate about what we're including
578
+ args += [ " -I " , self . modulesPath. parentDirectory. pathString]
579
+ case . none:
580
+ break
581
+ }
582
+
522
583
// Only add the build path to the framework search path if there are binary frameworks to link against.
523
584
if !self . libraryBinaryPaths. isEmpty {
524
585
args += [ " -F " , self . buildParameters. buildPath. pathString]
0 commit comments