Stati c соединение с Boost Filesystem не работает - PullRequest
1 голос
/ 25 февраля 2020

Я пытаюсь создать boost из источника, и мне нужно установить статическое связывание c, поскольку я собираюсь переместить этот статически связанный проект boost на AWS лямбда-серверы.

Я сделал следующие шаги:

  1. Я загрузил boost_1_72_0.tar.gz и tar xzvf boost_1_72_0.tar.gz в каталоге Third_party.
  2. cd внутри boost_1_72_0.
  3. DST_DIR=/my local path/, куда я хочу установить.
  4. ./bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system.
  5. ./b2 link=static --prefix=${DST_DIR} install --, который создает каталоги include и lib внутри DST_DIR
  6. Внутри моего каталога сборки я делаю CMake, где присутствует мой CMakeLists.txt .
  7. Команда CMake работает нормально.
  8. Но команда make выдает ошибку.

Вот мой CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_STANDARD 11)
project(executable LANGUAGES CXX)

set(TARGET "/path to boost directory/boost_1_72_0")

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBS OFF)
SET(CMAKE_EXE_LINKER_FLAGS "-static")

set(Boost_NO_SYSTEM_PATHS True)

message(STATUS "${Boost_NO_SYSTEM_PATHS}")
if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${TARGET}")
  message(STATUS "${Boost_ROOT}")
  set(BOOST_INCLUDE_DIRS "${TARGET}/include/")
  set(BOOST_LIBRARY_DIRS "${TARGET}/lib/")
endif (Boost_NO_SYSTEM_PATHS)

message(STATUS "${BOOST_INCLUDE_DIRS}")
message(STATUS "boost library dirs")
message(STATUS "${BOOST_LIBRARY_DIRS}")
find_package(Boost REQUIRED filesystem system)
if(Boost_FOUND)      
    include_directories(${BOOST_INCLUDE_DIRS})
    add_executable(${PROJECT_NAME} "execute_code.cpp") 
    message(STATUS "boost libraries" "${BOOST_LIBRARIES}")
    target_link_libraries(executable ${BOOST_LIBRARIES})
endif()

execute_code. cpp

#include <boost/filesystem.hpp>
#include<iostream>

bool path_exists(string file_path)
{
    boost::filesystem::path p{file_path};
    return boost::filesystem::exists(p);
}

int main(int argc, char** argv) {
 string source_file = argv[1];
 if (!path_exists(source)) {
    cout << "source file doesn't exist";
    return 0;
 }
 return 0;
}

Ошибка, которую я получаю:

CMakeFiles/executable.dir/execute_code.cpp.o: In function `boost::filesystem::exists(boost::filesystem::path const&)':
execute_code.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x2f): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status
CMakeFiles/executable.dir/build.make:113: recipe for target 'executable' failed
make[2]: *** [executable] Error 1
CMakeFiles/Makefile2:75: recipe for target 'CMakeFiles/executable.dir/all' failed
make[1]: *** [CMakeFiles/executable.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

Я новичок в C ++ и CMake. Есть ли что-нибудь глупое, чего мне здесь не хватает?

Я прошел Как мне получить CMake, чтобы найти альтернативную установку Boost? и другие ответы, но, похоже, не работает в моем случай.

1 Ответ

2 голосов
/ 25 февраля 2020

Вы, кажется, используете старые переменные CMake для Boost. Начиная с Boost 1.70, Boost теперь предоставляет поддержку CMake, чтобы CMake упростил поиск и использование Boost для вашего проекта (см. Документацию на этой странице).

При сборке Boost вы увидите файлы конфигурации пакета CMake для каждой библиотеки Boost (обычно помещаются вместе со встроенными библиотеками в папку cmake). Вы можете использовать find_package() в режиме CONFIG, чтобы найти эти файлы конфигурации пакета. Они предоставляют импортированные цели, такие как Boost::filesystem, на которые вы можете напрямую ссылаться. Таким образом, если библиотека filesystem отсутствует, вам не нужно просеивать список библиотек в переменной BOOST_LIBRARIES, когда компиляция / компоновка не удалась. Вместо этого CMake сообщит вам, что библиотека отсутствует во время настройки CMake.

Кроме того, теперь необходимо автоматически разрешать зависимости библиотеки Boost. Поэтому, если вы используете filesystem, вам больше не нужно явно вызывать библиотеку system. Повышение должно разрешить эту зависимость для вас. С этими изменениями использование команды find_package() может выглядеть следующим образом:

find_package(Boost CONFIG REQUIRED filesystem)
if(Boost_FOUND)
    add_executable(${PROJECT_NAME} "execute_code.cpp") 
    target_link_libraries(executable PRIVATE Boost::filesystem)
endif()

Для чего бы вы ни стояли, вы можете запустить make VERBOSE=1, чтобы увидеть подробный вывод на этапе соединения с проверьте , что все правильные библиотеки связаны. Вы должны увидеть, что библиотеки Boost filesystem и system связаны между собой, и вы можете убедиться, что они являются необходимыми stati c (.a) библиотеками.

...