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
Using SDL2 with CMake
提问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.cmake
file 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_DIR
variable. 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.9
tag, possibly earlier.)
(至少从release-2.0.9
tag 开始,可能更早。)
回答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_PATH
as 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.cmake
file, 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_DIRECTORIES
defined, which means we don't need to manually specify include_directories
for SDL2.
它们中的每一个都已INTERFACE_INCLUDE_DIRECTORIES
定义,这意味着我们不需要include_directories
为 SDL2手动指定。
But by only adding SDL2::SDL2main
and SDL2::SDL2
as target_link_libraries
is not enough. The g++ compiler might be complaining about "undefined reference to `WinMain'".
但是仅仅添加SDL2::SDL2main
和SDL2::SDL2
astarget_link_libraries
是不够的。g++ 编译器可能会抱怨“对‘WinMain’的未定义引用”。
By inspecting the compiler options, I found that the SDL2 libraries are added before -lmingw32
option. In order to make the -lmingw32
option comes before SDL2 libraries, we have to also specify mingw32
as 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 -lmingw32
option 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 --libs
to 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 --cflags
option, 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_PATHS
line 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)