【问题标题】:Building GCC on OS X 10.11在 OS X 10.11 上构建 GCC
【发布时间】:2015-11-22 22:15:52
【问题描述】:

在这里使用命令行在 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 的 stage1 构建正在引用 libcpp,它使用来自 libiconv 的符号。所以这里有些不对劲。

我该如何解决?

【问题讨论】:

  • 是否有特殊原因需要从头开始构建它?如果没有,那么您可以从例如安装最新的 gcc。 Homebrew?
  • 我正在尝试破解它。
  • 好的 - 在这种情况下,祝你好运!
  • 哈,没错。我之前确实看过自制公式,主要区别似乎是我的构建是使用 clang 编译器系统来引导的。
  • 您可以在Install GNU GCC on Mac 看到我上次报告的技术。从那时起,我使用类似的技术在 Mac OS X 10.11 上构建并安装了 GCC 5.2.0,但库版本略有升级。 OTOH,我不得不避免使用最新版本的 GMP(6.0.0a 不起作用;5.1.3 很好)和 ISL(0.14 还可以,但 0.15 不行)。我仍然使用 GCC 源目录中的 Cloog、GMP、ISL、MPC、MPFR 的源代码进行构建。我最近在 GCC 源目录之外的那些方面没有成功。

标签: macos gcc building


【解决方案1】:

一般性讨论

在 Mac OS X 上构建 GCC 是一个偶尔令人担忧的过程。多年来,我遇到了各种版本的 GCC 和各种版本的 Mac OS X 的各种问题。你可以看到我在Install GCC on Mac OS X 中所做的更早的解释——那是在 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() 或其等效项解析名称并将/work4/gcc/vX.Y.Z 嵌入到二进制文件中,而不是中性名称/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 pre-requisites)放在 GCC 源目录中,以便 GCC 构建自己的这些库版本。我发现这是确保 GCC 正确定位这些库的最简单方法。

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

在运行 Intel Core i7、2.3 GHz、16 GiB 1333 MHz DDR3 主内存和 750 GB 5400 rpm 硬盘驱动器的 17" MacBook Pro(2011 年初)上构建时间约为 2h 15m。源代码占用大约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) 使用最新的 MacPorts 包用于 gmp、mpfr、mpc、isl、libiconv 对我来说似乎工作得很好,尽管从源代码构建可能更万无一失,2) 我需要先在 MacPorts 上停用/卸载 libunwind-headers 包,以免它干扰构建。
  • 很好的答案。我一直在我的 Mac 上构建 gcc 版本,并且遇到了几个类似的问题。我还有几个建议,在这个答案上作为 cmets 效果不佳,所以我将添加第二个答案,尽管它最终不会成为一个非常好的或完整的答案。对于社区 wiki 答案,这可能是一个很好的主题。 (但我对那些开始的了解不够。)
  • 除了完全不使用 Cloog 和使用最新版本的 ISL 和 GMP 之外,这里的指南是我在 macOS Sierra 10.12.5 上安装 GCC 7.2.0 时使用的指南——而且对我来说似乎工作正常。我还在 macOS 和 Mac OS X 的中间版本上将它们用于 GCC 的中间版本。运行 C++ 代码时,我仍然需要设置 DYLD_LIBRARY_PATH 来获取 GCC 标准 C++ 库。
【解决方案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 下的那些路径名包含不同的版本号,这些版本号在您的系统上可能会有所不同。

(如 Jonathan 所述,如果最新版本的 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% 可靠)会检测到在这种情况下可能需要重建的内容。 (删除并重新开始很令人沮丧,我同意,但从长远来看,它确实可以节省时间。)

最后,如果您正在尝试构建一个交叉编译器,请在install gcc 4.6.1 on OS X 10.11 上查看一些额外的建议和评论。

【讨论】:

    【解决方案3】:

    对于它的价值,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) 代码并针对 Qt5 和使用各种 clang 编译器版本构建的 KF5 框架运行它。 (补丁文件在 .../gcc6/files 中。)

    一些可能有助于解释链接文件的 Tcl 代码的解释:

    忽略特定于 $subport == "libgcc" 的任何内容。

    如您所见,您需要 gmp、mpc、mpfr 和 isl(如果您自己安装,其他依赖项应该不感兴趣)。

    configure.args 表达式为配置脚本构造参数列表,configure.env 和 build.env 为 configure 和 build (make) 命令添加环境变量。这里的许多配置选项是为了确保构建使用来自 MacPorts 的依赖项,但如果您想要或必须使用不受 SIP 控制且不包含在标准 PATH 定义中的位置(编译器通过重置路径的进程调用时仍然应该工作)。

    配置和构建是在源目录旁边的构建目录中完成的,这使得重新开始或只是清理而不丢弃源非常容易。 在配置步骤之后,使用“make bootstrap-lean”完成构建 - 它仍然在该构建目录中创建大约 1.7Gb 的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-02
      • 2016-05-10
      相关资源
      最近更新 更多