如何使用内置的rpath构建和安装gcc?

如何使用内置的rpath构建和安装gcc?,gcc,build,centos,shared-libraries,Gcc,Build,Centos,Shared Libraries,我正在尝试在/usr/local中构建并安装自己的GCC4.7.2,以替代/usr中的GCC4.4.6。(这是在CentOS 6.3上。) gcc生成可执行文件和动态库,动态链接到自己的动态库,例如libstdc++.so。如何构建和安装gcc,以便生成的二进制文件自动获得一个linker-rpath选项(-rpath/usr/local/lib64),该选项将链接/usr/local/lib64中的动态库,而不是/usr/lib64或/lib64中的动态库 如果它工作正常,在我使用gcc构建一

我正在尝试在/usr/local中构建并安装自己的GCC4.7.2,以替代/usr中的GCC4.4.6。(这是在CentOS 6.3上。)

gcc生成可执行文件和动态库,动态链接到自己的动态库,例如libstdc++.so。如何构建和安装gcc,以便生成的二进制文件自动获得一个linker-rpath选项(-rpath/usr/local/lib64),该选项将链接/usr/local/lib64中的动态库,而不是/usr/lib64或/lib64中的动态库

如果它工作正常,在我使用gcc构建一个可执行文件而不指定“-Wl,-rpath=/usr/local/lib64”之后,当我ldd可执行文件时,它应该显示/usr/local/lib64/libstdc++.so.6而不是/usr/lib64/libstdc++.so.6。类似地,libgcc_.so.1


我尝试了不同的方法,包括在“configure”命令行上为\u TARGET=-Wl,-rpath=/usr/local/lib64,-rpath=/usr/local/lib指定LDFLAGS\u,但没有任何效果。

如果您不想导出路径,有一个替代解决方案:

使用
路径中的工具链

gcc -dumpspecs > specsfile
编辑
specsfile
并在
链接
部分添加
-rpath
示例:

*link:
%{!static:--eh-frame-hdr} -m %(link_emulation) %{shared:-shared}   %{!shared:     %{!static:       %{rdynamic:-export-dynamic}       -dynamic-linker %(dynamic_linker)}       %{static:-static}} -rpath /usr/local/lib64
此时,您可以测试它是否适用于:

g++ -specs=specsfile test.cpp
readelf -d a.out |grep RPATH
如果有效,您可以将其永久化(无需每次都通过
-specs

grep应该显示
gcc
查找默认
specs
文件的路径

这些文件足够灵活,可以根据变量进行条件链接,例如:

{!static: %{mabi=n32:-rpath-link %R/lib32:%R/usr/lib32} %{mabi=64:-rpath-link %R/lib64:%R/usr/lib64} %{mabi=32:-rpath-link %R/lib:%R/usr/lib}}
应根据mabi(尚未测试)使用不同的多个路径,
%R
应为
sysroot
路径,可以使用所需的完整路径进行更改

还有一个
--with specs=
选项最终将在构建时使用,我还不清楚如何使用
链接
部分(处理它)

它工作了,我使用了
共享
和非
!共享的
仅用于测试,可能应该使用一些更智能的条件,请注意,
-dumpspecs
中没有报告该条件

通过阅读gcc邮件列表中的某个线程,我有一种印象,
specs
不是每个人都喜欢的(但如果我没有错的话,4.9添加另一个选项
——使用额外的specs
),相反,进行此类定制的首选方式似乎是
configure.host
,但我已经完成,并且没有查看它,祝您玩得开心!:-)

另见:

以上更新

我不知道你是否可以设置一个预定义的
rpath
,也许你可以在
binutils
的链接器
ld
中,而不是在
gcc/g++
中,但你为什么要这样做呢

只需在运行时导出
LD\u库路径
,在构建时导出
LD\u运行路径

export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
ldd a.out
ldd
应显示导出的路径

引用使用libtool构建共享库时给出的消息:

