如何在 cmake 中使用 SDL2 和 SDL_image

Posted

技术标签:

【中文标题】如何在 cmake 中使用 SDL2 和 SDL_image【英文标题】:How to use SDL2 and SDL_image with cmake 【发布时间】:2014-07-14 01:36:55 【问题描述】:

我正在寻找使用 SDL2SDL_image 和 cmake 编译 c++ 程序的最简单方法。

经过数小时的搜索,这是我最好的尝试:

CMakeLists.txt

project(shooter-cmake2)

cmake_minimum_required(VERSION 2.8)

set(SOURCES
shooter.cpp
classes.cpp
utils.cpp
)

set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -std=c++0x")

add_executable($PROJECT_NAME $SOURCES)

INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2_image REQUIRED sdl2_image)
INCLUDE_DIRECTORIES($SDL2_INCLUDE_DIRS $SDL2IMAGE_INCLUDE_DIR)
TARGET_LINK_LIBRARIES($PROJECT_NAME $SDL2_LIBRARIES $SDL2IMAGE_LIBRARY)

我收到以下错误:

In function `loadTexture(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SDL_Renderer*)':
undefined reference to `IMG_LoadTexture'
collect2: ld returned 1 exit status

这里是函数调用:

#include "SDL.h"
#include "SDL_image.h"

SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren)
    SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
    texture != nullptr or die("LoadTexture");
    return texture;

我很绝望。请帮我! 谢谢! :)

【问题讨论】:

请记住,SDL 是一个 C 库,而不是 C++ 库。因此,使用像 std::string 这样的 C++ 类作为参数很可能不起作用。 另外,由于您是 SO 新手,如果您对构建(编译器或链接器)错误有任何疑问,请包括 completeunedited 在您的问题中记录错误,包括导致错误的代码(最好是Minimal, Complete, and Verifiable example)。在您的情况下,请编辑您的问题以包含您调用IMG_LoadTexture 的代码以及足够的上下文以理解代码(如变量声明等)。 不知道任何 cmake 细节,但你不应该加上 $SDL2_IMAGE_LIBRARIES 吗? @keltar 我试过了:同样的错误。 (我编辑了我的帖子) 【参考方案1】:

我认为以下方法会起作用,因为它会在我的 ubuntu 系统上找到库,并且您提供的示例函数可以链接:

project(shooter-cmake2)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -std=c++0x")

add_executable($PROJECT_NAME src/test.cpp)

INCLUDE(FindPkgConfig)

PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)

INCLUDE_DIRECTORIES($SDL2_INCLUDE_DIRS $SDL2IMAGE_INCLUDE_DIRS)
TARGET_LINK_LIBRARIES($PROJECT_NAME $SDL2_LIBRARIES $SDL2IMAGE_LIBRARIES)

如果使用 --debug-output 执行 cmake,它会输出:

-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26") 
Called from: [2]    /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake
            [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'sdl2'
Called from: [1]    $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'SDL2_image>=2.0.0'
Called from: [1]    $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt

这让我检查了

的内容
/usr/lib/x86_64-linux-gnu/pkgconfig/sdl2.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/SDL2_image.pc

我注意到 SDL2_image.pc 包含 名称:SDL2_image 我认为应该将第三个参数与该库的 PKG_SEARCH_MODULE 匹配。

【讨论】:

谢谢,这就像一个魅力!你在哪里找到如何做到这一点的?参考什么? 我没有使用任何参考资料,只是我可以从您使用的模块的源代码中读取到我对 .pc 文件如何工作的了解。我用其他信息更新了答案。 :) 感谢编辑!但是--debug-output 对您有什么帮助?我只是想了解您是如何解决的。 调试输出告诉我使用了 pkg,并且配置的一个库使用了一个 pkg 文件正在工作,而另一个没有。这缩小了范围。 自 CMake 3.1 起,set(CMAKE_CXX_STANDARD yy) 优于修改 CMAKE_CXX_FLAGS【参考方案2】:

