【问题标题】:Shared libraries and linking on Linux (elf)Linux (elf) 上的共享库和链接
【发布时间】:2012-01-14 17:55:06
【问题描述】:

我已阅读Creating Library with backward compatible ABI that uses Boost 上的帖子,现在我正在尝试了解如何链接我的共享库以保持稳定的 ABI,并避免出现干扰符号的问题。

我创建了以下简单的测试项目:

cat <<EOF > a.c
#define ABI __attribute__((visibility("default")))

int common();
int ABI a() { return common() + 1; }
EOF

cat <<EOF > b.c
#define ABI __attribute__((visibility("default")))

int common();
int ABI b() { return common() + 2; }
EOF

cat <<EOF > common_v1.c
int common() { return 1; }
EOF

cat <<EOF > common_v2.c
int common() { return 2; }
EOF

cat <<EOF > test.c
#include <assert.h>

int a();
int b();

int main(int argc, const char *argv[])
{
    assert( a() + b() == 6 );
    return 0;
}
EOF

cat <<EOF > CMakeLists.txt
cmake_minimum_required(VERSION 2.8)

project(TEST)

add_library(common_v1 STATIC common_v1.c)
add_library(common_v2 STATIC common_v2.c)

SET_SOURCE_FILES_PROPERTIES( a.c b.c COMPILE_FLAGS -fvisibility=hidden )
add_library(a SHARED a.c)
target_link_libraries(a common_v1)

add_library(b SHARED b.c)
target_link_libraries(b common_v2)

add_executable(test test.c)
target_link_libraries(test a b)
EOF

库 common_v1 和 common_v2 应该模拟库 a 和 b 的外部依赖(如 Boost)。因为 common_v1 和 common_v2 被视为外部库,所以我不希望更改它们的构建系统(并且不更改它们编译时使用的标志)。

上面的项目,编译正常,但是不行!执行测试应用程序时,它会跳转到断言语句。

这让我相信在 liba 和 libb 中使用了相同的 common 定义。为什么会这样,我做错了什么?

【问题讨论】:

    标签: c++ c compilation linker abi


    【解决方案1】:

    您可以在创建ab 库时使用ld--retain-symbols-file 选项修复您的测试程序,并且只保留a()b() 符号,这样common() 符号就不会由这些库导出(因此一个库不会尝试使用另一个库的common() 符号):

    --retain-symbols-file 文件名 仅保留文件文件名中列出的符号,丢弃所有 其他。 filename 只是一个平面文件,每行有一个符号名称。

    您也可以使用--version-script 选项:

    --version-script=版本-脚本文件 为链接器指定版本脚本的名称。

    version-scriptfile 如下:

    鬼{ 全局:一个;乙; # 要导出的符号 当地的: *; #隐藏其他人 };

    相关话题:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 2023-03-25
      • 2023-03-10
      相关资源
      最近更新 更多