【问题标题】:link static library with shared library problem链接静态库与共享库问题
【发布时间】:2019-04-19 16:11:24
【问题描述】:

我是Linux 的新手,很抱歉,如果我的问题真的很愚蠢。

我有共享跨平台库项目,使用第三方静态库(Libtorrent)。

Windows/Android/macOS - 构建和工作正常。

但我不知道如何在 Linux (Ubuntu) 和 GCC 中构建它。

我收到以下链接器错误:

/usr/bin/ld: /home/user/Desktop/project/libtorrent-build/prebuilt/linux/lib/libtorrent-rasterbar.a(create_torrent.o): relocation R_X86_64_TPOFF32 against symbol `_ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /home/user/Desktop/project/libtorrent-build/prebuilt/linux/lib/libtorrent-rasterbar.a(disk_io_thread.o): relocation R_X86_64_TPOFF32 against symbol `_ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /home/user/Desktop/project/libtorrent-build/prebuilt/linux/lib/libtorrent-rasterbar.a(peer_connection.o): relocation R_X86_64_TPOFF32 against symbol `_ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /home/user/Desktop/project/libtorrent-build/prebuilt/linux/lib/libtorrent-rasterbar.a(session.o): relocation R_X86_64_TPOFF32 against symbol `_ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E' can not be used when making a shared object; recompile with -fPIC

我尝试使用-fPIC 标志重建BoostLibtorrent:没有任何改变。

Boost 构建脚本:

#!/bin/bash
set -e

BOOST_VERSION=1.63.0

BOOST_VERSION_UNDERSCORES=${BOOST_VERSION//./_}

echo "Boost version $BOOST_VERSION"
echo "Downloading..."

BOOST_ARCH_NAME=boost_${BOOST_VERSION_UNDERSCORES}.tar.gz

curl -O -L https://dl.bintray.com/boostorg/release/$BOOST_VERSION/source/$BOOST_ARCH_NAME

echo "Extracting..."
tar -xvzf $BOOST_ARCH_NAME

BOOST_FOLDER_NAME=boost_${BOOST_VERSION_UNDERSCORES}

cd $BOOST_FOLDER_NAME

chmod +x bootstrap.sh
./bootstrap.sh

chmod +x b2
./b2 headers

./b2    \
    --layout=versioned \
    --with-thread \
    --with-date_time \
    --with-filesystem \
        --with-chrono \
        --with-random \
    toolset=gcc \
    threading=multi \
    link=static \
    runtime-link=shared \
    variant=release \
    threadapi=pthread \
        debug-symbols=off \
        warnings=off \
        warnings-as-errors=off \
        architecture=x86 \
        address-model=64 \
    --stagedir=stage/linux \
        cxxflags="-std=gnu++0x -fPIC" \
    stage

echo "Copying prebuilt..."

mkdir -p ../prebuilt/linux/lib
cp -rf ./stage/linux/lib ../prebuilt/linux/

cd ../

echo "Cleaning up..."

rm $BOOST_ARCH_NAME
rm -rf $BOOST_FOLDER_NAME

echo "Done."

Libtorrent 构建脚本:

#!/bin/sh
set -e

MY_PWD=$PWD

LIBTORRENT_VERSION=1_1_8
LIBTORRENT_NAME=libtorrent-$LIBTORRENT_VERSION
export LIBTORRENT_FOLDER_NAME=libtorrent-$LIBTORRENT_NAME

curl -O -L "https://github.com/arvidn/libtorrent/archive/${LIBTORRENT_NAME}.tar.gz"

echo "Extracting..."
rm -rf ./$LIBTORRENT_FOLDER_NAME
tar xfz "${LIBTORRENT_NAME}.tar.gz"

echo "Building for linux..."

cd $LIBTORRENT_FOLDER_NAME

. ./autotool.sh

mkdir -p lib

if [ ! -d "./include/boost" ]; then
  ln -s $PWD/../../boost-build/prebuilt/include/boost $PWD/include/boost
  ln -s $PWD/../../boost-build/prebuilt/linux/lib/* $PWD/lib/
fi

if [ ! -d "./include/openssl" ]; then
  ln -s $PWD/../../openssl-build/prebuilt/include/openssl $PWD/include/openssl
  ln -s $PWD/../../openssl-build/prebuilt/linux/lib/* $PWD/lib/
fi

export CXX=g++
export CC=gcc
export CXXFLAGS="-std=gnu++0x -fPIC -fPIE"
export CPPFLAGS="-I"$PWD"/include"

./configure --enable-debug=no --with-boost-python=no --enable-logging=no \
--enable-tests=no --with-openssl=$PWD \
--with-boost=$PWD \
--enable-shared=no \
--enable-encryption

make -j4

mkdir -p ../prebuilt/linux/lib
cp -rf ./src/.libs/libtorrent-rasterbar.a ../prebuilt/linux/lib/

cd $MY_PWD

echo "cleaning up"

rm -rf $LIBTORRENT_FOLDER_NAME
rm -rf ${LIBTORRENT_NAME}.tar.gz

echo "done"

我的共享库本身是一个基于Qt 的库。我使用Qt Creator 构建它,在 .pro 文件中提供所有必需的头文件和库。

【问题讨论】:

  • 共享库中的代码必须使用-fPIC 构建(如错误消息中所述)。即使对于链接到共享库的静态库,也需要这样做。
  • 我已经在所有可能的地方添加了这个 -fPIC - 没有帮助......
  • 即使在使用-fPIC 重新编译后,它仍然显示recompile with -fPIC 吗?您重新编译的版本是否在 prebuilt 目录之外的其他地方结束?
  • 是的,确实如此。不,我确定库在预建目录中。我在构建之前删除了该文件夹。

标签: c++ linux gcc libtorrent libtorrent-rasterbar


【解决方案1】:

问题出在 Libtorrent 构建脚本中。我删除了-fPIE 选项并添加了

export CFLAGS="-fPIC"

重建,现在链接没有错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    相关资源
    最近更新 更多