【问题标题】:How to build and install gcc with built-in rpath?如何使用内置 rpath 构建和安装 gcc?
【发布时间】:2012-10-31 07:42:18
【问题描述】:

我正在尝试在 /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”后,当我 ldd 可执行文件时,它应该显示 /usr/local/lib64/libstdc++ .so.6 而不是 /usr/lib64/libstdc++.so.6。对于 libgcc_s.so.1 也是如此。

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

【问题讨论】:

    标签: gcc build centos shared-libraries


    【解决方案1】:

    如果您不想导出路径,还有另一种解决方案:

    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 最终将在构建时使用,我还不清楚如何与link 部分一起使用(正在处理)。 p>

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

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

    阅读 gcc 邮件列表的某些主题后,我的印象是 specs 并不是每个人都喜欢(但如果我没记错的话 4.9 添加另一个选项 --with-extra-specs)相反,进行此类自定义的首选方式似乎是是configure.host,但我已经完成了,没有调查,玩得开心! :-)

    另见:gcc faq rpath

    以上更新

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

    只需在运行时导出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) 手册页。

    为了完整性 Makefile 我用来测试的东西,所有的配置选项,环境变量(见引导 ldflags)我试过没用,包括--enable-rpath

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

    注意所用选项仅用于本测试用例,请勿作为参考。

    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}}'
    【解决方案2】:

    我正在安装 httpd-2.4.51 并且需要指定 -rpath 来编译程序。我使用链接器标志-Wl,-rpath -Wl,LIBDIR

    使用命令:

    sudo mv httpd.c /usr/lib #create a .c file and move it to the default directory for the library file
    sudo gcc -o httpd httpd.c -L$--prefix=/usr/lib -lhttpd -Wl,-rpath=$--prefix=/usr/lib
    

    您可以检查 gcc 的安装位置:

    whereis gcc
    

    gcc: /usr/bin/gcc /usr/lib/gcc /usr/share/man/man1/gcc.1.gz

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2017-01-11
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 2022-08-16
      相关资源
      最近更新 更多