C++ 在 CMake 中使用 SDL2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28395833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:58:35  来源:igfitidea点击:

Using SDL2 with CMake

c++cmakesdl-2

提问by Ovenkoek

I'm trying to use CLion to create a SDL2 project. The problem is that the SDL headers can't be found when using #include's.

我正在尝试使用 CLion 创建一个 SDL2 项目。问题是在使用#include 时找不到 SDL 标头。

My CMakeLists.txt file:

我的 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 2.8.4)
project(ChickenShooter)

set(SDL2_INCLUDE_DIR C:/SDL/SDL2-2.0.3/include)
set(SDL2_LIBRARY C:/SDL/SDL2-2.0.3/lib/x64)

include_directories(${SDL2_INCLUDE_DIR})
set(SOURCE_FILES main.cpp)

add_executable(ChickenShooter ${SOURCE_FILES})
target_link_libraries(ChickenShooter ${SDL2_LIBRARY})

My test main.cpp:

我的测试 main.cpp:

#include <iostream>
#include "SDL.h" /* This one can't be found */

int main(){
    if (SDL_Init(SDL_INIT_VIDEO) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }
    SDL_Quit();
    return 0;
}

Thank you for any help you could give me.

谢谢你能给我的任何帮助。

Edit: I'm using Windows and CLion is configured to use cygwin64.

编辑:我使用的是 Windows 并且 CLion 配置为使用 cygwin64。

采纳答案by usr1234567

Don't set the path to SDL2 by hand. Use the proper find command which uses FindSDL. Should look like:

不要手动设置 SDL2 的路径。使用使用FindSDL的正确 find 命令。应该看起来像:

find_file(SDL2_INCLUDE_DIR NAME SDL.h HINTS SDL2)
find_library(SDL2_LIBRARY NAME SDL2)
add_executable(ChickenShooter main.cpp)
target_include_directories(ChickenShooter ${SDL2_INCLUDE_DIR})
target_link_libraries(ChickenShooter ${SDL2_LIBRARY})    

If SDL2 is not found, you have to add the path to SDL2 to CMAKE_PREFIX_PATH, that's the place where CMake looks for installed software.

如果未找到 SDL2,则必须将 SDL2 的路径添加到CMAKE_PREFIX_PATH,这是 CMake 查找已安装软件的地方。

If you can use Pkg-config, its use might be easier, see How to use SDL2 and SDL_image with cmake

如果您可以使用 Pkg-config,它的使用可能会更容易,请参阅How to use SDL2 and SDL_image with cmake

If you feel more comfortable to use a FindSDL2.cmake file similar to FindSDL.cmake provided by CMake, see https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/

如果您觉得使用类似于 CMake 提供的 FindSDL.cmake 的 FindSDL2.cmake 文件更舒服,请参阅https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/

回答by trenki

This blog post shows how you can do it: Using SDL2 with CMake

这篇博客文章展示了如何做到这一点:在 CMake 中使用 SDL2

On Linux you can use a recent CMake (e.g. version 3.7) and using SDL2 works out of the box.

在 Linux 上,您可以使用最新的 CMake(例如 3.7 版)并使用 SDL2 开箱即用。

cmake_minimum_required(VERSION 3.7)
project(SDL2Test)

find_package(SDL2 REQUIRED)
include_directories(SDL2Test ${SDL2_INCLUDE_DIRS})

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

Under Windows you can download the SDL2 development package, extract it somewhere and then create a sdl-config.cmakefile in the extracted location with the following content:

在 Windows 下,您可以下载 SDL2 开发包,将其解压到某处,然后sdl-config.cmake在解压位置创建一个包含以下内容的文件:

set(SDL2_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/include")

# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
  set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2main.lib")
else ()
  set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2main.lib")
endif ()

string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)

When you now configure inside the CMake-GUI application there will be a SDL2_DIRvariable. You have to point it to the SDL2 directory where you extracted the dev package and reconfigure then everything should work.

