From d76a6d6a9c0dce00b00cf69b26de921884b2b189 Mon Sep 17 00:00:00 2001 From: Andrey Yastrebov Date: Mon, 12 Feb 2024 10:31:23 +0100 Subject: [PATCH] KT-65741 Add Swift Export KGP tasks --- .../kotlin-gradle-plugin/build.gradle.kts | 5 + .../gradle/plugin/PropertiesProvider.kt | 4 + .../plugin/mpp/apple/AppleXcodeTasks.kt | 20 +- ...dSyntheticProjectWithSwiftExportPackage.kt | 157 +++ ...CopySwiftExportIntermediatesForConsumer.kt | 74 ++ .../GenerateSPMPackageFromSwiftExport.kt | 131 +++ .../mpp/apple/swiftexport/SwiftExport.kt | 222 +++++ .../mpp/apple/swiftexport/SwiftExportTask.kt | 79 ++ .../plugin/registerKotlinPluginExtensions.kt | 6 +- .../src/common/resources/spm/project.pbxproj | 907 ++++++++++++++++++ 10 files changed, 1599 insertions(+), 6 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/BuildSyntheticProjectWithSwiftExportPackage.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportTask.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/resources/spm/project.pbxproj diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts index 620cd35743b..cdc2dfc741e 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts @@ -74,6 +74,7 @@ dependencies { } commonCompileOnly(project(":kotlin-tooling-metadata")) commonCompileOnly(project(":compiler:build-tools:kotlin-build-statistics")) + commonCompileOnly(project(":native:swift:swift-export-standalone")) commonCompileOnly(commonDependency("org.jetbrains.intellij.deps:asm-all")) { isTransitive = false } commonImplementation(project(":kotlin-gradle-plugin-idea")) @@ -90,6 +91,10 @@ dependencies { commonRuntimeOnly(project(":kotlin-util-klib")) commonRuntimeOnly(project(":kotlin-compiler-embeddable")) + if (kotlinBuildProperties.isSwiftExportPluginPublishingEnabled) { + embedded(project(":native:swift:swift-export-embeddable")) + } + embedded(project(":kotlin-gradle-build-metrics")) embedded(project(":kotlin-gradle-statistics")) embedded(commonDependency("org.jetbrains.intellij.deps:asm-all")) { isTransitive = false } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index bbfe83d8e80..7413e5f3be3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -500,6 +500,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val cocoapodsExecutablePath: RegularFile? get() = property(PropertyNames.KOTLIN_APPLE_COCOAPODS_EXECUTABLE).orNull?.let { RegularFile { File(it) } } + val swiftExportEnabled: Boolean + get() = booleanProperty(PropertyNames.KOTLIN_SWIFT_EXPORT_ENABLED) ?: false + /** * Allows the user to specify a custom location for the Kotlin/Native distribution. * This property takes precedence over the 'KONAN_DATA_DIR' environment variable. @@ -662,6 +665,7 @@ internal class PropertiesProvider private constructor(private val project: Proje val KOTLIN_NATIVE_TOOLCHAIN_ENABLED = property("kotlin.native.toolchain.enabled") val KOTLIN_APPLE_COPY_FRAMEWORK_TO_BUILT_PRODUCTS_DIR = property("kotlin.apple.copyFrameworkToBuiltProductsDir") val KOTLIN_APPLE_COCOAPODS_EXECUTABLE = property("kotlin.apple.cocoapods.bin") + val KOTLIN_SWIFT_EXPORT_ENABLED = property("kotlin.swift-export.enabled") /** * Internal properties: builds get big non-suppressible warning when such properties are used diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt index d403e2817e7..fc5bf402e73 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt @@ -22,9 +22,9 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic import org.jetbrains.kotlin.gradle.plugin.mpp.Framework import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.apple.FrameworkCopy.Companion.dsymFile +import org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport.registerSwiftExportTask import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost -import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask -import org.jetbrains.kotlin.gradle.tasks.dependsOn +import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.getFile @@ -139,13 +139,13 @@ private fun Project.registerAssembleAppleFrameworkTask(framework: Framework): Ta task.description = "Packs $frameworkBuildType fat framework for Xcode" task.baseName = framework.baseName task.destinationDirProperty.fileProvider(appleFrameworkDir(frameworkTaskName)) - task.isEnabled = frameworkBuildType == envBuildType + task.isEnabled = !project.kotlinPropertiesProvider.swiftExportEnabled && frameworkBuildType == envBuildType }.also { it.configure { task -> task.from(framework) } } else -> registerTask(frameworkTaskName) { task -> task.description = "Packs $frameworkBuildType ${frameworkTarget.name} framework for Xcode" - task.isEnabled = frameworkBuildType == envBuildType + task.isEnabled = !project.kotlinPropertiesProvider.swiftExportEnabled && frameworkBuildType == envBuildType task.sourceFramework.fileProvider(framework.linkTaskProvider.flatMap { it.outputFile }) task.sourceDsym.fileProvider(dsymFile(task.sourceFramework.mapToFile())) task.dependsOn(framework.linkTaskProvider) @@ -220,6 +220,13 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework val frameworkTaskName = framework.embedAndSignTaskName() + val swiftExportTask: TaskProvider<*>? = + if (project.kotlinPropertiesProvider.swiftExportEnabled && XcodeEnvironment.targets.contains(framework.target.konanTarget)) { + registerSwiftExportTask(framework) + } else { + null + } + if (envBuildType == null || envTargets.isEmpty() || envEmbeddedFrameworksDir == null) { locateOrRegisterTask(frameworkTaskName) { task -> task.group = BasePlugin.BUILD_GROUP @@ -250,7 +257,7 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework val embedAndSignTask = locateOrRegisterTask(frameworkTaskName) { task -> task.group = BasePlugin.BUILD_GROUP task.description = "Embed and sign ${framework.namePrefix} framework as requested by Xcode's environment variables" - task.isEnabled = !framework.isStatic + task.isEnabled = !(project.kotlinPropertiesProvider.swiftExportEnabled || framework.isStatic) task.inputs.apply { property("type", envBuildType) property("targets", envTargets) @@ -270,6 +277,9 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework embedAndSignTask.configure { task -> val frameworkFile = framework.outputFile task.dependsOn(assembleTask) + if (swiftExportTask != null) { + task.dependsOn(swiftExportTask) + } task.sourceFramework.fileProvider(appleFrameworkDir(frameworkTaskName).map { it.resolve(frameworkFile.name) }) task.destinationDirectory.set(envEmbeddedFrameworksDir) if (envSign != null) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/BuildSyntheticProjectWithSwiftExportPackage.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/BuildSyntheticProjectWithSwiftExportPackage.kt new file mode 100644 index 00000000000..de5924f6d3e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/BuildSyntheticProjectWithSwiftExportPackage.kt @@ -0,0 +1,157 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport + +import org.gradle.api.DefaultTask +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.* +import org.gradle.work.DisableCachingByDefault +import org.jetbrains.kotlin.gradle.plugin.mpp.apple.AppleXcodeTasks +import org.jetbrains.kotlin.gradle.utils.appendLine +import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty +import org.jetbrains.kotlin.gradle.utils.mapToFile +import org.jetbrains.kotlin.gradle.utils.runCommand +import org.jetbrains.kotlin.utils.keysToMap +import java.io.File +import javax.inject.Inject + +@DisableCachingByDefault(because = "Swift Export is experimental, so no caching for now") +abstract class BuildSyntheticProjectWithSwiftExportPackage : DefaultTask() { + + @get:Inject + abstract val providerFactory: ProviderFactory + + @get:Input + abstract val swiftApiModuleName: Property + + @get:Input + abstract val swiftLibraryName: Property + + @get:Input + val inheritedBuildSettingsFromEnvironment: Map> + get() = listOf( + "CONFIGURATION", "ARCHS", "ONLY_ACTIVE_ARCH", + ).keysToMap { + providerFactory.environmentVariable(it) + } + + @get:Optional + @get:Input + val targetDeviceIdentifier: Provider get() = providerFactory.environmentVariable("TARGET_DEVICE_IDENTIFIER") + + @get:Input + val platformName: Provider get() = providerFactory.environmentVariable("PLATFORM_NAME") + + @get:OutputDirectory + val syntheticInterfacesPath: Provider get() = syntheticProjectDirectory.map { it.dir("dd-interfaces") } + + private val syntheticObjectFilesDirectory get() = syntheticProjectDirectory.map { it.dir("dd-o-files") } + + @get:OutputFile + val syntheticLibraryPath: Provider get() = syntheticObjectFilesDirectory.map { it.file("lib${swiftLibraryName.get()}.a") } + + @get:OutputDirectory + val syntheticBuildIntermediatesPath: Provider get() = syntheticProjectDirectory.map { it.dir("dd-other") }.mapToFile() + + @get:Internal + abstract val syntheticProjectDirectory: DirectoryProperty + + @TaskAction + fun run() { + val syntheticProjectPath = setUpSyntheticProject() + val syntheticObjectFilesDirectory = buildSyntheticProject(syntheticProjectPath) + packObjectFilesIntoLibrary(syntheticObjectFilesDirectory) + } + + private fun setUpSyntheticProject(): File { + val syntheticForSpm = syntheticProjectDirectory.get().asFile + val syntheticProjectPath = syntheticForSpm.resolve("synthetic.xcodeproj") + syntheticProjectPath.mkdirs() + + val pbxprojPath = syntheticProjectPath.resolve("project.pbxproj") + val syntheticProjectTemplate = + AppleXcodeTasks.javaClass.getResourceAsStream("/spm/project.pbxproj") ?: error("Missing synthetic project resource") + + pbxprojPath.outputStream().writer().use { pbxprojWriter -> + syntheticProjectTemplate.reader().forEachLine { line -> + pbxprojWriter + .append(line.replace(SYNTHETIC_PROJECT_MARKER, swiftApiModuleName.get())) + .appendLine() + } + } + return syntheticProjectPath + } + + private fun buildSyntheticProject(syntheticProjectPath: File): File { + val syntheticObjectFilesDirectory = this.syntheticObjectFilesDirectory.get().asFile + val intermediatesDestination = mapOf( + // Thin/universal object files + "TARGET_BUILD_DIR" to syntheticObjectFilesDirectory.canonicalPath, + // .swiftmodule interface + "BUILT_PRODUCTS_DIR" to syntheticInterfacesPath.get().asFile.canonicalPath + ) + val inheritedBuildSettings = inheritedBuildSettingsFromEnvironment.mapValues { + it.value.get() + } + + // FIXME: This will not work with dynamic libraries + runCommand( + listOf( + "xcodebuild", + "build", + "-derivedDataPath", syntheticBuildIntermediatesPath.get().canonicalPath, + "-project", syntheticProjectPath.canonicalPath, + "-scheme", swiftLibraryName.get(), + "-destination", destination(), + ) + (inheritedBuildSettings + intermediatesDestination).map { (k, v) -> "$k=$v" } + ) + return syntheticObjectFilesDirectory + } + + private fun packObjectFilesIntoLibrary(syntheticObjectFilesDirectory: File) { + val objectFilePaths = syntheticObjectFilesDirectory.listFilesOrEmpty().filter { + it.extension == "o" + }.map { it.canonicalPath } + if (objectFilePaths.isEmpty()) { + error("Synthetic project build didn't produce any object files") + } + + runCommand( + listOf( + "libtool", "-static", + "-o", syntheticLibraryPath.get().asFile.canonicalPath, + ) + objectFilePaths, + ) + } + + private fun destination(): String { + val deviceId: String? = targetDeviceIdentifier.orNull + if (deviceId != null) return "id=$deviceId" + + val platformName = platformName.orNull ?: error("Missing a target device identifier and a platform name") + val platform = mapOf( + "iphonesimulator" to "iOS Simulator", + "iphoneos" to "iOS", + "watchsimulator" to "watchOS Simulator", + "watchos" to "watchOS", + "appletvos" to "tvOS", + "appletvsimulator" to "tvOS Simulator", + "macosx" to "macOS", + )[platformName] ?: error("Unknown PLATFORM_NAME $platformName") + + return "generic/platform=$platform" + } + + companion object { + const val SYNTHETIC_PROJECT_MARKER = "" + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt new file mode 100644 index 00000000000..f296f866ba9 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/CopySwiftExportIntermediatesForConsumer.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.* +import org.gradle.work.DisableCachingByDefault +import java.io.File +import javax.inject.Inject + +@DisableCachingByDefault(because = "This task only copies files") +abstract class CopySwiftExportIntermediatesForConsumer @Inject constructor( + objectFactory: ObjectFactory, + projectLayout: ProjectLayout, + providerFactory: ProviderFactory, + private val fileSystem: FileSystemOperations +) : DefaultTask() { + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val includeBridgeDirectory: RegularFileProperty + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val kotlinLibraryPath: RegularFileProperty + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val syntheticLibraryPath: RegularFileProperty + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val syntheticInterfacesPath: RegularFileProperty + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + val builtProductsDirectory: DirectoryProperty = objectFactory.directoryProperty().convention( + projectLayout.dir(providerFactory.environmentVariable("BUILT_PRODUCTS_DIR").map { + File(it) + }) + ) + + @get:OutputDirectory + val syntheticInterfacesDestinationPath: DirectoryProperty = objectFactory.directoryProperty().convention( + builtProductsDirectory.flatMap { + projectLayout.dir(providerFactory.provider { + it.asFile.resolve("KotlinBridge") + }) + } + ) + + @TaskAction + fun copy() { + fileSystem.copy { + it.from(kotlinLibraryPath) + it.from(syntheticInterfacesPath) + it.from(syntheticLibraryPath) + it.into(builtProductsDirectory) + } + fileSystem.copy { + it.from(includeBridgeDirectory) + it.into(syntheticInterfacesDestinationPath) + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt new file mode 100644 index 00000000000..21de7a714c7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/GenerateSPMPackageFromSwiftExport.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.work.DisableCachingByDefault +import org.jetbrains.kotlin.gradle.utils.appendLine +import org.jetbrains.kotlin.gradle.utils.getFile +import org.jetbrains.kotlin.incremental.createDirectory +import org.jetbrains.kotlin.incremental.deleteRecursivelyOrThrow + +@DisableCachingByDefault(because = "Swift Export is experimental, so no caching for now") +abstract class GenerateSPMPackageFromSwiftExport : DefaultTask() { + + @get:Input + abstract val swiftApiModuleName: Property + + @get:Input + abstract val headerBridgeModuleName: Property + + @get:Input + abstract val swiftLibraryName: Property + + @get:Input + abstract val kotlinLibraryName: Property + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val swiftApiPath: RegularFileProperty + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val headerBridgePath: RegularFileProperty + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val libraryPath: RegularFileProperty + + @get:OutputDirectory + abstract val packagePath: DirectoryProperty + + @get:Internal + val headerBridgeIncludePath get() = headerBridgeModulePath.resolve("include") + + private val swiftApiModule get() = swiftApiModuleName.get() + private val headerBridgeModule get() = headerBridgeModuleName.get() + private val spmPackageRootPath get() = packagePath.getFile() + + private val sourcesPath get() = spmPackageRootPath.resolve("Sources") + private val swiftApiModulePath get() = sourcesPath.resolve(swiftApiModule) + private val headerBridgeModulePath get() = sourcesPath.resolve(headerBridgeModule) + + @TaskAction + fun generate() { + preparePackageDirectory() + createHeaderTarget() + createSwiftTarget() + createPackageManifest() + } + + private fun preparePackageDirectory() { + if (spmPackageRootPath.exists()) { + spmPackageRootPath.deleteRecursivelyOrThrow() + } + swiftApiModulePath.createDirectory() + headerBridgeIncludePath.createDirectory() + } + + private fun createHeaderTarget() { + headerBridgePath.get().asFile.copyTo( + headerBridgeIncludePath.resolve("Kotlin.h") + ) + headerBridgeIncludePath.resolve("module.modulemap").writeText( + """ + module $headerBridgeModule { + umbrella "." + export * + + link "${swiftLibraryName.get()}" + link "${kotlinLibraryName.get()}" + } + """.trimIndent() + ) + headerBridgeModulePath.resolve("linkingStub.c").writeText("\n") + } + + private fun createSwiftTarget() { + swiftApiModulePath.resolve("Kotlin.swift").writer().use { kotlinApi -> + swiftApiPath.get().asFile.reader().forEachLine { + kotlinApi.append(it).appendLine() + } + } + } + + private fun createPackageManifest() { + val manifest = spmPackageRootPath.resolve("Package.swift") + manifest.writeText( + """ + // swift-tools-version: 5.9 + + import PackageDescription + let package = Package( + name: "$swiftApiModule", + products: [ + .library( + name: "${swiftApiModule}Library", + targets: ["$swiftApiModule"] + ), + ], + targets: [ + .target( + name: "$swiftApiModule", + dependencies: ["$headerBridgeModule"] + ), + .target( + name: "$headerBridgeModule" + ) + ] + ) + """.trimIndent() + ) + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt new file mode 100644 index 00000000000..64fbb93136e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExport.kt @@ -0,0 +1,222 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport + +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.tasks.dependsOn +import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask +import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.gradle.utils.future +import org.jetbrains.kotlin.gradle.utils.getOrCreate +import org.jetbrains.kotlin.gradle.utils.konanDistribution +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.utils.mapToFile + +fun Project.registerSwiftExportTask( + framework: Framework, +): TaskProvider<*> { + return registerSwiftExportTask( + swiftApiModuleName = framework.baseNameProvider, + target = framework.target, + buildType = framework.buildType, + ) +} + +private fun Project.registerSwiftExportTask( + swiftApiModuleName: Provider, + target: KotlinNativeTarget, + buildType: NativeBuildType, +): TaskProvider<*> { + val taskNamePrefix = lowerCamelCaseName( + target.disambiguationClassifier ?: target.name, + buildType.getName(), + ) + val mainCompilation = target.compilations.getByName("main") + + val swiftExportTask = registerSwiftExportRun( + swiftApiModuleName = swiftApiModuleName, + taskNamePrefix = taskNamePrefix, + mainCompilation = mainCompilation, + ) + val staticLibrary = registerSwiftExportCompilationAndGetBinary( + buildType = buildType, + compilations = target.compilations, + binaries = target.binaries, + mainCompilation = mainCompilation, + swiftExportTask = swiftExportTask, + ) + + val kotlinStaticLibraryName = staticLibrary.linkTaskProvider.flatMap { it.binary.baseNameProvider } + val swiftApiLibraryName = swiftApiModuleName.map { it + "Library" } + + val syntheticBuildRoot = layout.buildDirectory.dir("${taskNamePrefix}SPMPackage") + val packageGenerationTask = registerPackageGeneration( + taskNamePrefix = taskNamePrefix, + swiftApiModuleName = swiftApiModuleName, + swiftApiLibraryName = swiftApiLibraryName, + kotlinStaticLibraryName = kotlinStaticLibraryName, + swiftExportTask = swiftExportTask, + staticLibrary = staticLibrary, + syntheticBuildRoot = syntheticBuildRoot, + ) + val syntheticProjectBuild = registerSyntheticProjectBuild( + taskNamePrefix = taskNamePrefix, + swiftApiModuleName = swiftApiModuleName, + swiftApiLibraryName = swiftApiLibraryName, + syntheticBuildRoot = syntheticBuildRoot, + packageGenerationTask = packageGenerationTask, + ) + + return registerCopyTask( + taskNamePrefix = taskNamePrefix, + staticLibrary = staticLibrary, + packageGenerationTask = packageGenerationTask, + syntheticProjectBuild = syntheticProjectBuild, + ) +} + +private fun Project.registerSwiftExportRun( + swiftApiModuleName: Provider, + taskNamePrefix: String, + mainCompilation: KotlinCompilation<*>, +): TaskProvider { + val swiftExportTaskName = taskNamePrefix + "SwiftExport" + return locateOrRegisterTask(swiftExportTaskName) { task -> + val directoryProvider = project.future { + kotlinPluginLifecycle.await(KotlinPluginLifecycle.Stage.AfterFinaliseRefinesEdges) + mainCompilation.allKotlinSourceSets.flatMap { + it.kotlin.srcDirs + } + } + + val outputs = layout.buildDirectory.dir(swiftExportTaskName) + val swiftIntermediates = outputs.map { it.dir("swiftIntermediates") } + val kotlinIntermediates = outputs.map { it.dir("kotlinIntermediates") } + + // Input + task.sourceRoots.from(project.files(directoryProvider.getOrThrow())) + task.bridgeModuleName.set(swiftApiModuleName.map { "${it}Bridge" }) + task.debugMode.set(true) + task.konanDistribution.set(konanDistribution.root) + + // Output + task.swiftApiPath.set(swiftIntermediates.map { it.file("KotlinAPI.swift") }) + task.headerBridgePath.set(swiftIntermediates.map { it.file("KotlinBridge.h") }) + task.kotlinBridgePath.set(kotlinIntermediates.map { it.file("KotlinBridge.kt") }) + } +} + +private fun registerSwiftExportCompilationAndGetBinary( + buildType: NativeBuildType, + compilations: NamedDomainObjectContainer, + binaries: KotlinNativeBinaryContainer, + mainCompilation: KotlinCompilation<*>, + swiftExportTask: TaskProvider, +): StaticLibrary { + val swiftExportCompilationName = "swiftExportMain" + val swiftExportBinary = "swiftExportBinary" + + compilations.getOrCreate( + swiftExportCompilationName, + invokeWhenCreated = { swiftExportCompilation -> + swiftExportCompilation.associateWith(mainCompilation) + swiftExportCompilation.defaultSourceSet.kotlin.srcDir(swiftExportTask.map { it.kotlinBridgePath.getFile().parent }) + swiftExportCompilation.compileTaskProvider.configure { + it.compilerOptions.optIn.add("kotlin.experimental.ExperimentalNativeApi") + } + + binaries.staticLib(swiftExportBinary) { staticLib -> + staticLib.compilation = swiftExportCompilation + } + } + ) + + return binaries.getStaticLib( + swiftExportBinary, + buildType + ) +} + +private fun Project.registerPackageGeneration( + taskNamePrefix: String, + swiftApiModuleName: Provider, + swiftApiLibraryName: Provider, + kotlinStaticLibraryName: Provider, + swiftExportTask: TaskProvider, + staticLibrary: StaticLibrary, + syntheticBuildRoot: Provider, +): TaskProvider { + val spmPackageGenTaskName = taskNamePrefix + "GenerateSPMPackage" + val packageGenerationTask = locateOrRegisterTask(spmPackageGenTaskName) { task -> + task.group = BasePlugin.BUILD_GROUP + task.description = "Generates $taskNamePrefix SPM Package" + + // Input + task.swiftApiPath.set(swiftExportTask.flatMap { it.swiftApiPath }) + task.headerBridgePath.set(swiftExportTask.flatMap { it.headerBridgePath }) + task.headerBridgeModuleName.set(swiftExportTask.flatMap { it.bridgeModuleName }) + task.libraryPath.set { staticLibrary.linkTaskProvider.flatMap { it.outputFile }.get() } + task.swiftLibraryName.set(swiftApiLibraryName) + task.kotlinLibraryName.set(kotlinStaticLibraryName) + task.swiftApiModuleName.set(swiftApiModuleName) + + // Output + task.packagePath.set(syntheticBuildRoot.flatMap { root -> + swiftApiModuleName.map { root.dir(it) } + }) + } + + packageGenerationTask.dependsOn(staticLibrary.linkTaskProvider) + return packageGenerationTask +} + +private fun Project.registerSyntheticProjectBuild( + taskNamePrefix: String, + swiftApiModuleName: Provider, + swiftApiLibraryName: Provider, + syntheticBuildRoot: Provider, + packageGenerationTask: TaskProvider<*>, +): TaskProvider { + val buildTaskName = taskNamePrefix + "BuildSyntheticProject" + val syntheticProjectBuild = locateOrRegisterTask(buildTaskName) { task -> + task.group = BasePlugin.BUILD_GROUP + task.description = "Builds $taskNamePrefix synthetic project" + task.swiftApiModuleName.set(swiftApiModuleName) + task.swiftLibraryName.set(swiftApiLibraryName) + task.syntheticProjectDirectory.set(syntheticBuildRoot) + } + syntheticProjectBuild.dependsOn(packageGenerationTask) + return syntheticProjectBuild +} + +private fun Project.registerCopyTask( + taskNamePrefix: String, + staticLibrary: StaticLibrary, + packageGenerationTask: TaskProvider, + syntheticProjectBuild: TaskProvider, +): TaskProvider<*> { + val copyTaskName = taskNamePrefix + "CopySyntheticProjectIntermediates" + val copyTask = locateOrRegisterTask(copyTaskName) { task -> + task.group = BasePlugin.BUILD_GROUP + task.description = "Copy $taskNamePrefix synthetic project intermediates" + task.includeBridgeDirectory.convention(layout.file(packageGenerationTask.map { it.headerBridgeIncludePath })) + task.kotlinLibraryPath.convention(layout.file(staticLibrary.linkTaskProvider.flatMap { it.outputFile })) + task.syntheticLibraryPath.convention(layout.file(syntheticProjectBuild.flatMap { it.syntheticLibraryPath.mapToFile() })) + task.syntheticInterfacesPath.convention(layout.file(syntheticProjectBuild.flatMap { it.syntheticInterfacesPath.mapToFile() })) + } + copyTask.dependsOn(syntheticProjectBuild) + return copyTask +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportTask.kt new file mode 100644 index 00000000000..9f4abc16be9 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/swiftexport/SwiftExportTask.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.apple.swiftexport + +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.work.DisableCachingByDefault +import org.jetbrains.kotlin.gradle.internal.LogType +import org.jetbrains.kotlin.gradle.internal.processLogMessage +import org.jetbrains.kotlin.gradle.utils.getFile +import org.jetbrains.kotlin.konan.target.Distribution +import org.jetbrains.kotlin.swiftexport.standalone.* + +@DisableCachingByDefault(because = "Swift Export is experimental, so no caching for now") +abstract class SwiftExportTask : DefaultTask(), SwiftExportLogger { + + @get:Input + abstract val bridgeModuleName: Property + + @get:Input + abstract val debugMode: Property + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.ABSOLUTE) + abstract val konanDistribution: DirectoryProperty + + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val sourceRoots: ConfigurableFileCollection + + @get:OutputFile + abstract val swiftApiPath: RegularFileProperty + + @get:OutputFile + abstract val headerBridgePath: RegularFileProperty + + @get:OutputFile + abstract val kotlinBridgePath: RegularFileProperty + + @TaskAction + fun run() { + runSwiftExport( + input = SwiftExportInput( + sourceRoot = sourceRoots.filter { it.exists() }.map { it.toPath() }.first() + ), + config = SwiftExportConfig( + settings = mapOf( + SwiftExportConfig.DEBUG_MODE_ENABLED to debugMode.getOrElse(false).toString(), + SwiftExportConfig.BRIDGE_MODULE_NAME to bridgeModuleName.getOrElse(SwiftExportConfig.DEFAULT_BRIDGE_MODULE_NAME), + ), + this, + distribution = Distribution(konanDistribution.getFile().absolutePath), + ), + output = SwiftExportOutput( + swiftApi = swiftApiPath.get().asFile.toPath(), + kotlinBridges = kotlinBridgePath.get().asFile.toPath(), + cHeaderBridges = headerBridgePath.get().asFile.toPath(), + ) + ) + } + + override fun report(severity: SwiftExportLogger.Severity, message: String) { + logger.processLogMessage(message, severity.logType()) + } +} + +private fun SwiftExportLogger.Severity.logType(): LogType = when (this) { + SwiftExportLogger.Severity.Info -> LogType.INFO + SwiftExportLogger.Severity.Warning -> LogType.WARN + SwiftExportLogger.Severity.Error -> LogType.ERROR + else -> LogType.LOG +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt index 87ab6359ecb..88c06eb2f2a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt @@ -31,6 +31,10 @@ import org.jetbrains.kotlin.gradle.targets.native.CreateFatFrameworksSetupAction import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeConfigureBinariesSideEffect import org.jetbrains.kotlin.gradle.targets.native.SetupEmbedAndSignAppleFrameworkTaskSideEffect import org.jetbrains.kotlin.gradle.targets.native.internal.* +import org.jetbrains.kotlin.gradle.targets.native.internal.AddKotlinPlatformIntegersSupportLibrary +import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizedCInteropApiElementsConfigurationsSetupAction +import org.jetbrains.kotlin.gradle.targets.native.internal.SetupCInteropApiElementsConfigurationSideEffect +import org.jetbrains.kotlin.gradle.targets.native.internal.SetupKotlinNativePlatformDependenciesForLegacyImport import org.jetbrains.kotlin.gradle.targets.native.tasks.artifact.KotlinArtifactsExtensionSetupAction import org.jetbrains.kotlin.gradle.tooling.RegisterBuildKotlinToolingMetadataTask @@ -148,4 +152,4 @@ private val Project.isJvm get() = kotlinJvmExtensionOrNull != null private val Project.isJs get() = kotlinExtensionOrNull is KotlinJsProjectExtension -private val Project.isAndroid get() = kotlinExtension is KotlinAndroidProjectExtension \ No newline at end of file +private val Project.isAndroid get() = kotlinExtension is KotlinAndroidProjectExtension diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/resources/spm/project.pbxproj b/libraries/tools/kotlin-gradle-plugin/src/common/resources/spm/project.pbxproj new file mode 100644 index 00000000000..980ab8eeacb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/resources/spm/project.pbxproj @@ -0,0 +1,907 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXCopyFilesBuildPhase section */ + 05F2823A27BFF52F00A213D9 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 05F281E327BFA36E00A213D9 /* ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 05F2820027BFF4EB00A213D9 /* macos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "macos.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 05F2821827BFF52C00A213D9 /* watchos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "watchos.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 05F2824827BFF63B00A213D9 /* tvos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tvos.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 05F2824827BFF73B00A213D9 /* */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = ; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 05F281E027BFA36E00A213D9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 05F2825A27BFF65D00A213D9 + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F281FD27BFF4EB00A213D9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 05F2825A27BFF65D00A213D9 + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F2824527BFF63B00A213D9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 05F2825A27BFF65D00A213D9 + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 05F281BA27BFA02500A213D9 = { + isa = PBXGroup; + children = ( + 05F2824827BFF73B00A213D9 /* */, + 05F281C627BFA08C00A213D9 /* Products */, + ); + sourceTree = ""; + }; + 05F281C627BFA08C00A213D9 /* Products */ = { + isa = PBXGroup; + children = ( + 05F281E327BFA36E00A213D9 /* ios.app */, + 05F2820027BFF4EB00A213D9 /* macos.app */, + 05F2821827BFF52C00A213D9 /* watchos.app */, + 05F2824827BFF63B00A213D9 /* tvos.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 05F281E227BFA36E00A213D9 /* ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 05F281F927BFA37000A213D9 /* Build configuration list for PBXNativeTarget "ios" */; + buildPhases = ( + 05F281DF27BFA36E00A213D9 /* Sources */, + 05F281E027BFA36E00A213D9 /* Frameworks */, + 05F281E127BFA36E00A213D9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ios"; + packageProductDependencies = ( + 05F2825A27BFF64D00A213D9 /* */, + ); + productName = "ios"; + productReference = 05F281E327BFA36E00A213D9 /* ios.app */; + productType = "com.apple.product-type.application"; + }; + 05F281FF27BFF4EB00A213D9 /* macos */ = { + isa = PBXNativeTarget; + buildConfigurationList = 05F2821027BFF4ED00A213D9 /* Build configuration list for PBXNativeTarget "macos" */; + buildPhases = ( + 05F281FC27BFF4EB00A213D9 /* Sources */, + 05F281FD27BFF4EB00A213D9 /* Frameworks */, + 05F281FE27BFF4EB00A213D9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "macos"; + productName = "macos-app"; + productReference = 05F2820027BFF4EB00A213D9 /* macos.app */; + productType = "com.apple.product-type.application"; + }; + 05F2821727BFF52B00A213D9 /* watchos */ = { + isa = PBXNativeTarget; + buildConfigurationList = 05F2823B27BFF52F00A213D9 /* Build configuration list for PBXNativeTarget "watchos" */; + buildPhases = ( + 05F2821627BFF52B00A213D9 /* Resources */, + 05F2823A27BFF52F00A213D9 /* Embed App Extensions */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "watchos"; + productName = "watchos"; + productReference = 05F2821827BFF52C00A213D9 /* watchos.app */; + productType = "com.apple.product-type.application.watchapp2"; + }; + 05F2824727BFF63B00A213D9 /* tvos */ = { + isa = PBXNativeTarget; + buildConfigurationList = 05F2825A27BFF63D00A213D9 /* Build configuration list for PBXNativeTarget "tvos" */; + buildPhases = ( + 05F2824427BFF63B00A213D9 /* Sources */, + 05F2824527BFF63B00A213D9 /* Frameworks */, + 05F2824627BFF63B00A213D9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "tvos"; + productName = "tvos"; + productReference = 05F2824827BFF63B00A213D9 /* tvos.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 05F281BB27BFA02500A213D9 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1320; + TargetAttributes = { + 05F281E227BFA36E00A213D9 = { + CreatedOnToolsVersion = 15.0; + }; + 05F281FF27BFF4EB00A213D9 = { + CreatedOnToolsVersion = 15.0; + }; + 05F2821727BFF52B00A213D9 = { + CreatedOnToolsVersion = 15.0; + }; + 05F2824727BFF63B00A213D9 = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 05F281BE27BFA02500A213D9 /* Build configuration list for PBXProject "" */; + compatibilityVersion = "Xcode 15.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 05F281BA27BFA02500A213D9; + productRefGroup = 05F281C627BFA08C00A213D9 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 05F281E227BFA36E00A213D9 /* ios */, + 05F281FF27BFF4EB00A213D9 /* macos */, + 05F2821727BFF52B00A213D9 /* watchos */, + 05F2824727BFF63B00A213D9 /* tvos */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 05F281E127BFA36E00A213D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F281FE27BFF4EB00A213D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F2821627BFF52B00A213D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F2824627BFF63B00A213D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 05F281DF27BFA36E00A213D9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F281FC27BFF4EB00A213D9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 05F2824427BFF63B00A213D9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 05F281BF27BFA02500A213D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 05F281C027BFA02500A213D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 05F281FA27BFA37000A213D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ""; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.ios"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 05F281FB27BFA37000A213D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ""; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.ios"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 05F2821127BFF4ED00A213D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = "macos-app/macos_app.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.1; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.macos-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; + }; + name = Debug; + }; + 05F2821227BFF4ED00A213D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = "macos-app/macos_app.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.1; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.macos-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; + }; + name = Release; + }; + 05F2823C27BFF52F00A213D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + IBSC_MODULE = watchos_target_WatchKit_Extension; + INFOPLIST_KEY_CFBundleDisplayName = "watchos"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.watchos.watchkitapp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 8.3; + }; + name = Debug; + }; + 05F2823D27BFF52F00A213D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + IBSC_MODULE = watchos_target_WatchKit_Extension; + INFOPLIST_KEY_CFBundleDisplayName = "watchos"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.watchos.watchkitapp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = 4; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 8.3; + }; + name = Release; + }; + 05F2825B27BFF63D00A213D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.tvos"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.2; + }; + name = Debug; + }; + 05F2825C27BFF63D00A213D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.dummy.tvos"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.2; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 05F281BE27BFA02500A213D9 /* Build configuration list for PBXProject "" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 05F281BF27BFA02500A213D9 /* Debug */, + 05F281C027BFA02500A213D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 05F281F927BFA37000A213D9 /* Build configuration list for PBXNativeTarget "ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 05F281FA27BFA37000A213D9 /* Debug */, + 05F281FB27BFA37000A213D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 05F2821027BFF4ED00A213D9 /* Build configuration list for PBXNativeTarget "macos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 05F2821127BFF4ED00A213D9 /* Debug */, + 05F2821227BFF4ED00A213D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 05F2823B27BFF52F00A213D9 /* Build configuration list for PBXNativeTarget "watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 05F2823C27BFF52F00A213D9 /* Debug */, + 05F2823D27BFF52F00A213D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 05F2825A27BFF63D00A213D9 /* Build configuration list for PBXNativeTarget "tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 05F2825B27BFF63D00A213D9 /* Debug */, + 05F2825C27BFF63D00A213D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 05F2825A27BFF64D00A213D9 /* LocalLibrary */ = { + isa = XCSwiftPackageProductDependency; + productName = Library; + }; +/* End XCSwiftPackageProductDependency section */ + +/* Begin PBXBuildFile section */ + 05F2825A27BFF65D00A213D9 /* LocalLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = 05F2825A27BFF64D00A213D9 /* LocalLibrary */; }; +/* End PBXBuildFile section */ + }; + rootObject = 05F281BB27BFA02500A213D9 /* Project object */; +}