我正在使用 CppUTest 来测试 fornol.c
中定义的 C 代码源文件。该文件定义了主要生产 main()
功能。
我还有一个AllTests.cpp
文件也有 main()
功能,但是main()
应该仅在运行单元测试时使用。
AllTests.cpp
被编译为 .o
文件,而 fornol.c
被编译为 libfornol.a
存档。
然后 CppUTest 尝试将所有内容链接在一起,但我得到的是:
Linking fornol_tests
cc -o fornol_tests objs/tests/AllTests.o objs/tests/FornolTests.o lib/libfornol.a ../../CppUTest/lib/libCppUTest.a ../../CppUTest/lib/libCppUTestExt.a -lstdc++ -lgcov
lib/libfornol.a(fornol.o): In function `main':
/home/dlindelof/Work/endor/nol/fornol/fornol.c:453: multiple definition of `main'
objs/tests/AllTests.o:/home/dlindelof/Work/endor/nol/fornol/tests/AllTests.cpp:4: first defined here
collect2: ld returned 1 exit status
看起来好像 main()
fornol.c
中定义的函数并存在于文件中libfornol.a
与 main()
冲突定义于 AllTests.cpp
。但我的理解是,仅当给定符号尚未被引用时才会搜索存档/库文件。因此,只要所有定义都在存档/库文件中,多次定义相同的符号应该不是问题。
我在这里做错了什么?
最佳答案
您需要从 AllTests.cpp
中删除 main()
并将其放入自己的源文件中。
当链接器在库中进行链接时,它无法拆分库中的目标文件;它必须将库中的每个目标文件作为一个单元进行链接或省略。 (我知道 LLVM 是不同的,但那是另一个话题了。)这就是为什么,如果您查看像 glibc 这样的库的源代码,每个函数都有自己的源文件。
因此,链接器需要从库 (libfornol.a
) 中提取目标文件 (fornol.o
) 来满足依赖关系,但该目标文件带有重复的符号 (main
)。
将测试代码放入库中(我们在工作中经常这样做)是完全可以的,但将其保留在自己的源文件中(我们传统上使用 main.cc
)。 (无论如何,这是一个更好的测试,因为测试代码不应该访问 static
声明的符号。)
关于c - 为什么链接存档时会出现 'multiple definition' 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9129087/