Подтвердить что ты не робот

Как я могу изменить OTHER_LDFLAGS через CocoaPods после установки?

В моем проекте используются 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: # ...

Как я могу на самом деле изменить OTHER_LDFLAGS через CocoaPods после установки?

4b9b3361

Ответ 1

Я наткнулся на ту же проблему. Сначала я попытался изменить 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 не получил изменения. В конце концов я нашел обходное решение, которое хорошо работает - сначала прочитайте содержимое файла xcconfig в тэге post_intall, измените его и запишите:

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: улучшение над 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

Ответ 2

Основываясь на ответах выше и официальных рубидоках cocoapods и xcodeproj, я придумал это решение, которое основано исключительно на 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 любой совокупной цели ( "Pod -..." ).

Протестировано с cocoapods 1.2.0 и 1.3.0 на Xcode8.3.3 и Xcode9 Beta 4.

Ответ 3

Здесь пример использования для v1.0: Я наткнулся на этот поток, потому что у нас есть несколько приложений, у которых есть отдельные xcconfigs и общие файлы xcconfig. Использование стручков стало разваливаться, как только мы добавили расширение приложения в качестве цели и больше не могли делиться наследованием уровня проекта для активной конфигурации (например, отладки). Sooooo, используя v1.0 сверху, вы можете повторно назвать элементы уровня pod, такие как OTHER_LDFLAGS, PODS_OTHER_LDFLAGS, а затем безопасно # включить их в свои xcconfigs (без топания других значений), объединить их с обычными, приложениями, целевыми настройками 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)

Ответ 4

Я не мог найти хороший способ изменить xcconfig. Я могу просмотреть их и даже изменить их в post install, но мои изменения не записываются в 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 в post install script выполняется следующим образом. Но поскольку они не записываются в файл xcconfig, мне приходилось прибегать к хакерскому решению выше. Если вы можете понять, как получить эти изменения, записанные в файл, это будет потрясающе.

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