Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble building gcc on Mac - can't find system headers

Tags:

macos

gcc

I'm on a Mac running OS-X High Sierra and wanted to create a separate build of gcc. Lemme share a little of the process it took me a week to work out so it will help others:

I made a safe directory "gcc" and used svn to get the latest source code from gcc, which it created in a subdirectory called "trunk". I initially created a directory called "build" in the top level of trunk.

It wouldn't compile without the 4 dependencies, so I ran ./contrib/download prerequisites to get them, but it still wouldn't compile, so I went into each of those 4 directories individually and did ./configure, ./make, ./make install, and ./make check. I did the install part because even these dependencies depended on each other, so installing seemed like a safe way to make sure they could be found. Later I found out there is no other way, despite instructions to the contrary...

I succeeded in building the dependencies GMP, MPFR, ISL, and MPC. Then I went back to ./build and the ../configure succeeded, but the build (make) quickly failed saying "source directory already configured; run "make distclean there first". Googling showed this was when you configure in the source directory. I thought maybe my trunk/build directory was considered "in the source directory", so I moved it and tried again and the same thing happened. When I tried to go into trunk and type "make distclean" is just said No rule to make target distclean.

So I thought, maybe it's the 4 dependency directories? Maybe now that they're installed it's safe to distclean them all? There, make distclean worked and took out everything - even the tests I ran. Seems wasteful and necessitates pre make-installing them, but it worked.

Back in build, make then started some serious compile work during the make, but crashed saying "the directory that should contain system headers does not exist: /usr/include".

How should I bootstrap this? Where would I find the system headers to copy into /usr/include? And will I have the same problem with missing libc and libraries later on? Also, if I want to transplant this to a new computer without rebuilding, what do I need to copy besides the executables and the headers? And where would I put them?

Thanks for any advice... - Jeff

like image 549
user2465201 Avatar asked Sep 06 '18 20:09

user2465201


1 Answers

I managed to hackily get GCC building on macOS Sierra with Xcode 8.3.3. Try the following on your system. (You might need to make some tweaks if you have a newer version of macOS or a newer version of Xcode.)

Prerequisites

  • macOS Sierra 10.12.6
  • Xcode 8.3.3

Details:

$ xcode-select -p
/Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer

$ clang --version                     
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ as --version
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-278.4
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
LTO support using: LLVM version 8.1.0, (clang-802.0.42)
TAPI support using: Apple TAPI version 1.33.11

Configuring and building

$ # Download GCC's source code.
$ git clone git://gcc.gnu.org/git/gcc.git gcc
$ # I tested the following revision (SVN r278004 from November 9, 2019):
$ (cd gcc && git checkout a9ad50cb8ec15c509d27c1dbd47b76f56d20fb3b)
$ # Download GCC's uncommon dependencies.
$ ./contrib/download_prerequisites
$ # Apply a build fix: https://gcc.gnu.org/ml/gcc-patches/2019-11/msg01109.html
$ patch -p1 <<<EOF
diff --git a/libstdc++-v3/include/bits/alloc_traits.h
b/libstdc++-v3/include/bits/alloc_traits.h
index 55211ac1d72..6ad02df16f7 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -566,7 +566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif

   template<typename _Alloc>
-    _GLIBCXX14_CONSTEXPR void
+    _GLIBCXX14_CONSTEXPR inline void
     __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
@@ -580,7 +580,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }

   template<typename _Alloc>
