Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc, how to force the final executable link a unused shared library?

Tags:

c

gcc

I have an executable shared_main , a shared library libbar.so and a dynamic load shared library libfoo.so (load in shared_main via dlopen).

shared_main doesn't use any symbols from libbar.so but libfoo.so does.

So gcc -g -Wall -o shared_main shared_main.c libbar.so -ldl doesn't link libbar.so to shared_main. Checked via ldd shared_main.

How to let gcc force shared_main link libbar.so?

P.S. I know I can link libfoo.so with libbar.so. But I want to try if I can force shared_main to link libbar.so here.


shared_main.c

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main(){    
    void* libHandle = dlopen("./libfoo.so", RTLD_LAZY);
    if(libHandle == NULL){
        printf("dlopen:%s", dlerror());
        exit(1);
    }
    int(*xyz)(int);
    xyz = (int(*)(int)) dlsym(libHandle, "xyz");
    if(xyz == NULL){
        printf("dlsym:%s", dlerror());
        exit(1);
    }
    int b = xyz(3);
    printf("xyz(3): %d\n", b);

}

foo.c (libfoo.so)

void func_in_bar();
int xyz(int b){
    func_in_bar();
    return b + 10;
}

bar.c (libbar.so)

//mimic python share library runtime
#include <stdio.h>
void func_in_bar(){
    printf("I am a Function in bar\n");
}

void another_func_in_bar(){
    printf("I am another function in bar\n");
}

makefile

shared_main:
    gcc -g -Wall -o shared_main shared_main.c libbar.so -ldl
shared:
    gcc -g -Wall -fPIC -shared -o libfoo.so foo.c
    gcc -g -Wall -fPIC -shared -o libbar.so bar.c
like image 936
Rick Avatar asked Oct 31 '25 17:10

Rick


1 Answers

You have an XY-problem, where X is: libfoo has unresolved symbols, but the linker doesn't warn about it

So use the -z defs option linkage-time, and when you get the linker error about the unresolved symbol add -lfoo to the linkage command.

That's still not enough, you will have to use a -L and a -Wl,-rpath option too. Here is a complete Makefile:

# Makefile

# LIBDIR should be the final place of the shared libraries
# such as /usr/local/lib or ~/libexec/myproject

LIBDIR  := ${PWD}
TARGETS := shared_main libbar.so libfoo.so

all: ${TARGETS}

clean:
    rm -f ${TARGETS} 2>/dev/null || true

shared_main: shared_main.c
    gcc -g -Wall -o shared_main shared_main.c -ldl

libbar.so: bar.c
    gcc -g -Wall -fPIC -shared -o libbar.so bar.c

libfoo.so: foo.c libbar.so
    gcc -g -Wall -fPIC -shared -z defs -o libfoo.so foo.c \
    -L${LIBDIR} -Wl,-rpath,${LIBDIR} -lbar

Edit: nonetheless, here is a hackish solution for the original question: use option -Wl,--no-as-needed

shared_main:
    gcc -g -Wall -o shared_main shared_main.c \
    -Wl,--no-as-needed -Wl,-rpath,${PWD} libbar.so -ldl
like image 174
Lorinczy Zsigmond Avatar answered Nov 02 '25 08:11

Lorinczy Zsigmond



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!