首页 > 解决方案 > 使用 cmake 将 boost 链接到 c++:命令行编译

问题描述

我正在尝试将 boost 链接到 c++ 项目。虽然项目编译没有问题,但链接器失败。

CMakeLists.txt的如下:

cmake_minimum_required( VERSION 3.0)

project(boost_test)

# -- Building with C++11 support
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/binaries)

# -- Search for Boost
set(Boost_USE_MULTITHREADED OFF)  
set(BOOST_ROOT /usr/local/boost/v1.69.0)
find_package(Boost 1.69.0 COMPONENTS system filesystem regex coroutine thread REQUIRED)

add_definitions(-DBOOST_LOG_DYN_LINK=1)

set( LIBS_TO_LINK
    ${Boost_LIBRARIES}
    ${CMAKE_THREAD_LIBS_INIT}
)

# -- Boost Test
add_executable(boost_test ${CMAKE_CURRENT_SOURCE_DIR}/src/boost_test.cpp)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIR})

target_link_libraries(boost_test LINK_PUBLIC ${LIBS_TO_LINK})

install(TARGETS boost_test DESTINATION ${CMAKE_SOURCE_DIR}/bin)

boost_test.cpp的如下:

#include <stdio.h>
#include <iostream>

/// BOOST includes
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/unordered_map.hpp>
#include <boost/algorithm/string.hpp>

namespace fs = boost::filesystem;
using namespace std;

int main(int argc, const char * argv[]) {

    cout << "Started Boost Test" << endl;
    fs::path RunDir((std::string)argv[1]);
    if(fs::exists(RunDir) && fs::is_directory(RunDir)){
        cout << "FileSystems Successfully imported and specified directory exists" << endl;
    }

    return 0;
}

使用以下命令成功编译并安装了 Boost:

./b2 --prefix=/usr/local/boost/v1.69.0/ --layout=versioned --build-type=complete variant=release link=shared runtime-link=shared threading=single install

在我配置和编译我的项目之前,我

export DYLD_LIBRARY_PATH=/usr/local/boost/v1.69.0/lib:$DYLD_LIBRARY_PATH 

当我配置和制作时,链接器失败并出现以下错误:

