如何在 cmake 中使用 SDL2 和 SDL_image
Posted
技术标签:
【中文标题】如何在 cmake 中使用 SDL2 和 SDL_image【英文标题】:How to use SDL2 and SDL_image with cmake 【发布时间】:2014-07-14 01:36:55 【问题描述】:我正在寻找使用 SDL2 和 SDL_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 新手,如果您对构建(编译器或链接器)错误有任何疑问,请包括 complete 和 unedited 在您的问题中记录错误,包括导致错误的代码(最好是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.cmake
和FindSDL2_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_PATH
和 SDL2_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 编程环境