在 CLion 上以一种美观、便携的方式使用 CMakeList.txt 配置 SDL2

Configure SDL2 with CMakeList.txt on CLion in a nice, portable way

我知道以前有人问过这个问题,但我对网上找到的答案不满意,所以希望有人能为我提供正确的见解。

我正在尝试在 Windows 上使用 CLion 配置 SDL2,但我遇到了一些问题。我之前在 linux 下载了 SDL2 源代码,成功构建并安装了它们,所以我知道它可以工作。但是,我现在无法访问那台计算机,我正在尝试在 Windows.

上进行设置

我下载了 http://libsdl.org/release/SDL2-devel-2.0.7-mingw.tar.gz 并将其内容提取到 E:\SDL2\SDL2-2.0.7E:\SDL2\SDL2-2.0.7\x86_64-w64-mingw32\bin 包含 SDL2.dll)。 None 我发现的指南中有关于 运行 configure、cmake、make 或其他内容的任何内容,并且由于它包含一个 DLL,我假设所有内容都是预构建的 (?)

这是我在 E:\repository\SDL_Project 中的 CLion 项目(名为 SDL_Project)中的 CMakeList.txt

cmake_minimum_required(VERSION 3.6)
project(SDL_Project)

set(CMAKE_CXX_STANDARD 14)

add_executable(SDL_Project src/main.cpp)

find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)

include_directories(${SDL2_INCLUDE_DIR}
        ${SDL2_IMAGE_INCLUDE_DIR}
        ${SDL2_TTF_INCLUDE_DIR})

target_link_libraries(SDL_Project ${SDL2_LIBRARY}
        ${SDL2_IMAGE_LIBRARIES}
        ${SDL2_TTF_LIBRARIES})

单独这样做是行不通的,因为 CMake 不知道在哪里寻找 SDL2(这与我的 Linux 经验不同。)

我在网上找到了几个版本的 FindSDL2.cmake,显然是在不同位置搜索 SDL2 的巨大脚本。

CMakeList.txt 旁边添加此脚本对我不起作用:

CMake Error at CMakeLists.txt:8 (find_package):
  By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "SDL2", but
  CMake did not find one.

[...]

我也通过控制面板在Windows系统环境变量中PATH添加了SDL2目录

这是我的编译器消息(当我注释掉 CMakeList.txt 中导致错误的 SDL2 行时):

E:\repository\SDL_Project\src\main.cpp:1:17: fatal error: SDL.h: No such file or directory
 #include <SDL.h>
                 ^
compilation terminated.

我知道这个错误很明显,但为了完整起见,我还是把它包括在这里。


我有以下问题:

  1. 如何以干净的方式为 Windows 正确设置它(将 SDL2 添加到 System32 对我来说似乎不太好..)
  2. 我想使用完全相同的 CMakeList.txt 文件从多台机器构建(linux、Windows..),所以理想情况下它不包含硬编码路径或 OS-特定代码或配置。
  3. 使用包含大量硬编码位置列表的大型 FindSDL2.cmake 文件进行搜索,对我来说也不太好..
  4. 理想情况下,设置构建环境所需的配置最少; a) 克隆存储库,b) download/unzip SDL2,c) 以某种方式告诉编译器 SDL2 的位置。

换句话说;什么是这个问题的一个好的、便携的、最小的解决方案?请尽可能激发答案,我想了解 为什么 这是一个很好的解决方案以及如何做到这一点。谢谢!!

查找库很复杂,尽管 Unix 非常努力地欺骗您,让您认为它不是。

最后,库只是文件系统上的一个文件(文件系统上的任意位置),您需要以某种方式告诉您的构建脚本到哪里寻找该文件。 Unix 在这里有一些合理的默认值(例如 /usr/lib/),Windows 没有,但是一旦安装,Unix 上的情况就和 Windows 上一样糟糕您的图书馆到 non-standard 位置。

CMake 有 ,但在 SDL2 的情况下,可以说使用查找脚本更合适。

查找脚本现在应该可以解决定位库文件的问题,该库文件可能位于文件系统的任何位置。可能有一些合理的默认值,它会自动检查以方便您使用,但最后,如果没有您的帮助,它无法完成工作,因为文件可能在 任何地方

这就是为什么,如果我们查看 a typical find script,它总是会为您提供一个自定义点来告诉构建系统在哪里可以找到有问题的库:

FIND_LIBRARY(SDL2_LIBRARY_TEMP
  NAMES SDL2
  HINTS
  $ENV{SDL2DIR}
  PATH_SUFFIXES lib64 lib
  PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIR}/../..
)

注意这里的HINTS $ENV{SDL2DIR}。这个will make CMake search在环境变量SDL2DIR中指定的目录,以及里面的子目录liblib64,对于一个名为SDL2的库文件(在除了上述始终搜索的默认路径之外)¹。

请注意,这是一个特定于机器的提示,因此该目录有意不在任何脚本中进行硬编码,而是从环境变量中检索。这样,构建脚本本身仍然是完全可移植的,用户有责任相应地配置构建环境。

因此,您的设置过程是:获取您喜欢的库的二进制文件(通过下载二进制文件或自行构建),将其安装到您选择的位置,然后以某种方式知道该库的位置建立,例如。通过在构建 shell 中设置环境变量。请注意,此过程对于所有平台始终相同,如果您的库已经安装在 find-mechanism 识别的默认位置,例如 Unix 上的 /usr/lib,或者Windows.

上的 CMake 包注册表

还缺少一个细节。无论是使用外部查找脚本还是包配置文件来查找库,CMake 都必须能够找到那个脚本,然后才能继续搜索库。同样,为了您的方便,CMake 已经附带了 a bunch of preinstalled scripts,但 SDL2 不是其中之一。幸运的是,如果您必须提供自己的查找脚本,通常只需将它放在源代码树中,因此让 CMake 知道它的位置不是问题。例如,如果您将 FindSDL2.cmake 放在项目源根目录下的文件夹 cmake 中,只需调用 list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") 让 CMake 使用该位置的查找脚本。

¹ 请注意,since CMake 3.12 find_package(Foo) 自动将 Foo_ROOT 环境变量视为所有相关 find_* 调用的搜索提示,除非脚本明确选择退出NO_PACKAGE_ROOT_PATH 选项的行为。