如果您碰巧想要链接给定目录LIBDIR中已安装的库,则必须使用libtool并指定库的完整路径名,或者在链接过程中使用“-LLIBDIR”标志并至少执行以下操作之一:

  • 在执行期间将LIBDIR添加到“LD_LIBRARY_PATH”环境变量
  • 在链接期间将LIBDIR添加到“LD_RUN_PATH”环境变量
  • 使用“-Wl,--rpath-Wl,LIBDIR”链接器标志
  • 让系统管理员将LIBDIR添加到“/etc/ld.so.conf”
有关详细信息,请参阅有关共享库的任何操作系统文档 更多信息,如ld(1)和ld.so(8)手册页面

完整性 我用来测试这个东西的
Makefile
,我尝试的所有配置选项、环境变量(请参阅boot ldflags)都不起作用,
--包括enable rpath

mkdir~/gcc
一起使用,将下面的
Makefile
复制到
~/gcc
中,然后
cd~/gcc&&makebuildgcc

注意使用的选项仅用于此测试用例,不用作参考

FETCH = aria2c --file-allocation=none -c -d dl
NICE = nice -n 19
PARALLEL = -j4
DESTDIR = $(HOME)/gcc/install
SRCDIR = $(HOME)/gcc/src

all:

# if more downloads are added just remove {dl,src}/*-my-stamp not the .bak
# the .bak should avoid to rebuild targets because of timestamp
touch_stamp = if [ -f $@.bak ]; then \
        touch -r $@.bak $@; \
    else \
        touch $@ $@.bak; \
    fi

dl/dl-my-stamp:
    $(FETCH) https://ftp.gnu.org/gnu/gcc/gcc-4.7.2/gcc-4.7.2.tar.bz2
    $(FETCH) http://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
    $(FETCH) ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
    $(FETCH) https://ftp.gnu.org/gnu/mpfr/mpfr-2.4.2.tar.bz2
    $(FETCH) --check-certificate=false http://www.mirrorservice.org/sites/sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2 \
        ftp://sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2
    $(touch_stamp)

untar_dep = src/untar-my-stamp
src/untar-my-stamp: dl/dl-my-stamp
    mkdir -p src
    tar -C src -xjf dl/gcc-4.7.2.tar.bz2
    tar -C src -xjf dl/gmp-4.3.2.tar.bz2
    tar -C src -xzf dl/mpc-0.8.1.tar.gz
    tar -C src -xjf dl/mpfr-2.4.2.tar.bz2
    tar -C src -xjf dl/binutils-2.24.51.tar.bz2
    $(touch_stamp)

define configure-rule
$(1)_install = $(DESTDIR)/$(1)-install-my-stamp
$(1)_builddir = $$($(1)_dir)/build
$(DESTDIR)/$(1)-install-my-stamp: $$($(1)_deps)
    mkdir -p $$($(1)_builddir)
    cd $$($(1)_builddir) && \
        $$($(1)_env) ../configure --cache-file=$(SRCDIR)/$(1)-config.cache \
            $$($(1)_configure)
    $(NICE) make -C $$($(1)_builddir) $$($(1)_make_target) $(PARALLEL)
ifneq ($$($(1)_post_make),)
    $$($(1)_post_make)
endif
    touch $$@
.PHONY: build-$(1) clean-$(1)
build-$(1): $$($(1)_install)
clean-$(1):
    -rm -fr $$($(1)_builddir)
endef

gmp_dir = src/gmp-4.3.2
gmp_env =   CONFIG_SITE=$(SRCDIR)/config.site
gmp_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static --enable-cxx
gmp_deps = $(untar_dep)
gmp_make_target = install
$(eval $(call configure-rule,gmp))

mpfr_dir = src/mpfr-2.4.2
mpfr_env =  CONFIG_SITE=$(SRCDIR)/config.site
mpfr_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static \
                --with-gmp=$(DESTDIR)
mpfr_deps = $(untar_dep) $(gmp_install)
mpfr_make_target = install
$(eval $(call configure-rule,mpfr))