$ make
Scanning dependencies of target boost_test
[ 50%] Building CXX object CMakeFiles/boost_test.dir/src/boost_test.cpp.o
[100%] Linking CXX executable boost_test
Undefined symbols for architecture x86_64:
  "std::runtime_error::what() const", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::ios_base::getloc() const", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::runtime_error::runtime_error(char const*)", referenced from:
      boost::system::system_error::system_error(boost::system::error_code, char const*) in boost_test.cpp.o
  "std::runtime_error::runtime_error(std::runtime_error const&)", referenced from:
      boost::system::system_error::system_error(boost::system::system_error const&) in boost_test.cpp.o
  "std::runtime_error::~runtime_error()", referenced from:
      boost::system::system_error::~system_error() in boost_test.cpp.o
      boost::system::system_error::system_error(boost::system::system_error const&) in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)", referenced from:
      boost::system::detail::generic_error_category_message(int) in boost_test.cpp.o
      _main in boost_test.cpp.o
      boost::asio::error::detail::netdb_category::message(int) const in boost_test.cpp.o
      boost::asio::error::detail::addrinfo_category::message(int) const in boost_test.cpp.o
      boost::asio::error::detail::misc_category::message(int) const in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", referenced from:
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*)", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long)", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      boost::filesystem::path::path(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in boost_test.cpp.o
      boost::system::system_error::system_error(boost::system::system_error const&) in boost_test.cpp.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
      _main in boost_test.cpp.o
      boost::system::error_category::message(int, char*, unsigned long) const in boost_test.cpp.o
      boost::filesystem::path::~path() in boost_test.cpp.o
      boost::system::system_error::~system_error() in boost_test.cpp.o
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in boost_test.cpp.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::cout", referenced from:
      _main in boost_test.cpp.o
  "std::__1::ctype<char>::id", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::locale::~locale()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::ios_base::__set_badbit_and_consider_rethrow()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::__1::ios_base::clear(unsigned int)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "std::terminate()", referenced from:
      ___clang_call_terminate in boost_test.cpp.o
  "typeinfo for std::runtime_error", referenced from:
      typeinfo for boost::system::system_error in boost_test.cpp.o
  "vtable for __cxxabiv1::__class_type_info", referenced from:
      typeinfo for boost::system::error_category in boost_test.cpp.o
      typeinfo for boost::exception in boost_test.cpp.o
      typeinfo for boost::exception_detail::clone_base in boost_test.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__si_class_type_info", referenced from:
      typeinfo for boost::system::detail::generic_error_category in boost_test.cpp.o
      typeinfo for boost::system::detail::system_error_category in boost_test.cpp.o
      typeinfo for boost::system::system_error in boost_test.cpp.o
      typeinfo for boost::asio::error::detail::netdb_category in boost_test.cpp.o
      typeinfo for boost::asio::error::detail::addrinfo_category in boost_test.cpp.o
      typeinfo for boost::asio::error::detail::misc_category in boost_test.cpp.o
      typeinfo for boost::wrapexcept<boost::system::system_error> in boost_test.cpp.o
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__vmi_class_type_info", referenced from:
      typeinfo for boost::exception_detail::error_info_injector<boost::system::system_error> in boost_test.cpp.o
      typeinfo for boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> > in boost_test.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete(void*)", referenced from:
      boost::system::system_error::~system_error() in boost_test.cpp.o
      boost::exception_detail::error_info_injector<boost::system::system_error>::~error_info_injector() in boost_test.cpp.o
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::~clone_impl() in boost_test.cpp.o
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::clone() const in boost_test.cpp.o
      boost::wrapexcept<boost::system::system_error>::~wrapexcept() in boost_test.cpp.o
      boost::asio::detail::posix_global_impl<boost::asio::system_context>::~posix_global_impl() in boost_test.cpp.o
      boost::asio::detail::thread_group::join() in boost_test.cpp.o
      ...
  "operator new(unsigned long)", referenced from:
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::clone() const in boost_test.cpp.o
  "___cxa_allocate_exception", referenced from:
      void boost::throw_exception<boost::system::system_error>(boost::system::system_error const&) in boost_test.cpp.o
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::rethrow() const in boost_test.cpp.o
  "___cxa_begin_catch", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
      ___clang_call_terminate in boost_test.cpp.o
      boost::system::error_category::message(int, char*, unsigned long) const in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "___cxa_call_unexpected", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
      boost::system::system_error::~system_error() in boost_test.cpp.o
      boost::exception::~exception() in boost_test.cpp.o
  "___cxa_end_catch", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
      boost::system::error_category::message(int, char*, unsigned long) const in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in boost_test.cpp.o
  "___cxa_free_exception", referenced from:
      void boost::throw_exception<boost::system::system_error>(boost::system::system_error const&) in boost_test.cpp.o
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::rethrow() const in boost_test.cpp.o
  "___cxa_guard_abort", referenced from:
      boost::asio::error::get_netdb_category() in boost_test.cpp.o
      boost::asio::error::get_addrinfo_category() in boost_test.cpp.o
      boost::asio::error::get_misc_category() in boost_test.cpp.o
      boost::system::generic_category() in boost_test.cpp.o
      boost::system::system_category() in boost_test.cpp.o
  "___cxa_guard_acquire", referenced from:
      boost::asio::error::get_netdb_category() in boost_test.cpp.o
      boost::asio::error::get_addrinfo_category() in boost_test.cpp.o
      boost::asio::error::get_misc_category() in boost_test.cpp.o
      boost::system::generic_category() in boost_test.cpp.o
      boost::system::system_category() in boost_test.cpp.o
  "___cxa_guard_release", referenced from:
      boost::asio::error::get_netdb_category() in boost_test.cpp.o
      boost::asio::error::get_addrinfo_category() in boost_test.cpp.o
      boost::asio::error::get_misc_category() in boost_test.cpp.o
      boost::system::generic_category() in boost_test.cpp.o
      boost::system::system_category() in boost_test.cpp.o
  "___cxa_pure_virtual", referenced from:
      vtable for boost::system::error_category in boost_test.cpp.o
      vtable for boost::exception in boost_test.cpp.o
      vtable for boost::exception_detail::clone_base in boost_test.cpp.o
  "___cxa_throw", referenced from:
      void boost::throw_exception<boost::system::system_error>(boost::system::system_error const&) in boost_test.cpp.o
      boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >::rethrow() const in boost_test.cpp.o
  "___gxx_personality_v0", referenced from:
      boost::system::system_error::what() const in boost_test.cpp.o
      boost::asio::error::get_netdb_category() in boost_test.cpp.o
      boost::asio::error::get_addrinfo_category() in boost_test.cpp.o
      boost::asio::error::get_misc_category() in boost_test.cpp.o
      _main in boost_test.cpp.o
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in boost_test.cpp.o
      boost::system::error_category::message(int, char*, unsigned long) const in boost_test.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)
make[2]: *** [boost_test] Error 1
make[1]: *** [CMakeFiles/boost_test.dir/all] Error 2
make: *** [all] Error 2

我的编译器是:

Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix

我的操作系统是:

macOS High Sierra

我已经咨询并尝试过的帖子:

  1. https://stackoverflow.com/a/25837220/4782513
  2. https://stackoverflow.com/a/32307981/4782513
  3. https://stackoverflow.com/a/13996013/4782513

然而,如果我生成一个 Xcode 项目,在那里构建并执行,那么可行。

cmake .. -G Xcode

但是,我想从命令行编译。我该如何继续?

标签: c++boostcmake

解决方案


On compiling boost, the darwin toolset used gcc and g++ as compilers. This linked boost to /usr/local/gcc-7.3/lib/libstdc++.6.dylib (@ThomasSablik's comments helped narrow down on the problem).

$ otool -L libboost_filesystem-xgcc73-x64-1_69.dylib 
libboost_filesystem-xgcc73-x64-1_69.dylib:
    libboost_filesystem-xgcc73-x64-1_69.dylib (compatibility version 0.0.0, current version 0.0.0)
    libboost_system-xgcc73-x64-1_69.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/gcc-7.3/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.24.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
    /usr/local/gcc-7.3/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

To ensure that the same compilers are used for my project, now CMakeLists.txt has been edited to:

# -- Building with C++11 support
set(CMAKE_C_COMPILER /usr/local/gcc-7.3/bin/gcc)
set(CMAKE_CXX_COMPILER /usr/local/gcc-7.3/bin/g++)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/binaries)

This resolved the issue.


推荐阅读