Xcode 创建应用程序二进制文件后,删除框架和 link 到框架
Remove a framework and the link to the framework after the app binary is created by Xcode
我想在 Xcode 中构建同一个应用程序的两个版本,一个使用 Sparkle 框架,一个不使用 Sparkle 框架。我不想维护一个单独的目标。相反,我想使用 2 个独立的方案,它们依赖于 2 个独立的构建配置(嗯,总共 4 个,因为我将使用一个用于调试构建,一个用于发布构建)。
据我所知,问题是 'Copy Bundle Resources' 和 'Build Phases' 中的 'Link Binary' 步骤对于给定目标上的所有方案都是相同的。
所以我认为我唯一的选择是 运行 在构建之后(以及在签名之前)编写一个脚本,该脚本将:
- 从应用程序包中删除框架。
- 取消框架与可执行文件的链接(如
ottol -L
所列)。
有什么建议吗?
经过相当多的工作,我想出了一个解决方案。
- 首先,确保框架 linking 是 "weak",Xcode 在 'Link Binary' 阶段调用 "Optional"。还要确保代码中对 Sparkle 的任何使用都能处理缺少的 Sparkle 框架。
为调试和发布创建单独的构建配置,例如调用 'Debug-no_sparkle' 和 'Release-no_sparkle',方法是转到项目设置,在 'Configurations' 选项卡的 'Info' 下。还可以通过转到 'Schemes' 弹出菜单创建相应的方案,复制您的常规方案,然后在方案的各种操作中使用 'no_sparkle' 配置。
在目标设置中的构建阶段添加一个 'Run Script' 步骤。
这是我使用的 Ruby 脚本:
config = ENV['CONFIGURATION']
if (config =~ /no_sparkle/)
$stderr.puts "Removing Sparkle Framework"
sparkle_path = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['FRAMEWORKS_FOLDER_PATH']}/Sparkle.framework"
`rm -Rf "#{sparkle_path}"`
$stderr.puts "Removing Sparkle Framework linking"
binary_path = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['EXECUTABLE_PATH']}"
`install_name_tool -change @rpath/Sparkle.framework/Versions/A/Sparkle @rpath/ "#{binary_path}"`
end
我不能做的一件事是用 install_name_tool
完全删除与框架 link 对应的行。我只能将它更改为 '/' 以删除它的任何痕迹,因此如果框架以某种方式可访问,它甚至不会意外加载。能完全去掉就好了
我想在 Xcode 中构建同一个应用程序的两个版本,一个使用 Sparkle 框架,一个不使用 Sparkle 框架。我不想维护一个单独的目标。相反,我想使用 2 个独立的方案,它们依赖于 2 个独立的构建配置(嗯,总共 4 个,因为我将使用一个用于调试构建,一个用于发布构建)。
据我所知,问题是 'Copy Bundle Resources' 和 'Build Phases' 中的 'Link Binary' 步骤对于给定目标上的所有方案都是相同的。
所以我认为我唯一的选择是 运行 在构建之后(以及在签名之前)编写一个脚本,该脚本将:
- 从应用程序包中删除框架。
- 取消框架与可执行文件的链接(如
ottol -L
所列)。
有什么建议吗?
经过相当多的工作,我想出了一个解决方案。
- 首先,确保框架 linking 是 "weak",Xcode 在 'Link Binary' 阶段调用 "Optional"。还要确保代码中对 Sparkle 的任何使用都能处理缺少的 Sparkle 框架。
为调试和发布创建单独的构建配置,例如调用 'Debug-no_sparkle' 和 'Release-no_sparkle',方法是转到项目设置,在 'Configurations' 选项卡的 'Info' 下。还可以通过转到 'Schemes' 弹出菜单创建相应的方案,复制您的常规方案,然后在方案的各种操作中使用 'no_sparkle' 配置。
在目标设置中的构建阶段添加一个 'Run Script' 步骤。
这是我使用的 Ruby 脚本:
config = ENV['CONFIGURATION']
if (config =~ /no_sparkle/)
$stderr.puts "Removing Sparkle Framework"
sparkle_path = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['FRAMEWORKS_FOLDER_PATH']}/Sparkle.framework"
`rm -Rf "#{sparkle_path}"`
$stderr.puts "Removing Sparkle Framework linking"
binary_path = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['EXECUTABLE_PATH']}"
`install_name_tool -change @rpath/Sparkle.framework/Versions/A/Sparkle @rpath/ "#{binary_path}"`
end
我不能做的一件事是用 install_name_tool
完全删除与框架 link 对应的行。我只能将它更改为 '/' 以删除它的任何痕迹,因此如果框架以某种方式可访问,它甚至不会意外加载。能完全去掉就好了