@@ -33,7 +33,7 @@ open class CompileSwiftTask @Inject constructor(
33
33
@get:Internal
34
34
internal val targetDir: File
35
35
get() {
36
- return project.buildDir.resolve (" ${EXTENSION_NAME } /$cinteropName /$compileTarget " )
36
+ return project.layout.buildDirectory.file (" ${EXTENSION_NAME } /$cinteropName /$compileTarget " ).get().asFile
37
37
}
38
38
39
39
@get:OutputDirectory
@@ -96,15 +96,21 @@ open class CompileSwiftTask @Inject constructor(
96
96
val sourceFilePathReplacements = mapOf (
97
97
buildDir().absolutePath to pathProperty.get().absolutePath
98
98
)
99
+ val extraArgs = if (xcodeVersion >= 15 && compileTarget in SDKLESS_TARGETS ) {
100
+ additionalSysrootArgs()
101
+ } else {
102
+ emptyList()
103
+ }
104
+ val args = generateBuildArgs() + extraArgs
105
+
106
+ logger.info(" -- Running swift build --" )
107
+ logger.info(" Working directory: $swiftBuildDir " )
108
+ logger.info(" xcrun ${args.joinToString(" " )} " )
109
+
99
110
project.exec {
100
111
it.executable = " xcrun"
101
112
it.workingDir = swiftBuildDir
102
- val extraArgs = if (xcodeVersion >= 15 && compileTarget in SDKLESS_TARGETS ) {
103
- additionalSysrootArgs()
104
- } else {
105
- emptyList()
106
- }
107
- it.args = generateBuildArgs() + extraArgs
113
+ it.args = args
108
114
it.standardOutput = StringReplacingOutputStream (
109
115
delegate = System .out ,
110
116
replacements = sourceFilePathReplacements
@@ -115,42 +121,43 @@ open class CompileSwiftTask @Inject constructor(
115
121
)
116
122
}
117
123
124
+ val releaseBuildPath = File (swiftBuildDir, " .build/${compileTarget.arch()} -apple-macosx/release" )
125
+
118
126
return SwiftBuildResult (
119
- libPath = File (
120
- swiftBuildDir,
121
- " .build/${compileTarget.arch()} -apple-macosx/release/lib${cinteropName} .a"
122
- ),
123
- headerPath = File (
124
- swiftBuildDir,
125
- " .build/${compileTarget.arch()} -apple-macosx/release/$cinteropName .build/$cinteropName -Swift.h"
126
- )
127
+ libPath = File (releaseBuildPath, " lib${cinteropName} .a" ),
128
+ headerPath = File (releaseBuildPath, " $cinteropName .build/$cinteropName -Swift.h" )
127
129
)
128
130
}
129
131
130
- private fun generateBuildArgs (): List <String > = listOf (
131
- " swift" ,
132
- " build" ,
133
- " --arch" ,
134
- compileTarget.arch(),
135
- " -c" ,
136
- " release" ,
137
- " -Xswiftc" ,
138
- " -sdk" ,
139
- " -Xswiftc" ,
140
- readSdkPath(),
141
- " -Xswiftc" ,
142
- " -target" ,
143
- " -Xswiftc" ,
144
- " ${compileTarget.archPrefix()} -apple-${operatingSystem(compileTarget)} .0${compileTarget.simulatorSuffix()} " ,
145
- )
132
+ private fun generateBuildArgs (): List <String > {
133
+ val sdkPath = readSdkPath()
134
+ val baseArgs = " swift build --arch ${compileTarget.arch()} -c release" .split(" " )
135
+
136
+ val xcrunArgs = listOf (
137
+ " -sdk" ,
138
+ sdkPath,
139
+ " -target" ,
140
+ compileTarget.asSwiftcTarget(compileTarget.operatingSystem()),
141
+ ).asSwiftcArgs()
142
+
143
+ return baseArgs + xcrunArgs
144
+ }
146
145
147
146
/* * Workaround for bug in toolchain where the sdk path (via `swiftc -sdk` flag) is not propagated to clang. */
148
- private fun additionalSysrootArgs (): List <String > = listOf (
149
- " -Xcc" ,
150
- " -isysroot" ,
151
- " -Xcc" ,
152
- readSdkPath(),
153
- )
147
+ private fun additionalSysrootArgs (): List <String > =
148
+ listOf (
149
+ " -isysroot" ,
150
+ readSdkPath(),
151
+ ).asCcArgs()
152
+
153
+ private fun List<String>.asSwiftcArgs () = asBuildToolArgs(" swiftc" )
154
+ private fun List<String>.asCcArgs () = asBuildToolArgs(" cc" )
155
+
156
+ private fun List<String>.asBuildToolArgs (tool : String ): List <String > {
157
+ return this .flatMap {
158
+ listOf (" -X$tool " , it)
159
+ }
160
+ }
154
161
155
162
private fun readSdkPath (): String {
156
163
val stdout = ByteArrayOutputStream ()
@@ -209,22 +216,41 @@ open class CompileSwiftTask @Inject constructor(
209
216
if (xcodeVersion >= 15 ) compileTarget.linkerPlatformVersionName()
210
217
else compileTarget.linkerMinOsVersionName()
211
218
219
+ val modulePath = headerPath.parentFile.absolutePath
220
+
221
+ val basicLinkerOpts = listOf (
222
+ " -L/usr/lib/swift" ,
223
+ " -$linkerPlatformVersion " ,
224
+ " ${minOs(compileTarget)} .0" ,
225
+ " ${minOs(compileTarget)} .0" ,
226
+ " -L${xcodePath} /Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/${compileTarget.os()} "
227
+ )
228
+
229
+ val linkerOpts = basicLinkerOpts.joinToString(" " )
230
+
212
231
val content = """
213
232
package = $packageName
214
233
language = Objective-C
215
- headers = ${headerPath.absolutePath}
234
+ modules = $cinteropName
216
235
217
236
# md5 ${libPath.md5()}
218
237
staticLibraries = ${libPath.name}
219
238
libraryPaths = ${libPath.parentFile.absolutePath}
220
239
221
- linkerOpts = -L/usr/lib/swift -$linkerPlatformVersion ${minOs(compileTarget)} .0 ${minOs(compileTarget)} .0 -L${xcodePath} /Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/${compileTarget.os()}
240
+ compilerOpts = -fmodules -I$modulePath
241
+ linkerOpts = $linkerOpts
222
242
""" .trimIndent()
243
+
244
+ logger.info(" --- Generated cinterop def file for $cinteropName ---" )
245
+ logger.info(" --- cinterop def ---" )
246
+ logger.info(content)
247
+ logger.info(" ---/ cinterop def /---" )
248
+
223
249
defFile.create(content)
224
250
}
225
251
226
- private fun operatingSystem (compileTarget : CompileTarget ): String =
227
- when (compileTarget ) {
252
+ private fun CompileTarget. operatingSystem (): String =
253
+ when (this ) {
228
254
CompileTarget .iosX64, CompileTarget .iosArm64, CompileTarget .iosSimulatorArm64 -> " ios$minIos "
229
255
CompileTarget .watchosX64, CompileTarget .watchosArm64, CompileTarget .watchosSimulatorArm64 -> " watchos$minWatchos "
230
256
CompileTarget .tvosX64, CompileTarget .tvosArm64, CompileTarget .tvosSimulatorArm64 -> " tvos$minTvos "
0 commit comments