Create active symlinks for installed formula
Similar to the LinkedKegs record, we write a symlink for installed kegs to PREFIX/opt. Unlike the linked-keg record, unlinking doesn't remove the link, only uninstalling, and keg-only formula have a record too. The reason for this addition is so that formula that depend on keg-only formula can build against the opt directory and not the cellar keg. Thus surviving upgrades. To enforce this fix_install_names and built were adapted to use the opt path. Standard kegs also create an opt symlink so that caveats can now refer to the opt directory and thus provide steps that survive upgrades too. Thus the choice of /opt. It is short, neat and the right choice: POSIX dictates that opt is for stand-alone prefixes of software.
This commit is contained in:
parent
50767c6077
commit
f02d81ecbf
@ -61,14 +61,18 @@ def install f
|
||||
f.recursive_deps.uniq.each do |dep|
|
||||
dep = Formula.factory dep
|
||||
if dep.keg_only?
|
||||
ENV.prepend 'LDFLAGS', "-L#{dep.lib}"
|
||||
ENV.prepend 'CPPFLAGS', "-I#{dep.include}"
|
||||
ENV.prepend 'PATH', "#{dep.bin}", ':'
|
||||
opt = HOMEBREW_PREFIX/:opt/dep.name
|
||||
|
||||
pcdir = dep.lib/'pkgconfig'
|
||||
raise "#{opt} not present\nReinstall #{dep}." unless opt.directory?
|
||||
|
||||
ENV.prepend 'LDFLAGS', "-L#{opt}/lib"
|
||||
ENV.prepend 'CPPFLAGS', "-I#{opt}/include"
|
||||
ENV.prepend 'PATH', "#{opt}/bin", ':'
|
||||
|
||||
pcdir = opt/'lib/pkgconfig'
|
||||
ENV.prepend 'PKG_CONFIG_PATH', pcdir, ':' if pcdir.directory?
|
||||
|
||||
acdir = dep.share/'aclocal'
|
||||
acdir = opt/'share/aclocal'
|
||||
ENV.prepend 'ACLOCAL_PATH', acdir, ':' if acdir.directory?
|
||||
end
|
||||
end
|
||||
|
||||
@ -10,6 +10,7 @@ module Homebrew extend self
|
||||
puts "Uninstalling #{keg}..."
|
||||
keg.unlink
|
||||
keg.uninstall
|
||||
rm_opt_link keg.fname
|
||||
end
|
||||
else
|
||||
ARGV.named.each do |name|
|
||||
@ -30,10 +31,18 @@ module Homebrew extend self
|
||||
end
|
||||
rack.rmtree
|
||||
end
|
||||
|
||||
rm_opt_link name
|
||||
end
|
||||
end
|
||||
rescue MultipleVersionsInstalledError => e
|
||||
ofail e
|
||||
puts "Use `brew remove --force #{e.name}` to remove all versions."
|
||||
end
|
||||
|
||||
def rm_opt_link name
|
||||
optlink = HOMEBREW_PREFIX/:opt/name
|
||||
optlink.unlink if optlink.symlink?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -148,6 +148,8 @@ class Formula
|
||||
self.class.build
|
||||
end
|
||||
|
||||
def opt_prefix; HOMEBREW_PREFIX/:opt/name end
|
||||
|
||||
# Use the @active_spec to detect the download strategy.
|
||||
# Can be overriden to force a custom download strategy
|
||||
def download_strategy
|
||||
|
||||
@ -172,10 +172,18 @@ class FormulaInstaller
|
||||
def finish
|
||||
ohai 'Finishing up' if ARGV.verbose?
|
||||
|
||||
unless f.keg_only?
|
||||
if f.keg_only?
|
||||
begin
|
||||
Keg.new(f.prefix).optlink
|
||||
rescue Exception => e
|
||||
onoe "Failed to create: #{f.opt_prefix}"
|
||||
puts "Things that depend on #{f} will probably not build."
|
||||
end
|
||||
else
|
||||
link
|
||||
check_PATH
|
||||
check_PATH unless f.keg_only?
|
||||
end
|
||||
|
||||
fix_install_names
|
||||
|
||||
ohai "Summary" if ARGV.verbose? or show_summary_heading
|
||||
|
||||
@ -42,7 +42,7 @@ class Keg < Pathname
|
||||
Find.prune if src.directory?
|
||||
end
|
||||
end
|
||||
linked_keg_record.unlink if linked_keg_record.exist?
|
||||
linked_keg_record.unlink if linked_keg_record.symlink?
|
||||
n
|
||||
end
|
||||
|
||||
@ -126,7 +126,25 @@ class Keg < Pathname
|
||||
|
||||
linked_keg_record.make_relative_symlink(self) unless mode == :dryrun
|
||||
|
||||
optlink unless mode == :dryrun
|
||||
|
||||
return $n + $d
|
||||
rescue Exception
|
||||
opoo "Could not link #{fname}. Unlinking..."
|
||||
unlink
|
||||
raise
|
||||
end
|
||||
|
||||
def optlink
|
||||
from = HOMEBREW_PREFIX/:opt/fname
|
||||
if from.symlink?
|
||||
from.delete
|
||||
elsif from.directory?
|
||||
from.rmdir
|
||||
elsif from.exist?
|
||||
from.delete
|
||||
end
|
||||
from.make_relative_symlink(self)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
@ -56,8 +56,13 @@ class Keg
|
||||
end
|
||||
|
||||
# the shortpath ensures that library upgrades don’t break installed tools
|
||||
shortpath = HOMEBREW_PREFIX + Pathname.new(file).relative_path_from(self)
|
||||
id = if shortpath.exist? then shortpath else file end
|
||||
relative_path = Pathname.new(file).relative_path_from(self)
|
||||
shortpath = HOMEBREW_PREFIX.join(relative_path)
|
||||
id = if shortpath.exist?
|
||||
shortpath
|
||||
else
|
||||
"#{HOMEBREW_PREFIX}/opt/#{fname}/#{relative_path}"
|
||||
end
|
||||
|
||||
yield id, install_names
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user