首页 > 解决方案 > 学习 c 的艰难方法 ex29 编译/链接问题

问题描述

我有一个代表我的练习文件夹的github存储库。运行make all编译器时会抛出错误消息(Ubuntu):

cc -g -O2 -Wall -Wextra -Isrc -DNDEBUG  -fPIC   -c -o src/libex29.o src/libex29.c
src/libex29.c: In function ‘fail_on_purpose’:
src/libex29.c:36:33: warning: unused parameter ‘msg’ [-Wunused-parameter]
 int fail_on_purpose(const char* msg)
                                 ^~~
ar rcs build/libex29.a src/libex29.o
ranlib build/libex29.a
cc -shared -o build/libex29.so src/libex29.o
cc -g -Wall -Wextra -Isrc     test/ex29_test.c   -o test/ex29_test
/tmp/cc7dbqDt.o: In function `main':
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:21: undefined reference to `dlopen'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:22: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:25: undefined reference to `dlsym'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:26: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:33: undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'test/ex29_test' failed
make: *** [test/ex29_test] Error 1

我花了很多时间试图弄清楚如何fix undefined references。dlfcn.h 包括在内,一切似乎都很好。我错过了什么吗?请帮忙

标签: c

解决方案


You must add following option when linking code using dlopen(3) :

-ldl

Here is a demo for Ubuntu 18:

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ cat dl.c
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{

    void *r;

    r = dlopen("", RTLD_LAZY);
    if (r != NULL)
        printf("r is not null \n");

    return 0;
}
$ gcc -o dl -Wall -pedantic -std=c11 dl.c -ldl
$ echo $?
0

Here is a very simple Makefile(note position of -ldl) and related make commands:

$ cat Makefile
CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS) $(OPTLIBS)  

dl.o    :dl.c
    $(CC) -c $< $(CFLAGS)

dl  :dl.o
    $(CC) -o $@ $^ $(CFLAGS) -ldl

clean   : 
    rm -f dl dl.o
$ make clean
rm -f dl dl.o
$ make dl
cc -c dl.c -g -O2 -Wall -Wextra -Isrc -DNDEBUG    
dl.c: In function ‘main’:
dl.c:5:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
 int main(int argc, char **argv)
              ^~~~
dl.c:5:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
 int main(int argc, char **argv)
                           ^~~~
cc -o dl dl.o -g -O2 -Wall -Wextra -Isrc -DNDEBUG     -ldl
$ ./dl
r is not null 

推荐阅读