| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  | # typed: true | 
					
						
							|  |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "os/linux/glibc" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DependencyCollector | 
					
						
							|  |  |  |   extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   undef gcc_dep_if_needed | 
					
						
							|  |  |  |   undef glibc_dep_if_needed | 
					
						
							|  |  |  |   undef init_global_dep_tree_if_needed! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) } | 
					
						
							|  |  |  |   def gcc_dep_if_needed(related_formula_names) | 
					
						
							| 
									
										
										
										
											2022-08-25 12:27:00 -07:00
										 |  |  |     # gcc is required for libgcc_s.so.1 if glibc or gcc are too old | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     return unless DevelopmentTools.needs_build_formulae? | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  |     return if building_global_dep_tree? | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  |     return if related_formula_names.include?(GCC) | 
					
						
							|  |  |  |     return if global_dep_tree[GCC]&.intersect?(related_formula_names) | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     return unless formula_for(GCC) | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Dependency.new(GCC) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) } | 
					
						
							|  |  |  |   def glibc_dep_if_needed(related_formula_names) | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     return unless DevelopmentTools.needs_libc_formula? | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  |     return if building_global_dep_tree? | 
					
						
							|  |  |  |     return if related_formula_names.include?(GLIBC) | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  |     return if global_dep_tree[GLIBC]&.intersect?(related_formula_names) | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     return unless formula_for(GLIBC) | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Dependency.new(GLIBC) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GLIBC = "glibc" | 
					
						
							| 
									
										
										
										
											2022-09-18 00:58:47 +01:00
										 |  |  |   GCC = OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   sig { void } | 
					
						
							|  |  |  |   def init_global_dep_tree_if_needed! | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     return unless DevelopmentTools.needs_build_formulae? | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  |     return if building_global_dep_tree? | 
					
						
							|  |  |  |     return unless global_dep_tree.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     building_global_dep_tree! | 
					
						
							|  |  |  |     global_dep_tree[GLIBC] = Set.new(global_deps_for(GLIBC)) | 
					
						
							|  |  |  |     # gcc depends on glibc | 
					
						
							|  |  |  |     global_dep_tree[GCC] = Set.new([*global_deps_for(GCC), GLIBC, *@@global_dep_tree[GLIBC]]) | 
					
						
							|  |  |  |     built_global_dep_tree! | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |   sig { params(name: String).returns(T.nilable(Formula)) } | 
					
						
							|  |  |  |   def formula_for(name) | 
					
						
							|  |  |  |     @formula_for ||= {} | 
					
						
							|  |  |  |     @formula_for[name] ||= Formula[name] | 
					
						
							|  |  |  |   rescue FormulaUnavailableError | 
					
						
							|  |  |  |     nil | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  |   sig { params(name: String).returns(T::Array[String]) } | 
					
						
							|  |  |  |   def global_deps_for(name) | 
					
						
							|  |  |  |     @global_deps_for ||= {} | 
					
						
							|  |  |  |     # Always strip out glibc and gcc from all parts of dependency tree when | 
					
						
							|  |  |  |     # we're calculating their dependency trees. Other parts of Homebrew will | 
					
						
							|  |  |  |     # catch any circular dependencies. | 
					
						
							| 
									
										
										
										
											2022-11-09 14:45:43 +00:00
										 |  |  |     @global_deps_for[name] ||= if (formula = formula_for(name)) | 
					
						
							|  |  |  |       formula.deps.map(&:name).flat_map do |dep| | 
					
						
							|  |  |  |         [dep, *global_deps_for(dep)].compact | 
					
						
							|  |  |  |       end.uniq | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       [] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Use class variables to avoid this expensive logic needing to be done more | 
					
						
							|  |  |  |   # than once. | 
					
						
							|  |  |  |   # rubocop:disable Style/ClassVars | 
					
						
							|  |  |  |   @@global_dep_tree = {} | 
					
						
							|  |  |  |   @@building_global_dep_tree = false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  |   sig { returns(T::Hash[String, T::Set[String]]) } | 
					
						
							|  |  |  |   def global_dep_tree | 
					
						
							|  |  |  |     @@global_dep_tree | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-08-30 12:54:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   sig { void } | 
					
						
							|  |  |  |   def building_global_dep_tree! | 
					
						
							|  |  |  |     @@building_global_dep_tree = true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { void } | 
					
						
							|  |  |  |   def built_global_dep_tree! | 
					
						
							|  |  |  |     @@building_global_dep_tree = false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { returns(T::Boolean) } | 
					
						
							|  |  |  |   def building_global_dep_tree? | 
					
						
							|  |  |  |     @@building_global_dep_tree.present? | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-08-25 11:04:37 +01:00
										 |  |  |   # rubocop:enable Style/ClassVars | 
					
						
							|  |  |  | end |