首页 文章

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

提问于
浏览
8

我正在尝试在/ usr / local中构建和安装我自己的gcc 4.7.2,以代替/ usr中的gcc 4.4.6 . (这是在CentOS 6.3上 . )

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

如果它正常工作,在我使用gcc构建可执行文件而不指定“-Wl,-rpath = / usr / local / lib64”之后,当我查看可执行文件时,它应该显示/ usr / local / lib64 / libstdc .so . 6而不是/ usr / lib64 / libstdc .so.6 . 同样适用于libgcc_s.so.1 .

我尝试过不同的方法,包括在'configure'命令行中指定LDFLAGS_FOR_TARGET = -Wl,-rpath = / usr / local / lib64,-rpath = / usr / local / lib,但没有任何效果 .

1 回答

  • 5

    如果您不想导出路径,则可以使用其他解决方案:

    使用 PATH 中的工具链:

    gcc -dumpspecs > specsfile
    

    编辑 specsfile 并在 link 部分添加您的 -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

    strace -fF -o /tmp/g++.log g++ test.cpp
    grep specs /tmp/g++.log
    

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

    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= 选项gcc configure最终将在构建时使用,我还不清楚如何使用链接部分(处理它) .

    --with-specs="%{shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}%{!shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}"
    

    它工作,我使用 shared 而不是 !shared 只是为了测试,可能应该使用一些更聪明的条件,请注意它不报告 -dumpspecs .

    通过gcc邮件列表的一些帖子阅读我的印象是 specs aren 't liked by everyone (but if I' m没有错4.9添加另一个选项 --with-extra-specs )而不是首选方式来做这样的自定义似乎是 configure.host ,但我已经完成而没有调查它,玩得开心! :-)

    另见:gcc faq rpath

    update above

    我不知道你是否可以设置一个预先定义的 rpath ,可能是因为你可以在 binutilsbinutils 链接器 ld 中,但你为什么要这样做呢?

    只需在运行时导出 LD_LIBRARY_PATH ,在构建时导出 LD_RUN_PATH

    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)手册页 .

    for completeness Makefile 我用来测试的东西,所有的配置选项,环境变量(参见boot ldflags)我试过没用, --enable-rpath 包括在内 .

    使用 mkdir ~/gccMakefile 复制到 ~/gcc 然后 cd ~/gcc && make build-gcc

    notice 使用的选项仅适用于此测试用例,请勿用作参考 .

    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
    

相关问题