Skip to content

Instantly share code, notes, and snippets.

@mcmurrym
Last active August 16, 2019 21:32
Show Gist options
  • Save mcmurrym/10ca32a1ab698e19beb4522d3aac3064 to your computer and use it in GitHub Desktop.
Save mcmurrym/10ca32a1ab698e19beb4522d3aac3064 to your computer and use it in GitHub Desktop.
Load this file at the top of your Podfile `load 'pods_mac_catalyst.rb'` in your post_install function call this: adjust_pod_installation_for_mac_catalyst(installer, [pods_with_bundles], 'dev team idea to assign to pod bundles')
# frozen_string_literal: true
require 'set'
def adjust_pod_installation_for_mac_catalyst(installer, resource_bundles_needing_dev_team, team_id)
puts('Updating Pod Configuration To Support Mac Catalyst')
exclusions = scan_for_exclusions(installer)
update_xcconfig(installer, exclusions)
update_frameworks_script(installer, exclusions)
disable_mac_catalyst_build_setting(installer.pods_project.targets, exclusions)
configure_dev_team_for_resources_bundles(installer.pods_project.targets, resource_bundles_needing_dev_team, team_id)
puts('Completed Pod Configuration updates.')
end
def scan_for_exclusions(installer)
puts('• Scanning for exclusions')
exclusions = Set.new
work_dir = Dir.pwd
installer.generated_pod_targets.each do |pod_target|
dir = "#{work_dir}/Pods/#{pod_target.name}"
target_exclusions = Set.new
search_result_framework_list = `find #{dir} -name "*.framework"`.split("\n")
search_result_framework_list.each do |path|
expected_framework = "#{pod_target.name}.framework"
expected_path = "#{dir}/#{expected_framework}"
if path != expected_path
find_framework = /#{Regexp.quote(pod_target.name)}\.framework/
if framework_match = !path.match(find_framework)
path_components = path.split('/')
next unless last_component = path_components.last
framework_components = last_component.split('.')
next unless framework_name = framework_components.first
next if library_supports_catalyst(path, framework_name)
target_exclusions << framework_name
else
unless library_supports_catalyst(path, pod_target.name)
target_exclusions << pod_target.name
end
end
else
unless library_supports_catalyst(path, pod_target.name)
target_exclusions << pod_target.name
end
end
expected_path_with_any_framework = %r{#{Regexp.quote(dir)}/[^/]*\.framework}
next if path.match(expected_path_with_any_framework)
capture_alternate_path_component = %r{#{Regexp.quote(work_dir)}/Pods/(.*)/.*\.framework}
next unless alternate_path = path.match(capture_alternate_path_component)[1]
target_exclusions << alternate_path
end
if target_exclusions.empty?
search_result_a_list = `find #{dir} -name "*.a"`.split("\n")
search_result_a_list.each do |path|
unless library_supports_catalyst(path, nil)
target_exclusions << pod_target.name
end
end
else
target_exclusions << pod_target.name
end
exclusions |= target_exclusions
end
loop do
additional_exclusions = scan_for_dependent_exclusions(installer, exclusions)
if additional_exclusions.empty?
break
else
exclusions |= additional_exclusions
end
end
exclusions
end
def scan_for_dependent_exclusions(installer, current_exclusions)
exclusions = Set.new
installer.generated_pod_targets.each do |pod_target|
dependent_targets = pod_target.dependent_targets.map(&:name)
dependent_targets_set = dependent_targets.to_set
if !current_exclusions.include?(pod_target.name) && !(dependent_targets_set & current_exclusions).empty?
exclusions << pod_target.name
end
end
exclusions
end
def library_supports_catalyst(path, framework)
search_path = path
search_path = "#{search_path}/#{framework}" unless framework.nil?
return false unless File.exist?(search_path)
support_count = `objdump -full-contents #{search_path} | grep uikitformac | wc -l`
supports_mac_catalyst = support_count.to_i > 0
if supports_mac_catalyst
puts("HEY!! this library supports mac catalyst! #{path}")
end
supports_mac_catalyst
end
def update_xcconfig(installer, exclusions)
puts('• Updating xcconfig files')
work_dir = Dir.pwd
installer.aggregate_targets.each do |target|
target.user_build_configurations.each do |_key, value|
xcconfig_file = "#{work_dir}/Pods/Target Support Files/#{target.name}/#{target.name}.#{value}.xcconfig"
xcconfig_lines = File.readlines(xcconfig_file)
new_xcconfig_lines = []
xcconfig_lines.each do |line|
line_updates = line_update_for_paths_and_flags(line, exclusions)
if !line_updates.empty?
new_xcconfig_lines.push(*line_updates)
else
new_xcconfig_lines.push(line)
end
end
File.open(xcconfig_file, 'w') do |file|
new_xcconfig_lines.each { |element| file.puts(element) }
end
end
end
end
def line_update_for_paths_and_flags(line, exclusions)
lines = []
config_elements_to_check.each do |check|
next unless line.include?(check)
ios_line = line.gsub(check, "#{check}[sdk=iphone*]")
lines.push(ios_line)
mac_line = line.gsub(check, "#{check}[sdk=mac*]")
exclusions.each do |exclusion|
remove_strings = strings_to_remove_for(exclusion)
remove_strings.each do |string|
mac_line = mac_line.gsub(string, '')
end
end
lines.push(mac_line)
end
lines
end
def update_frameworks_script(installer, exclusions)
puts('• Updating pods framework script')
not_mac_catalyst_if = ' if [[ ! "$IS_MACCATALYST" ]]; then'
not_mac_catalyst_end = ' fi'
work_dir = Dir.pwd
installer.aggregate_targets.each do |target|
build_script_file = "#{work_dir}/Pods/Target Support Files/#{target.name}/#{target.name}-frameworks.sh"
build_script_lines = File.readlines(build_script_file)
newbuild_script_lines = []
build_script_lines.each do |line|
found = false
exclusions.each do |pod|
framework_line = " install_framework \"${BUILT_PRODUCTS_DIR}/#{pod}/#{pod}.framework\""
next unless line.include?(framework_line)
newbuild_script_lines.push(not_mac_catalyst_if)
newbuild_script_lines.push(" #{framework_line}")
newbuild_script_lines.push(not_mac_catalyst_end)
found = true
break
end
newbuild_script_lines.push(line) unless found
end
File.open(build_script_file, 'w') do |file|
newbuild_script_lines.each { |element| file.puts(element) }
end
end
end
def disable_mac_catalyst_build_setting(targets, exclusions)
puts('• Disabling Mac Catalyst for unsupported pods')
targets.each do |target|
target.build_configurations.each do |config|
if exclusions.include?(target.name)
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
end
end
end
end
def configure_dev_team_for_resources_bundles(targets, resource_bundles_needing_dev_team, team_id)
return if resource_bundles_needing_dev_team.nil? || team_id.nil?
puts('• Setting development team pod resource bundles')
targets.each do |target|
next unless resource_bundles_needing_dev_team.any? do |resource|
target.name.include?(resource)
end
target.build_configurations.each do |config|
config.build_settings['DEVELOPMENT_TEAM'] = team_id
end
end
end
def config_elements_to_check
%w[
OTHER_LDFLAGS
OTHER_CFLAGS
HEADER_SEARCH_PATHS
FRAMEWORK_SEARCH_PATHS
LIBRARY_SEARCH_PATHS
]
end
def strings_to_remove_for(exclusion)
[
"-iframework \"${PODS_CONFIGURATION_BUILD_DIR}/#{exclusion}\"",
"-iframework \"${PODS_ROOT}/#{exclusion}\"",
"-isystem \"${PODS_CONFIGURATION_BUILD_DIR}/#{exclusion}/#{exclusion}.framework/Headers\"",
" -framework \"#{exclusion}\"",
"\"${PODS_ROOT}/#{exclusion}\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/#{exclusion}/#{exclusion}.framework/Headers\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/#{exclusion}\""
]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment