class XcodeArchiveCache::Injection::Injector
Attributes
@return [BuildFlagsChanger]
@return [String]
@return [DependencyRemover]
@return [FrameworkEmbedder]
@return [HeadersMover]
@return [ModulemapFixer]
@return [PodsScriptFixer]
@return [Storage]
Public Class Methods
@param [String] configuration_name
@param [XcodeArchiveCache::Injection::Storage] storage
# File lib/injection/injector.rb, line 10 def initialize(configuration_name, storage) @configuration_name = configuration_name @storage = storage @headers_mover = HeadersMover.new(storage) @dependency_remover = DependencyRemover.new @build_flags_changer = BuildFlagsChanger.new @pods_fixer = PodsScriptFixer.new @modulemap_fixer = XcodeArchiveCache::Modulemap::HeaderPathFixer.new(storage) @framework_embedder = FrameworkEmbedder.new end
Public Instance Methods
@param [XcodeArchiveCache::BuildGraph::Graph] graph
# File lib/injection/injector.rb, line 23 def perform_internal_injection(graph) inject_unpacked_and_rebuilt(graph.nodes) add_header_paths(graph.nodes) save_graph_projects(graph) end
@param [XcodeArchiveCache::BuildGraph::Graph] graph @param [Xcodeproj::Project::Object::PBXNativeTarget] target
# File lib/injection/injector.rb, line 32 def perform_outgoing_injection(graph, target) root_node = graph.root_node if root_node.native_target.project == target.project && root_node.native_target.uuid == target.uuid return end no_rebuild_performed = root_node.state == :unpacked graph.nodes.each do |node| if no_rebuild_performed || node.state == :rebuilt_and_cached headers_mover.prepare_headers_for_injection(node) modulemap_fixer.fix_modulemap(node) end add_as_prebuilt_dependency(node, target) remove_native_target_from_project(node) end add_header_paths_to_target(target, storage.get_all_headers_storage_paths) # pretty dummy but should work in most cases; # here we assume that if graph has a pods target # then all graph nodes are built as pods and therefore # are covered by "Embed Pods Frameworks" script # if graph.node_by_name(get_pods_target_name(target)) pods_fixer.fix_embed_frameworks_script(target, graph, storage.container_dir_path) pods_fixer.fix_copy_resources_script(target, graph, storage.container_dir_path) else framework_nodes = graph.nodes.select { |node| node.has_framework_product? } framework_file_paths = framework_nodes.map { |node| File.join(storage.get_storage_path(node), node.product_file_name) } framework_embedder.embed(framework_file_paths, target) end save_graph_projects(graph) target.project.save end
Private Instance Methods
@param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
# File lib/injection/injector.rb, line 171 def add_as_prebuilt_dependency(prebuilt_node, dependent_target) target_identifier = get_target_identifier(dependent_target) return if prebuilt_node.targets_injected_to.include?(target_identifier) debug("adding #{prebuilt_node.name} as prebuilt to #{dependent_target.display_name}") unless prebuilt_node.has_acceptable_product? raise XcodeArchiveCache::Informative, "#{prebuilt_node.name} has unsupported product type: #{prebuilt_node.native_target.product_type}" end if prebuilt_node.has_framework_product? add_as_prebuilt_framework(prebuilt_node, dependent_target) elsif prebuilt_node.has_static_library_product? add_as_prebuilt_static_lib(prebuilt_node, dependent_target) end prebuilt_node.targets_injected_to.push(target_identifier) debug("done with #{prebuilt_node.name} for #{dependent_target.display_name}") end
@param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
# File lib/injection/injector.rb, line 195 def add_as_prebuilt_framework(prebuilt_node, dependent_target) build_configuration = dependent_target.find_build_configuration(configuration_name) artifact_location = storage.get_storage_path(prebuilt_node) build_flags_changer.replace_or_add_framework_search_path(build_configuration, prebuilt_node.native_target.name, artifact_location) build_flags_changer.add_framework_headers_iquote(build_configuration, artifact_location, prebuilt_node) if dependency_remover.is_linked(prebuilt_node, dependent_target) build_flags_changer.add_framework_linker_flag(build_configuration, prebuilt_node) end dependency_remover.remove_dependency(prebuilt_node, dependent_target) end
@param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
# File lib/injection/injector.rb, line 212 def add_as_prebuilt_static_lib(prebuilt_node, dependent_target) build_configuration = dependent_target.find_build_configuration(configuration_name) injected_modulemap_file_path = storage.get_modulemap_path(prebuilt_node) if injected_modulemap_file_path modulemap_file_names = [prebuilt_node.resulting_modulemap_file_name] build_flags_changer.fix_module_map_path(build_configuration, modulemap_file_names, injected_modulemap_file_path) original_modulemap_path = prebuilt_node.original_modulemap_file_path add_header_paths_to_target(dependent_target, [File.dirname(original_modulemap_path)]) end artifact_location = storage.get_storage_path(prebuilt_node) build_flags_changer.replace_or_add_library_search_path(build_configuration, prebuilt_node.native_target.name, artifact_location) build_flags_changer.add_swift_include_path(build_configuration, artifact_location) if dependency_remover.is_linked(prebuilt_node, dependent_target) if dependent_target.product_type == Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library] build_flags_changer.add_static_lib_libtool_flag(build_configuration, prebuilt_node) else build_flags_changer.add_static_lib_linker_flag(build_configuration, prebuilt_node) end end dependency_remover.remove_dependency(prebuilt_node, dependent_target) end
@param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
# File lib/injection/injector.rb, line 149 def add_as_prebuilt_to_dependents(prebuilt_node) dependent_to_rebuild = prebuilt_node .all_dependent_nodes .select(&:waiting_for_rebuild) dependent_to_rebuild.each do |dependent_node| add_as_prebuilt_dependency(prebuilt_node, dependent_node.native_target) end remove_native_target_from_project(prebuilt_node) end
@param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
# File lib/injection/injector.rb, line 122 def add_header_paths(nodes) header_storage_paths = storage.get_all_headers_storage_paths return if header_storage_paths.length == 0 nodes .select(&:waiting_for_rebuild) .each { |node| add_header_paths_to_target(node.native_target, header_storage_paths) } end
@param [Xcodeproj::Project::Object::PBXNativeTarget] target @param [Array<String>] paths
# File lib/injection/injector.rb, line 134 def add_header_paths_to_target(target, paths) return if paths == nil debug("adding #{paths} to #{target.display_name}") build_configuration = target.find_build_configuration(configuration_name) paths.each do |path| build_flags_changer.add_headers_search_path(build_configuration, path) build_flags_changer.add_iquote_path(build_configuration, path) build_flags_changer.add_capital_i_path(build_configuration, path) end end
@param [Xcodeproj::Project::Object::PBXNativeTarget] target
# File lib/injection/injector.rb, line 241 def get_pods_target_name(target) "Pods-#{target.display_name}" end
@param [Xcodeproj::Project::Object::PBXNativeTarget] target
@return [String]
# File lib/injection/injector.rb, line 261 def get_target_identifier(target) target.uuid + target.project.path.realpath.to_s end
@param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
# File lib/injection/injector.rb, line 106 def inject_unpacked_and_rebuilt(nodes) cached_nodes = nodes.select { |node| node.state == :unpacked } cached_nodes.each do |node| headers_mover.prepare_headers_for_injection(node) modulemap_fixer.fix_modulemap(node) add_as_prebuilt_to_dependents(node) end built_nodes = nodes.select { |node| node.state == :rebuilt_and_cached } built_nodes.each do |node| add_as_prebuilt_to_dependents(node) end end
@param [XcodeArchiveCache::BuildGraph::Node] node
since 10.2 Xcode looks for implicit dependencies in -l and -framework linker flags, so we need to delete dependency target to make sure Xcode has no way to build it as implicit dependency
# File lib/injection/injector.rb, line 252 def remove_native_target_from_project(node) debug("deleting #{node.name} target") node.native_target.project.targets.delete(node.native_target) end
@param [XcodeArchiveCache::BuildGraph::Graph] graph
# File lib/injection/injector.rb, line 162 def save_graph_projects(graph) projects = graph.nodes.map(&:native_target).map(&:project).uniq debug("updating #{projects.length} projects") projects.each { |project| project.save } end