Skip to content
This repository has been archived by the owner on Jul 4, 2023. It is now read-only.

GCC version changes break bottle linkage #33948

Closed
ianml opened this issue Nov 5, 2014 · 13 comments
Closed

GCC version changes break bottle linkage #33948

ianml opened this issue Nov 5, 2014 · 13 comments

Comments

@ianml
Copy link
Contributor

ianml commented Nov 5, 2014

GCC's practice of installing to target/version subdirectories breaks linkage in downstream formulae for each release. So right now all three bottles here that depend on :fortran need to be rebuilt because they link against 4.9.1.

  • open-mpi
  • libxc
  • grib-api

This is a much more obvious problem in Homebrew/science, where we get an influx of issues and recompiling of massive builds like Octave and its dependencies after each minor GCC release. Looking at the docs, there doesn't seem to be a reasonable way to get around this. Perhaps someone more experienced with GCC could provide insight.

@mistydemeo
Copy link
Member

Looking at the configure script, there doesn't seem to be an official way to do this. It should be possible though, and I think it's a good idea.

@MikeMcQuaid
Copy link
Member

Rebottling them now.

@kfine
Copy link

kfine commented Nov 6, 2014

I don't think this is limited to just bottles. Pgplot, for instance, also breaks due to the GCC release changing version numbers as it can no longer find libgfortran.3.dylib

@DomT4
Copy link
Member

DomT4 commented Nov 6, 2014

Could we symlink the previously named dylibs & such onto the current version? ie, symlink a libgfortran.3.dylib onto libgfortran.3.9.dylib or such. Would that work? It's pretty hacky, but ❓

@mistydemeo
Copy link
Member

GCC uses the contents of gcc/BASE-VER to determine both the version number in the version string and the install locations. I tried changing it, which fixes the install names but of course breaking the version number in --version isn't very helpful. I'll look at patching the configure script to adjust the install locations.

Moving forward, we could have GCC install to a directory that doesn't contain minor version so it doesn't break on point releases, e.g. 4.9 instead of 4.9.1 or 4.9.2.

@jacknagel
Copy link
Contributor

I thought this was because we pass --enable-version-specific-runtime-libs? Or is that something else?

@mistydemeo
Copy link
Member

It is, yes. --enable-version-specific-runtime-libs uses the full version (e.g. 4.9.2) - I think it'd be a good idea to move to sandboxing libs within the series release (e.g. 4.9), so we don't break things when we bump point releases.

@jacknagel
Copy link
Contributor

We should ask the gcc developers for suggestions before we make any changes.

@tkelman
Copy link
Contributor

tkelman commented Nov 8, 2014

This breaks most of JuliaLang's bottles at every point release as well, making testing on OSX Travis impossible until our lone bottle-builder gets a chance to rebuild everything. Hopefully there's a good long-term solution here.

@staticfloat
Copy link
Contributor

I'd like to also point out that entwined with this issue is the fact that the paths contain OSX minor version numbers as well, such as this path on my 10.8 machine: /usr/local/Cellar/gcc/4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/libgfortran.dylib. This forces us to rebottle gcc every time an OSX minor version comes out simply because the paths between a bottled version of gcc has different paths than a from-source build does.

I don't have problems with C-compiled programs, it's only things that get linked by gfortran, so if we could figure out a way to get gfortran to, e.g. use our opt paths, that would be heavenly.

@tdsmith
Copy link
Contributor

tdsmith commented Nov 9, 2014

