我正在学习“以艰难的方式学习C”电子书(?),并完成了练习32。
它使用以前开发的项目结构,其中测试链接到内置库。但是,当我运行时make test
,会得到“对X的未定义引用”,其中X是库标头中定义的每个函数。
twoll_tests.c
是我的测试文件,libds
是库。请参阅此问题底部的项目树。
测试的编译行是这样的:
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG -std = c11 build / libds.a tests / twoll_tests.c -o tests / twoll_tests
Makefile内容:
CFLAGS = -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG -std = c11 $(OPTFLAGS) LIBS = -ldl $(OPTLIBS) 前缀?= / usr / local 源= $(通配符src / ** / *。c src / *。c) OBJECTS = $(部分%.c,%。o,$(源)) TEST_SRC = $(通配符测试/*_tests.c) TESTS = $(部分%.c,%,$(TEST_SRC)) TARGET = build / libds.a SO_TARGET = $(部分%.a,%。so,$(TARGET)) #目标构建 全部:$(TARGET)$(SO_TARGET) dev:CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS) dev:全部 $(目标):CFLAGS + = -fPIC $(TARGET):建立$(OBJECTS) ar rcs $ @ $(对象) ranlib $ @ $(SO_TARGET):$(TARGET)$(OBJECTS) $(CC)-共享-o $ @ $(对象) 建造: @mkdir -p构建 @mkdir -p bin #单元测试 .PHONY:测试 测试:CFLAGS + = $(TARGET) 测试:$(TESTS) sh ./tests/runtests.sh valgrind: VALGRIND =“ valgrind --log-file = / tmp / valgrind-%p.log” $(MAKE) #清洁工 干净的: rm -rf生成$(对象)$(测试) rm -f测试/tests.log 找 。-name“ * .gc *” -exec rm {} \; rm -rf`find。名称“ * .dSYM” -print` #安装 安装:全部 安装-d $ {DESTDIR)/ $ {PREFIX)/ lib / 安装$(TARGET)$(DESTDIR)/ $(PREFIX)/ lib / #检查器 BADFUNCS ='[^ _。> a-zA-Z0-9](str(n?cpy | n?cat | xfrm | n?dup | str | pbrk | tok | _)| stpn?cpy | a?sn? printf | byte_)' 查看: @echo具有潜在危险功能的文件。 @egrep $(BADFUNCS)$(源)|| 真的
最后,项目树:
。 ├──箱 ├──建筑 │├──libds.a │└──libds.so ├──许可 ├──Makefile ├──README.md ├──src │└──libds │├──twoll.c │├──twoll.h │└──twoll.o └──测试 ├──runtests.sh ├──tester.h ├──tests.log └──twoll_tests.c
编辑:这是的完整输出make test
:
kroltan @ kroltan〜/ Projects / learncthehardway / ex32 $全部制作 cc -g -O2 -Wall -Wextra -Isrc -rdynamic -std = c11 -fPIC -c -o src / libds / twoll.o src / libds / twoll.c ar rcs build / libds.a src / libds / twoll.o ranlib build / libds.a cc -shared -o build / libds.so src / libds / twoll.o kroltan @ kroltan〜/ Projects / learncthehardway / ex32 $做测试 cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG -std = c11 build / libds.a tests / twoll_tests.c -o tests / twoll_tests /tmp/ccnOW9OX.o:在功能twotwo_new_test中: /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:8:对“ twoll_new”的未定义引用 /tmp/ccnOW9OX.o:在函数twotwo_del_test中: /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:13:对“ twoll_new”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:13:对“ twoll_del”的未定义引用 /tmp/ccnOW9OX.o:在函数twotwo_push_pop_test中: /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_new”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_push”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_push”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_push”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_pop”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_pop”的未定义引用 /home/kroltan/Projects/learncthehardway/ex32/tests/twoll_tests.c:18:对“ twoll_pop”的未定义引用 collect2:错误:ld返回1退出状态 make:*** [tests / twoll_tests]错误1
在@unwind和@Umamahesh P的帮助下,发现在调用编译器时必须在目标之后添加库。在互联网上进行了一些额外的搜索之后,我发现正确的Make变量实际上是LDLIBS
,而不是LIBS
本书中给出的。我更改了变量用法,并向test
目标添加了以下分配:
测试:LDLIBS + = $(TARGET)
这样,链接就成功了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句