2015-05-14 16 views
21

Il mio progetto utilizza CocoaPods e anche i file personalizzati xcconfig. Fino ad ora, questo non ha causato alcun problema: ho appena dovuto #include la configurazione generata da CocoaPods alla fine della mia configurazione personalizzata.Come posso modificare OTHER_LDFLAGS tramite l'hook post-installazione di CocoaPods?

Tuttavia, ho riscontrato un problema in cui è necessario specificare condizionatamente OTHER_LDFLAGS in base a xcconfig, ma non riesco a capire come farlo.

Per cominciare, ho cercato semplicemente accedendo al OTHER_LDFLAGS come questo, ma le bandiere non sono effettivamente registrati:

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 

L'output è simile al seguente:

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: # ... 

Come può In realtà modifico OTHER_LDFLAGS tramite l'hook post-installazione di CocoaPods?

+1

Che cosa stai cercando di fare esattamente? Se vuoi cambiare OTHER_LDFLAGS, puoi farlo direttamente nella specifica del pod – Loegic

+0

Dopo tutto, non penso che questa domanda abbia senso. Come dice @Loegic: i pod possono dichiarare gli OTHER_LDFLAGS nei loro podspecs. Non vuoi scherzare con i pod target come IMO. – hfossli

+0

@Loegic, mi trovo nella sfortunata situazione in cui devo usare un framework statico di terze parti, che non ha un CocoaPod ed è troppo grande per funzionare bene come un pod (8 GB ...: /). Ho scritto degli script per farlo, ma richiede anche aggiunte agli OTHER_LDFLAGS. Non puoi ignorare OTHER_LDFLAGS nelle impostazioni di generazione del tuo target, altrimenti i xcconfigs di CocoaPods verranno ignorati. Non è possibile farlo in xcconfig personalizzato, o uno o l'altro flag di configurazione (a seconda di come si include il pod xcconfig) verrà sovrascritto. Quindi, ho pensato di usare il gancio di installazione. –

risposta

22

Mi sono imbattuto nello stesso problema. Per prima cosa ho cercato di modificare OTHER_LDFLAGS con l'ovvio:

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 

, ma non ha funzionato. Il xcconfig rilevante non ha ottenuto la modifica. Alla fine ho trovato una soluzione che funziona bene - prima di leggere il contenuto del file xcconfig rilevante nel gancio post_intall, modificarlo e scrivere di nuovo:

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: miglioramento rispetto il v1.0. Invece di operare direttamente sul contenuto di xcconfig String, leggere xccconfig in build_configuration Hash, modificare l'hash e quindi scaricarlo in 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 
+0

+1: sembra promettente! :) Ho intenzione di dare questo andare e assicurarsi che funzioni come previsto. Se è così, ti darò la vittoria. –

+0

@ JRG-Developer Ha funzionato per te? – mrvincenzo

+0

La 'v1.5' ha funzionato alla grande. L'unica modifica che dovevo fare era 'file = File.open (xcconfig_path," w ")' (usando write invece di append). Grazie! –

0

Non sono riuscito a trovare un buon modo per modificare xcconfig. Posso vederli e persino modificarli in post installazione, ma le mie modifiche non vengono scritte nel pod xcconfig.

Questo è quello che uso per modificare il file 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 

Il modo per modificare la OTHER_LD_FLAGS nel post script di installazione direttamente è il seguente. Ma dal momento che non vengono scritti nel file xcconfig, ho dovuto ricorrere alla soluzione hacky di cui sopra. Se riesci a capire come ottenere queste modifiche scritte nel file, sarebbe fantastico.

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 
2

Ecco un caso d'uso per v1.0: mi sono imbattuto in questa discussione perché abbiamo più applicazioni che hanno tutti i singoli xcconfigs e condividere file xcconfig comuni. L'utilizzo dei pod ha iniziato a cadere a pezzi una volta che abbiamo aggiunto un'estensione per app come destinazione e non potevamo più condividere l'ereditarietà del livello di progetto per la configurazione attiva (come il debug). Sooooo usando v1.0 dall'alto è possibile rinominare gli elementi di livello pod, come OTHER_LDFLAGS a PODS_OTHER_LDFLAGS e poi tranquillamente # include nel vostro xcconfigs (senza calpestare gli altri valori) unirle con comuni, app, impostazioni di destinazione ala:

OTHER_LDFLAGS = $(inherited) $(PODS_OTHER_LDFLAGS) $(COMMON_OTHER_LDFLAGS) 

Quindi, a mio baccelli file che abbiamo una sezione come questo all'interno di un ciclo come 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 } 

e xcconfig colla che viene impostato al ala livello obiettivo:

#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" 

wh ere le varie impostazioni app/config/common/Pod sono tirati dentro e merge.xcconfig tira tutto insieme in questo modo:

//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) 
4

Sulla base delle risposte di cui sopra e le rubydocs ufficiali cocoapods e xcodeproj, sono arrivato fino a questo soluzione, che è puramente basato sulle API fornite dai gemme citati:

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 

Questo aggiunge con successo la bandiera linker -l"AFNetworking" a qualsiasi file xcconfig di qualsiasi bersaglio aggregata ('Pod -...').

testato con cocoapods 1.2.0 e 1.3.0 su Xcode8.3.3 e Xcode9 Beta 4.

Problemi correlati