0%

Linking shared library with conflicting symbols

Problem

夜路走多了總是會碰到鬼,講述一下遇到的情形
我們有兩個Shared library,liba.solibb.so
內容類似如此

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
void inner()
{
printf("inner in a\n");
}
void outer_a()
{
printf("outer in a\n");
inner();
}

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
void inner()
{
printf("inner in b\n");
}
void outer_b()
{
printf("outer in b\n");
inner();
}

如果有個程式這樣寫

1
2
3
4
5
6
7
void outer_a();
void outer_b();
int main()
{
outer_a();
outer_b();
}

當我們編譯這個程式

1
2
$ gcc main.c liba.so libb.so -o main
$ LD_LIBRARY_PATH=./ ./main

結果匯出呼常理預料之外ㄝ,取決於Linking順序,跟我們想要的結果不同。

Simple Solution

將其中一個inner function加上static即可。如

1
2
3
4
static void inner()
{
printf("inner in b\n");
}

這樣結果就可以正常運作了,不過不適用於C++ Member Function之類的,我遇到的情形不是用這種寫法。

Best Solution (Hidden Visibility)

跟上面的方法類似,只需要將其中之一的inner隱藏寢來不可見就行了,將需要的Function輸出

1
2
3
4
5
6
7
8
9
10
11
#define EXPORTED __attribute__((visibility("default")))
#include <stdio.h>
void inner()
{
printf("inner in b\n");
}
EXPORTED void outer_b()
{
printf("outer in b\n");
inner();
}

編譯的時候就選擇

1
$ gcc -fPIC -shared -fvisibility=hidden b.c -o libb.so

就可以達成想要的結果了

Reference

how to link with two shared libraries with many conflicting functions