当您现在在 CMake-GUI 应用程序中进行配置时,将会有一个SDL2_DIR变量。您必须将其指向提取开发包的 SDL2 目录并重新配置,然后一切正常。

You can then include SDL2 headers by just writing #include "SDL.h".

然后,您只需编写#include "SDL.h".

回答by genpfault

You can also pull in the SDL source repository as a submodule and build/link it statically along with your main program via add_subdirectory()and target_link_libraries():

您还可以将 SDL 源存储库作为子模块引入,并通过add_subdirectory()和静态构建/链接它与您的主程序target_link_libraries()

cmake_minimum_required( VERSION 3.7.0 )
project( sdl2-demo )

set( SDL_STATIC ON CACHE BOOL "" FORCE )
set( SDL_SHARED OFF CACHE BOOL "" FORCE )
add_subdirectory( external/sdl )

add_executable(
    sdl2-demo
    "src/main.cpp"
    )
target_link_libraries( sdl2-demo SDL2main SDL2-static )

(At least as of the release-2.0.9tag, possibly earlier.)

(至少从release-2.0.9tag 开始,可能更早。)

回答by bibinsyamnath

cmake_minimum_required(VERSION 2.8.4)

project(ChickenShooter)

set(SDL2_INCLUDE_DIR C:/SDL/SDL2-2.0.3/include/SDL2)
set(SDL2_LIB_DIR C:/SDL/SDL2-2.0.3/lib/x64)

include_directories(${SDL2_INCLUDE_DIR})
link_directories(${SDL2_LIB_DIR})

set(SOURCE_FILES main.cpp)

add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} SDL2main SDL2)

回答by aminosbh

Using the SDL2 CMake modulethat I developed, you can integrate the SDL2 library easily in a modern and portable approach.

使用我开发的SDL2 CMake 模块,您可以以现代且可移植的方式轻松集成 SDL2 库。

You should just copy the module in cmake/sdl2(Or just clone the modules repo) in your project:

你应该cmake/sdl2在你的项目中复制模块(或者只是克隆模块 repo):

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

Then add the following lines in your CMakeLists.txt:

然后在 CMakeLists.txt 中添加以下几行:

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main)

Note:If CMake didn't find the SDL2 library (in Windows), we can specify the CMake option SDL2_PATHas follows:

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

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

For more details, please read the README.mdfile.

有关更多详细信息,请阅读README.md文件。

The SDL2 CMake modules support other related libraries : SDL2_image, SDL2_ttf, SDL2_mixer, SDL2_net and SDL2_gfx.

SDL2 CMake 模块支持其他相关库:SDL2_image、SDL2_ttf、SDL2_mixer、SDL2_net 和 SDL2_gfx。

You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects

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

回答by xiGUAwanOU

With the compiled version of SDL2-2.0.9 with MinGW-w64 in Windows, the following configuration works for me:

在 Windows 中使用 MinGW-w64 的 SDL2-2.0.9 编译版本,以下配置对我有用:

find_package(SDL2 REQUIRED)

add_executable(sdl-test ${SOURCES})

target_link_libraries(sdl-test
  mingw32
  SDL2::SDL2main
  SDL2::SDL2
)

A longer explanation

更长的解释

By reading SDL2Targets.cmakefile, I've learned that SDL2 is providing several targets:

通过阅读SDL2Targets.cmake文件,我了解到 SDL2 提供了几个目标:

  • SDL2::SDL2main(lib/libSDL2main.a)
  • SDL2::SDL2(lib/libSDL2.dll.a)
  • SDL2::SDL2-static(lib/libSDL2-static.a)
  • SDL2::SDL2main( lib/libSDL2main.a)
  • SDL2::SDL2( lib/libSDL2.dll.a)
  • SDL2::SDL2-static( lib/libSDL2-static.a)