I half-seriously opened a PR at homebrew-python to keep a copy of the relevant gcc libraries inside scipy's prefix and to rewrite linkages to point to the sequestered libraries. There's a tool called delocate which does this (which is used to make Python wheel binary distributions and happens to be written in Python but isn't otherwise Python-specific) but I think the functionality would be relatively straightforward to reimplement in Ruby and pull into Homebrew core if we chose to implement a sequester_gcc_libraries method or something.

@tdsmith
Copy link
Contributor

tdsmith commented Nov 9, 2014

There is some new progress on a -static-libquadmath switch that, together with -static-libgfortran -static-libgcc, could provide another option. Previous discussions had stalled.

@mistydemeo
Copy link
Member

I'm experimenting with a few tweaks to the formula to remove --enable-version-specific-runtime-libs and instead sandbox GCC within libexec, to avoid linking most of its contents. File list here: https://gist.github.com/mistydemeo/e3808c634f70b66af45a

This links share and the contents of bin publicly while keeping the rest of GCC private. Since it's no longer using --enable-version-specific-runtime-libs, libraries now have paths that won't change between versions.

diff --git a/Library/Formula/gcc.rb b/Library/Formula/gcc.rb
index 899c5f3..13f3a40 100644
--- a/Library/Formula/gcc.rb
+++ b/Library/Formula/gcc.rb
@@ -87,7 +87,7 @@ class Gcc < Formula

     args = [
       "--build=#{arch}-apple-darwin#{osmajor}",
-      "--prefix=#{prefix}",
+      "--prefix=#{libexec}",
       "--enable-languages=#{languages.join(",")}",
       # Make most executables versioned to avoid conflicts.
       "--program-suffix=-#{version_suffix}",
@@ -97,10 +97,6 @@ class Gcc < Formula
       "--with-cloog=#{Formula["cloog"].opt_prefix}",
       "--with-isl=#{Formula["isl"].opt_prefix}",
       "--with-system-zlib",
-      # This ensures lib, libexec, include are sandboxed so that they
-      # don't wander around telling little children there is no Santa
-      # Claus.
-      "--enable-version-specific-runtime-libs",
       "--enable-libstdcxx-time=yes",
       "--enable-stage1-checking",
       "--enable-checking=release",
@@ -143,10 +139,14 @@ class Gcc < Formula
       system "../configure", *args
       system "make", "bootstrap"
       system "make", "install"
+    end

-      if build.with?("fortran") || build.with?("all-languages")
-        bin.install_symlink bin/"gfortran-#{version_suffix}" => "gfortran"
-      end
+    # Symlink contents from bin and share
+    Dir.glob(libexec/"bin/*") {|file| bin.install_symlink file}
+    prefix.install_symlink libexec/"share"
+
+    if build.with?("fortran") || build.with?("all-languages")
+      bin.install_symlink bin/"gfortran-#{version_suffix}" => "gfortran"
     end

     # Handle conflicts between GCC formulae and avoid interfering
@@ -161,10 +161,10 @@ class Gcc < Formula
     # Rename java properties
     if build.with?("java") || build.with?("all-languages")
       config_files = [
-        "#{lib}/logging.properties",
-        "#{lib}/security/classpath.security",
-        "#{lib}/i386/logging.properties",
-        "#{lib}/i386/security/classpath.security"
+        "#{libexec}/lib/logging.properties",
+        "#{libexec}/lib/security/classpath.security",
+        "#{libexec}/lib/i386/logging.properties",
+        "#{libexec}/lib/i386/security/classpath.security"
       ]
       config_files.each do |file|
         add_suffix file, version_suffix if File.exist? file

mistydemeo added a commit to mistydemeo/homebrew that referenced this issue Nov 19, 2014
mistydemeo added a commit to mistydemeo/homebrew that referenced this issue Nov 20, 2014
mistydemeo added a commit to mistydemeo/homebrew that referenced this issue Nov 22, 2014
mistydemeo added a commit to mistydemeo/homebrew that referenced this issue Dec 7, 2014
mistydemeo added a commit to mistydemeo/homebrew that referenced this issue Dec 13, 2014
ClashTheBunny pushed a commit to ClashTheBunny/homebrew that referenced this issue Jan 22, 2015
lumaxis pushed a commit to lumaxis/homebrew that referenced this issue Feb 17, 2015
@Homebrew Homebrew locked and limited conversation to collaborators Feb 17, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants