在OS X 10.11上构建GCC

3
在OS X 10.11.1上使用命令行构建最新版本的GCC:
../gccx/configure --with-gmp="/opt/local" --with-mpfr="/opt/local" \
    --with-mpc="/opt/local" --with-libiconv-prefix="/opt/local" --with-pkgversion="GCCX" \
    --program-transform-name='s/^gcc$/gccx/; s/^g++$/g++x/' --enable-languages=c

完全按照构建说明操作,但出现了以下错误:

g++ -std=gnu++98   -g  -DIN_GCC    -fno-strict-aliasing
-fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-format -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -DGENERATOR_FILE -fno-PIE -Wl,-no_pie   -o build/genmatch \
        build/genmatch.o ../build-x86_64-apple-darwin15.0.0/libcpp/libcpp.a build/errors.o build/vec.o build/hash-table.o ../build-x86_64-apple-darwin15.0.0/libiberty/libiberty.a Undefined symbols for architecture x86_64:  "_iconv", referenced from:
     convert_using_iconv(void*, unsigned char const*, unsigned long, _cpp_strbuf*) in libcpp.a(charset.o)
    (maybe you meant: __Z14cpp_init_iconvP10cpp_reader, __cpp_destroy_iconv )  "_iconv_close", referenced from:
     __cpp_destroy_iconv in libcpp.a(charset.o)
     __cpp_convert_input in libcpp.a(charset.o)  "_iconv_open", referenced from:
     init_iconv_desc(cpp_reader*, char const*, char const*) in libcpp.a(charset.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[3]: *** [build/genmatch] Error 1 make[2]: *** [all-stage1-gcc] Error 2 make[1]: *** [stage1-bubble] Error 2 make:
*** [all] Error 2

(完整的日志可在 https://gist.github.com/3cb5d044533e657f4add 获取。)
经过调查 gcc/Makefile,似乎 BUILD_CPPLIB 变量不包括 $(LIBICONV),因为在错误发生时它处于 stage1 引导状态。相关部分之前是:
# For stage1 and when cross-compiling use the build libcpp which is
# built with NLS disabled.  For stage2+ use the host library and
# its dependencies.

很明显,build/genmatch的第一阶段构建正在引用libcpp,而libcpp使用来自libiconv的符号。因此,这里出现了一些问题。

我该如何解决这个问题呢?


你需要从头开始构建的特定原因吗?如果没有,那么你可以从 Homebrew 安装最新的 gcc。 - Paul R
哈哈,没错。我之前确实看过homebrew的公式,似乎主要区别在于我的构建使用clang编译器系统进行引导。 - Noldorin
1
你可以在在Mac上安装GNU GCC中看到我最后报告的技术。从那时起,我使用类似的技术构建并安装了GCC 5.2.0在Mac OS X 10.11上,但是升级了一些库版本。另一方面,我必须避免使用最新版本的GMP(6.0.0a无法工作;5.1.3很好)和ISL(0.14可以,但0.15不行)。我仍然在GCC源目录中使用Cloog、GMP、ISL、MPC、MPFR的源代码进行构建。但是我最近没有成功地使用那些在GCC源目录之外的源代码。 - Jonathan Leffler
@JonathanLeffler 很遗憾,我还是没有运气。您使用IRC吗?我应该给您发送电子邮件吗?无论哪种方式最好。最好在SO之外完成这项工作,正如您所说的那样。 - Noldorin
电子邮件 - 请查看我的个人资料。 - Jonathan Leffler
显示剩余5条评论
3个回答

3

一般讨论

在Mac OS X上构建GCC是一个偶尔会出现问题的过程。多年来,我在不同版本的GCC和Mac OS X上遇到了各种问题。您可以在 在Mac OS X上安装GCC 中看到我以前所做的解释 - 这是用于在Mavericks 10.9.x(或可能是Mountain Lion 10.8.x)上构建GCC 4.8.x的; 它还报告成功在Mavericks 10.9.x上构建GCC 4.9.0,但在Yosemite 10.10.x上无法构建。

这是在Mac OS X 10.11.1 El Capitan上构建GCC 5.2.0的更新配方。它开始使用XCode 7.1.1-我不知道哪些其他版本的XCode可以使用。

请注意,El Capitan具有SIP(系统完整性保护)功能,而Yosemite和早期版本没有。这意味着您不能再在/usr下创建任意目录。我以前习惯安装在/usr/gcc/vX.Y.Z中; 在El Capitan中不再允许。因此,一个主要的变化是我现在安装在/opt/gcc/v.X.Y.Z中。

我发现设置DYLD_LIBRARY_PATH有问题-特别是在El Capitan上。与过去的重大变化不同,我现在根本没有设置它。请注意,脚本解除了它。还要注意,脚本将第1阶段的编译器CC和CXX显式设置为/usr/bin/clang/usr/bin/clang++(XCode编译器)。当前版本的GCC需要一个能力强大的C ++编译器而不是(或以及)C编译器。

我偶尔会遇到libiconv的问题,但目前我通过不安装自己的版本来避免这些问题。同样,我偶尔会遇到GCC源中的一些awk脚本问题。我必须修改它/它们才能正常工作。然而,使用GCC 5.2.0源代码的发布版本,我似乎可以直接构建出箱子。

如果您只有一个磁盘分区,那么下一个步骤并不重要。 如果您有多个磁盘,请确保目标目录不存在,或者确保其名称与您想要的完全相同。 在工作机器上(不是 Mac 但是 Linux 机器等等),我仍然将/usr/gcc/vX.Y.Z用作“官方”安装位置,但软件最终位于某个任意的文件系统中,在那里有足够的空间,例如/work4/gcc,最后有一个符号链接,以便/usr/gcc/vX.Y.Z到达/work4/gcc/vX.Y.Z。 但是,在编译 GCC 时,关键是/work4/gcc/vX.Y.Z不存在,因为它将通过realpath()或其等效物解析名称,而不是中性名称/usr/gcc/vX.Y.Z嵌入到二进制文件中。这限制了安装的可移植性;无论将其移动到任何其他机器,都必须具有一个/work4/gcc/vX.Y.Z目录,即使您要求在/usr/gcc/vX.Y.Z中安装它也是如此。

使用XCode 7.1.1在Mac OS X 10.11.1上编译GCC 5.2.0

我必须使用GMP(5.1.3而不是6.0.0a)和ISL(0.14而不是0.15)的较低版本。 较新版本的构建都给我带来了麻烦。

请注意,我将GMP、MPC、MPFR、ISL和Cloog(请参见GCC先决条件)的库代码放在GCC源目录中,以便GCC构建其自己的这些库的版本。 我发现这是确保GCC正确定位这些库的最简单方法。

目标目录:/opt/gcc/v5.2.0

在17英寸MacBook Pro(2011年初)上运行Intel Core i7 2.3 GHz,16 GiB 1333 MHz DDR3主存储器和750 GB 5400 rpm硬盘驱动器,构建时间约为2小时15分钟。 源代码大约占用850 MiB;构建树最终达到约4.6 GiB — 您需要足够的磁盘空间。 安装后的代码大约为420 MiB。

使用的脚本 - extract-gcc-5.2.0.sh

#!/bin/bash

unset DYLD_LIBRARY_PATH

TAR=tar
VER_NUM=5.2.0
GCC_VER=gcc-${VER_NUM}
TGT_BASE=/opt/gcc
TGT_DIR=${TGT_BASE}/v${VER_NUM}
CC=/usr/bin/clang
CXX=/usr/bin/clang++

extract() {
    echo "Extract $1"
    $TAR -xf $1
}

if [ ! -d "$GCC_VER" ]
then extract ${GCC_VER}.tar.bz2 || exit 1
fi

(
cd ${GCC_VER} || exit

nbncl <<EOF |
    cloog 0.18.1 tar.gz 
    gmp 5.1.3 tar.xz 
#   gmp 6.0.0 tar.lz 
    isl 0.14 tar.bz2 
#    isl 0.15 tar.bz2 
    mpc 1.0.3 tar.gz 
    mpfr 3.1.3 tar.xz
EOF

while read file vrsn extn
do
    tarfile="../$file-$vrsn.$extn"
    if [ ! -f "$tarfile" ]
    then echo "Cannot find $tarfile" >&2; exit 1;
    fi
    if [ ! -d "$file-$vrsn" ]
    then
        (
        set -x
        extract "$tarfile" &&
        ln -s "$file-$vrsn" "$file"
        ) || exit 1
    fi
done
)

if [ $? = 0 ]
then
    mkdir ${GCC_VER}-obj
    cd ${GCC_VER}-obj
    ../${GCC_VER}/configure --prefix="${TGT_DIR}" \
        CC="${CC}" \
        CXX="${CXX}"
    make -j8 bootstrap
fi

脚本nbncl — 非空白非注释行

#!/usr/bin/env perl
#
# Non-blank, non-comment lines only

use warnings;
use strict;

while (<>)
{
    chomp;
    s/\s+$//;
    s/\s*#.*$//;
    print "$_\n" unless /^$/;
}

感谢您在这里发布,乔纳森。我认为这相当完整,但是让我提两件事:1)对于gmp、mpfr、mpc、isl、libiconv,使用最新的MacPorts软件包似乎对我来说足够好,尽管从源代码构建可能更加稳妥;2)我需要先在MacPorts上停用/卸载libunwind-headers软件包,以便它不会干扰构建过程。 - Noldorin
很好的回答。我一直在我的Mac上构建gcc的版本,也遇到了几个类似的问题。我还有几个建议,但它们不适合作为对这个答案的评论,所以我要添加一个第二个答案,尽管它最终可能不会成为一个非常好的或完整的答案。这可能是一个很好的社区wiki答案的主题。(但我不知道足够关于那些去开始一个。) - Steve Summit
除了完全不使用Cloog并使用最新版本的ISL和GMP之外,这里的指南是我用于在macOS Sierra 10.12.5上安装GCC 7.2.0的 - 对我来说似乎可以正常工作。我还将它们用于中间版本的GCC和中间版本的macOS和Mac OS X。运行C ++代码时,我仍然需要设置DYLD_LIBRARY_PATH以获取GCC标准C ++库。 - Jonathan Leffler

2
值得一提的是,MacPorts有适用于所有最新版本的端口,对于不想安装MacPorts但更喜欢其他方式安装这里提到的各种依赖项并且懂得如何编码的人来说应该足够容易阅读。
稍微调整过的gcc 6.3.0版本的个人端口: https://github.com/RJVB/macstrop/blob/master/lang/gcc6/Portfile 我之所以提到它(并发布了这个答案),是因为这个调整过的版本展示了如何让G++使用libc++而不是libstdc++。这是能够使用G++作为真正的clang++替代品并且无需担心C ++运行时不兼容性的特权。这个补丁使我能够使用g++构建KDE(KF5)代码,并与使用各种clang编译器版本构建的Qt5和KF5框架一起运行。(补丁文件在... / gcc6 / files中。)
以下是一些可能有助于解释链接文件中Tcl代码的说明:
忽略任何特定于 $subport == "libgcc" 的内容。
如您所见,您需要gmp、mpc、mpfr和isl(如果您正在自行安装,则其他依赖项应该不感兴趣)。
configure.args表达式构造了configure脚本的参数列表,configure.env和build.env为configure和build(make)命令添加环境变量。这里的许多configure选项是为了确保构建使用来自MacPorts的依赖项,但如果您想要或必须使用SIP不控制的位置并且未包含在标准PATH定义中,那么它们可能也会被需要(当通过重置路径调用编译器时,它仍然应该工作)。
configure和build都在与源目录相邻的构建目录中完成,这使得重新开始或仅清理而不丢弃源代码非常容易。 在configure步骤之后,使用"make bootstrap-lean"进行构建 - 这仍然会在构建目录中创建约1.7GB的数据。

2

首先,查看Jonathan Leffler的非常详细的回答。我有几个更多的建议。

gcc配置和构建过程需要找到您系统的本地头文件和C运行时库。较新的基于clang的Xcode版本将它们隐藏得相当深,并且旧版本的gcc似乎不知道如何找到它们。为了使gcc 4.6能够构建,我不得不创建这些符号链接:

ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include /usr
ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib/dylib1.10.5.o /usr/local/lib
ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib/crt1.10.5.o /usr/local/lib
ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib/bundle1.o /usr/local/lib

您的结果可能会略有不同:请注意那些在 /Applications/Xcode.app/Contents 下面的路径名中都嵌入了各种版本号,这些在您的系统上可能会有所不同。

(如果像乔纳森描述的那样,最新版本的 MacOS 不允许您将任何东西放入 /usr 中,则可能必须在 /usr/local/include 中创建 /usr/include 符号链接,我认为那也可以正常工作。)

此外,虽然其他地方已经提到过,但这是一个不寻常的要求,很容易被忽视:不要尝试在其自身源树中构建 gcc。请始终创建一个构建目录,该目录是您提取 gcc 源代码的目录的相对平行同级别目录,而不是其子目录。 也就是说,不要这样做:

tar xzf gcc-x.y.z.tar.bz2
cd gcc-x.y.z       # WRONG
mkdir build
cd build
../configure       # WRONG
make

相反,请这样做:
tar xzf gcc-x.y.z.tar.bz2
mkdir build
cd build
../gcc-x.y.z/configure
make

这虽然有些违反直觉,不同于其他大部分软件包的操作方式,但这绝对适用于gcc,并且也是推荐的方法。
此外,如果您发现构建失败是因为配置错误,导致必须使用不同选项重新运行configure,则更安全的做法是删除整个构建目录并从头开始。配置和构建系统有时会检测到需要重新构建的内容,但似乎不是100%可靠。(删除并重新开始很让人沮丧,我知道,但再次强调,从长远来看它确实可以节省时间。)
最后,如果您正在尝试构建交叉编译器,请参阅在Mac OS X 10.11上安装GCC 4.6.1 中提供的其他建议和评论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接