我正在使用 Ubuntu 14.04 LTS。这已经发货了一个打包的gcc
4.8.4但我想要更高版本的gcc
.
使用现有版本4.8.4,我构建的版本4.9.4从源代码通过推荐链编译-构建-测试-安装。./configure
除了前缀目录和程序后缀之外,我没有使用任何外来设置。其余的都是默认的。一切似乎都很顺利。测试摘要g++
显示没有 FAIL,仅显示两次 XPASS 调用
XPASS: g++.dg/tls/thread_local-order2.C -std=c++11 execution test
XPASS: g++.dg/tls/thread_local-order2.C -std=c++1y execution test
然后我想构建版本5.4.0使用新安装的 4.9.4,以最小的学习曲线对后者进行测试。我仅通过指定make
标志CC
和 来编辑用于 4.9.4 的相同安装脚本CXX
。这些标志现在指向 4.9.4 安装目录中的二进制文件。
这配置5.4.0 阶段进展顺利。我从文件中看到config.log
,Makefile
新的二进制文件的路径已正确读取。
这建造但阶段失败并stderr
报告大约 100 个错误。最早和最频繁出现的类型是
`error: template with C linkage`
`error: template specialization with C linkage`
它们以块的形式出现,如下所示:
In file included from ${installation directory for 4.9.4}/include/c++/4.9.4/bits/stringfwd.h:40:0,
from ${installation directory for 4.9.4}/include/c++/4.9.4/iosfwd:39,
from /usr/include/x86_64-linux-gnu/gmp.h:25,
from /usr/local/include/isl/val_gmp.h:4,
from ${source directory for 5-4-0}/gcc/graphite-isl-ast-to-gimple.c:35:
${installation directory for 4.9.4}/include/c++/4.9.4/bits/memoryfwd.h:63:3: error: template with C linkage
template<typename>
^
${installation directory for 4.9.4}/include/c++/4.9.4/bits/memoryfwd.h:66:3: error: template specialization with C linkage
template<>
^
${installation directory for 4.9.4}/include/c++/4.9.4/bits/memoryfwd.h:70:3: error: template with C linkage
template<typename, typename>
^
我认为 5.4.0 源代码很好,因为所有信息都以与 4.9.4 相同的方式收集和处理。 4.9.4 或 5.4.0 或两者的配置阶段可能存在错误/遗漏。
这些错误表明了哪些缺陷?你如何修复它们?
感谢您的思考。
StackExchange 上的搜索查询error: template with C linkage
给出了大约 171,000 个结果。我浏览的帖子似乎没有解决这一点:
https://stackoverflow.com/questions/4115930/using-cygwin-to-build-template-with-c-linkage
请注意,我对分类代码不感兴趣,而是对设置一个(强大的)工作编译器感兴趣。
答案1
--with-local-prefix=/usr
通过设置shell脚本的编译开关,已经避免了该问题configure
。默认值为/usr/local
,而 Ubuntu 似乎将查找的文件存储在/usr
.这修复了 HDF5 源代码的另一个编译中的致命错误(请参阅https://unix.stackexchange.com/a/346171/132913)
但不推荐此设置。请参阅GCC 在线配置帮助:
--with-local-prefix=目录名
指定本地包含文件的安装目录。默认是/usr/local。如果您希望编译器搜索目录,请指定此选项目录名/包含对于本地安装的头文件而不是/usr/local/包括。
仅当您的站点对放置站点特定文件的位置有不同的约定(不是 /usr/local)时,才应指定 --with-local-prefix。
无论 --prefix 的值如何,--with-local-prefix 的默认值为 /usr/local。指定 --prefix 对 GCC 搜索本地头文件的目录没有影响。这看似违反直觉,但实际上是合乎逻辑的。
--prefix 的目的是指定安装 GCC 的位置。 /usr/local/include 中的本地头文件(如果您将任何文件放入该目录中)不是 GCC 的一部分。它们是其他项目的一部分——也许还有很多其他项目。 (GCC 在另一个基于 --prefix 值的目录中安装自己的头文件。)
local-prefix include 目录和GCC-prefix include 目录都是GCC“系统include”目录的一部分。尽管这两个目录不是固定的,但需要以正确的顺序搜索它们,以便正确处理 include_next 指令。在 GCC 前缀包含目录之前搜索本地前缀包含目录。系统包含目录的另一个特征是,这些目录中的标头的迂腐警告被关闭。
一些 autoconf 宏将 -I 目录选项添加到编译器命令行,以确保搜索包含已安装软件包标头的目录。当目录是 GCC 的系统包含目录之一时,GCC 将忽略该选项,以便系统目录继续按正确的顺序进行处理。这可能会导致搜索顺序与指定的顺序不同,但仍会搜索目录。
GCC 使用 GCC_EXEC_PREFIX 自动搜索普通库。因此,当 GCC 和包使用相同的安装前缀时,GCC 将自动搜索标头和库。这提供了易于使用的配置。 GCC 的行为方式与将其作为系统编译器安装在 /usr 中时类似。
需要安装多个版本GCC的站点可能不希望使用上面的简单配置。可以使用 --program-prefix、--program-suffix 和 --program-transform-name 选项将多个版本安装到单个目录中,但使用不同的前缀和 --with- 可能更简单local-prefix 选项指定每个版本的站点特定文件的位置。然后,用户需要明确指定本地站点库的位置(例如,使用 LIBRARY_PATH)。
如果不是 /usr,则 --with-local-prefix 和 --prefix 可以使用相同的值。这可用于避免默认搜索 /usr/local/include。
不要将 /usr 指定为 --with-local-prefix!用于 --with-local-prefix 的目录不得包含任何系统的标准头文件。如果它确实包含它们,某些程序将被错误编译(包括在某些目标上的 GNU Emacs),因为这将覆盖并取消由 fixincludes 脚本所做的头文件更正。
有迹象表明,使用此选项的人是基于对其用途的错误认识而使用它的。人们使用它就好像它指定了 GCC 部分的安装位置。也许他们做出这个假设是因为安装 GCC 会创建目录。
我将尽早在另一篇文章中解决这些不一致的问题。