LINK не может найти библиотеку при сборке проекта CMAKE
Есть затык в написании cmake файла для мультиплатформенной сборки. Подробности: Разбиваю проект на несколько библиотек для простоты работы. Выношу библиотеку доступа к БД в отдельную dll. Сразу оговорюсь - все модули работают если находятся в теле основной программы, то есть ошибок там нет (пока что :) )
Для сборки проекта создал новый cmake-проект, который включается как подпроект в основной:
cmake_minimum_required(VERSION 3.5)
project(plgconnector LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (WIN32)
message("[PLG CONNECTOR] Build Windows revision!")
find_package(QT NAMES Qt5 COMPONENTS Widgets Core svg REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core svg Widgets REQUIRED)
find_package(PostgreSQL REQUIRED)
endif(WIN32)
if (UNIX AND NOT APPLE)
message("[PLG CONNECTOR] Build Linux revision!")
find_package(QT NAMES Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED)
find_package(PostgreSQL REQUIRED)
endif()
message("[PLG CONNECTOR] PostgreSQL VER: " ${PostgreSQL_VERSION_STRING})
message("[PLG CONNECTOR] Include files PostgreSQL: " ${PostgreSQL_INCLUDE_DIRS})
message("[PLG CONNECTOR] Lib files PostgreSQL: " ${PostgreSQL_LIBRARY_DIRS})
add_library(plgconnector SHARED
plgconnector_global.h
tconnector.cpp
tnotifyer.cpp
tquery.cpp
treader.cpp
tconnector.h
pgerror.ui
pgerror.h
pgerror.cpp
sqlhighlighter.h
sqlhighlighter.cpp
sqlloghlighter.h
sqlloghlighter.cpp
)
include_directories(AFTER ${PostgreSQL_INCLUDE_DIRS})
link_directories(AFTER ${PostgreSQL_LIBRARY_DIRS} ${PLG_LIB})
if (WIN32)
target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets
"${PostgreSQL_LIBRARY_DIRS}/libpq.lib"
)
endif(WIN32)
if (UNIX AND NOT APPLE)
target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets pq)
endif()
target_compile_definitions(plgconnector PRIVATE PLGCONNECTOR_LIBRARY)
set_target_properties(plgconnector PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
)
приведенный текст проекта работает как надо, но есть вопрос. Ранее в основном проекте я писал
if (WIN32)
target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets libpq
)
endif(WIN32)
и проект вполне себе нормально собирался и собирается, все нормально. Но если я тут пишу просто libpq, то на стадии линковки мне вываливает ошибку, что - файл не найден, но если я задаю путь напрямую - то все нормально. Причем этот косяк только для WIN32, в Linux все собирается нормально.
Не могу понять, что я делаю не так. Ведь есть код добавления:
link_directories(AFTER ${PostgreSQL_LIBRARY_DIRS} ${PLG_LIB})
У кого есть мысли?
UPD: Для сборки в винде используется MS VC 2022.
Ответы (1 шт):
Команда link_directories влияет только на таргеты, созданные после неё.
Так как у Вас в коде таргет plgconnector создаётся (вызовом add_library) до вызова link_directories, то директории поиска библиотек не добавляются.
Один из вариантов решения - перенос вызова link_directories до создания таргета:
link_directories(AFTER ${PostgreSQL_LIBRARY_DIRS} ${PLG_LIB})
...
add_library(plgconnector SHARED ...)
...
target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets
libpq
)
Но вообще, использование link_directories не рекомендуется, а предпочтительно как раз передавать полные пути в target_link_libraries. Если не хотите хардкодить расширении библиотеки libpq, то можно выполнить поиск библиотеки в заданных директориях:
add_library(plgconnector SHARED ...)
# Ищем библиотеку libpq, используя директорию PostgreSQL_LIBRARY_DIRS в качестве подсказки
find_library(LIBRARY_PQ libpq HINTS ${PostgreSQL_LIBRARY_DIRS})
#
target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets
${LIBRARY_PQ}
)