C:尽管添加了 `-ldl` 标志,但未定义对 `dlopen`/`dlsym` 的引用
Posted
技术标签:
【中文标题】C:尽管添加了 `-ldl` 标志,但未定义对 `dlopen`/`dlsym` 的引用【英文标题】:C: Undefined reference to `dlopen`/`dlsym` despite adding `-ldl` flags 【发布时间】:2014-10-31 19:58:19 【问题描述】:TL;DR:我正在做一个 C 练习,它使用 dlfcn.h
打开共享库。尽管根据其他帖子添加了(我认为是)正确的标志,但我仍然收到dlopen
、dlsym
和dlfcn.h
中定义的其他一些函数的undefined reference to
错误(错误消息和生成文件包括在下面)。
我在 .c
文件的开头包含以下内容:#include <dlfcn.h>
我做错了什么?
详细版本:
我正在处理exercise 30 of Learn C The Hard Way
,我不知道我还需要做什么才能使libex29_tests.c
程序(页面上的最后一段代码)正确编译。正如您可能知道的那样,共享库/makefiles/编译器标志目前对我来说是新的。
到目前为止我所做的尝试:根据以下帖子,我尝试通过将 LIBS=-ldl fPIC
和/或 LDFLAGS+=-ldl
添加到我的 Makefile 的各个部分来添加 -ldl
标志,但仍然遇到问题。书中的 makefile 版本(包括在下面,作为参考)确实包含一个-ldl
标志,尽管语法略有不同。在任何情况下,我都会继续收到相同的错误消息。
有什么建议吗?
这些是我得到的错误。这些错误假定下面包含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
【问题讨论】:
【参考方案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
这里。
【讨论】:
我设法通过将第 2 行更改为DLIBS=-ldl $(OPTLIBS)
和 tests: CFLAGS += $(TARGET)
更改为 tests: LDLIBS += $(TARGET)
来使这个示例工作。 Make 执行如下汇编的编译命令:“cc CFLAGS program.c LDLIBS -o program”,在此示例中为cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG tests/libex29_tests.c -ldl build/libYOUR_LIBRARY.a -o tests/libex29_tests
以上是关于C:尽管添加了 `-ldl` 标志,但未定义对 `dlopen`/`dlsym` 的引用的主要内容,如果未能解决你的问题,请参考以下文章
解决:linux eclipse 对‘dlopen’未定义的引用, 对‘xxx’未定义的引用