Each of them has INTERFACE_INCLUDE_DIRECTORIESdefined, which means we don't need to manually specify include_directoriesfor SDL2.

它们中的每一个都已INTERFACE_INCLUDE_DIRECTORIES定义,这意味着我们不需要include_directories为 SDL2手动指定。

But by only adding SDL2::SDL2mainand SDL2::SDL2as target_link_librariesis not enough. The g++ compiler might be complaining about "undefined reference to `WinMain'".

但是仅仅添加SDL2::SDL2mainSDL2::SDL2astarget_link_libraries是不够的。g++ 编译器可能会抱怨“对‘WinMain’的未定义引用”。

By inspecting the compiler options, I found that the SDL2 libraries are added before -lmingw32option. In order to make the -lmingw32option comes before SDL2 libraries, we have to also specify mingw32as the first target_link_libraries. Which will make this configuration working.

通过检查编译器选项,我发现在-lmingw32选项之前添加了 SDL2 库。为了使该-lmingw32选项出现在 SDL2 库之前,我们还必须指定mingw32为第一个target_link_libraries. 这将使此配置工作。

The command that I have used for building it is:

我用于构建它的命令是:

$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .

The only small problem here is in the finally generated compiler options, the -lmingw32option is duplicated. But since it doesn't affect the linking process, I've ignored it for now.

这里唯一的小问题是在最终生成的编译器选项中,该-lmingw32选项是重复的。但由于它不影响链接过程,我暂时忽略了它。

回答by jordsti

You don't seems to have a CMake error whike generating your make file. But I think your problem is, the SDL Header are located in a subfolder named "SDL2".

您在生成 make 文件时似乎没有 CMake 错误。但我认为您的问题是,SDL 标题位于名为“SDL2”的子文件夹中。

Change your CMakeLists.txt to include

更改您的 CMakeLists.txt 以包括

C:/SDL/SDL2-2.0.3/include/SDL2

Instead of

代替

C:/SDL/SDL2-2.0.3/include

回答by Alexo Po.

by the time of my answer, SDL2 is provided with sdl2-configexecutable (as I understand, developers call him "experimental"). After "make install" of SDL2 you can try calling it from terminal with sdl2-config --cflags --libsto see what it outputs.

到我回答时,SDL2 提供了sdl2-config可执行文件(据我了解,开发人员称他为“实验性”)。在 SDL2 的“make install”之后,您可以尝试从终端调用它 sdl2-config --cflags --libs以查看它输出的内容。

And then you can add call to it in your makefile:

然后你可以在你的 makefile 中添加对它的调用:

set(PROJECT_NAME SomeProject)

project(${PROJECT_NAME})

execute_process(COMMAND /usr/local/bin/sdl2-config --libs RESULT_VARIABLE CMD_RES OUTPUT_VARIABLE SDL2_CFLAGS_LIBS ERROR_VARIABLE ERR_VAR OUTPUT_STRIP_TRAILING_WHITESPACE)
message("SDL2_CFLAGS_LIBS=${SDL2_CFLAGS_LIBS}; CMD_RES=${CMD_RES}; ERR_VAR=${ERR_VAR}")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${SDL2_CFLAGS_LIBS}")

set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})

Here I have a problem - if I only put an executable name without path like

在这里我有一个问题 - 如果我只输入一个没有路径的可执行文件名