mpc_dir = src/mpc-0.8.1
mpc_env =   CONFIG_SITE=$(SRCDIR)/config.site
mpc_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static \
                --with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR)
mpc_deps = $(untar_dep) $(gmp_install) $(mpfr_install)
mpc_make_target = install
$(eval $(call configure-rule,mpc))

gcc_dir = src/gcc-4.7.2
gcc_env =   CONFIG_SITE=$(SRCDIR)/config.site \
    CFLAGS="-I/usr/include/i386-linux-gnu" \
    CXXFLAGS="-I/usr/include/i386-linux-gnu"
gcc_configure = --prefix=$(DESTDIR) \
                --libdir=$(DESTDIR)/lib \
                --with-local-prefix=$(DESTDIR) \
                --with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR) \
                --with-mpc=$(DESTDIR) \
                --disable-bootstrap \
                --enable-languages=c,c++ \
                --disable-libgomp --disable-multilib \
                --disable-libmudflap --disable-libssp \
                --disable-libquadmath \
                --enable-rpath \
                MAKEINFO=missing
gcc_deps = $(untar_dep) $(gmp_install) $(mpfr_install) $(mpc_install)
gcc_make_target = 
gcc_post_make = make -C $(gcc_builddir) install
$(eval $(call configure-rule,gcc))

binutils_dir = src/binutils-2.24.51
#binutils_env = LDFLAGS=-Wl,-rpath\ $(DESTDIR)/lib
binutils_env = CONFIG_SITE=$(SRCDIR)/config.site \
    CFLAGS="-I/usr/include/i386-linux-gnu" \
    BOOT_LDFLAGS="-rpath-link=$(DESTDIR)/lib -rpath=$(DESTDIR)/lib"
binutils_configure = --prefix=$(DESTDIR) \
                --libdir=$(DESTDIR)/lib \
                --with-gmp=$(DESTDIR) \
                --enable-rpath
binutils_deps = $(untar_dep) $(gmp_install)
#binutils_make_target = install
binutils_post_make = make -C $(binutils_builddir) install
$(eval $(call configure-rule,binutils))


.PHONY: env
env:
    @echo export PATH=$(DESTDIR)/bin:\$$PATH
    @echo export LIBRARY_PATH=/usr/lib/i386-linux-gnu

我不知道这在2014年是否还不存在,但现在使用
*link:+-rpath=/usr/local/lib64
可能比实际修改主
*link
规范字符串行更好。要使用
-m32
以及
-m64
的正确路径,您可以使用
--with specs='%{!static:%{m32:-Wl,-rpath,/usr/local/lib64}%{m32:-Wl,-rpath,/usr/local/lib}}'
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
ldd a.out
FETCH = aria2c --file-allocation=none -c -d dl
NICE = nice -n 19
PARALLEL = -j4
DESTDIR = $(HOME)/gcc/install
SRCDIR = $(HOME)/gcc/src

all:

# if more downloads are added just remove {dl,src}/*-my-stamp not the .bak
# the .bak should avoid to rebuild targets because of timestamp
touch_stamp = if [ -f $@.bak ]; then \
        touch -r $@.bak $@; \
    else \
        touch $@ $@.bak; \
    fi

dl/dl-my-stamp:
    $(FETCH) https://ftp.gnu.org/gnu/gcc/gcc-4.7.2/gcc-4.7.2.tar.bz2
    $(FETCH) http://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
    $(FETCH) ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
    $(FETCH) https://ftp.gnu.org/gnu/mpfr/mpfr-2.4.2.tar.bz2
    $(FETCH) --check-certificate=false http://www.mirrorservice.org/sites/sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2 \
        ftp://sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2
    $(touch_stamp)

untar_dep = src/untar-my-stamp
src/untar-my-stamp: dl/dl-my-stamp
    mkdir -p src
    tar -C src -xjf dl/gcc-4.7.2.tar.bz2
    tar -C src -xjf dl/gmp-4.3.2.tar.bz2
    tar -C src -xzf dl/mpc-0.8.1.tar.gz
    tar -C src -xjf dl/mpfr-2.4.2.tar.bz2
    tar -C src -xjf dl/binutils-2.24.51.tar.bz2
    $(touch_stamp)

