Я столкнулся с этой проблемой: компоновщик не может найти библиотеку Boost.Log, которая явно существует в месте назначения. Я использую MS Visual Studio 2022, поэтому мой компилятор точно такой же, как указано в библиотеке.
У меня установлены переменные среды следующим образом:
И мой CMakeLists.txt:
cmake_minimum_required(VERSION 3.28)
project(SMTPLogger)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(Boost 1.85 REQUIRED COMPONENTS log thread)
if (Boost_FOUND)
message(STATUS "Boost include directories: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost libraries: ${Boost_LIBRARIES}")
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARYDIR})
else()
message(FATAL_ERROR "Could not find Boost")
endif ()
find_package(Threads REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(Logger src/Logger.cpp main.cpp)
target_include_directories(Logger PRIVATE ${CMAKE_SOURCE_DIR}/include ${Boost_INCLUDE_DIRS})
target_link_libraries(Logger Boost::log Boost::thread Threads::Threads)
При сборке CMake выводит следующее сообщение:
1> [CMake] CMake Warning at C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindBoost.cmake:1398 (message):
1> [CMake] New Boost version may have incorrect or missing dependencies and imported
1> [CMake] targets
1> [CMake] Call Stack (most recent call first):
1> [CMake] C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindBoost.cmake:1523 (_Boost_COMPONENT_DEPENDENCIES)
1> [CMake] C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindBoost.cmake:2135 (_Boost_MISSING_DEPENDENCIES)
1> [CMake] CMakeLists.txt:7 (find_package)
В msvc143
нет libboost_log-vc143-mt-gd-x64-1_85.lib:
1> [CMake] -- Boost include directories: C:/dev/utilities/boost_1_85_0
1> [CMake] -- Boost libraries: optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_log-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_log-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_thread-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_thread-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_log_setup-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_log_setup-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_filesystem-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_filesystem-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_regex-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_regex-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_chrono-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_chrono-vc143-mt-gd-x64-1_85.lib;
optimized;C:/dev/utilities/boost_1_85_0/stage/lib/boost_atomic-vc143-mt-x64-1_85.lib;
debug;C:/dev/utilities/boost_1_85_0/stage/lib/boost_atomic-vc143-mt-gd-x64-1_85.lib
Как видно ниже, библиотека расположена по пути message(STATUS "Boost libraries: ${Boost_LIBRARIES}")
.
Изучая этот вопрос, я понял, что не могу перейти к свойствам конфигурации и дальше, поскольку для проекта CMake они не показаны. Я пробовал перестроить, очистить кеш CMake, но ничего не помогло. Я предполагаю, что проблема может заключаться в версии Boost, которую я сейчас использую, 1.85.0 и версии CMake 3.28.3.
Заранее спасибо.
@Цыварев, окей, спасибо, я этого не знал
Пробовали ли вы установить макрос BOOST_ALL_DYN_LINK
, как предложено в паре вопрос/ответ? Вы можете установить этот макрос либо в исходном файле перед включением заголовков Boost, либо в вашем CMakeLists.txt
с помощью команды target_compile_definitions
.
Попробуйте добавить log_setup в свой список компонентов COMPONENTS log_setup log thread)
Я сам помню что-то подобное, и это было решение. Далеко и, возможно, неправильно, конечно, но попробовать легко.
Опубликованный вами вывод CMake показывает, что CMake находит библиотеки Boost, поскольку они присутствуют в Boost_LIBRARIES
. Однако могут отсутствовать целевые псевдонимы, такие как Boost::log
. Не могли бы вы показать командную строку компоновщика и сообщение об ошибке?
Я подозреваю, что CMake не использует файлы конфигурации CMake, созданные в процессе сборки Boost. Эти файлы обычно размещаются в папке <BOOST_ROOT>/stage/lib/cmake
. Вы можете увидеть список путей, которые CMake использует для поиска файлов конфигурации здесь. Вы можете попробовать установить для переменной среды CMAKE_PREFIX_PATH
значение <BOOST_ROOT>/stage/lib/cmake
и посмотреть, поможет ли это.
Я исправил это, добавив #include <boost/config/user.hpp>
в заголовочный файл. В user.hpp
я включил (ракомментировал) #define BOOST_ALL_DYN_LINK
, что
... заставляет все библиотеки, имеющие отдельный источник, связываться как dll, а не как статические библиотеки в Microsoft Windows (этот макрос используется для включения модификаторов __declspec(dllimport), чтобы компилятор знал, какие символы искать в dll а не в статической библиотеке). Обратите внимание, что могут существовать библиотеки, которые можно связать только одним способом (статически или динамически), в этих случаях этот макрос не имеет никакого эффекта.
И это решило мою проблему. Я читал, что этот макрос также можно определить через файл CMakeLists.txt
, добавив
set_target_properties(Boost::dynamic_linking PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK")
но мне вариант user.hpp
кажется более удобным.
При использовании find_package(Boost)
определяется особая цель Boost::dynamic_linking
. При связывании с этой целью автоматически определяется макрос BOOST_ALL_DYN_LINK
, который необходим для использования динамических библиотек Boost в Windows:
target_link_libraries(Logger Boost::log Boost::thread Boost::dynamic_linking Threads::Threads)
Примечание. Нет смысла проверять переменную
Boost_FOUND
, если вы используете ключевое словоREQUIRED
сfind_package
. Если этот поиск не удастся, CMake сам прекратит настройку.