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

Posted

技术标签:

【中文标题】在 Ubuntu 上使用 C++ 和 cmake 使用 SDL2 + SDL2Image 加载 PNG【英文标题】:Loading a PNG using SDL2 + SDL2Image using C++ and cmake on Ubuntu 【发布时间】:2020-06-01 07:51:38 【问题描述】:

我正在编写一个简单的教程:https://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php

我的初始程序没有进行任何图像加载。它只是显示一个屏幕就走了。一切正常。这是我最初的CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.7)
project(01_hello_world)


set(CXX_STANDARD 17)

find_package(SDL2 REQUIRED)

add_executable(hello 01_hello_SDL.cpp)
target_include_directories(hello PRIVATE $SDL2_INCLUDE_DIRS)
target_link_libraries(hello $SDL2_LIBRARIES)

一切工作和编译都很好。然而,我想加载一个PNG图像,我认为这很容易。谷歌搜索将我带到 SDL2 图像库和 IMG_Load 方法。所以我继续安装libsdl2-image-dev,我的CMakeLists.txt 文件又增加了两行::

set(SDL2IMAGE_INCLUDE_DIRS $SDL2_INCLUDE_DIRS)
set(SDL2IMAGE_LIBRARIES "/usr/lib/x86_64-linux-gnu/libSDL2_image.a")

然而,仅仅使用IMG_Load 方法,make 命令就抛出了一大堆库要求:libtiff-devlibpng-devlibjpeg-devlibwebp-dev。这一切只是为了加载一个 png 文件!所以我继续安装了所有这些,现在我的CMakeLists.txt 文件看起来很可恶(我在可以的地方使用了find_package,并在我不能的地方手动设置变量):

cmake_minimum_required(VERSION 3.7)
project(01_hello_world)

set(CXX_STANDARD 17)

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(SDL2 REQUIRED)
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
find_package(TIFF REQUIRED)

set(SDL2IMAGE_INCLUDE_DIRS $SDL2_INCLUDE_DIRS)
set(SDL2IMAGE_LIBRARIES "/usr/lib/x86_64-linux-gnu/libSDL2_image.a")
set(WEBP_LIBRARIES "/usr/lib/x86_64-linux-gnu/libwebp.a")

add_executable(hello 01_hello_SDL.cpp)
target_include_directories(hello PRIVATE $SDL2_INCLUDE_DIRS $SDL2IMAGE_INCLUDE_DIRS $PNG_INCLUDE_DIRS)
target_link_libraries(hello $SDL2_LIBRARIES $SDL2IMAGE_LIBRARIES $PNG_LIBRARY $JPEG_LIBRARY $WEBP_LIBRARIES $TIFF_LIBRARIES Threads::Threads)

此时,当我制作时,我收到此错误:

[ 50%] Linking CXX executable hello
/usr/bin/ld: cannot find -lTIFF_LIBRARIES
collect2: error: ld returned 1 exit status
CMakeFiles/hello.dir/build.make:98: recipe for target 'hello' failed
make[2]: *** [hello] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hello.dir/all' failed
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

我已经在谷歌上搜索了几个小时。谁能在这黑暗中提供一盏灯?

这也是使用 sdl + cmake 的正确方法吗?

【问题讨论】:

错误信息的重要部分是cannot find -lTIFF_LIBRARIES。看来您在$TIFF_LIBRARIES 中缺少$。您确定您显示的 CMakeLists.txt 文件是正确的并且您正在使用的文件是正确的吗?如果您在重新运行 cmake 后再次尝试使用您当前显示的 CMakeLists.txt 文件重新生成构建文件,会发生什么情况? 而不是$TIFF_LIBRARIES,我建议你使用导入的目标TIFF::TIFF(在the documentation中提到)。您应该从使用变量更改为使用所有库的导入目标。 当我使用TIFF:TIFF 代替$TIFF_LIBRARIES 时,我得到/usr/bin/ld: cannot find -lTIFF:TIFF。编辑:哦,好的。我漏掉了一个分号。我对构建文件夹进行了核对并完成了整个 cmake + make,现在它很好。真是过山车。 PS 使用 "JPEG::JPEG" 而不是 "$JPEG_LIBRARIES" 不起作用。 cmake 命令产生关于未找到目标的错误。顺便说一下,您链接的页面,我访问过很多次,但我不知道FindTIFF 到底是什么。它是一种方法吗?我该如何调用它?和find_package有什么关系??不是很明显。 请阅读the CMake module list。在那里你可以找到FindTIFF 模块,以及FindJPEG 模块(表示它创建了JPEG::JPEG 目标)。 【参考方案1】:
set(SDL2IMAGE_LIBRARIES "/usr/lib/x86_64-linux-gnu/libSDL2_image.a")

您似乎没有将 SDL2_image 动态链接到您的程序。 我不知道如何在 CMake 中更改它,但您可以使用此模式编译程序:

g++ your_program.cpp -o your_program -lSDL2 -lSDL2_image

您也可以使用这样的 Makefile:

OBJS = your_program.cpp

OBJ_NAME = your_program_output

all:
    g++ $(OBJS) -o $(OBJ_NAME) -lSDL2 -lSDL2_image # don't forget about replacing the four spaces by a tab character

最后一件事,lazy foo 有一个教程,教您如何使用 IDE(代码::块)或不使用 IDE(命令行和 Makefile)在 linux 上安装和设置 SDL2_image 库。 http://lazyfoo.net/tutorials/SDL/06_extension_libraries_and_loading_other_image_formats/linux/index.php

【讨论】:

以上是关于在 Ubuntu 上使用 C++ 和 cmake 使用 SDL2 + SDL2Image 加载 PNG的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 Ubuntu 上配置 CMake 工具链

使用 CMake、Clang 和 Ninja 在 Windows 上构建 c++ 项目

ubuntu(Linux)安装Vs code并配置c++编译及cmake多文件编译

Ubuntu 20.04下搭建C++ & OpenCV 4.6.0 & cmake编译

在 C++ Ubuntu 中安装 FTP 客户端(库)

ubuntu vscode上使用cmake编译调试