C:尽管添加了`-ldl`标志,但未定义对`dlopen` /`dlsym`的引用

 风信子的春天R 发布于 2022-12-13 20:10

TL; DR:我正在开展一个dlfcn.h用于打开共享库的C练习.尽管添加(我认为是)基于其他帖子的正确标志,我仍然会收到undefined reference to错误dlopen,dlsym并且在其中定义了一些其他函数dlfcn.h(错误消息和make文件包含在下面).

我在.c文件的开头包括以下内容:#include

我究竟做错了什么?

详细版本:

我正在进行练习30,Learn C The Hard Way并且我很困惑我还需要做什么才能使libex29_tests.c程序(页面上的最后一段代码)正确编译.您可能已经知道,共享库/ makefile /编译器标志对我来说是新的.

到目前为止我尝试过的内容:基于以下帖子,我尝试-ldl通过添加LIBS=-ldl fPIC和/或添加LDFLAGS+=-ldl到Makefile的各个部分来添加标记,但仍然存在问题.书中的makefile版本(包含在下面,作为参考)确实包含一个-ldl标志,尽管语法略有不同.无论如何,我继续得到相同的错误消息.

Linux c ++错误:对'dlopen'的未定义引用

即使使用-ldl标志,g ++也无法链接到libdl

在安装phonetisaurus时未定义引用'dlopen'

C++:使用dlopen()加载共享库时未定义的符号

有什么建议?


这些是我得到的错误.这些错误假定makefile下面包含的版本.但是,正如我所提到的,更改-ldl标志的语法会导致几乎相同的错误消息.

~/.../lchw/ex30_automated$ make
cc -std=gnu99 -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/libex29.o src/libex29.c
src/libex29.c: In function ‘fail_on_purpose’:
src/libex29.c:42:33: warning: unused parameter ‘msg’ [-Wunused-parameter]
 int fail_on_purpose(const char *msg)
                                 ^
ar rcs build/libYOUR_LIBRARY.a src/libex29.o
ranlib build/libYOUR_LIBRARY.a
cc -shared -o build/libYOUR_LIBRARY.so src/libex29.o
cc -std=gnu99 -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  build/libYOUR_LIBRARY.a    tests/libex29_tests.c   -o tests/libex29_tests
In file included from tests/libex29_tests.c:1:0:
tests/libex29_tests.c: In function ‘main’:
src/minunit.h:14:38: warning: parameter ‘argc’ set but not used [-Wunused-but-set-parameter]
 #define RUN_TESTS(name) int main(int argc, char *argv[]) {\
                                      ^
tests/libex29_tests.c:64:1: note: in expansion of macro ‘RUN_TESTS’
 RUN_TESTS(all_tests);
 ^
/tmp/dchaudh/ccwzxpC3.o: In function `check_function':
/home/dchaudh/Dropbox/dchaudh/wc/lchw/ex30_automated/tests/libex29_tests.c:10: undefined reference to `dlsym'
/home/dchaudh/Dropbox/dchaudh/wc/lchw/ex30_automated/tests/libex29_tests.c:11: undefined reference to `dlerror'
/tmp/dchaudh/ccwzxpC3.o: In function `test_dlopen':
/home/dchaudh/Dropbox/dchaudh/wc/lchw/ex30_automated/tests/libex29_tests.c:23: undefined reference to `dlopen'
/tmp/dchaudh/ccwzxpC3.o: In function `test_dlclose':
/home/dchaudh/Dropbox/dchaudh/wc/lchw/ex30_automated/tests/libex29_tests.c:46: undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
make: *** [tests/libex29_tests] Error 1

这是makefile本书的最新内容.它确实包括-ldl标志,你可以在第二行看到.

CFLAGS=-std=gnu99 -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local

SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))

TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))

TARGET=build/libYOUR_LIBRARY.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))

# The Target Build
all: $(TARGET) $(SO_TARGET) tests

dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all

$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
    ar rcs $@ $(OBJECTS)
    ranlib $@

$(SO_TARGET): $(TARGET) $(OBJECTS)
    $(CC) -shared -o $@ $(OBJECTS)

build:
    @mkdir -p build
    @mkdir -p bin

# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
    sh ./tests/runtests.sh

valgrind:
    VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)

# The Cleaner
clean:
    rm -rf build $(OBJECTS) $(TESTS)
    rm -f tests/tests.log
    find . -name "*.gc*" -exec rm {} \;
    rm -rf `find . -name "*.dSYM" -print`

# The Install
install: all
    install -d $(DESTDIR)/$(PREFIX)/lib/
    install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/

# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
    @echo Files with potentially dangerous functions.
    @egrep $(BADFUNCS) $(SOURCES) || true

ensc.. 6

${LIBS}(和你的-ldl)在makefile中没有使用.看来,您正在使用内置规则进行编译,并且可以使用LDLIBS而不是LIBS此变量的名称.

除此之外,还有

  tests: CFLAGS += $(TARGET)

在你的例子中是错误的,因为它TARGET是一个必须进入的库(LD)LIBS.

$(TARGET): build $(OBJECTS)
build:
    @mkdir -p build

也不健全.这将打破并行构建($(OBJECTS)应该依赖build)并将导致不需要的构建(build是一个目录并由每个编译/链接操作更改).平原build对于VPATH构建会有问题,我建议使用

$(OBJECTS): | build/.dirstamp
build/.dirstamp:
    mkdir ${@D}

这里.

1 个回答
  • ${LIBS}(和你的-ldl)在makefile中没有使用.看来,您正在使用内置规则进行编译,并且可以使用LDLIBS而不是LIBS此变量的名称.

    除此之外,还有

      tests: CFLAGS += $(TARGET)
    

    在你的例子中是错误的,因为它TARGET是一个必须进入的库(LD)LIBS.

    $(TARGET): build $(OBJECTS)
    build:
        @mkdir -p build
    

    也不健全.这将打破并行构建($(OBJECTS)应该依赖build)并将导致不需要的构建(build是一个目录并由每个编译/链接操作更改).平原build对于VPATH构建会有问题,我建议使用

    $(OBJECTS): | build/.dirstamp
    build/.dirstamp:
        mkdir ${@D}
    

    这里.

    2022-12-13 20:15 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有