rtayl0a
rtayl0a

Reputation: 23

Dynamic Link Library using makefile

Hello to the good people of Stack Overflow, I am back at it again with the questions! haha So I have a couple of files that I am trying to compile and link together. The library I have created is a DLL. Using a RTLD_LAZY method. I have the library in the same directory as the application. I'm having a tough time completing this task. I'm trying to link it using -ldl.

My files that I have are:

lab3.c        //Which has my main
myLibrary.c   //which is my library
sdv.h         //which is my header file 
testDynamic.c //which is my handle file for the RTLD_LAZY

Here is what I have done so far, but I'm clearly screwing something up..

dynamic: lab3.o myLibrary.o test
        gcc -o dynamic lab3.o myLibrary.o -lm

lab3.o: lab3.c
        gcc -fPIC -c -o lab3.o lab3.c -lm

myLibrary.o: myLibrary.c
        gcc -fPIC -c myLibrary.c -o myLibrary.o -lm 

libmyLibrary.so: myLibrary.o
        gcc -shared -o libmyLibrary.so myLibrary.o -lm

testDynamic.o:
        gcc testDynamic.c -L. -lmyLibrary -o test -ldl

export LD_LIBRARY_PATH=./

Any advice will be greatly appreciated! Thanks in advance!

Upvotes: 1

Views: 7374

Answers (1)

jdarthenay
jdarthenay

Reputation: 3147

Here comes an example close to your own makefile.

makefile:

CC=gcc
CFLAGS=-Wall -Wextra -Werror -std=gnu99

.PHONY:all mrproper clean


all:libmyLibrary.so dynamic testDynamic 

dynamic:lab3.o
    $(CC) $(CFLAGS) -o dynamic lab3.o -L. -lmyLibrary -lm

lab3.o:lab3.c
    $(CC) $(CFLAGS) -c -o lab3.o lab3.c

myLibrary.o:myLibrary.c
    $(CC) $(CFLAGS) -fPIC -c myLibrary.c -o myLibrary.o

libmyLibrary.so:myLibrary.o
    $(CC) $(CFLAGS) -shared -o libmyLibrary.so myLibrary.o -lm

testDynamic.o:testDynamic.c
    $(CC) $(CFLAGS) -o testDynamic.o -c testDynamic.c

testDynamic:testDynamic.o
    $(CC) $(CFLAGS) -o testDynamic testDynamic.o -ldl

mrproper:clean
    rm -f dynamic libmyLibrary.so testDynamic

clean:
    rm -f lab3.o myLibrary.o testDynamic.o

Use -lm only when linking. -fPic is only necessary when linking dynamic library. -lmyLibrary is only necessary when linking program with dynamic library. So generating testDynamic does not need it as it will load library dynamically, it does not require being linked to it.

sdv.h:

#ifndef SDV_H
#define SDV_H

extern void sdv_print_version();

#endif

myLibrary.c:

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

void sdv_print_version()
{
    printf("v1.0\n");
}

testDynamic.c:

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

#include <dlfcn.h>

#define MY_LIB "libmyLibrary.so"
#define PRINT_VERSION "sdv_print_version"

int main()
{
    void *handle = dlopen(MY_LIB, RTLD_LAZY);
    if (handle == NULL)
    {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    void (*p_print_version)() = NULL;
    p_print_version = dlsym(handle, PRINT_VERSION);
    if (p_print_version == NULL)
    {
        printf("No version available.\n");
        fprintf(stderr, "%s\n", dlerror());
    }
    else
    {
        (*p_print_version)();
    }

    if (dlclose(handle) != 0)
    {
        fprintf(stderr, "%s\n", dlerror());
    }

    return 0;
}

Now building:

>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
gcc -Wall -Wextra -Werror -std=gnu99 -c -o lab3.o lab3.c
gcc -Wall -Wextra -Werror -std=gnu99 -o dynamic lab3.o -L. -lmyLibrary -lm
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic.o -c testDynamic.c
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic testDynamic.o -ldl

Let's keep a first version of dynamic library:

>mkdir v1.0
>mv libmylibrary.so v1.0/

Now update myLibrary.c:

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

void sdv_print_version()
{
    printf("v2.0\n");
}

Build again:

>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm

Let's move this new dynamic library to another directory:

>mkdir v2.0
>mv libmylibrary.so v2.0/

Now testing with no dynamic library available:

>export LD_LIBRARY_PATH=./
>PATH=$PATH:.
>dynamic
dynamic: error while loading shared libraries: libmyLibrary.so: cannot open shared object file: No such file or directory
>testDynamic
libmyLibrary.so: cannot open shared object file: No such file or directory

What's the difference? In "testDynamic.c" we could, instead of showing a message error, do an alternative algorithm not requiring "libmyLibrary.so".

Now checking we can use "libmyLibrary.so":

>cd v1.0
>../dynamic
v1.0
>../testDynamic
v1.0
>cd ../v2.0
>../dynamic
v2.0
>../testDynamic
v2.0

Upvotes: 3

Related Questions