I have read the thread on Creating Library with backward compatible ABI that uses Boost and I'm now trying to understand how I should link my shared libraries to maintain a stable ABI, and avoid problems with interfering symbols.
I have created the following simple test project:
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
The libraries common_v1 and common_v2 should emulate an external dependency of the libraries a and b (like Boost). Because common_v1 and common_v2 is considered as external libraries, I would prefer not to change their build system (and there by not change the flags they are compiled with).
The project above, compiles fine, but it does not work! When the test application is executed it jumps into the assert statement.
This makes me believe the same definition of common is used in both liba and libb. Why is this the case, and what am I doing wrong?