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

标签 gcc build centos shared-libraries

我正在尝试在/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,但没有任何效果。

最佳答案

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

PATH 中使用您的工具链:

gcc -dumpspecs > specsfile

编辑specsfilelink 部分添加您的 -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 一起使用部分(正在处理)

--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 ,如果可以的话,可能会在链接器中 ldbinutils不在 gcc/g++ ,但你为什么要这样做?

只导出LD_LIBRARY_PATH在运行时和 LD_RUN_PATH在构建时

export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
ldd a.out

ldd应显示您导出的路径。

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

If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following:

  • add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution
  • add LIBDIR to the `LD_RUN_PATH' environment variable during linking
  • use the `-Wl,--rpath -Wl,LIBDIR' linker flag
  • have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages.

完整性 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

关于gcc - 如何使用内置的 rpath 构建和安装 gcc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13334300/

相关文章:

如果在 gcc 中使用 --static 标志会出现编译错误

ios - 使用没有代码设计的 xcodebuild 构建 iOS 应用程序

Redis 守护进程不创建 PID 文件

ruby-on-rails - Rails 应用程序部署问题

c - 如何从单独的库文件中包含 syscalls.c?

python - ImageMagick: OSError:/lib/libc.so.6: 找不到版本 `GLIBC_2.XX'

c++ - GCC 内联汇编错误 : junk `(%ebp)+4' after expression

java - 在当前项目和插件组 [org.apache.maven.plugins, org.codehaus.mojo] 本地中找不到前缀 'archetype' 的插件

iphone - 连接到一台 Mac 的多个 iPhone OS 设备 - 如何选择构建

c - 如何从 C 代码中找到 kernel.shmmax 的值