-    constexpr _Alloc
+    constexpr inline _Alloc
     __alloc_on_copy(const _Alloc& __a)
     {
       typedef allocator_traits<_Alloc> __traits;
@@ -598,7 +598,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif

   template<typename _Alloc>
-    _GLIBCXX14_CONSTEXPR void
+    _GLIBCXX14_CONSTEXPR inline void
     __alloc_on_move(_Alloc& __one, _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
@@ -625,7 +625,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif

   template<typename _Alloc>
-    _GLIBCXX14_CONSTEXPR void
+    _GLIBCXX14_CONSTEXPR inline void
     __alloc_on_swap(_Alloc& __one, _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
EOF

$ # Configure a build directory for a 3-stage build.
$ mkdir gcc-build-release
$ cd gcc-build-release
$ ../gcc/configure \
    --disable-werror \
    --enable-checking=release \
    --enable-languages=c,c++ \
    --prefix="${PWD}/../usr" \
    --with-native-system-header-dir=/Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ \
    --disable-multilib

$ # Build.
$ flags='-mmacosx-version-min=10.12 -Wa,-mmacosx-version-min=10.5 -iframework /Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/' ; \
    make -w -j9 BOOT_CFLAGS="${flags}" CFLAGS_FOR_TARGET="${flags}" CXXFLAGS_FOR_TARGET="${flags}"

Troubleshooting

Problem: Building fails:

the directory that should contain system headers does not exist: /usr/include

Cause: GCC's configure scripts default to --with-native-system-header-dir=/usr/include. That director does not exist.

Solution: Configure with --with-native-system-header-dir=/Users/strager/Applications/Xcode_8.3.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/.


Problem: Linking or configuring fails:

checking whether the C compiler works... no
configure: error: in `/Users/strager/tmp/Projects/gcc/build-release/x86_64-apple-darwin16.7.0/libgomp':
configure: error: C compiler cannot create executables

config.log shows:

ld: library not found for -lcrt1.10.6.o

or any of the following:

ld: library not found for -ldylib1.o
ld: library not found for -ldylib1.10.5.o

Cause: The value of -mmacosx-version-min= given to the linker driver doesn't match the SDK in Xcode. GCC tries to link the wrong objects.

Solution: Build stages 2 and 3 with -mmacosx-version-min=10.12 (for Xcode 8.3.3's MacOSX10.12.sdk) using the BOOT_CFLAGS, CFLAGS_FOR_TARGET, and CXXFLAGS_FOR_TARGET make variables.


Problem: libstdc++.6.dylib fails to link:

0 0x1059a453b __assert_rtn + 129
1 0x1059a940a mach_o::relocatable::CUSection::personalityName(mach_o::relocatable::Parser&, macho_relocation_info > const*) + 170
2 0x1059b8c2e mach_o::relocatable::CUSection::parse(mach_o::relocatable::Parser&, unsigned int, mach_o::relocatable::CUSection::Info*) + 306
3 0x1059b666b mach_o::relocatable::Parser::parse(mach_o::relocatable::ParserOptions const&) + 695
4 0x1059af1c9 mach_o::relocatable::Parser::parse(unsigned char const*, unsigned long long, char const*, long, ld::File::Ordinal, mach_o::relocatable::ParserOptions const&) + 261
5 0x1059d9758 archive::File::makeObjectFileForMember(archive::File::Entry const*) const + 748
6 0x1059d8b8c archive::File::forEachAtom(ld::File::AtomHandler&) const + 238
7 0x1059f2955 ld::tool::InputFiles::forEachInitialAtom(ld::File::AtomHandler&, ld::Internal&) + 533
8 0x1059fe49c ld::tool::Resolver::resolve() + 44
9 0x1059a5289 main + 725
A linker snapshot was created at:
/tmp/libstdc++.6.dylib-2019-10-13-002048.ld-snapshot
ld: Assertion failed: ((parser.sectionForAddress(personalityAddr)->type() == ld::Section::typeCode) && "personality column in __compact_unwind section is not pointer to function"), function personalityName, file /Library/Caches/com.apple.xbs/Sources/ld64/ld64-278.4/src/ld/parsers/macho_relocatable_file.cpp, line 5128.
collect2: error: ld returned 1 exit status

Cause: LLVM's assembler (as) generates __compact_unwind sections. Despite GCC linking with -no_compact_unwind, ld64 validates the __compact_unwind sections. The data is malformed (to cause unknown), so the linker complains.

Solution: Tell the assembler to not generate __compact_unwind sections using -Wa,-mmacos-version-min=10.5 for stages 2 and 3 using the BOOT_CFLAGS, CFLAGS_FOR_TARGET, and CXXFLAGS_FOR_TARGET make variables.


Problem: libstdc++.6.dylib fails to link:

Undefined symbols for architecture x86_64:
"__ZSt15__alloc_on_copyISaIcEEvRT_RKS1_", referenced from:
__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_ in libstdc++.a(string-inst.o)
"__ZSt15__alloc_on_moveISaIcEEvRT_S2_", referenced from:
__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEOS4_ in libstdc++.a(string-inst.o)
"__ZSt15__alloc_on_swapISaIcEEvRT_S2_", referenced from:
__ZN9__gnu_cxx14__alloc_traitsISaIcEcE10_S_on_swapERS1_S3_ in libstdc++.a(string-inst.o)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

Cause: -fno-implicit-templates causes these symbols to not be created, even though they are necessary.

Solution: Mark function templates inline.


Problem: ASAN (libsanitizer) fails to compile:

In file included from ../../../../gcc/libsanitizer/asan/asan_malloc_mac.cpp:64:
../../../../gcc/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc:20:10: fatal error: CoreFoundation/CFBase.h: No such file or directory
20 | #include

Cause: GCC isn't told where CoreFoundation is in Xcode's SDK.

Solution: Build stages 2 and 3 with -iframework .../SDKs/MacOSX.sdk/System/Library/Frameworks using the BOOT_CFLAGS, CFLAGS_FOR_TARGET, and CXXFLAGS_FOR_TARGET make variables.

like image 164
strager Avatar answered Nov 15 '22 09:11

strager