| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |  | class Keg | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |  |   PREFIX_PLACEHOLDER = "@@HOMEBREW_PREFIX@@".freeze | 
					
						
							|  |  |  |  |   CELLAR_PLACEHOLDER = "@@HOMEBREW_CELLAR@@".freeze | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-02 22:12:13 -07:00
										 |  |  |  |   def fix_install_names options={} | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |  |         change_dylib_id(dylib_id_for(file, options), 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 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |  |           next if bad_name.start_with? '/' and not 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 | 
					
						
							|  |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-02 22:12:13 -07:00
										 |  |  |  |   def relocate_install_names old_prefix, new_prefix, old_cellar, new_cellar, options={} | 
					
						
							| 
									
										
										
										
											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? | 
					
						
							|  |  |  |  |           id = dylib_id_for(file, options).sub(old_prefix, new_prefix) | 
					
						
							|  |  |  |  |           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 | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:58 -06:00
										 |  |  |  |     (pkgconfig_files | libtool_files).each do |file| | 
					
						
							|  |  |  |  |       file.ensure_writable do | 
					
						
							|  |  |  |  |         file.open('rb') do |f| | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |  |           s = f.read | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:58 -06:00
										 |  |  |  |           s.gsub!(old_cellar, new_cellar) | 
					
						
							|  |  |  |  |           s.gsub!(old_prefix, new_prefix) | 
					
						
							|  |  |  |  |           f.reopen(file, 'wb') | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |  |           f.write(s) | 
					
						
							|  |  |  |  |         end | 
					
						
							|  |  |  |  |       end | 
					
						
							|  |  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-03-11 18:56:26 +00:00
										 |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |  |   def change_dylib_id(id, file) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |  |     puts "Changing dylib ID in #{file} to #{id}" if ARGV.debug? | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |  |     install_name_tool("-id", id, file) | 
					
						
							|  |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |  |   def change_install_name(old, new, file) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |  |     puts "Changing install name in #{file} from #{old} to #{new}" if ARGV.debug? | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:57 -06:00
										 |  |  |  |     install_name_tool("-change", old, new, file) | 
					
						
							|  |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-06 01:51:31 -07:00
										 |  |  |  |   # Detects the C++ dynamic libraries in place, scanning the dynamic links | 
					
						
							| 
									
										
										
										
											2013-10-08 09:03:17 -07:00
										 |  |  |  |   # of the files within the keg. This searches only libs contained within | 
					
						
							|  |  |  |  |   # lib/, and ignores binaries and other mach-o objects | 
					
						
							| 
									
										
										
										
											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++ | 
					
						
							| 
									
										
										
										
											2014-01-20 10:04:27 -08:00
										 |  |  |  |   def detect_cxx_stdlibs(opts={: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-01-20 10:04:27 -08:00
										 |  |  |  |       next if file.mach_o_executable? && opts[: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 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 20:46:42 -06:00
										 |  |  |  |   def each_unique_file_matching string | 
					
						
							|  |  |  |  |     IO.popen("/usr/bin/fgrep -lr '#{string}' '#{self}' 2>/dev/null") do |io| | 
					
						
							|  |  |  |  |       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 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |  |   private | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:11:21 -05:00
										 |  |  |  |   def install_name_tool(*args) | 
					
						
							|  |  |  |  |     system(MacOS.locate("install_name_tool"), *args) | 
					
						
							|  |  |  |  |   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}" | 
					
						
							|  |  |  |  |     elsif (abs_name = find_dylib(Pathname.new(bad_name).basename)) && abs_name.exist? | 
					
						
							|  |  |  |  |       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 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  |   def lib; join 'lib' end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06: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 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   def dylib_id_for file, options={} | 
					
						
							| 
									
										
										
										
											2011-06-16 15:11:41 +01:00
										 |  |  |  |     # the shortpath ensures that library upgrades don’t break installed tools | 
					
						
							| 
									
										
										
										
											2013-12-27 16:09:31 -06:00
										 |  |  |  |     relative_path = file.relative_path_from(self) | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |  |     shortpath = HOMEBREW_PREFIX.join(relative_path) | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if shortpath.exist? and not options[:keg_only] | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |  |       shortpath | 
					
						
							|  |  |  |  |     else | 
					
						
							|  |  |  |  |       "#{HOMEBREW_PREFIX}/opt/#{fname}/#{relative_path}" | 
					
						
							|  |  |  |  |     end | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  |   def find_dylib name | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:58 -06:00
										 |  |  |  |     lib.find { |pn| break pn if pn.basename == name } | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  |   end | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-16 16:14:47 -05:00
										 |  |  |  |   def mach_o_files | 
					
						
							|  |  |  |  |     mach_o_files = [] | 
					
						
							| 
									
										
										
										
											2012-11-06 13:04:40 -06:00
										 |  |  |  |     dirs = %w{bin lib Frameworks} | 
					
						
							|  |  |  |  |     dirs.map! { |dir| join(dir) } | 
					
						
							|  |  |  |  |     dirs.reject! { |dir| not dir.directory? } | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-06 13:04:40 -06:00
										 |  |  |  |     dirs.each do |dir| | 
					
						
							|  |  |  |  |       dir.find do |pn| | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  |         next if pn.symlink? or pn.directory? | 
					
						
							| 
									
										
										
										
											2012-11-06 13:04:40 -06:00
										 |  |  |  |         mach_o_files << pn if pn.dylib? or pn.mach_o_bundle? or pn.mach_o_executable? | 
					
						
							| 
									
										
										
										
											2012-09-04 10:49:14 -05:00
										 |  |  |  |       end | 
					
						
							|  |  |  |  |     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
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   def pkgconfig_files | 
					
						
							|  |  |  |  |     pkgconfig_files = [] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # find .pc files, which are stored in lib/pkgconfig | 
					
						
							|  |  |  |  |     pc_dir = self/'lib/pkgconfig' | 
					
						
							|  |  |  |  |     if pc_dir.directory? | 
					
						
							|  |  |  |  |       pc_dir.find do |pn| | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |  |         next if pn.symlink? or pn.directory? or pn.extname != '.pc' | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |  |         pkgconfig_files << pn | 
					
						
							|  |  |  |  |       end | 
					
						
							|  |  |  |  |     end | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # find name-config scripts, which can be all over the keg | 
					
						
							|  |  |  |  |     Pathname.new(self).find do |pn| | 
					
						
							|  |  |  |  |       next if pn.symlink? or pn.directory? | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |  |       pkgconfig_files << pn if pn.basename.to_s.end_with? '-config' and pn.text_executable? | 
					
						
							| 
									
										
										
										
											2013-10-31 01:08:57 -07:00
										 |  |  |  |     end | 
					
						
							|  |  |  |  |     pkgconfig_files | 
					
						
							|  |  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:58 -06:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   def libtool_files | 
					
						
							|  |  |  |  |     libtool_files = [] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # find .la files, which are stored in lib/ | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |  |     lib.find do |pn| | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |  |       next if pn.symlink? or pn.directory? or pn.extname != '.la' | 
					
						
							| 
									
										
										
										
											2013-12-04 22:37:58 -06:00
										 |  |  |  |       libtool_files << pn | 
					
						
							|  |  |  |  |     end | 
					
						
							|  |  |  |  |     libtool_files | 
					
						
							|  |  |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  |  | end |