我尝试使用CLion创建SDL2项目。 问题是在使用#include时无法找到SDL标头。
我的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})
我的测试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;
}
感谢您提供任何帮助。
编辑: 我使用Windows并且CLion配置为使用cygwin64。
答案 0 :(得分:16)
不要手动设置SDL2的路径。使用正确的find命令,该命令使用FindSDL。应该是这样的:
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})
如果未找到SDL2,则必须将SDL2的路径添加到CMAKE_PREFIX_PATH
,这是CMake查找已安装软件的位置。
如果您可以使用Pkg-config,它的使用可能会更容易,请参阅How to use SDL2 and SDL_image with cmake
如果您觉得使用类似于CMake提供的FindSDL.cmake的FindSDL2.cmake文件感觉更舒服,请参阅https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/
答案 1 :(得分:10)
此博客文章介绍了如何执行此操作:Using SDL2 with CMake
在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})
在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)
当您现在在CMake-GUI应用程序内部配置时,将有一个SDL2_DIR
变量。您必须将它指向SDL2目录,在该目录中您解压缩开发包并重新配置,然后一切都应该工作。
然后,您只需撰写#include "SDL.h"
即可包含SDL2标头。
答案 2 :(得分:1)
您似乎没有生成make文件的CMake错误。但我认为您的问题是,SDL标题位于名为&#34; SDL2&#34;的子文件夹中。
更改您的CMakeLists.txt以包含
C:/SDL/SDL2-2.0.3/include/SDL2
而不是
C:/SDL/SDL2-2.0.3/include
答案 3 :(得分:1)
使用我开发的SDL2 CMake module,您可以轻松地以现代且可移植的方式集成SDL2库。
您应该只在项目中的cmake/sdl2
中复制模块(或仅克隆模块存储库):
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
然后在您的CMakeLists.txt中添加以下行:
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main)
注意::如果CMake在Windows中找不到SDL2库,我们可以按以下方式指定CMake选项SDL2_PATH
:
cmake .. -DSDL2_PATH="/path/to/sdl2"
有关更多详细信息,请阅读README.md文件。
SDL2 CMake模块支持其他相关的库:SDL2_image,SDL2_ttf,SDL2_mixer,SDL2_net和SDL2_gfx。
您可以在此处找到使用这些模块的示例/示例和项目的列表:https://github.com/aminosbh/sdl-samples-and-projects
答案 4 :(得分:0)
到我回答时,SDL2提供了 sdl2-config 可执行文件(据我所知,开发人员称他为“实验性”)。
在SDL2的“make install”之后,您可以尝试从终端调用它
sdl2-config --cflags --libs
了解它的输出结果。
然后你可以在你的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})
这里我有一个问题 - 如果我只放一个没有路径的可执行文件名
execute_process(COMMAND sdl2-config --libs <...>
我收到错误“没有这样的文件”,即cmake不在当前路径中搜索,我现在不知道如何正确编写它。
还有一个注意事项:在我的makefile中,我没有使用--cflags
选项,因为cmake发现包含正确,我不需要明确指定它们。
答案 5 :(得分:0)
我遇到了同样的问题,其他解决方案都没有。 但是我最终通过遵循这个解决方案来实现它:How to properly link libraries with cmake?
简而言之,问题是 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)
答案 6 :(得分:0)
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)
答案 7 :(得分:0)
您还可以将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 )
(至少自release-2.0.9
tag起,可能更早。)
答案 8 :(得分:0)
重点介绍如何使用FindSDL2.cmake模块最终完成此操作的步骤:
Decodable
行,并将复制的SDL2开发目录添加为新行:SET(SDL2_SEARCH_PATHS
"/Program Files (x86)/SDL2-2.0.9" # Windows
在此之后,运行CMake对我有用。我将其余的CMakeList包括在内,以防进一步澄清我可能遗漏的内容:
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
希望这会在不久的将来对某人有所帮助。
答案 9 :(得分:0)
对于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
)
详细说明
通过阅读SDL2Targets.cmake
文件,我了解到SDL2提供了几个目标:
SDL2::SDL2main
(lib/libSDL2main.a
)SDL2::SDL2
(lib/libSDL2.dll.a
)SDL2::SDL2-static
(lib/libSDL2-static.a
)它们每个都定义了INTERFACE_INCLUDE_DIRECTORIES
,这意味着我们不需要为SDL2手动指定include_directories
。
但是仅将SDL2::SDL2main
和SDL2::SDL2
添加为target_link_libraries
是不够的。 g ++编译器可能会抱怨“对WinMain的未定义引用”。
通过检查编译器选项,我发现SDL2库被添加到-lmingw32
选项之前。为了使-lmingw32
选项先于SDL2库,我们还必须指定mingw32
作为第一个target_link_libraries
。这将使此配置正常工作。
我用来构建它的命令是:
$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .
这里唯一的小问题是在最终生成的编译器选项中,-lmingw32
选项是重复的。但由于它不会影响链接过程,因此我暂时将其忽略。
答案 10 :(得分:0)
供您参考,在链接到SDL2源代码时,我能够成功构建和编译SDL2_ttf。
起初,由于cmake无法定位SDL2,即使在cmake中使用cmake中的SLD2_DIR变量指定了SDL2,我也遇到了错误。
似乎由于某些原因,cmake SDL2无法创建SDL2_ttf搜索的SDL2Targets.cmake文件。
在这种情况下,请从https://bugs.archlinux.org/task/57972获取SDL2Targets.cmake文件,并按如下所示修改文件:
您可以删除以下几行:
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
并添加一个:
set(_IMPORT_PREFIX "C:/SDL2-2.0.12")
显然将文件路径更改为您解压缩SDL2源代码的位置
我不确定这是否正是您的问题,但是确实存在。
答案 11 :(得分:0)
我最近发现最新版本的SDL2(2.0.12版)现在带有所有必需的CMake配置/安装脚本,因此不再需要使用FindSDL。
我从https://www.libsdl.org/download-2.0.php下载了SDL源,然后从根文件夹运行了...
cmake -S . -B build/debug -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Debug
cmake --build build/debug --target install
这将构建并安装该库的调试版本,然后您还可以运行...
cmake -S . -B build/release -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build/release --target install
将构建并安装该库的发行版(并且由于SDL CMake脚本使用DEBUG_POSTFIX,因此该库的发行版不会覆盖调试版本,因为所有调试版本都在其名称后附加了“ d”)
然后在您的CMakeLists.txt文件中,只需执行以下操作:
find_package(SDL2 REQUIRED)
add_executable(${PROJECT_NAME} ...)
target_link_libraries(
${PROJECT_NAME} PRIVATE
SDL2::SDL2
SDL2::SDL2main
如果您使用示例中的自定义位置,则需要告诉您的应用程序在哪里可以找到SDL安装文件夹。为此,请在应用程序的根文件夹中运行:
cmake -S . -B build/debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=</absolute/path/to/install/dir>
cmake --build build/debug
注意:您可以使用
$(pwd)
(* nix / macOS)或%cd%
(Windows)创建混合的相对路径,这可能非常有用。
如果要将SDL安装到默认系统位置,则可以省略DCMAKE_INSTALL_PREFIX
和DCMAKE_PREFIX_PATH
。
在我选择使用Ninja生成器的示例中,因为它在macOS / Windows上是一致的-可以与MSVC / Visual Studio一起使用,只需确保运行此命令(路径可能会因年份/版本而略有不同)以将Ninja添加到您的路径。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
更新:
我记得在Windows上有用的另一件事是能够将SDL .dll文件复制到应用程序二进制目录中,可以这样实现:
if (WIN32)
# copy the .dll file to the same folder as the executable
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:SDL2::SDL2>
$<TARGET_FILE_DIR:${PROJECT_NAME}>
VERBATIM)
endif()