Commit cffad7d0 authored by Marius Rackwitz's avatar Marius Rackwitz

[Analyzer] Revised model-generation

The analyzer generates now first deduplicated pod targets and instantiates them with all target definitions, where they are used, and then generates all the aggregate targets. So it can select the required pod target for each the aggregate target and doesn't need to alter intermediate products as before.
parent 9a4f361d
...@@ -219,16 +219,15 @@ module Pod ...@@ -219,16 +219,15 @@ module Pod
private private
# Creates the models that represent the libraries generated by CocoaPods. # Creates the models that represent the targets generated by CocoaPods.
# #
# @return [Array<Target>] the generated libraries. # @return [Array<AggregateTarget>]
# #
def generate_targets def generate_targets
targets = [] pod_targets = generate_pod_targets(result.specs_by_target)
result.specs_by_target.each do |target_definition, specs| result.specs_by_target.map do |target_definition, _|
targets << generate_target(target_definition, specs, targets.map(&:pod_targets).flatten) generate_target(target_definition, pod_targets)
end end
targets
end end
# Setup the aggregate target for a single user target # Setup the aggregate target for a single user target
...@@ -236,16 +235,12 @@ module Pod ...@@ -236,16 +235,12 @@ module Pod
# @param [TargetDefinition] target_definition # @param [TargetDefinition] target_definition
# the target definition for the user target. # the target definition for the user target.
# #
# @param [Array<Specification>] specs
# the specifications that need to be installed grouped by the
# given target definition.
#
# @param [Array<PodTarget>] pod_targets # @param [Array<PodTarget>] pod_targets
# the pod targets, which were generated so far. # the pod targets, which were generated.
# #
# @return [AggregateTarget] # @return [AggregateTarget]
# #
def generate_target(target_definition, specs, pod_targets) def generate_target(target_definition, pod_targets)
target = AggregateTarget.new(target_definition, sandbox) target = AggregateTarget.new(target_definition, sandbox)
target.host_requires_frameworks |= target_definition.uses_frameworks? target.host_requires_frameworks |= target_definition.uses_frameworks?
...@@ -265,64 +260,72 @@ module Pod ...@@ -265,64 +260,72 @@ module Pod
end end
end end
target.pod_targets = generate_pod_targets(target, specs, pod_targets) target.pod_targets = pod_targets.select do |pod_target|
pod_target.target_definitions.include?(target_definition)
end
target target
end end
# Setup the pod targets for an aggregate target. Group specs and subspecs # Setup the pod targets for an aggregate target. Deduplicates resulting
# by their root to create a {PodTarget} for each spec. # targets by grouping by grouping by platform and subspec by their root
# # to create a {PodTarget} for each spec.
# @param [AggregateTarget] target
# the aggregate target
# #
# @param [Array<Specification>] specs # @param [Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
# the specifications that need to be installed. # the resolved specifications grouped by target.
#
# @param [Array<PodTarget>] pod_targets
# the pod targets, which were generated so far.
# #
# @return [Array<PodTarget>] # @return [Array<PodTarget>]
# #
def generate_pod_targets(target, specs, pod_targets) def generate_pod_targets(specs_by_target)
grouped_specs = specs.group_by(&:root).values.uniq if config.deduplicate_targets?
grouped_specs.map do |pod_specs| all_specs = specs_by_target.flat_map do |target_definition, dependent_specs|
if config.deduplicate_targets? dependent_specs.group_by(&:root).map do |root_spec, specs|
# If there are no or already multiple pod targets with a common root, [root_spec, specs, target_definition]
# or the one which exists differs in the activated subspec set, then end
# we need to generate another pod target end
root_spec = pod_specs.first.root
common_root_pod_targets = pod_targets. distinct_targets = all_specs.each_with_object({}) do |dependency, hash|
select { |t| t.platform == target.platform }. root_spec, specs, target_definition = *dependency
select { |t| t.root_spec == root_spec } hash[root_spec] ||= {}
if common_root_pod_targets.count != 1 || common_root_pod_targets.first.specs != pod_specs (hash[root_spec][[specs, target_definition.platform]] ||= []) << target_definition
pod_target = generate_pod_target(target, pod_specs) end
unless common_root_pod_targets.empty?
common_root_pod_targets.each { |t| t.scoped = true } distinct_targets.values.flat_map do |targets_by_distinctors|
pod_target.scoped = true if targets_by_distinctors.count > 1
# There are different sets of subspecs or the spec is used across different platforms
targets_by_distinctors.map do |distinctor, target_definitions|
specs, _ = *distinctor
generate_pod_target(target_definitions, specs, scoped: true)
end end
pod_target
else else
common_root_pod_targets.first (specs, _), target_definitions = targets_by_distinctors.first
generate_pod_target(target_definitions, specs)
end
end
else
specs_by_target.flat_map do |target_definition, specs|
grouped_specs = specs.group_by.group_by(&:root).values.uniq
grouped_specs.flat_map do |pod_specs|
generate_pod_target([target_definition], pod_specs, scoped: true)
end end
else
generate_pod_target(target, pod_specs).scoped
end end
end end
end end
# Create a target for each spec group and add it to the aggregate target # Create a target for each spec group
# #
# @param [AggregateTarget] target # @param [TargetDefinitions] target_definitions
# the aggregate target # the aggregate target
# #
# @param [Array<Specification>] specs # @param [Array<Specification>] specs
# the specifications of an equal root. # the specifications of an equal root.
# #
# @param [Bool] scoped
# whether the pod target should be scoped
#
# @return [PodTarget] # @return [PodTarget]
# #
def generate_pod_target(target, pod_specs) def generate_pod_target(target_definitions, pod_specs, scoped: false)
pod_target = PodTarget.new(pod_specs, target.target_definition, sandbox) pod_target = PodTarget.new(pod_specs, target_definitions, sandbox, scoped)
if config.integrate_targets? if config.integrate_targets?
target_inspections = result.target_inspections.select { |t, _| target_definitions.include?(t) }.values target_inspections = result.target_inspections.select { |t, _| target_definitions.include?(t) }.values
...@@ -330,7 +333,7 @@ module Pod ...@@ -330,7 +333,7 @@ module Pod
pod_target.archs = target_inspections.map(&:archs).uniq.sort pod_target.archs = target_inspections.map(&:archs).uniq.sort
else else
pod_target.user_build_configurations = {} pod_target.user_build_configurations = {}
if target.platform.name == :osx if target_definitions.first.platform.name == :osx
pod_target.archs = '$(ARCHS_STANDARD_64_BIT)' pod_target.archs = '$(ARCHS_STANDARD_64_BIT)'
end end
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment