Pregunta

He leído el hilo de rosca en La creación de la Biblioteca con compatible ABI que utiliza el Boost y ahora estoy tratando de entender cómo debo enlace de mi las bibliotecas compartidas para mantener estable el ABI, y evitar problemas con la interferencia de los símbolos.

He creado el siguiente proyecto de prueba:

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

Las bibliotecas common_v1 y common_v2 debe emular a una dependencia externa de las bibliotecas a y b (como Boost).Porque common_v1 y common_v2 es considerado como bibliotecas externas, prefiero no cambiar su sistema de construcción (y no por no cambiar las banderas están compilados con).

El proyecto anterior, compila bien, pero no funciona!Cuando la aplicación de la prueba se ejecuta saltos en la instrucción assert.

Esto me hace creer que la misma definición de común se utiliza en ambos liba y la libb.¿Por qué es este el caso, y lo que estoy haciendo mal?

¿Fue útil?

Solución

Usted puede arreglar su programa de pruebas mediante el uso de --retain-symbols-file opción de ld cuando la creación de su a y b las bibliotecas y sólo conservan a() y b() símbolos, de modo que common() símbolo de no ser exportados por estas bibliotecas (y, por tanto, una biblioteca no intente utilizar common() símbolo de otra):

  --retain-symbols-file filename
        Retain only the symbols listed in the file filename, discarding all
        others. filename is simply a flat file, with one symbol name per line.

También puede utilizar --version-script opción:

  --version-script=version-scriptfile
        Specify the name of a version script to the linker.

donde el version-scriptfile es la siguiente:

  FOO {
    global: a; b; # symbols to be exported
    local: *;     # hide others
  };

Temas relacionados con:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top