Невозможно связать библиотеки Boost с CMake

У меня есть образец кода C++, который использует boost (модуль параметров программы), как показано ниже:

#include <iostream>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

namespace po = boost::program_options;

int main(int argc, const char* argv[]){
    po::options_description description("MyTool Usage");

    description.add_options()
        ("help,h", "Display this help message")
        ("version,v", "Display the version number");

    po::positional_options_description p;

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
    po::notify(vm);

    if (vm.count("help")){
        std::cout << description;

        return 0;
    }

    if (vm.count("version")){
        std::cout << "MyTool Version 1.0" << std::endl;

        return 0;
    }

    return 0;
}

Я пробовал компилировать с помощью cmake. Соответствующий файл CMakeLists.txt показан ниже:

cmake_minimum_required(VERSION 2.6)

set(CMAKE_CXX_LINK_FLAGS "-std=c++11 -g -Wall -fsigned-char -lboost_program_options-mt")

set(BOOST_ROOT /opt/local/include/boost)
set(BOOST_LIBRARYDIR /opt/local/lib)
find_package(Boost COMPONENTS program_options system filesystem REQUIRED)
include_directories(${BOOST_INCLUDE_DIR})
link_libraries(${BOOST_LIBRARIES})

add_executable(testboostpo testboostpo_simple.cpp)
target_link_libraries(testboostpo ${Boost_LIBRARIES})

Хотя cmake . кажется успешным и он также обнаруживает все модули повышения, которые я обычно использую (параметры программы, система, файловая система),

$ cmake .
-- The C compiler identification is GNU 5.5.0
-- The CXX compiler identification is GNU 5.5.0
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Check for working C compiler: /opt/local/bin/gcc-mp-5
-- Check for working C compiler: /opt/local/bin/gcc-mp-5 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Check for working CXX compiler: /opt/local/bin/g++-mp-5
-- Check for working CXX compiler: /opt/local/bin/g++-mp-5 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Boost version: 1.66.0
-- Found the following Boost libraries:
--   program_options
--   system
--   filesystem
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/params/libraries/coding_interview/every_test/boost_test

следующий шаг make завершается ошибкой со следующей ошибкой: $ make

Scanning dependencies of target testboostpo
[ 50%] Building CXX object CMakeFiles/testboostpo.dir/testboostpo_simple.cpp.o
[100%] Linking CXX executable testboostpo
ld: library not found for -lboost_program_options-mt
collect2: error: ld returned 1 exit status
make[2]: *** [testboostpo] Error 1
make[1]: *** [CMakeFiles/testboostpo.dir/all] Error 2
make: *** [all] Error 2

Похоже, возникла проблема с подключением библиотеки ускорения для параметров программы. Однако я вижу, что библиотека установлена ​​на /opt/local/lib/libboost_program_options-mt.dylib.

В качестве альтернативы я также попытался изолировать компиляцию, но это тоже не удалось.

$ g++ -L/opt/local/lib testboostpo_simple.cpp -lboost_program_options-mt
Undefined symbols for architecture x86_64:
  "boost::program_options::to_internal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > boost::program_options::to_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) in ccg8tggM.o
  ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

$ g++ -L/opt/local/lib testboostpo_simple.cpp /opt/local/lib/libboost_program_options-mt.dylib
Undefined symbols for architecture x86_64:
  "boost::program_options::to_internal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > boost::program_options::to_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) in ccg8tggM.o
  ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

Я использую gcc5, boost 1.66 и cmake 3.12 (все они установлены с помощью macports). Файлы заголовков boost находятся в расположении: /opt/local/include/boost/ а файлы библиотеки ускорения находятся в расположении: /opt/local/lib

Кто-нибудь здесь знает, что может быть причиной того, что связь с ускорением все еще не работает, несмотря на предоставление путей? Чего еще здесь не хватает или неправильно указано?

Спасибо,

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 874
2

Ответы 2

Похоже, вы пытаетесь связать 32-битную библиотеку с 64-битной сборкой. Подсказка - ld: symbol(s) not found for architecture x86_64.

Связывание библиотек требует точного соответствия типу сборки. Вот еще немного информации о процессе связывания.

https://www.boost.org/doc/libs/1_63_0/more/getting_started/windows.html

Похоже, я действительно использую 64-битную библиотеку. Что вы думаете? $ file /opt/local/lib/libboost_filesystem-mt.dylib --> gives the output --> /opt/local/lib/libboost_filesystem-mt.dylib: Mach-O universal binary with 2 architectures: [i386:Mach-O dynamically linked shared library i386] [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] /opt/local/lib/libboost_filesystem-mt.dylib (for architecture i386): Mach-O dynamically linked shared library i386

Params Raman 25.08.2018 20:31

Поскольку вы использовали CMAKE_CXX_LINK_FLAGS, и cmake сначала проверит его вместо использования ваших target_link_libraries, если вы хотите сделать это самостоятельно, вам также нужно добавить -L / opt / local / lib, более простой способ - позволить cmake делать это для вас. Вот мой пример:

cmake_minimum_required(VERSION 2.6)
project(server CXX)
set(CXX_FLAGS
-g
-Wall
)

# set(Boost_NO_SYSTEM_PATHS ON)
set(BOOST_ROOT /mnt/d/Code/boost)
set(BOOST_LIBRARYDIR /mnt/d/Code/boost/stage/lib)
find_package(Threads REQUIRED)
find_package(Boost 1.68.0 COMPONENTS program_options REQUIRED)
file(GLOB SRC 
 "*cpp*"
 )
if (Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
  message(${Boost_PROGRAM_OPTIONS_LIBRARIES})
  add_executable(main ${SRC})
  target_link_libraries(main Threads::Threads ${Boost_PROGRAM_OPTIONS_LIBRARIES})
endif ()

Кроме того, если вы создаете его отдельно, вы должны сначала скомпилировать объект, а затем связать его, иначе он может превратиться в неопределенную ссылку. В вашем случае вы должны ссылаться в конце, результат будет другим, когда вы поместите ссылку спереди или в хвосте, извините, я не понимаю, почему это происходит.

Спасибо. Как я показал выше, я также пробовал следующие две команды, но обе, похоже, не работают: $ g ++ -L / opt / local / lib testboostpo_simple.cpp -lboost_program_options-mt И $ g ++ -L / opt / local / lib testboostpo_simple.cpp /opt/local/lib/libboost_program_options-mt.dylib

Params Raman 28.08.2018 06:28

Я просто пробовал использовать ваш файл CMakeLists.txt. Он по-прежнему не работает с той же ошибкой. Есть ли у вас какие-нибудь мысли о том, что еще здесь может пойти не так?

Params Raman 28.08.2018 06:34

Мой пример только для справки. $ g ++ testboostpo_simple.cpp -L / opt / local / lib /opt/local/lib/libboost_program_options-mt.dylib должен работать.

FrankX 28.08.2018 07:45

Кроме того, после изменения конфигурации удалите CMakeCache.txt, чтобы создать новый.

FrankX 28.08.2018 09:01

Спасибо, да, эта команда должна работать, но это не так. У меня есть скрипт, который очищает CMakeFiles / *, CMakeCache.txt и cmake_install.cmake. Я запускаю его каждый раз перед запуском cmake. Так что я не думаю, что проблема в этом. Кажется, что он терпит неудачу по другой причине.

Params Raman 28.08.2018 20:35

Другие вопросы по теме