我正在尝试在 x86_64 机器上从头开始设置 gcc 编译器。我使用它配置了
./configure --enable-shared --enable-languages=c,c++,fortran --disable-multilib --libdir=/cluster/apps/lib --with-gmp=/cluster/apps/ --with-mpfr=/cluster/apps --with-mpc=/cluster/apps --prefix=/cluster/apps
Run Code Online (Sandbox Code Playgroud)
构建并运行后,make install库将安装在
/cluster/apps/lib64
Run Code Online (Sandbox Code Playgroud)
而不是想要的
/cluster/apps/lib
Run Code Online (Sandbox Code Playgroud)
我如何建议配置脚本用作/cluster/apps/lib库目标?
事实证明,这有点不简单,具体取决于您想如何去做。构建 GCC 时,您可以将其配置为支持大量目标平台和体系结构,并且每个目标可能需要自己版本的各种支持库。这些库(例如 libatomic.a)在每个目标上都具有相同的名称,但当然必须根据目标位于不同的目录中。Debian 的MultiArch约定是对此的更正式的概括,IIUC 早于 GCC 中的multilib 支持。
因此,GCC 在哪里安装库很大程度上取决于它要支持的目标;这又具有一些默认值,具体取决于您正在构建的主机系统(如果您在配置时没有另外指定一些目标)。对于 x86_64 Linux 目标,默认情况下有两个 multilib 选项,一个用于构建-m32(编译 32 位二进制文件),一个用于-m64,对于-m64需要在 中找到库的情况${libdir}/../lib64,而 for-m32它需要(通常)在 中找到库${libdir}/../lib。此信息可在 makefile 片段中找到gcc/config/i386/t-linux64。
这些变量的含义MULTILIB_在genmultilib它们由Makefile.
“但是等一下”,你可能会打断,“我传递--disable-multilib给./configure所以它应该忘记所有这些 multilib 的东西并${prefix}/lib像我问的那样安装东西。但这并不是那么简单。正如你在前面链接的 Makefile 模板中看到的那样--disable-multilib如果您的目标碰巧指定了一个非空的段落,则会被悄悄忽略$(MULTILIB_OSDIRNAMES)。毕竟,这种情况下的目标支持两个必须-m64支持多个库的目标体系结构选项(和-m32),因此它仍然会生成多库支持的设置。
那么,如果您想要不同的目录布局,该怎么办?理想情况下,由于在这种情况下我们只想覆盖$(MULTILIB_OSDIRNAMES)变量的默认值,因此如果我们可以在配置时或运行 make 时提供覆盖(例如make MULTILIB_OSDIRNAMES="m32=../lib32 m64=../lib"),那就太好了。我相信这应该是一种方便,但不幸的是事实并非如此:顶层Makefile支持 GCC 稍微复杂的多阶段构建过程,并且涉及多个递归 make 调用,并且我无法让它可靠地将变量覆盖传递给相关子品牌无需进行任何修补。我认为这很不幸。
我发现目前最简单的方法是像 Debian 那样进行修补gcc/config/i386/t-linux64(以及其他体系结构的类似文件)以反映他们喜欢的目录布局。
另一种可能性是修补gcc/config.gcc脚本。该脚本查看您正在构建 GCC 的目标,并根据目标确定许多 makefile 变量和片段。例如,请参阅本节,了解适用于 x86_64 Linux 目标的一些设置。该tmake_file变量实际上是一个通常包含多个文件的列表gcc/config,其开头的t-含义是它们包含要由主 gcc Makefile 包含的 Makefile 片段。这是gcc/config/i386/t-linux64选择文件和其他文件的地方。理论上,您可以将自己的自定义目标添加到此文件(some x86_64-mycustom-linux),并让它加载自己的附加 Makefile 片段以覆盖 Linux 的默认 multilib 选项。然而,我认为此时你最好只是修补t-linux64并保留它。