Как я могу связать статическую библиотеку, которая зависит от других библиотек в cmake?

У меня есть статическая библиотека, зависящая от gtkmm. Я успешно создаю файл liblibrary.a, однако когда я пытаюсь связать клиентское приложение с этой библиотекой, я получаю неопределенную ссылку на функции gtkmm. Как я могу связать статическую библиотеку, которая зависит от других библиотек?

Файл cmake библиотеки:

cmake_minimum_required(VERSION 3.28)
project(library)

set(CMAKE_CXX_STANDARD 23)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)
include_directories(${GTKMM_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS})


add_library(library STATIC library.cpp library.h)

target_link_libraries(library ${GTKMM_LIBRARIES})

Файл cmake клиентского приложения:

cmake_minimum_required(VERSION 3.28)
project(cairomotion)

set(CMAKE_CXX_STANDARD 23)

include_directories(/home/user/Projects/library)

add_executable(client main.cpp)


target_link_libraries(client /home/user/Projects/library/cmake-build-debug/liblibrary.a)

спасибо за помощь

target_link_libraries(library PUBLIC ${GTKMM_LIBRARIES})/target_link_libraries(client library)?
Jarod42 27.07.2024 16:52

@Jarod42, я поменял на target_link_libraries(library PUBLIC ${GTKMM_LIBRARIES}), к сожалению, безрезультатно. Что касается target_link_libraries(client library), статическая библиотека не установлена ​​в масштабе всей системы, поэтому мне приходится использовать абсолютный путь.

Abraham Zsombor Nagy 27.07.2024 17:54

Извините, я обнаружил, что статическое связывание gtkmm не рекомендуется... поэтому вопрос не стоит ответа. stackoverflow.com/questions/8229094/…

Abraham Zsombor Nagy 27.07.2024 18:06

«статическая библиотека не установлена ​​во всей системе». Обычно она есть в вашем CMakelist как include(library), и поэтому использование target будет выполнять работу (использование материала INTERFACE CMake, например, использование PUBLIC для «наследования» некоторой «автоматической» ссылки/ включает/определяет).

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

Ответы 2

Извините, я обнаружил, что статическое связывание gtkmm не рекомендуется... Статическая компоновка – работа с приложением GTKmm? - переработано

Этот CMakeLists.txt работает:

cmake_minimum_required(VERSION 3.28)
project(cairomotion)

set(CMAKE_CXX_STANDARD 23)

include_directories(/home/user/Projects/library)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)
include_directories(${GTKMM_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS})

add_executable(client main.cpp)

target_link_libraries(client /home/user/Projects/library/cmake-build-debug/liblibrary.a ${GTKMM_LIBRARIES})

Указывать абсолютный путь к библиотеке в target_link_libraries неправильно в 100% случаев. Не делай это.

Alex Reinking 27.07.2024 22:46
Ответ принят как подходящий

Если вы собираетесь разделить свою библиотеку и клиент на два проекта, вам необходимо экспортировать библиотеку из ее сборки. Вот широко комментируемый пример:

Библиотека

CMakeLists.txt

cmake_minimum_required(VERSION 3.28)

## Declare the project and its version.
# A version number is essential for find_package to work
# correctly. Set the major version to zero until you have
# defined a stable API/ABI.
project(library VERSION 0.1.0)

## Find our dependencies.
# We ask PkgConfig to create an imported target because
# one should ALWAYS link to a target rather than to a
# raw library by path. Linking to a target also sets up
# include directories
find_package(PkgConfig REQUIRED)
pkg_check_modules(gtkmm-3.0 REQUIRED IMPORTED_TARGET gtkmm-3.0)

## Create our main library target.
# We also create an alias that will match its exported
# name in case we want to support add_subdirectory or
# FetchContent down the line. The installation rules
# below would need to be guarded by an off-by-default
# option() and components would need to be added.
add_library(library STATIC library.cpp)
add_library(library::library ALIAS library)

## Declare the public headers.
# These headers will be installed along with the binaries.
# Additionally, targets linking to this library will have
# their include paths set appropriately.
target_sources(library PUBLIC FILE_SET HEADERS FILES library.h)

## Set the language level.
# Declaring this as a public build requirement of the
# library will ensure that other targets that link to
# it will also require C++23.
target_compile_features(library PUBLIC cxx_std_23)

