我的项目使用CocoaPods和自定义xcconfig
文件。到目前为止,这还没有引起任何问题:我在自定义配置结束时只需要#include
CocoaPods生成的配置。
但是,我遇到了需要根据OTHER_LDFLAGS
有条件地指定xcconfig
的问题,但我无法弄清楚如何执行此操作。
首先,我尝试过像这样简单地记录OTHER_LDFLAGS
,但标志实际上并未记录:
post_install do |installer_representation|
installer_representation.project.targets.each do |target|
target.build_configurations.each do |config|
name = target.name
puts "Target Found: #{name}"
flags = config.build_settings['OTHER_LDFLAGS']
puts "OTHER_LDFLAGS Found: #{flags}"
end
end
end
输出如下:
Target Found: Pods-ProjectName-DependencyName1
OTHER_LDFLAGS Found: # nothing here...?
Target Found: Pods-ProjectName-DependencyName2
OTHER_LDFLAGS Found: # again nothing...
# etc...
Target Found: Pods-ProjectName # Cool, this is the main target pod
OTHER_LDFLAGS Found: # ...
如何通过CocoaPods安装后挂钩实际修改OTHER_LDFLAGS
?
答案 0 :(得分:28)
我偶然发现了同样的问题。首先,我尝试用明显的方法修改OTHER_LDFLAGS
:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "Pods-SomeTarget"
puts "Updating #{target.name} OTHER_LDFLAGS"
target.build_configurations.each do |config|
config.build_settings['OTHER_LDFLAGS'] ||= ['$(inherited)']
config.build_settings['OTHER_LDFLAGS'] << '-l"AFNetworking"'
end
end
end
end
但它没有用。相关的xcconfig没有得到改变。最终我找到了一个运行良好的解决方法 - 首先阅读post_intall
钩子中的相关xcconfig文件内容,修改它并将其写回:
<强> 1.0 强>
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "Pods-SomeTarget"
puts "Updating #{target.name} OTHER_LDFLAGS"
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
new_xcconfig = xcconfig.sub('OTHER_LDFLAGS = $(inherited)', 'OTHER_LDFLAGS = $(inherited) -l"AFNetworking"')
File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
end
end
end
end
编辑:对 v1.0 的改进。不要直接对xcconfig String
内容进行操作,而是将xccconfig读入build_configuration Hash
,修改哈希值,然后将其刷新到xcconfig。
v1.5
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "Pods-SomeTarget"
puts "Updating #{target.name} OTHER_LDFLAGS"
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
# read from xcconfig to build_settings dictionary
build_settings = Hash[*File.read(xcconfig_path).lines.map{|x| x.split(/\s*=\s*/, 2)}.flatten]
# modify OTHER_LDFLAGS
build_settings['OTHER_LDFLAGS'] << '-l"AFNetworking"'
# write build_settings dictionary to xcconfig
build_settings.each do |key,value|
File.open(xcconfig_path, "a") {|file| file.puts key = value}
end
end
end
end
end
答案 1 :(得分:10)
基于上面的答案以及cocoapods和xcodeproj的官方rubydocs,我提出了这个解决方案,它纯粹基于上述宝石提供的API:
post_install do |installer|
installer.aggregate_targets.each do |aggregate_target|
aggregate_target.xcconfigs.each do |config_name, config_file|
config_file.attributes['OTHER_LDFLAGS'] << '-l"AFNetworking"'
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
这成功地将链接器标志-l"AFNetworking"
添加到任何聚合目标的任何xcconfig文件中(&#39; Pod -...&#39;)。
在Xcode8.3.3和Xcode9 Beta 4上使用cocoapods 1.2.0和1.3.0进行测试。
答案 2 :(得分:3)
这是v1.0的用例: 我偶然发现了这个帖子,因为我们有多个应用程序都有单独的xcconfigs并共享常见的xcconfig文件。一旦我们添加了应用程序扩展作为目标,并且无法再共享活动配置的项目级继承(如调试),则使用pod开始崩溃。 Sooooo使用上面的v1.0你可以重命名pod级元素,比如OTHER_LDFLAGS到PODS_OTHER_LDFLAGS,然后安全#include它们到你的xcconfigs(不用踩其他值)将它们与常见的,app,target设置合并ala:
OTHER_LDFLAGS = $(inherited) $(PODS_OTHER_LDFLAGS) $(COMMON_OTHER_LDFLAGS)
所以,在我的pods文件中,我们在循环中有一个像v1.0这样的部分:
puts "Updating #{target.name} adapting settings like OTHER_LDFLAGS for merging at target level"
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig = xcconfig.sub('OTHER_LDFLAGS = $(inherited)', 'PODS_OTHER_LDFLAGS = ')
xcconfig = xcconfig.sub('OTHER_CFLAGS = $(inherited)', 'PODS_OTHER_CFLAGS = ')
xcconfig = xcconfig.sub('GCC_PREPROCESSOR_DEFINITIONS = $(inherited)', 'PODS_GCC_PREPROCESSOR_DEFINITIONS = ')
xcconfig = xcconfig.sub('HEADER_SEARCH_PATHS = $(inherited)', 'PODS_HEADER_SEARCH_PATHS = ')
xcconfig = xcconfig.sub('LIBRARY_SEARCH_PATHS = $(inherited)', 'PODS_LIBRARY_SEARCH_PATHS = ')
File.open(xcconfig_path, "w") { |file| file << xcconfig }
和在目标级别设置的胶水xcconfig ala:
#include "../../Pods/Target Support Files/Pods-Fusion/Pods-Fusion.release.xcconfig"
#include "../../shared/main/config/release.xcconfig"
#include "../../shared/main/config/allTargetsCommon.xcconfig"
#include "Fusion.xcconfig"
#include "../../shared/main/config/merge.xcconfig"
将各种app / config / common / pod设置拉入,merge.xcconfig将所有内容拉到一起,如下所示:
//merge up the pods, common base target and target configs
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) $(PODS_GCC_PREPROCESSOR_DEFINITIONS) $(TARGET_GCC_PREPROCESSOR_DEFINITIONS) $(APP_GCC_PREPROCESSOR_DEFINITIONS)
HEADER_SEARCH_PATHS = $(inherited) $(PODS_HEADER_SEARCH_PATHS)
OTHER_CFLAGS = $(inherited) $(PODS_OTHER_CFLAGS) $(TARGET_OTHER_CFLAGS)
OTHER_LDFLAGS = $(inherited) $(PODS_OTHER_LDFLAGS) $(COMMON_OTHER_LDFLAGS)
答案 3 :(得分:1)
如果您需要修改LDFLAGS并将一个框架移至末尾,那么此脚本将为您提供帮助。如果您拥有同一框架的两个版本,并且您主要想使用特定的实现,那么这会有所帮助。 (由于having FFMPEG twice in my app,我需要解决此问题,这是MobileVLCKit的一部分。)经过CocoaPods 1.9和1.10的测试。
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "Pods-MYPROJECT"
puts "Updating #{target.name} OTHER_LDFLAGS"
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
# read from xcconfig to build_settings dictionary
build_settings = Hash[*File.read(xcconfig_path).lines.map{|x| x.split(/\s*=\s*/, 2)}.flatten]
# modify OTHER_LDFLAGS
vlc_flag = ' -framework "MobileVLCKit"'
build_settings['OTHER_LDFLAGS'].gsub!(vlc_flag, "")
build_settings['OTHER_LDFLAGS'].gsub!("\n", "")
build_settings['OTHER_LDFLAGS'] += vlc_flag + "\n"
# write build_settings dictionary to xcconfig
File.open(xcconfig_path, "w") do |file|
build_settings.each do |key,value|
file.write(key + " = " + value)
end
end
end
end
end
end
答案 4 :(得分:0)
我正在运行pod版本1.8.4,但以上所有内容均不适用于我,因此请在此处发布以防万一。
下面的脚本基于@mrvincenzo的答案,但是我必须做一些更改以使其起作用,这将成功地将-ObjC
标志附加到OTHER_LDFLAGS
上,请记住,这将保留现有列表并仅在其上附加标志
post_install do |installer|
installer.pods_project.targets.each do |target|
#replace `Pod-target-lib` with your target library
if target.name == "Pod-target-lib"
puts "Updating #{target.name} OTHER_LDFLAGS"
xcconfig_path = ""
target.build_configurations.each do |config|
new_xcconfig_path = config.base_configuration_reference.real_path
if new_xcconfig_path != xcconfig_path
xcconfig_path = config.base_configuration_reference.real_path
# read from xcconfig to build_settings dictionary
build_settings = Hash[*File.read(xcconfig_path).lines.map{|x| x.split(/\s*=\s*/, 2)}.flatten]
# modify OTHER_LDFLAGS
build_settings['OTHER_LDFLAGS'] = "-ObjC #{build_settings['OTHER_LDFLAGS']}"
# clear current file content
File.open(xcconfig_path, "w") {|file| file.puts ""}
# write build_settings dictionary to xcconfig
build_settings.each do |key,value|
File.open(xcconfig_path, "a") {|file| file.puts "#{key} = #{value}"}
end
end
end
end
end
end
答案 5 :(得分:0)
如果您需要修改一些现有标志,则此示例可能对您有用:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/-framework "YourFramework"/, "-weak_framework \"YourFramework\"")
File.open(xcconfig_path, "w") { |file| file << xcconfig_mod }
end
end
end
答案 6 :(得分:0)
此解决方案基于@ sven-driemecker的解决方案, 但由于使用了更多的纯可可足API,因此效果略好。 它不会简单地追加字符串,而是将其添加到set中以保持数据一致。
在当前示例中,我修改了聚合目标,例如<a>
,以排除某些静态库无法链接,因为它们已经被依赖项之一链接了。
Pods-MYPROJECT
答案 7 :(得分:-1)
我无法找到修改xcconfig
的好方法。我可以查看它们甚至在安装后更改它们,但我的更改不会写入pod xcconfig
。
这是我用来修改xcconfig文件的内容:
post_install do |installer|
installer.libraries.each do |lib|
if lib.name != "Pods-lib"
next
end
target = lib.library
target.xcconfigs.each do |key, value|
config_file_path = target.xcconfig_path(key)
File.open("config.tmp", "w") do |io|
io << File.read(config_file_path).gsub(/-l"c\+\+"/, '').gsub(/-l"icucore"/,'')
end
FileUtils.mv("config.tmp", config_file_path)
end
end
end
直接在安装后脚本中修改OTHER_LD_FLAGS
的方法如下。但由于它们没有写入xcconfig
文件,我不得不求助于上面的hacky解决方案。如果你能弄清楚如何将这些更改写入文件,那就太棒了。
post_install do |installer|
libs_to_remove = ['c++', 'icucore']
installer.libraries.each do |lib|
if lib.name != "Pods-lib"
next
end
target = lib.library
target.xcconfigs.each do |key, value|
other_ld = value.other_linker_flags
libs = other_ld[:libraries]
libs.subtract(libs_to_remove)
value.other_linker_flags[:libraries] = libs
end
end
end