У меня есть образец кода 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
Кто-нибудь здесь знает, что может быть причиной того, что связь с ускорением все еще не работает, несмотря на предоставление путей? Чего еще здесь не хватает или неправильно указано?
Спасибо,





Похоже, вы пытаетесь связать 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
Поскольку вы использовали 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
Я просто пробовал использовать ваш файл CMakeLists.txt. Он по-прежнему не работает с той же ошибкой. Есть ли у вас какие-нибудь мысли о том, что еще здесь может пойти не так?
Мой пример только для справки. $ g ++ testboostpo_simple.cpp -L / opt / local / lib /opt/local/lib/libboost_program_options-mt.dylib должен работать.
Кроме того, после изменения конфигурации удалите CMakeCache.txt, чтобы создать новый.
Спасибо, да, эта команда должна работать, но это не так. У меня есть скрипт, который очищает CMakeFiles / *, CMakeCache.txt и cmake_install.cmake. Я запускаю его каждый раз перед запуском cmake. Так что я не думаю, что проблема в этом. Кажется, что он терпит неудачу по другой причине.
Похоже, я действительно использую 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