Xcode 10 构建阶段 Shell 脚本
Posted
技术标签:
【中文标题】Xcode 10 构建阶段 Shell 脚本【英文标题】:Xcode 10 Build Phase Shell Script 【发布时间】:2018-09-26 18:46:53 【问题描述】:在我们的项目中,我们从 git tag 等中派生发布版本,然后使用 shell 脚本将其写入构建文件夹的 Info.plist:
GIT_RELEASE_VERSION=$(some git command)
defaults write "$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH%.*" "CFBundleShortVersionString" "$GIT_RELEASE_VERSION#*v"
这对所有过去的 Xcode 版本都运行良好,但在 Xcode 10 的新构建系统中,这实际上无法更新 info.list 文件中的 CFBundleShortVersionString。不过,该值已使用 Xcode 10 的 Legacy Build System 正确更新。
我在脚本中添加了一些回声,并比较了新系统和旧系统上的构建日志,看不出有任何区别:
echo "git release version:" $GIT_RELEASE_VERSION
echo "info path:" $BUILT_PRODUCTS_DIR/$INFOPLIST_PATH%.*
echo "grv:" "$GIT_RELEASE_VERSION#*v"
不确定是否有人在新构建系统中遇到过类似问题?
【问题讨论】:
我使用来自gist.github.com/airdrummingfool/ecfa9827f47c5d02af53 的代码,它可以工作:/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $version" "$TARGET_BUILD_DIR/$INFOPLIST_PATH"
。不同之处在于将BUILT_PRODUCTS_DIR
替换为TARGET_BUILD_DIR
。并确保此脚本是运行的最后一步。
感谢@Cœur,但更改为TARGET_BUILD_DIR
似乎对我的情况没有帮助
谁能发布完整的运行脚本来创建通用目标?
@SatishMavani 您的问题与此处的原始问题并不真正相关。你能把它作为一个新线程发布吗?
【参考方案1】:
问题似乎是有时您的Run Script Phase
会在Xcode 创建Info.plist
之前执行。如果您想确保您的脚本阶段在特定步骤之后运行,您需要使用输入来标记您的依赖项。
例如,添加:
$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)
作为脚本阶段的输入,应强制执行您正在寻找的顺序:Xcode 将创建 Info.plist
,之后的某个时间,您的脚本将执行并修改 Info.plist
。
【讨论】:
这对我有用:我有一个预编译脚本,它根据自上次标记以来的 git 提交计数更新内部版本号。为了避免影响存储库,我必须在处理完 info.plist 后重置内部版本号。将此添加到重置中即可实现。 完美 ? 我正在使用它来动态设置应用程序传输安全性 - 根据链接到我的方案的配置允许任意加载。 Xcode 在生成我试图修改的 plist 之前正在运行我的脚本。这修正了订单! 这成功了!我最初将括号打错为大括号,更正后,它可以工作。【参考方案2】:(Xcode 11.2)
在新构建系统中,任何自定义构建步骤都将在新构建系统的Process .../Info.plist
步骤之前运行:
要在 Xcode 完成构建后运行 shell 脚本,您可以将其作为构建后操作添加到您的方案中:
Product > Scheme > Edit Scheme... > Build > Post-actions
如果您要引用任何构建系统环境变量(例如 BUILT_PRODUCTS_DIR
或 INFOPLIST_PATH
),请务必更改 Provide build settings from 选择。
添加您的 shell 脚本,但请记住,如果您编辑应用程序包中的任何文件(即 Info.plist
),则需要重新签署应用程序。将此添加到您的后期构建步骤中:
export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
/usr/bin/codesign --force --sign - --entitlements "$TARGET_TEMP_DIR/$FULL_PRODUCT_NAME.xcent" --timestamp=none "$CODESIGNING_FOLDER_PATH"
【讨论】:
【参考方案3】:同样的问题...一种解决方法是清理然后执行完整构建。
Xcode 10 中的新构建系统在完整构建和增量构建中以不同方式运行 Process Info.plist 步骤:
完整构建:在处理资产之后,在链接故事板之前(链接 步骤) 增量:嵌入框架后,签名前。实际的问题是作为构建步骤运行并更新已处理的 Info.plist 文件的脚本需要始终在文件处理之后但在签名之前运行。
【讨论】:
【参考方案4】:与上面的答案类似(尚无法评论),但略有变化。
脚本输入文件:
$(PROJECT_DIR)/$(INFOPLIST_FILE)
$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)
输出文件:
$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)
我用一个脚本创建了一个要点,用于设置捆绑版本和一些额外的信息,如标签、日期、分支。
https://gist.github.com/JoeMatt/aedd459c54a383373231719e508a2a36
【讨论】:
这对我不起作用。 @david G 的回答有效。添加此处建议的其他两个条目会导致错误:“invalid task blahblahblah with mutable output but no other virtual output node”以上是关于Xcode 10 构建阶段 Shell 脚本的主要内容,如果未能解决你的问题,请参考以下文章