使用makefile的动态链接库

时间:2016-04-08 04:25:21

标签: c dynamic makefile shared-libraries gnu-make

你好Stack Overflow的好人,我再次回答这个问题吧!哈哈 所以我有几个文件,我试图编译和链接在一起。我创建的库是一个DLL。使用RTLD_LAZY方法。我将该库与应用程序放在同一目录中。我很难完成这项任务。我正在尝试使用-ldl链接它。

我的文件是:

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

这是我到目前为止所做的,但我显然已经搞砸了......

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=./

任何建议将不胜感激!提前谢谢!

1 个答案:

答案 0 :(得分:0)

这是一个靠近你自己的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

仅在链接时使用-lm。只有在链接动态库时才需要-fPic。仅在将程序与动态库链接时才需要-lmyLibrary。因此生成testDynamic不需要它,因为它会动态加载库,它不需要链接到它。

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;
}

现在建设:

>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

让我们保留动态库的第一个版本:

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

现在更新myLibrary.c:

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

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

再次建造:

>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

让我们将这个新的动态库移动到另一个目录:

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

现在测试时没有动态库:

>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

有什么区别?在“testDynamic.c”中,我们可以,而不是显示消息错误,做一个不需要“libmyLibrary.so”的替代算法。

现在检查我们可以使用“libmyLibrary.so”:

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