| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  | class Keg | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |   PREFIX_PLACEHOLDER = "@@HOMEBREW_PREFIX@@".freeze | 
					
						
							|  |  |  |   CELLAR_PLACEHOLDER = "@@HOMEBREW_CELLAR@@".freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-08 23:01:03 +01:00
										 |  |  |   def fix_install_names | 
					
						
							| 
									
										
										
										
											2012-06-16 16:14:47 -05:00
										 |  |  |     mach_o_files.each do |file| | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |       file.ensure_writable do | 
					
						
							| 
									
										
										
										
											2015-11-08 23:01:03 +01:00
										 |  |  |         change_dylib_id(dylib_id_for(file), file) if file.dylib? | 
					
						
							| 
									
										
										
										
											2012-06-16 16:14:47 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |         each_install_name_for(file) do |bad_name| | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |           # Don't fix absolute paths unless they are rooted in the build directory | 
					
						
							| 
									
										
										
										
											2015-08-03 14:25:38 +01:00
										 |  |  |           next if bad_name.start_with?("/") && !bad_name.start_with?(HOMEBREW_TEMP.to_s) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |           new_name = fixed_name(file, bad_name) | 
					
						
							|  |  |  |           change_install_name(bad_name, new_name, file) unless new_name == bad_name | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-09-11 16:32:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     symlink_files.each do |file| | 
					
						
							|  |  |  |       link = file.readlink | 
					
						
							|  |  |  |       # Don't fix relative symlinks | 
					
						
							|  |  |  |       next unless link.absolute? | 
					
						
							|  |  |  |       if link.to_s.start_with?(HOMEBREW_CELLAR.to_s) || link.to_s.start_with?(HOMEBREW_PREFIX.to_s) | 
					
						
							|  |  |  |         FileUtils.ln_sf(link.relative_path_from(file.parent), file) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-08 23:01:03 +01:00
										 |  |  |   def relocate_install_names(old_prefix, new_prefix, old_cellar, new_cellar) | 
					
						
							| 
									
										
										
										
											2013-03-11 18:56:26 +00:00
										 |  |  |     mach_o_files.each do |file| | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |       file.ensure_writable do | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |         if file.dylib? | 
					
						
							| 
									
										
										
										
											2015-11-08 23:01:03 +01:00
										 |  |  |           id = dylib_id_for(file).sub(old_prefix, new_prefix) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |           change_dylib_id(id, file) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |         each_install_name_for(file) do |old_name| | 
					
						
							|  |  |  |           if old_name.start_with? old_cellar | 
					
						
							|  |  |  |             new_name = old_name.sub(old_cellar, new_cellar) | 
					
						
							|  |  |  |           elsif old_name.start_with? old_prefix | 
					
						
							|  |  |  |             new_name = old_name.sub(old_prefix, new_prefix) | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           change_install_name(old_name, new_name, file) if new_name | 
					
						
							| 
									
										
										
										
											2013-03-11 18:56:26 +00:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-09-11 18:55:46 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 18:55:46 +08:00
										 |  |  |   def relocate_text_files(old_prefix, new_prefix, old_cellar, new_cellar) | 
					
						
							| 
									
										
										
										
											2015-07-23 16:29:37 +08:00
										 |  |  |     files = text_files | libtool_files | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     files.group_by { |f| f.stat.ino }.each_value do |first, *rest| | 
					
						
							| 
									
										
										
										
											2014-03-27 14:17:13 -05:00
										 |  |  |       s = first.open("rb", &:read) | 
					
						
							| 
									
										
										
										
											2014-03-27 21:42:09 -05:00
										 |  |  |       changed = s.gsub!(old_cellar, new_cellar) | 
					
						
							|  |  |  |       changed = s.gsub!(old_prefix, new_prefix) || changed | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-20 14:40:28 +00:00
										 |  |  |       next unless changed | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-05 23:07:28 -05:00
										 |  |  |       begin | 
					
						
							| 
									
										
										
										
											2014-03-27 21:42:09 -05:00
										 |  |  |         first.atomic_write(s) | 
					
						
							| 
									
										
										
										
											2014-09-25 14:34:28 -05:00
										 |  |  |       rescue SystemCallError | 
					
						
							| 
									
										
										
										
											2014-04-05 23:07:28 -05:00
										 |  |  |         first.ensure_writable do | 
					
						
							|  |  |  |           first.open("wb") { |f| f.write(s) } | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2014-03-27 21:42:09 -05:00
										 |  |  |         rest.each { |file| FileUtils.ln(first, file, :force => true) } | 
					
						
							| 
									
										
										
										
											2015-11-20 14:40:28 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-03-11 18:56:26 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-06 01:51:31 -07:00
										 |  |  |   # Detects the C++ dynamic libraries in place, scanning the dynamic links | 
					
						
							| 
									
										
										
										
											2015-06-27 20:04:45 -04:00
										 |  |  |   # of the files within the keg. | 
					
						
							| 
									
										
										
										
											2013-10-06 01:51:31 -07:00
										 |  |  |   # Note that this doesn't attempt to distinguish between libstdc++ versions, | 
					
						
							|  |  |  |   # for instance between Apple libstdc++ and GNU libstdc++ | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def detect_cxx_stdlibs(options = {}) | 
					
						
							| 
									
										
										
										
											2015-03-14 01:51:04 -04:00
										 |  |  |     skip_executables = options.fetch(:skip_executables, false) | 
					
						
							| 
									
										
										
										
											2013-10-06 01:51:31 -07:00
										 |  |  |     results = Set.new | 
					
						
							| 
									
										
										
										
											2013-10-08 09:03:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-24 20:29:14 -07:00
										 |  |  |     mach_o_files.each do |file| | 
					
						
							| 
									
										
										
										
											2014-08-09 17:37:57 -05:00
										 |  |  |       next if file.mach_o_executable? && skip_executables | 
					
						
							| 
									
										
										
										
											2013-10-06 01:51:31 -07:00
										 |  |  |       dylibs = file.dynamically_linked_libraries | 
					
						
							|  |  |  |       results << :libcxx unless dylibs.grep(/libc\+\+.+\.dylib/).empty? | 
					
						
							|  |  |  |       results << :libstdcxx unless dylibs.grep(/libstdc\+\+.+\.dylib/).empty? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     results.to_a | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def each_unique_file_matching(string) | 
					
						
							| 
									
										
										
										
											2014-07-05 13:50:54 -05:00
										 |  |  |     Utils.popen_read("/usr/bin/fgrep", "-lr", string, to_s) do |io| | 
					
						
							| 
									
										
										
										
											2013-12-17 20:46:42 -06:00
										 |  |  |       hardlinks = Set.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       until io.eof? | 
					
						
							|  |  |  |         file = Pathname.new(io.readline.chomp) | 
					
						
							|  |  |  |         next if file.symlink? | 
					
						
							|  |  |  |         yield file if hardlinks.add? file.stat.ino | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:40:57 -05:00
										 |  |  |   # If file is a dylib or bundle itself, look for the dylib named by | 
					
						
							|  |  |  |   # bad_name relative to the lib directory, so that we can skip the more | 
					
						
							|  |  |  |   # expensive recursive search if possible. | 
					
						
							|  |  |  |   def fixed_name(file, bad_name) | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |     if bad_name.start_with? PREFIX_PLACEHOLDER | 
					
						
							|  |  |  |       bad_name.sub(PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s) | 
					
						
							|  |  |  |     elsif bad_name.start_with? CELLAR_PLACEHOLDER | 
					
						
							|  |  |  |       bad_name.sub(CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s) | 
					
						
							|  |  |  |     elsif (file.dylib? || file.mach_o_bundle?) && (file.parent + bad_name).exist? | 
					
						
							| 
									
										
										
										
											2013-05-22 11:40:57 -05:00
										 |  |  |       "@loader_path/#{bad_name}" | 
					
						
							|  |  |  |     elsif file.mach_o_executable? && (lib + bad_name).exist? | 
					
						
							|  |  |  |       "#{lib}/#{bad_name}" | 
					
						
							| 
									
										
										
										
											2015-11-18 21:49:20 +01:00
										 |  |  |     elsif (abs_name = find_dylib(bad_name)) && abs_name.exist? | 
					
						
							| 
									
										
										
										
											2013-05-22 11:40:57 -05:00
										 |  |  |       abs_name.to_s | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-05-22 19:42:43 -05:00
										 |  |  |       opoo "Could not fix #{bad_name} in #{file}" | 
					
						
							|  |  |  |       bad_name | 
					
						
							| 
									
										
										
										
											2013-05-22 11:40:57 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   def lib | 
					
						
							|  |  |  |     path.join("lib") | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def each_install_name_for(file, &block) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |     dylibs = file.dynamically_linked_libraries | 
					
						
							|  |  |  |     dylibs.reject! { |fn| fn =~ /^@(loader_|executable_|r)path/ } | 
					
						
							|  |  |  |     dylibs.each(&block) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-08 23:01:03 +01:00
										 |  |  |   def dylib_id_for(file) | 
					
						
							| 
									
										
										
										
											2014-04-13 13:53:46 -05:00
										 |  |  |     # The new dylib ID should have the same basename as the old dylib ID, not | 
					
						
							|  |  |  |     # the basename of the file itself. | 
					
						
							|  |  |  |     basename = File.basename(file.dylib_id) | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     relative_dirname = file.dirname.relative_path_from(path) | 
					
						
							| 
									
										
										
										
											2015-09-02 11:05:31 -07:00
										 |  |  |     opt_record.join(relative_dirname, basename).to_s | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:49:20 +01:00
										 |  |  |   # Matches framework references like `XXX.framework/Versions/YYY/XXX` and | 
					
						
							|  |  |  |   # `XXX.framework/XXX`, both with or without a slash-delimited prefix. | 
					
						
							|  |  |  |   FRAMEWORK_RX = %r{(?:^|/)(([^/]+)\.framework/(?:Versions/[^/]+/)?\2)$}.freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def find_dylib_suffix_from(bad_name) | 
					
						
							|  |  |  |     if (framework = bad_name.match(FRAMEWORK_RX)) | 
					
						
							|  |  |  |       framework[1] | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       File.basename(bad_name) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def find_dylib(bad_name) | 
					
						
							|  |  |  |     return unless lib.directory? | 
					
						
							|  |  |  |     suffix = "/#{find_dylib_suffix_from(bad_name)}" | 
					
						
							|  |  |  |     lib.find { |pn| break pn if pn.to_s.end_with?(suffix) } | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-16 16:14:47 -05:00
										 |  |  |   def mach_o_files | 
					
						
							|  |  |  |     mach_o_files = [] | 
					
						
							| 
									
										
										
										
											2014-09-28 15:25:41 -07:00
										 |  |  |     path.find do |pn| | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |       next if pn.symlink? || pn.directory? | 
					
						
							|  |  |  |       mach_o_files << pn if pn.dylib? || pn.mach_o_bundle? || pn.mach_o_executable? | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-11-06 13:04:40 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-16 16:14:47 -05:00
										 |  |  |     mach_o_files | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-14 11:56:34 -07:00
										 |  |  |   def text_files | 
					
						
							|  |  |  |     text_files = [] | 
					
						
							|  |  |  |     path.find do |pn| | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |       next if pn.symlink? || pn.directory? | 
					
						
							| 
									
										
										
										
											2015-07-14 11:56:34 -07:00
										 |  |  |       next if Metafiles::EXTENSIONS.include? pn.extname | 
					
						
							| 
									
										
										
										
											2015-07-20 12:06:13 +01:00
										 |  |  |       if Utils.popen_read("/usr/bin/file", "--brief", pn).include?("text") || | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |          pn.text_executable? | 
					
						
							| 
									
										
										
										
											2015-07-20 12:06:13 +01:00
										 |  |  |         text_files << pn | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-14 11:56:34 -07:00
										 |  |  |     text_files | 
					
						
							| 
									
										
										
										
											2015-07-10 19:51:43 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-07-23 16:29:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def libtool_files | 
					
						
							|  |  |  |     libtool_files = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:06:14 +01:00
										 |  |  |     path.find do |pn| | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |       next if pn.symlink? || pn.directory? || pn.extname != ".la" | 
					
						
							| 
									
										
										
										
											2015-07-23 16:29:37 +08:00
										 |  |  |       libtool_files << pn | 
					
						
							| 
									
										
										
										
											2016-04-24 22:06:14 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-07-23 16:29:37 +08:00
										 |  |  |     libtool_files | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-09-11 16:32:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def symlink_files | 
					
						
							|  |  |  |     symlink_files = [] | 
					
						
							|  |  |  |     path.find do |pn| | 
					
						
							|  |  |  |       symlink_files << pn if pn.symlink? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     symlink_files | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  | end |