From ec08e257e8ba73f07add12ed0850f82f4682ba95 Mon Sep 17 00:00:00 2001 From: Dibyendu Majumdar Date: Thu, 13 Aug 2015 22:35:07 +0100 Subject: [PATCH] test libgccjit on OSX Yosemite --- cmake/FindGCCJIT.cmake | 4 +- patches/gcc.rb | 279 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 patches/gcc.rb diff --git a/cmake/FindGCCJIT.cmake b/cmake/FindGCCJIT.cmake index a964646..01fd304 100644 --- a/cmake/FindGCCJIT.cmake +++ b/cmake/FindGCCJIT.cmake @@ -1,12 +1,14 @@ find_path(GCCJIT_INC libgccjit.h PATHS ~/local/include + /usr/local/include ) find_library(GCCJIT_LIB - NAMES gccjit libgccjit + NAMES gccjit libgccjit PATHS ~/local/lib + /usr/local/lib/gcc/5 ) set( GCCJIT_INCLUDE_DIRS "${GCCJIT_INC}" ) diff --git a/patches/gcc.rb b/patches/gcc.rb new file mode 100644 index 0000000..3c1e983 --- /dev/null +++ b/patches/gcc.rb @@ -0,0 +1,279 @@ +class Gcc < Formula + def arch + if Hardware::CPU.type == :intel + if MacOS.prefer_64_bit? + "x86_64" + else + "i686" + end + elsif Hardware::CPU.type == :ppc + if MacOS.prefer_64_bit? + "powerpc64" + else + "powerpc" + end + end + end + + def osmajor + `uname -r`.chomp + end + + desc "GNU compiler collection" + homepage "https://gcc.gnu.org" + url "http://ftpmirror.gnu.org/gcc/gcc-5.2.0/gcc-5.2.0.tar.bz2" + mirror "https://ftp.gnu.org/gnu/gcc/gcc-5.2.0/gcc-5.2.0.tar.bz2" + sha256 "5f835b04b5f7dd4f4d2dc96190ec1621b8d89f2dc6f638f9f8bc1b1014ba8cad" + + bottle do + sha256 "b9a41591f99a25a5d57d818953def46c4c654eb5ec8738b5eb975b366068abc3" => :yosemite + sha256 "c70b4f9c65930c0f127cb8a0b220d7b1494edea11218f5ba519b758c3eb7a2cd" => :mavericks + sha256 "131566719249be8795422d86fff0c4b2ee12bb58ad5320dcbff0af2c40d3ece7" => :mountain_lion + end + + option "with-java", "Build the gcj compiler" + option "with-all-languages", "Enable all compilers and languages, except Ada" + option "with-nls", "Build with native language support (localization)" + option "with-jit", "Build the jit compiler" + option "without-fortran", "Build without the gfortran compiler" + # enabling multilib on a host that can't run 64-bit results in build failures + option "without-multilib", "Build without multilib support" if MacOS.prefer_64_bit? + + depends_on "gmp" + depends_on "libmpc" + depends_on "mpfr" + depends_on "isl" + depends_on "ecj" if build.with?("java") || build.with?("all-languages") + + if MacOS.version < :leopard + # The as that comes with Tiger isn't capable of dealing with the + # PPC asm that comes in libitm + depends_on "cctools" => :build + end + + fails_with :gcc_4_0 + fails_with :llvm + + # GCC bootstraps itself, so it is OK to have an incompatible C++ stdlib + cxxstdlib_check :skip + + # 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. + def pour_bottle? + MacOS::CLT.installed? + end + + def version_suffix + version.to_s.slice(/\d/) + end + + # Fix for libgccjit.so linkage on Darwin + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64089 + patch :DATA + + def install + # GCC will suffer build errors if forced to use a particular linker. + ENV.delete "LD" + + if MacOS.version < :leopard + ENV["AS"] = ENV["AS_FOR_TARGET"] = "#{Formula["cctools"].bin}/as" + end + + if build.with? "all-languages" + # Everything but Ada, which requires a pre-existing GCC Ada compiler + # (gnat) to bootstrap. GCC 4.6.0 adds go as a language option, but it is + # currently only compilable on Linux. + languages = %w[c c++ objc obj-c++ fortran java jit] + else + # C, C++, ObjC compilers are always built + languages = %w[c c++ objc obj-c++] + + languages << "fortran" if build.with? "fortran" + languages << "java" if build.with? "java" + languages << "jit" if build.with? "jit" + end + + args = [ + "--build=#{arch}-apple-darwin#{osmajor}", + "--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}", + "--with-system-zlib", + "--enable-libstdcxx-time=yes", + "--enable-stage1-checking", + "--enable-checking=release", + "--enable-lto", + # Use 'bootstrap-debug' build configuration to force stripping of object + # files prior to comparison during bootstrap (broken by Xcode 6.3). + "--with-build-config=bootstrap-debug", + "--disable-werror", + "--with-pkgversion=Homebrew #{name} #{pkg_version} #{build.used_options*" "}".strip, + "--with-bugurl=https://github.com/Homebrew/homebrew/issues" + ] + + # "Building GCC with plugin support requires a host that supports + # -fPIC, -shared, -ldl and -rdynamic." + args << "--enable-plugin" if MacOS.version > :tiger + + # Otherwise make fails during comparison at stage 3 + # See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45248 + args << "--with-dwarf2" if MacOS.version < :leopard + + args << "--disable-nls" if build.without? "nls" + + if build.with?("java") || build.with?("all-languages") + args << "--with-ecj-jar=#{Formula["ecj"].opt_share}/java/ecj.jar" + end + + if build.without?("multilib") || !MacOS.prefer_64_bit? + args << "--disable-multilib" + else + args << "--enable-multilib" + end + + args << "--enable-host-shared" if build.with?("jit") || build.with?("all-languages") + + # 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}" + + mkdir "build" do + unless MacOS::CLT.installed? + # For Xcode-only systems, we need to tell the sysroot path. + # "native-system-headers" will be appended + args << "--with-native-system-header-dir=/usr/include" + args << "--with-sysroot=#{MacOS.sdk_path}" + end + + system "../configure", *args + system "make", "bootstrap" + system "make", "install" + + if build.with?("fortran") || build.with?("all-languages") + bin.install_symlink bin/"gfortran-#{version_suffix}" => "gfortran" + end + end + + # Handle conflicts between GCC formulae and avoid interfering + # with system compilers. + # Since GCC 4.8 libffi stuff are no longer shipped. + # Rename man7. + Dir.glob(man7/"*.7") { |file| add_suffix file, version_suffix } + # Even when suffixes are appended, the info pages conflict when + # install-info is run. TODO fix this. + info.rmtree + + # Rename java properties + if build.with?("java") || build.with?("all-languages") + config_files = [ + "#{lib}/gcc/#{version_suffix}/logging.properties", + "#{lib}/gcc/#{version_suffix}/security/classpath.security", + "#{lib}/gcc/#{version_suffix}/i386/logging.properties", + "#{lib}/gcc/#{version_suffix}/i386/security/classpath.security" + ] + config_files.each do |file| + add_suffix file, version_suffix if File.exist? file + end + end + 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 caveats + if build.with?("multilib") then <<-EOS.undent + GCC has been built with multilib support. Notably, OpenMP may not work: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60670 + If you need OpenMP support you may want to + brew reinstall gcc --without-multilib + EOS + end + end + + test do + (testpath/"hello-c.c").write <<-EOS.undent + #include + int main() + { + puts("Hello, world!"); + return 0; + } + EOS + system "#{bin}/gcc-#{version_suffix}", "-o", "hello-c", "hello-c.c" + assert_equal "Hello, world!\n", `./hello-c` + + (testpath/"hello-cc.cc").write <<-EOS.undent + #include + int main() + { + std::cout << "Hello, world!" << std::endl; + return 0; + } + EOS + system "#{bin}/g++-#{version_suffix}", "-o", "hello-cc", "hello-cc.cc" + assert_equal "Hello, world!\n", `./hello-cc` + + if build.with?("fortran") || build.with?("all-languages") + fixture = <<-EOS.undent + 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 + print *, "done" + end + EOS + (testpath/"in.f90").write(fixture) + system "#{bin}/gfortran", "-c", "in.f90" + system "#{bin}/gfortran", "-o", "test", "in.o" + assert_equal "done", `./test`.strip + end + end +end +__END__ +diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in +index 44d0750..4df2a9c 100644 +--- a/gcc/jit/Make-lang.in ++++ b/gcc/jit/Make-lang.in +@@ -85,8 +85,7 @@ $(LIBGCCJIT_FILENAME): $(jit_OBJS) \ + $(jit_OBJS) libbackend.a libcommon-target.a libcommon.a \ + $(CPPLIB) $(LIBDECNUMBER) $(LIBS) $(BACKENDLIBS) \ + $(EXTRA_GCC_OBJS) \ +- -Wl,--version-script=$(srcdir)/jit/libgccjit.map \ +- -Wl,-soname,$(LIBGCCJIT_SONAME) ++ -Wl,-install_name,$(LIBGCCJIT_SONAME) + + $(LIBGCCJIT_SONAME_SYMLINK): $(LIBGCCJIT_FILENAME) + ln -sf $(LIBGCCJIT_FILENAME) $(LIBGCCJIT_SONAME_SYMLINK) +diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c +index 925fa86..01cfd4b 100644 +--- a/gcc/jit/jit-playback.c ++++ b/gcc/jit/jit-playback.c +@@ -2416,6 +2416,15 @@ invoke_driver (const char *ctxt_progname, + time. */ + ADD_ARG ("-fno-use-linker-plugin"); + ++#if defined (DARWIN_X86) || defined (DARWIN_PPC) ++ /* OS X's linker defaults to treating undefined symbols as errors. ++ If the context has any imported functions or globals they will be ++ undefined until the .so is dynamically-linked into the process. ++ Ensure that the driver passes in "-undefined dynamic_lookup" to the ++ linker. */ ++ ADD_ARG ("-Wl,-undefined,dynamic_lookup"); ++#endif ++ + /* pex argv arrays are NULL-terminated. */ + argvec.safe_push (NULL); +