这里有两篇关于此的博文:

Using SDL2 with CMake

Using SDL2_image with CMake

基本上你需要一个FindSDL2.cmakeFindSDL2_image.cmake 模块。它们可以基于已包含在 CMake 中的适用于 SDL 1.2 的那些。使用这些 Find 模块也可以在 Windows 上运行。

如果您使用的是 Linux 并且只需要 SDL2,那么您甚至不需要 FindSDL2.cmake,因为以下已经可以使用:

cmake_minimum_required(VERSION 3.7)

project(SDL2Test)

find_package(SDL2 REQUIRED)
include_directories($SDL2_INCLUDE_DIRS)

add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test $SDL2_LIBRARIES)

【讨论】:

这在 Linux 上是如何工作的? (我已经看到确实如此。)在 Linux 上是否安装了带有 CMake 的 FindSDL2.cmake? 当前 CMake (v3.12) here 的模块列表似乎不包括 SDL2 支持,那么它是如何工作的? linux下的SDL2包含一个CMake配置文件。这样它就可以在没有 FindSDL2 模块的情况下工作。【参考方案3】:

我在回答这些问题时遇到了麻烦,我认为 cmake 改变了导入目标的方式。在@trenki 博客文章之后,我需要将我的 CMakeLists.txt 更改为:

project(SDL2Test)
find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2)
add_executable(SDL2Test main.cpp)
target_link_libraries(SDL2Test SDL2::SDL2)

目前这在 Arch Linux 上开箱即用。

【讨论】:

我也看到了一些类似的双冒号,但无法让它与 SDL2_image 一起工作。这完全取决于您的系统上是否存在不同风格的临时“查找”配置文件。 CMake 确实需要您的耐心。我们不能都同意把我们的文件放在同一个地方吗:)【参考方案4】:

我介绍了一种现代且可移植的方法来链接到 SDL2,即 SDL2_image。这些SDL2 CMake modules 可以让您构建一个 SDL2 和 SDL2_image 项目,如下所示:

list(APPEND CMAKE_MODULE_PATH $CMAKE_CURRENT_SOURCE_DIR/cmake/sdl2)

find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
target_link_libraries($PROJECT_NAME SDL2::Main SDL2::Image)

您应该只在项目中克隆 repo:

git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2

注意:如果 CMake 没有找到 SDL2/SDL2_image 库(在 Windows 中),我们可以指定 CMake 选项 SDL2_PATHSDL2_IMAGE_PATH,如下所示:

cmake .. -DSDL2_PATH="/path/to/sdl2" -DSDL2_IMAGE_PATH="/path/to/sdl2-image"

它还支持其他相关库:SDL2_ttf、SDL2_net、SDL2_mixer 和 SDL2_gfx。更多详情请阅读README.md文件。

您可以在此处找到使用这些模块的示例/示例和项目列表:https://github.com/aminosbh/sdl-samples-and-projects

【讨论】:

【参考方案5】:

以下命令对我来说很好用:

set(SDL_INCLUDE_DIR "/usr/include/SDL2")
set(SDL_LIBRARY "SDL2")
include(FindSDL)  

if(SDL_FOUND)  
  message(STATUS "SDL FOUND")
endif()

【讨论】:

以上是关于如何在 cmake 中使用 SDL2 和 SDL_image的主要内容,如果未能解决你的问题,请参考以下文章

在 Ubuntu 上使用 C++ 和 cmake 使用 SDL2 + SDL2Image 加载 PNG

SDL2 简明教程:使用 Cmake 和 Conan 构建 SDL2 编程环境

SDL2 简明教程:使用 Cmake 和 Conan 构建 SDL2 编程环境

如何在 Visual Studio 2019 CMake 项目(Windows 10)上安装 SDL2

将 SDL2 与 CMake 一起使用

CMake 找不到 SDL2