define configure-rule
$(1)_install = $(DESTDIR)/$(1)-install-my-stamp
$(1)_builddir = $$($(1)_dir)/build
$(DESTDIR)/$(1)-install-my-stamp: $$($(1)_deps)
    mkdir -p $$($(1)_builddir)
    cd $$($(1)_builddir) && \
        $$($(1)_env) ../configure --cache-file=$(SRCDIR)/$(1)-config.cache \
            $$($(1)_configure)
    $(NICE) make -C $$($(1)_builddir) $$($(1)_make_target) $(PARALLEL)
ifneq ($$($(1)_post_make),)
    $$($(1)_post_make)
endif
    touch $$@
.PHONY: build-$(1) clean-$(1)
build-$(1): $$($(1)_install)
clean-$(1):
    -rm -fr $$($(1)_builddir)
endef

gmp_dir = src/gmp-4.3.2
gmp_env =   CONFIG_SITE=$(SRCDIR)/config.site
gmp_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static --enable-cxx
gmp_deps = $(untar_dep)
gmp_make_target = install
$(eval $(call configure-rule,gmp))

mpfr_dir = src/mpfr-2.4.2
mpfr_env =  CONFIG_SITE=$(SRCDIR)/config.site
mpfr_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static \
                --with-gmp=$(DESTDIR)
mpfr_deps = $(untar_dep) $(gmp_install)
mpfr_make_target = install
$(eval $(call configure-rule,mpfr))

mpc_dir = src/mpc-0.8.1
mpc_env =   CONFIG_SITE=$(SRCDIR)/config.site
mpc_configure = --prefix=$(DESTDIR) \
                --disable-shared --enable-static \
                --with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR)
mpc_deps = $(untar_dep) $(gmp_install) $(mpfr_install)
mpc_make_target = install
$(eval $(call configure-rule,mpc))

gcc_dir = src/gcc-4.7.2
gcc_env =   CONFIG_SITE=$(SRCDIR)/config.site \
    CFLAGS="-I/usr/include/i386-linux-gnu" \
    CXXFLAGS="-I/usr/include/i386-linux-gnu"
gcc_configure = --prefix=$(DESTDIR) \
                --libdir=$(DESTDIR)/lib \
                --with-local-prefix=$(DESTDIR) \
                --with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR) \
                --with-mpc=$(DESTDIR) \
                --disable-bootstrap \
                --enable-languages=c,c++ \
                --disable-libgomp --disable-multilib \
                --disable-libmudflap --disable-libssp \
                --disable-libquadmath \
                --enable-rpath \
                MAKEINFO=missing
gcc_deps = $(untar_dep) $(gmp_install) $(mpfr_install) $(mpc_install)
gcc_make_target = 
gcc_post_make = make -C $(gcc_builddir) install
$(eval $(call configure-rule,gcc))

binutils_dir = src/binutils-2.24.51
#binutils_env = LDFLAGS=-Wl,-rpath\ $(DESTDIR)/lib
binutils_env = CONFIG_SITE=$(SRCDIR)/config.site \
    CFLAGS="-I/usr/include/i386-linux-gnu" \
    BOOT_LDFLAGS="-rpath-link=$(DESTDIR)/lib -rpath=$(DESTDIR)/lib"
binutils_configure = --prefix=$(DESTDIR) \
                --libdir=$(DESTDIR)/lib \
                --with-gmp=$(DESTDIR) \
                --enable-rpath
binutils_deps = $(untar_dep) $(gmp_install)
#binutils_make_target = install
binutils_post_make = make -C $(binutils_builddir) install
$(eval $(call configure-rule,binutils))


.PHONY: env
env:
    @echo export PATH=$(DESTDIR)/bin:\$$PATH
    @echo export LIBRARY_PATH=/usr/lib/i386-linux-gnu