Kotlin多平台项目podspec的script_phases被AS同步修改致构建失败
问题描述
我正在开发一个Kotlin Multiplatform库,遇到以下问题:
- podspec被自动修改:podspec中的
spec.script_phases初始内容为:
spec.script_phases = [ { :name => 'Build kotlin_mpp', :execution_position => :before_compile, :shell_path => '/bin/sh', :script => <<-SCRIPT if [ "YES" = "$COCOAPODS_SKIP_KOTLIN_BUILD" ]; then echo "Skipping Gradle build task invocation due to COCOAPODS_SKIP_KOTLIN_BUILD environment variable set to \"YES\"" exit 0 fi set -ev REPO_ROOT="$PODS_TARGET_SRCROOT" "$REPO_ROOT/../gradlew" -p "$REPO_ROOT/.." $KOTLIN_PROJECT_PATH:syncFramework \ -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ -Pkotlin.native.cocoapods.archs="$ARCHS" \ -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \ -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \ -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \ -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS" SCRIPT } ]
但每次Android Studio同步(包括开机启动时),这段内容会被自动修改为:
spec.script_phases = [ { :name => 'Build kotlin_mpp', :execution_position => :before_compile, :shell_path => '/bin/sh', :script => <<-SCRIPT if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" exit 0 fi set -ev REPO_ROOT="$PODS_TARGET_SRCROOT" "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ -Pkotlin.native.cocoapods.archs="$ARCHS" \ -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" SCRIPT } ]
- 构建报错:执行
pod install后Xcode构建会抛出Gradle脚本编译错误:
* What went wrong: Script compilation errors: Line 14: alias(libs.plugins.kotlinMultiplatform) ^ Unresolved reference: libs Line 15: alias(libs.plugins.kotlinCocoapods) ^ Unresolved reference: libs Line 16: alias(libs.plugins.androidLibrary) ^ Unresolved reference: libs Line 18: alias(libs.plugins.sqldelight) ^ Unresolved reference: libs Line 19: alias(libs.plugins.kotlinSerialization) ^ Unresolved reference: libs Line 20: alias(libs.plugins.openapigen) ^ Unresolved reference: libs
- 临时修复:只能丢弃podspec的改动才能恢复正常构建。
- 当前Podfile配置:
use_frameworks! inhibit_all_warnings! pod 'kotlin_mpp', :path => './kotlin-mpp/kotlin-mpp' ...
解决方案
1. 阻止Gradle自动修改podspec
Kotlin Multiplatform的cocoapods插件默认会自动更新podspec文件。要保留自定义的script_phases,可以在KMP模块的build.gradle.kts(或build.gradle)中禁用自动生成逻辑:
cocoapods { // 禁用自动生成/更新podspec generatePodspec = false // 保留原有框架配置 framework { // ... 你的框架配置 } // ... 其他cocoapods配置 }
修改后,Android Studio同步时不会再覆盖podspec,你可以手动维护spec.script_phases的内容。
2. 自定义Gradle生成的podspec脚本
如果需要保留自动生成podspec的能力,可以在Gradle配置中直接定义script_phases的内容,确保生成的脚本符合需求:
cocoapods { framework { // ... 你的框架配置 } podspec { scriptPhases = listOf( PodspecScriptPhase( name = "Build kotlin_mpp", executionPosition = PodspecScriptPhase.ExecutionPosition.BEFORE_COMPILE, shellPath = "/bin/sh", script = """ if [ "YES" = "$COCOAPODS_SKIP_KOTLIN_BUILD" ]; then echo "Skipping Gradle build task invocation due to COCOAPODS_SKIP_KOTLIN_BUILD environment variable set to \"YES\"" exit 0 fi set -ev REPO_ROOT="$PODS_TARGET_SRCROOT" "$REPO_ROOT/../gradlew" -p "$REPO_ROOT/.." $KOTLIN_PROJECT_PATH:syncFramework \ -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ -Pkotlin.native.cocoapods.archs="$ARCHS" \ -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \ -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \ -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \ -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS" """.trimIndent() ) ) } }
这样Gradle生成的podspec会直接使用你定义的脚本,不会再替换为错误版本。
3. Podfile钩子临时适配(不推荐)
如果暂时无法修改Gradle配置,可以在Podfile中添加post_install钩子,自动恢复正确的脚本内容:
post_install do |installer| podspec_path = './kotlin-mpp/kotlin-mpp/kotlin_mpp.podspec' content = File.read(podspec_path) corrected_script = <<-SCRIPT if [ "YES" = "$COCOAPODS_SKIP_KOTLIN_BUILD" ]; then echo "Skipping Gradle build task invocation due to COCOAPODS_SKIP_KOTLIN_BUILD environment variable set to \"YES\"" exit 0 fi set -ev REPO_ROOT="$PODS_TARGET_SRCROOT" "$REPO_ROOT/../gradlew" -p "$REPO_ROOT/.." $KOTLIN_PROJECT_PATH:syncFramework \\ -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \\ -Pkotlin.native.cocoapods.archs="$ARCHS" \\ -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \\ -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \\ -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \\ -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS" SCRIPT content = content.gsub(/:script => <<-SCRIPT.*?SCRIPT/m, ":script => <<-SCRIPT\n#{corrected_script}\n SCRIPT") File.write(podspec_path, content) end
注意:这种方法是临时方案,Android Studio同步仍会覆盖podspec,优先推荐前两种Gradle层面的解决方式。
内容的提问来源于stack exchange,提问作者Vincenzo
相关产品推荐
相关产品推荐

