在自定义路径中安装库的cmake链接器错误

时间:2020-04-25 19:17:57

标签: cmake linker

我已经使用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 个答案:

答案 0 :(得分:1)

我缺少的是用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
)

有用的参考文献:

相关问题