来自不需要的库中的未定义引用错误

Undefined reference errors from an unneeded library

本文关键字:未定义 引用 错误 不需要      更新时间:2023-10-16

我在ld中遇到了一些"未定义的引用"错误,并且不知道是什么导致了它们。

我的生成文件使用如下命令构建多个可执行文件:

g++ -ogui_program1 -Lpath/to/MyLibs gui_program1.o -lMyUI -lMyBusinessLogic 
    -lMyUtil -lboost_regex
g++ -ogui_program2 -Lpath/to/MyLibs gui_program2.o -lMyUI -lMyBusinessLogic 
    -lMyUtil -lboost_regex
g++ -ocli_program1 -Lpath/to/MyLibs cli_program1.o -lMyUI -lMyBusinessLogic 
    -lMyUtil -lboost_regex
g++ -ocli_program2 -Lpath/to/MyLibs cli_program2.o -lMyUI -lMyBusinessLogic 
    -lMyUtil -lboost_regex

等等。 (实际上,还有比这更多的库,但这是一般的想法。

MyUIMyBusinessLogicMyUtil 都是我已经构建的动态库。 为了使编写生成文件更简单,GUI 和命令行程序使用相同的库列表,即使命令行程序不需要 libMyUI.so

当我尝试链接 Boost.Regex 符号时,一个也是唯一一个命令行程序给出了许多关于未定义引用的错误,即使我-lboost_regex与每个二进制文件链接:

libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher >, boost::regex_traits > >::construct_init(boost::basic_regex > > const&, boost::regex_constants::_match_flags)'
libMyBusinessLogic.so: undefined reference to `boost::cpp_regex_traits::toi(char const*&, char const*, int) const'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::match()'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::construct_init(boost::basic_regex > > const&, boost::regex_constants::_match_flags)'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::find()'
libMyBusinessLogic.so: undefined reference to `boost::basic_regex > >::do_assign(char const*, char const*, unsigned int)'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher >, boost::regex_traits > >::match()'

链接所有其他程序工作正常。 如果我从一个命令行程序中删除-lMyUI,那么即使MyUI没有显示在错误列表中的任何地方,它也能正常工作。

为什么当我在

命令末尾添加 -lboost_regex 时,ld 找不到 Boost.Regex 符号? 为什么删除看似无关的库可以修复它? 为什么其他程序链接没有任何问题?

我至少已经找到了大部分答案。 由于我的 makefile 规则有些草率,libMyUI.soboost_regex 相关联,但libMyBusinessLogic.so不是。 我猜,结果,链接MyUI导致boost_regex过早地被拉入,在链接器知道MyBusinessLogic需要从它那里得到的所有符号之前。

只要我保持一致 - 要么My*.so都与boost_regex链接,要么他们都没有 - 一切都有效。 我不确定这些解决方案中的哪一个最受欢迎,但至少我有一个解决方法。