execute_process(COMMAND sdl2-config --libs <...>

I get error "No such file", i.e. cmake does not search in current path and I don't know how to write it properly by now.

我收到错误“没有这样的文件”,即 cmake 不在当前路径中搜索,我现在不知道如何正确编写它。

One more notice: in my makefile I do not user --cflagsoption, because cmake finds includes correctly and I do not need to specify them explicitly.

另一个注意事项:在我的 makefile 中,我没有用户--cflags选项,因为 cmake 找到了正确的包含并且我不需要明确指定它们。

回答by My Stack Overfloweth

Highlighting the steps of how I was able to eventually accomplish this using the FindSDL2.cmake module:

突出显示我如何最终使用 FindSDL2.cmake 模块完成此任务的步骤:

  • Download SDL2-devel-2.0.9-VC.zip (or whatever version is out after this answer is posted) under the Development Libraries section of the downloads page.
  • Extract the zip folder and you should see a folder similar to "SDL2-2.0.9". Paste this folder in your C:\Program Files(x86)\ directory.
  • Copy the FindSDL2.cmake module and place it in a new "cmake" directory within your project. I found a FindSDL2.cmake file in the answer referenced in the Accepted Answer: https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/
  • Find the SET(SDL2_SEARCH_PATHSline in the FindSDL2.cmake and add your copied development directory for SDL2 as a new line: "/Program Files (x86)/SDL2-2.0.9" # Windows
  • Within my CMakeLists.txt, add this line: set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
  • 在下载页面的开发库部分下下载 SDL2-devel-2.0.9-VC.zip(或发布此答案后发布的任何版本)。
  • 解压 zip 文件夹,您应该会看到一个类似于“SDL2-2.0.9”的文件夹。将此文件夹粘贴到 C:\Program Files(x86)\ 目录中。
  • 复制 FindSDL2.cmake 模块并将其放在项目中的新“cmake”目录中。我在接受的答案中引用的答案中找到了 FindSDL2.cmake 文件:https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/
  • SET(SDL2_SEARCH_PATHS在 FindSDL2.cmake 中找到该行并将您复制的 SDL2 开发目录添加为新行:"/Program Files (x86)/SDL2-2.0.9" # Windows
  • 在我的 CMakeLists.txt 中,添加以下行: set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

After this, running CMake worked for me. I'm including the rest of my CMakeLists just in case it further clarifies anything I may have left out:

在此之后,运行 CMake 对我有用。我将其余的 CMakeLists 包括在内,以防它进一步澄清我可能遗漏的任何内容:

cmake_minimum_required(VERSION 2.8.4)
project(Test_Project)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

# includes cmake/FindSDL2.cmake
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

set(SOURCE_FILES src/main.cpp src/test.cpp)
add_executable(test ${SOURCE_FILES})

# The two lines below have been removed to run on my Windows machine
#INCLUDE(FindPkgConfig)
#PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
find_package(SDL2 REQUIRED)

INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(chip8 ${SDL2_LIBRARY})

Hope this helps somebody in the near future.

希望这可以在不久的将来帮助某人。

回答by Antonin G.

I had the same problem and none of the other solutions worked. But I finally got it working by following this solution : How to properly link libraries with cmake?

我遇到了同样的问题,其他解决方案都没有奏效。但我终于按照这个解决方案让它工作了:如何正确地将库与 cmake 链接?

In a nutshell, the problem was that the SDL2 library was not linked properly in my CMakeLists.txt. And by writing this into the file, it worked (more explainations in the other thread) :

简而言之,问题是SDL2 库在我的 CMakeLists.txt 中没有正确链接。通过将其写入文件,它起作用了(在另一个线程中有更多解释):

project (MyProgramExecBlaBla)  #not sure whether this should be the same name of the executable, but I always see that "convention"
cmake_minimum_required(VERSION 2.8)

ADD_LIBRARY(LibsModule 
    file1.cpp
    file2.cpp
)

target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule liblapack.a)
target_link_libraries(LibsModule -L/home/user/libs/somelibpath/)
ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp)
target_link_libraries(MyProgramExecBlaBla LibsModule)
project (MyProgramExecBlaBla)  #not sure whether this should be the same name of the executable, but I always see that "convention"
cmake_minimum_required(VERSION 2.8)

ADD_LIBRARY(LibsModule 
    file1.cpp
    file2.cpp
)

target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule liblapack.a)
target_link_libraries(LibsModule -L/home/user/libs/somelibpath/)
ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp)
target_link_libraries(MyProgramExecBlaBla LibsModule)