Ошибка компоновщика cmake с библиотекой, установленной по произвольному пути - PullRequest
0 голосов
/ 25 апреля 2020

Я скомпилировал и установил с CMake библиотеку SDL_bgi с пользовательским префиксом /custom/prefix/. Эта библиотека использует SDL2.

Теперь я хочу использовать ее в другом проекте со структурой ниже, но я получаю ошибку компоновщика при компиляции с make:

/usr/bin/c++     CMakeFiles/test.dir/test.cpp.o  -o test  -Wl,-rpath,/custom/prefix/lib: /custom/prefix/lib/libSDL_bgi.so 

/usr/bin/ld: /custom/prefix/lib/libSDL_bgi.so: undefined reference to `SDL_DestroyWindow'
/usr/bin/ld: /custom/prefix/lib/libSDL_bgi.so: undefined reference to `SDL_CreateRenderer'

У меня также есть записал файл cmake/modules/FindSDL_bgi.cmake, чтобы он тоже мог быть неправильным.

Если я скомпилирую следующую команду, я смогу скомпилировать правильно:

g++ test.cpp -I . -lSDL_bgi -lSDL2 -I /custom/prefix/include/ -L /custom/prefix/lib/ 

Что я делаю неправильно?

Структура проекта:

cmake/modules/FindSDL_bgi.cmake
src/test/CMakeLists.txt
src/test/test.cpp
CMakeLists.txt

Библиотеки:

/usr/lib/libSDL.so
/usr/include/SDL.h
/custom/prefix/lib/libSDL_bgi.so
/custom/prefix/include/graphics.h
/custom/prefix/include/SDL2/libSDL_bgi.h

cmake / modules / FindSDL_bgi.cmake:

# - Try to find LibXml2
# Once done this will define
#  SDL_BGI_FOUND - System has LibXml2
#  SDL_BGI_INCLUDE_DIRS - The LibXml2 include directories
#  SDL_BGI_LIBRARIES - The libraries needed to use LibXml2

# Hardcoded for now
set(SDL_BGI_PATH
    /custom/prefix/
)

set(SDL_BGI_SEARCH_PATHS
    /usr
    /usr/local
    /opt
    ${SDL_BGI_PATH}
)

find_path(SDL_BGI_INCLUDE_DIR graphics.h
    HINTS
    $ENV{SDL2DIR}
    PATH_SUFFIXES include
    PATHS ${SDL2_SEARCH_PATHS}
)

find_library(SDL_BGI_LIBRARY
    NAMES SDL_bgi
    HINTS
    $ENV{SDL2DIR}
    PATH_SUFFIXES lib64 lib
    PATHS ${SDL2_SEARCH_PATHS}
)

include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(SDL_bgi REQUIRED_VARS SDL_BGI_LIBRARY SDL_BGI_INCLUDE_DIR)

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(programmi_kennedy)

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")

set(COMPAT_HEADERS
    ${CMAKE_CURRENT_SOURCE_DIR}/include/
)

find_package(SDL_bgi REQUIRED)

add_subdirectory(src/test)

src / CMakeLists.txt:

add_executable(test test.cpp)
target_include_directories(test PUBLIC ${SDL_BGI_INCLUDE_DIR})
target_link_libraries(test PRIVATE ${SDL_BGI_LIBRARY})
install(TARGETS test DESTINATION bin)

/ custom / prefix / include / graphics.h:

#include <SDL2/SDL_bgi.h>

1 Ответ

1 голос
/ 25 апреля 2020

Что мне не хватало, так это ссылка на SDL2 с find_package(SDL2 REQUIRED) и ссылка на SDL2::SDL2. (Я пытался связать с ${SDL2_LIBRARIES}, но синтаксис теперь другой). Спасибо @KamilCuk, чтобы указать мне правильное направление.

РЕДАКТИРОВАТЬ:

Я изменил модуль FindBGI_sdl.cmake, чтобы искать зависимости (SDL2) и ссылаться на них, используя ключевое слово INTERFACE. Таким образом, цель test может связываться только с SDL_bgi и автоматически разрешать зависимости.

src / CMakeLists.txt:

add_executable(test test.cpp)
target_link_libraries(test PRIVATE SDL_bgi::SDL_bgi)
install(TARGETS test DESTINATION bin)

cmake / modules / FindSDL_bgi.cmake :

# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
FindSDL_bgi
-------

Finds the SDL_bgi library.

Imported Targets
^^^^^^^^^^^^^^^^

This module provides the following imported targets, if found:

``SDL_bgi::SDL_bgi``
  The SDL_bgi library

Result Variables
^^^^^^^^^^^^^^^^

This will define the following variables:

``SDL_bgi_FOUND``
  True if the system has the SDL_bgi library.
``SDL_bgi_VERSION``
  The version of the SDL_bgi library which was found.
``SDL_bgi_INCLUDE_DIRS``
  Include directories needed to use SDL_bgi.
``SDL_bgi_LIBRARIES``
  Libraries needed to link to SDL_bgi.

Cache Variables
^^^^^^^^^^^^^^^

The following cache variables may also be set:

``SDL_bgi_INCLUDE_DIR``
  The directory containing ``foo.h``.
``SDL_bgi_LIBRARY``
  The path to the SDL_bgi library.

#]=======================================================================]

find_package(SDL2 REQUIRED)
find_package(PkgConfig)
pkg_check_modules(PC_SDL_bgi QUIET SDL_bgi)

find_path(SDL_bgi_INCLUDE_DIR
    NAMES graphics.h
    PATHS ${PC_SDL_bgi_INCLUDE_DIRS}
)

find_library(SDL_bgi_LIBRARY
    NAMES SDL_bgi
    PATHS ${PC_SDL_bgi_LIBRARY_DIRS}
)

set(SDL_bgi_VERSION ${PC_SDL_bgi_VERSION})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL_bgi
  FOUND_VAR SDL_bgi_FOUND
  REQUIRED_VARS
    SDL_bgi_LIBRARY
    SDL_bgi_INCLUDE_DIR
  VERSION_VAR SDL_bgi_VERSION
)

if(SDL_bgi_FOUND AND NOT TARGET SDL_bgi::SDL_bgi)
  add_library(SDL_bgi::SDL_bgi UNKNOWN IMPORTED)
  set_target_properties(SDL_bgi::SDL_bgi PROPERTIES
    IMPORTED_LOCATION "${SDL_bgi_LIBRARY}"
    INTERFACE_COMPILE_OPTIONS "${PC_SDL_bgi_CFLAGS_OTHER}"
    INTERFACE_INCLUDE_DIRECTORIES "${SDL_bgi_INCLUDE_DIR}"
  )
  target_link_libraries(SDL_bgi::SDL_bgi INTERFACE SDL2::SDL2)
endif()

mark_as_advanced(
  SDL_bgi_INCLUDE_DIR
  SDL_bgi_LIBRARY
  SDL2_DIR
)

Полезные ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...