C++ 在 Mac "Undefined symbols for architecture x86_64:" 上提升 oarchive 编译错误。使用 cmake



我在使用boost序列化工具编译时遇到问题。信息:

  • macOS 10.15.5
  • cmake版本3.19.6(通过自制安装)
  • boost版本1.67.0(通过自制安装)

我构建了一个小测试程序,看起来像这样:

#include <boost/archive/text_oarchive.hpp>
#include <fstream>
void writeTest(std::string test, std::string filename) {
std::ofstream ofs( filename.c_str() );
boost::archive::text_oarchive oa( ofs );
oa << test;
}
int main(int argc, char *argv[]) {
writeTest("test123123123", "test.txt");
}

我的CMakeLists.txt文件是这样的:

cmake_minimum_required(VERSION 3.0.0)
project(testProj VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 17)
SET (BOOST_MIN_VERSION "1.55.0")
FIND_PACKAGE(Boost ${BOOST_MIN_VERSION} REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
add_executable(testProj main.cpp ${Boost_LIBRARIES})

然后我运行cmake --build .在我的构建文件夹,得到以下错误:

Undefined symbols for architecture x86_64:
"boost::archive::archive_exception::archive_exception(boost::archive::archive_exception::exception_code, char const*, char const*)", referenced from:
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<unsigned int>(unsigned int const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_id_type>(boost::archive::object_id_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_reference_type>(boost::archive::object_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_type>(boost::archive::class_id_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::tracking_type>(boost::archive::tracking_type const&, mpl_::bool_<false>&) in main.cpp.o
"boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)", referenced from:
void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
"boost::archive::archive_exception::~archive_exception()", referenced from:
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<unsigned int>(unsigned int const&, mpl_::bool_<false>&) in main.cpp.o
void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_id_type>(boost::archive::object_id_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_reference_type>(boost::archive::object_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_type>(boost::archive::class_id_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::tracking_type>(boost::archive::tracking_type const&, mpl_::bool_<false>&) in main.cpp.o
...
"boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(boost::archive::text_oarchive&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in main.cpp.o
"boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::text_oarchive_impl(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned int)", referenced from:
boost::archive::text_oarchive::text_oarchive(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned int) in main.cpp.o
"boost::archive::basic_text_oarchive<boost::archive::text_oarchive>::newtoken()", referenced from:
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<unsigned int>(unsigned int const&) in main.cpp.o
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::object_id_type>(boost::archive::object_id_type const&) in main.cpp.o
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::object_reference_type>(boost::archive::object_reference_type const&) in main.cpp.o
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::class_id_type>(boost::archive::class_id_type const&) in main.cpp.o
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&) in main.cpp.o
void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::tracking_type>(boost::archive::tracking_type const&) in main.cpp.o
"boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::~basic_text_oprimitive()", referenced from:
boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::~text_oarchive_impl() in main.cpp.o
"boost::archive::detail::basic_oarchive::end_preamble()", referenced from:
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::version_type>(boost::archive::text_oarchive&, boost::archive::version_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::object_id_type>(boost::archive::text_oarchive&, boost::archive::object_id_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::object_reference_type>(boost::archive::text_oarchive&, boost::archive::object_reference_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::class_id_type>(boost::archive::text_oarchive&, boost::archive::class_id_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::class_id_reference_type>(boost::archive::text_oarchive&, boost::archive::class_id_reference_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::tracking_type>(boost::archive::text_oarchive&, boost::archive::tracking_type const&) in main.cpp.o
void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(boost::archive::text_oarchive&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in main.cpp.o
...
"boost::archive::detail::basic_oarchive::~basic_oarchive()", referenced from:
boost::archive::detail::common_oarchive<boost::archive::text_oarchive>::~common_oarchive() in main.cpp.o
"typeinfo for boost::archive::archive_exception", referenced from:
void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
"typeinfo for boost::archive::detail::basic_oarchive", referenced from:
typeinfo for boost::archive::detail::common_oarchive<boost::archive::text_oarchive> in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

也许这与编译器有关?我在cmake中检查了CMAKE_CXX_COMPILER_ID,这是"AppleClang">

非常感谢你的帮助,我对制作和提升完全陌生。

Never 将包变量扩展到源代码中。总是优先选择导入的目标。如果你在现代CMake中尽可能用最简单的方式做事情,你会得到这样简单、可移植的构建:

cmake_minimum_required(VERSION 3.19)
project(testProj VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)
find_package(Boost 1.55 REQUIRED serialization)
add_executable(testProj main.cpp)
target_link_libraries(testProj PRIVATE Boost::serialization)

这就是所有需要的!导入目标如Boost::serialization设置库和包含路径为您。他们随身携带着这些信息。我在我的Mac Mini上用自制的CMake和Boost以及main.cpp进行了测试。

要确定一个包提供哪些导入的目标,请阅读它的文档。对于Boost,它在这里:https://cmake.org/cmake/help/latest/module/FindBoost.html

一些通用的CMake建议:CMake命令使用小写的名称。忘记include_directorieslink_directories的存在。不要创建不必要的变量,比如BOOST_MIN_VERSION。最后,从不设置一个最小的CMake版本低于你用来测试它的版本。如果你使用太新作为最小版本,CMake不会警告你。

最新更新