## Link our dependencies.
# This is the way to link libraries. With this, we have
# completed the process of defining our library and its
# usage requirements.
target_link_libraries(library PRIVATE PkgConfig::gtkmm-3.0)

## Import the build-in helpers for defining install rules
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

## Create a custom path variable for the location of the
# CMake package files.
set(library_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/library"
    CACHE STRING "Path to CMake config files")

## Create the package config file.
configure_package_config_file(
  "library-config.cmake.in" "${library_INSTALL_CMAKEDIR}/library-config.cmake"
  INSTALL_DESTINATION "${library_INSTALL_CMAKEDIR}")

## Create the package version file.
write_basic_package_version_file(
  "${library_INSTALL_CMAKEDIR}/library-config-version.cmake"
  COMPATIBILITY SameMajorVersion
)

## Install the package config/version files.
install(FILES
        "${CMAKE_CURRENT_BINARY_DIR}/${library_INSTALL_CMAKEDIR}/library-config.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/${library_INSTALL_CMAKEDIR}/library-config-version.cmake"
        DESTINATION "${library_INSTALL_CMAKEDIR}")

## Install the library
install(TARGETS library
        EXPORT library-targets
        FILE_SET HEADERS)

## Generate a file that contains the target definition
# for the library.
install(EXPORT library-targets
        DESTINATION "${library_INSTALL_CMAKEDIR}"
        NAMESPACE library::)

библиотека-config.cmake.in

@PACKAGE_INIT@

## We use find_dependency rather than find_package
# inside a package config file.
include(CMakeFindDependencyMacro)

## Look for gtkmm-3.0 in the downstream build
find_dependency(PkgConfig)
pkg_check_modules(gtkmm-3.0 IMPORTED_TARGET gtkmm-3.0)

## Provide a helpful error message if we cannot find it
# It is not appropriate to FATAL_ERROR for this since the
# downstream user should decide what to do if your package
# cannot be found.
if (NOT gtkmm-3.0_FOUND)
    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
        "dependency gtkmm-3.0 could not be found")
    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND 0)
    return()
endif ()

## Add the generated targets
include("${CMAKE_CURRENT_LIST_DIR}/library-targets.cmake")

## Ensure that no invalid components were requested
check_required_components(${CMAKE_FIND_PACKAGE_NAME})

Клиент

CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(cairomotion)

## Find the library
find_package(library REQUIRED)

## Create the client executable
add_executable(client main.cpp)
target_compile_features(client PRIVATE cxx_std_23)

## Link to the library
target_link_libraries(client PRIVATE library::library)

Этапы сборки:

Предполагая, что у вас есть оба каталога проекта в ~/workspace:

~/workspace$ ls
client  library
~/workspace$ export CMAKE_BUILD_TYPE=RelWithDebInfo
~/workspace$ export CMAKE_GENERATOR=Ninja
~/workspace$ export CMAKE_PREFIX_PATH = "$PWD/.local"
~/workspace$ cmake -S library -B library/build
~/workspace$ cmake --build library/build
~/workspace$ cmake --install library/build --prefix "$CMAKE_PREFIX_PATH"
~/workspace$ cmake -S client -B client/build
~/workspace$ cmake --build client/build

Установка CMAKE_PREFIX_PATH здесь обеспечивает связь между двумя проектами.

Большое спасибо!

Abraham Zsombor Nagy 31.07.2024 20:24

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

Похожие вопросы

Как написать ctor для класса, владеющего типами nocopy-nomove, один из которых должен быть инициализирован из другого, который может быть одним из нескольких типов?
Почему const Type&& не приводится к Type&&?
Графический интерфейс не отображает все компоненты (C++)
GlGetTexImage возвращает 0 для текстуры, даже если текстура загружена и правильно заполнена в памяти графического процессора
Нужно ли объявлять оператор < перед вызовом std::lexicographical_compare?
Как правильно использовать OpenMP Target Enter/Exit/Update для неструктурированных асинхронных вычислений на стороне устройства?
Конкатенация строк препроцессора макросов C++
Почему в конце двусвязного циклического связанного списка в C++ стоит нуль?
Объявите несколько переменных-членов разных типов в шаблонном классе в соответствии с параметром шаблона
Спрайты врагов не отображаются, когда я заполняю вектор циклом for