Created
March 25, 2022 00:45
-
-
Save dpo/2cf0684e2f44e30e401d86b881ef259d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GccAT7 < Formula | |
desc "GNU compiler collection" | |
homepage "https://gcc.gnu.org/" | |
url "https://ftp.gnu.org/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz" | |
mirror "https://ftpmirror.gnu.org/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz" | |
sha256 "b81946e7f01f90528a1f7352ab08cc602b9ccc05d4e44da4bd501c5a189ee661" | |
license all_of: [ | |
"LGPL-2.1-or-later", | |
"GPL-3.0-or-later" => { with: "GCC-exception-3.1" }, | |
] | |
revision 4 | |
livecheck do | |
url :stable | |
regex(%r{href=.*?gcc[._-]v?(7(?:\.\d+)+)(?:/?["' >]|\.t)}i) | |
end | |
bottle do | |
sha256 big_sur: "f53816251cabd7c7cc5818af052ad0cccab189156fd63243be2b1bee21d8a0b7" | |
sha256 catalina: "359aee8f81fae1591bb685a6c38dbcace62d32d1ba7a69b01c15061ce29e61bb" | |
sha256 mojave: "95659aa77c264356df8c2eb9d24800aba62f0d308b86d601e0d259885700aebf" | |
sha256 x86_64_linux: "a4e1eccf168ea1fb7b02b186f3dbe9f5c3c44b95fb815ddf692b5f13698d78ca" | |
end | |
# The bottles are built on systems with the CLT installed, and do not work | |
# out of the box on Xcode-only systems due to an incorrect sysroot. | |
pour_bottle? only_if: :clt_installed | |
depends_on arch: :x86_64 | |
depends_on "gmp" | |
depends_on "isl" | |
depends_on "libmpc" | |
depends_on "mpfr" | |
uses_from_macos "zlib" | |
on_linux do | |
depends_on "binutils" | |
end | |
# GCC bootstraps itself, so it is OK to have an incompatible C++ stdlib | |
cxxstdlib_check :skip | |
def version_suffix | |
version.major.to_s | |
end | |
def install | |
# GCC will suffer build errors if forced to use a particular linker. | |
ENV.delete "LD" | |
# Even when suffixes are appended, the info pages conflict when | |
# install-info is run so pretend we have an outdated makeinfo | |
# to prevent their build. | |
ENV["gcc_cv_prog_makeinfo_modern"] = "no" | |
# We avoiding building: | |
# - Ada, which requires a pre-existing GCC Ada compiler to bootstrap | |
# - Go, currently not supported on macOS | |
# - BRIG | |
languages = %w[c c++ objc obj-c++ fortran] | |
ENV.append "LIBRARY_PATH", "/usr/lib64" | |
args = [ | |
"--prefix=#{prefix}", | |
"--libdir=#{lib}/gcc/#{version_suffix}", | |
"--enable-languages=#{languages.join(",")}", | |
# Make most executables versioned to avoid conflicts. | |
"--program-suffix=-#{version_suffix}", | |
"--with-gmp=#{Formula["gmp"].opt_prefix}", | |
"--with-mpfr=#{Formula["mpfr"].opt_prefix}", | |
"--with-mpc=#{Formula["libmpc"].opt_prefix}", | |
"--with-isl=#{Formula["isl"].opt_prefix}", | |
"--enable-checking=release", | |
"--with-pkgversion=Homebrew GCC #{pkg_version} #{build.used_options*" "}".strip, | |
#"--with-bugurl=#{tap.issues_url}", | |
"--disable-nls", | |
] | |
if OS.mac? | |
args << "--build=x86_64-apple-darwin#{OS.kernel_version}" | |
args << "--with-system-zlib" | |
# Xcode 10 dropped 32-bit support | |
args << "--disable-multilib" if DevelopmentTools.clang_build_version >= 1000 | |
# System headers may not be in /usr/include | |
sdk = MacOS.sdk_path_if_needed | |
if sdk | |
args << "--with-native-system-header-dir=/usr/include" | |
args << "--with-sysroot=#{sdk}" | |
end | |
# Ensure correct install names when linking against libgcc_s; | |
# see discussion in https://github.com/Homebrew/homebrew/pull/34303 | |
inreplace "libgcc/config/t-slibgcc-darwin", "@shlib_slibdir@", "#{HOMEBREW_PREFIX}/lib/gcc/#{version_suffix}" | |
else | |
# Fix Linux error: gnu/stubs-32.h: No such file or directory. | |
args << "--disable-multilib" | |
# Change the default directory name for 64-bit libraries to `lib` | |
# http://www.linuxfromscratch.org/lfs/view/development/chapter06/gcc.html | |
inreplace "gcc/config/i386/t-linux64", "m64=../lib64", "m64=" | |
end | |
mkdir "build" do | |
system "../configure", *args | |
system "make" | |
if OS.mac? | |
system "make", "install" | |
else | |
system "make", "install-strip" | |
end | |
end | |
# Handle conflicts between GCC formulae and avoid interfering | |
# with system compilers. | |
# Rename man7. | |
Dir.glob(man7/"*.7") { |file| add_suffix file, version_suffix } | |
# Even when we disable building info pages some are still installed. | |
info.rmtree | |
end | |
def add_suffix(file, suffix) | |
dir = File.dirname(file) | |
ext = File.extname(file) | |
base = File.basename(file, ext) | |
File.rename file, "#{dir}/#{base}-#{suffix}#{ext}" | |
end | |
def post_install | |
if OS.linux? | |
gcc = bin/"gcc-#{version_suffix}" | |
libgcc = Pathname.new(Utils.safe_popen_read(gcc, "-print-libgcc-file-name")).parent | |
raise "command failed: #{gcc} -print-libgcc-file-name" if $CHILD_STATUS.exitstatus.nonzero? | |
glibc = Formula["glibc"] | |
glibc_installed = glibc.any_version_installed? | |
# Symlink crt1.o and friends where gcc can find it. | |
crtdir = if glibc_installed | |
glibc.opt_lib | |
else | |
Pathname.new(Utils.safe_popen_read("/usr/bin/cc", "-print-file-name=crti.o")).parent | |
end | |
ln_sf Dir[crtdir/"*crt?.o"], libgcc | |
# Create the GCC specs file | |
# See https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html | |
# Locate the specs file | |
specs = libgcc/"specs" | |
ohai "Creating the GCC specs file: #{specs}" | |
specs_orig = Pathname.new("#{specs}.orig") | |
rm_f [specs_orig, specs] | |
system_header_dirs = ["#{HOMEBREW_PREFIX}/include"] | |
if glibc_installed | |
# https://github.com/Linuxbrew/brew/issues/724 | |
system_header_dirs << glibc.opt_include | |
else | |
# Locate the native system header dirs if user uses system glibc | |
target = Utils.safe_popen_read(gcc, "-print-multiarch").chomp | |
raise "command failed: #{gcc} -print-multiarch" if $CHILD_STATUS.exitstatus.nonzero? | |
system_header_dirs += ["/usr/include/#{target}", "/usr/include"] | |
end | |
# Save a backup of the default specs file | |
specs_string = Utils.safe_popen_read(gcc, "-dumpspecs") | |
raise "command failed: #{gcc} -dumpspecs" if $CHILD_STATUS.exitstatus.nonzero? | |
specs_orig.write specs_string | |
# Set the library search path | |
# For include path: | |
# * `-isysroot #{HOMEBREW_PREFIX}/nonexistent` prevents gcc searching built-in | |
# system header files. | |
# * `-idirafter <dir>` instructs gcc to search system header | |
# files after gcc internal header files. | |
# For libraries: | |
# * `-nostdlib -L#{libgcc}` instructs gcc to use brewed glibc | |
# if applied. | |
# * `-L#{libdir}` instructs gcc to find the corresponding gcc | |
# libraries. It is essential if there are multiple brewed gcc | |
# with different versions installed. | |
# Noted that it should only be passed for the `gcc@*` formulae. | |
# * `-L#{HOMEBREW_PREFIX}/lib` instructs gcc to find the rest | |
# brew libraries. | |
libdir = HOMEBREW_PREFIX/"lib/gcc/#{version_suffix}" | |
specs.write specs_string + <<~EOS | |
*cpp_unique_options: | |
+ -isysroot #{HOMEBREW_PREFIX}/nonexistent #{system_header_dirs.map { |p| "-idirafter #{p}" }.join(" ")} | |
*link_libgcc: | |
#{glibc_installed ? "-nostdlib -L#{libgcc}" : "+"} -L#{libdir} -L#{HOMEBREW_PREFIX}/lib | |
*link: | |
+ --dynamic-linker #{HOMEBREW_PREFIX}/lib/ld.so -rpath #{libdir} -rpath #{HOMEBREW_PREFIX}/lib | |
EOS | |
end | |
end | |
test do | |
(testpath/"hello-c.c").write <<~EOS | |
#include <stdio.h> | |
int main() | |
{ | |
puts("Hello, world!"); | |
return 0; | |
} | |
EOS | |
system "#{bin}/gcc-#{version.major}", "-o", "hello-c", "hello-c.c" | |
assert_equal "Hello, world!\n", `./hello-c` | |
(testpath/"hello-cc.cc").write <<~EOS | |
#include <iostream> | |
int main() | |
{ | |
std::cout << "Hello, world!" << std::endl; | |
return 0; | |
} | |
EOS | |
system "#{bin}/g++-#{version.major}", "-o", "hello-cc", "hello-cc.cc" | |
assert_equal "Hello, world!\n", `./hello-cc` | |
(testpath/"test.f90").write <<~EOS | |
integer,parameter::m=10000 | |
real::a(m), b(m) | |
real::fact=0.5 | |
do concurrent (i=1:m) | |
a(i) = a(i) + fact*b(i) | |
end do | |
write(*,"(A)") "Done" | |
end | |
EOS | |
system "#{bin}/gfortran-#{version.major}", "-o", "test", "test.f90" | |
assert_equal "Done\n", `./test` | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment