How can I modify OTHER_LDFLAGS via CocoaPods post-install hook?
Here's a use case for v1.0: I stumbled across this thread because we have multiple apps that all have individual xcconfigs and share common xcconfig files. Using pods started to fall apart once we added an app extension as a target and could no longer share the project level inheritance for the active config(like debug). Sooooo using v1.0 from above you can re-name the pod level elements, like OTHER_LDFLAGS to PODS_OTHER_LDFLAGS and then safely #include them into your xcconfigs (without stomping other values) merge them with common, app, target settings ala:
OTHER_LDFLAGS = $(inherited) $(PODS_OTHER_LDFLAGS) $(COMMON_OTHER_LDFLAGS)
So, in my pods file we have a section like this inside a loop like 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 }
and a glue xcconfig that is set at the target level 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"
where the various app/config/common/pod settings are pulled in and merge.xcconfig pulls everything together like this:
//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)
I stumbled across the same problem. First I tried to modify OTHER_LDFLAGS
with the obvious:
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
but it didn't work. The relevant xcconfig didn't get the change. Eventually I found a workaround that works well - first read the relevant xcconfig file content in the post_intall
hook, modify it and write it back:
v1.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
EDIT: Improvement over the v1.0. Instead of operating on xcconfig String
content directly, read xccconfig into a build_configuration Hash
, modify the hash and then flush it to 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
Based on the answers above and the official rubydocs of cocoapods and xcodeproj, I came up with this solution, which is purely based on the APIs provided by the mentioned gems:
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
This successfully adds the linker flag -l"AFNetworking"
to any xcconfig file of any aggregate target ('Pod-...').
Tested with cocoapods 1.2.0 and 1.3.0 on Xcode8.3.3 and Xcode9 Beta 4.