Linking against older symbol version in a .so file

前端 未结 11 1848
长发绾君心
长发绾君心 2020-11-27 11:25

Using gcc and ld on x86_64 linux I need to link against a newer version of a library (glibc 2.14) but the executable needs to run on a system with an older version (2.5). Si

11条回答
  •  广开言路
    2020-11-27 12:00

    Minimal runnable self contained example

    GitHub upstream.

    main.c

    #include 
    #include 
    
    #include "a.h"
    
    #if defined(V1)
    __asm__(".symver a,a@LIBA_1");
    #elif defined(V2)
    __asm__(".symver a,a@LIBA_2");
    #endif
    
    int main(void) {
    #if defined(V1)
        assert(a() == 1);
    #else
        assert(a() == 2);
    #endif
        return EXIT_SUCCESS;
    }
    

    a.c

    #include "a.h"
    
    __asm__(".symver a1,a@LIBA_1");
    int a1(void) {
        return 1;
    }
    
    /* @@ means "default version". */
    __asm__(".symver a2,a@@LIBA_2");
    int a2(void) {
        return 2;
    }
    

    a.h

    #ifndef A_H
    #define A_H
    
    int a(void);
    
    #endif
    

    a.map

    LIBA_1{
        global:
        a;
        local:
        *;
    };
    
    LIBA_2{
        global:
        a;
        local:
        *;
    };
    

    Makefile

    CC := gcc -pedantic-errors -std=c89 -Wall -Wextra
    
    .PHONY: all clean run
    
    all: main.out main1.out main2.out
    
    run: all
        LD_LIBRARY_PATH=. ./main.out
        LD_LIBRARY_PATH=. ./main1.out
        LD_LIBRARY_PATH=. ./main2.out
    
    main.out: main.c libcirosantilli_a.so
        $(CC) -L'.' main.c -o '$@' -lcirosantilli_a
    
    main1.out: main.c libcirosantilli_a.so
        $(CC) -DV1 -L'.' main.c -o '$@' -lcirosantilli_a
    
    main2.out: main.c libcirosantilli_a.so
        $(CC) -DV2 -L'.' main.c -o '$@' -lcirosantilli_a
    
    a.o: a.c
        $(CC) -fPIC -c '$<' -o '$@'
    
    libcirosantilli_a.so: a.o
        $(CC) -Wl,--version-script,a.map -L'.' -shared a.o -o '$@'
    
    libcirosantilli_a.o: a.c
        $(CC) -fPIC -c '$<' -o '$@'
    
    clean:
        rm -rf *.o *.a *.so *.out
    

    Tested on Ubuntu 16.04.

提交回复
热议问题