我正在尝试使用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。
请勿手动设置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})
如果未找到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/
突出显示如何使用FindSDL2.cmake模块最终完成此操作的步骤:
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)
SET(SDL2_SEARCH_PATHS
"/Program Files (x86)/SDL2-2.0.9" # Windows
此后,运行CMake对我有用。我包括了我的其余CMakeLists,以防万一它进一步澄清了我可能遗漏的内容:
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
希望这会在不久的将来对某人有所帮助。
供您参考,在链接到SDL2源代码时,我能够成功构建和编译SDL2_ttf。
此博客文章显示了如何操作: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目录,在该目录中提取dev软件包并重新配置,然后一切正常。
然后您只需写#include "SDL.h"
就可以包括SDL2标头。
您还可以将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起,可能更早。)
您似乎并没有生成make文件的CMake错误。但是我认为您的问题是,SDL标头位于名为“ SDL2”的子文件夹中。
将您的CMakeLists.txt更改为包含
release-2.0.9
代替
C:/SDL/SDL2-2.0.3/include/SDL2
使用我开发的C:/SDL/SDL2-2.0.3/include
,您可以通过现代且可移植的方法轻松集成SDL2库。
您应该只在项目中的SDL2 CMake module中复制模块(或仅复制模块存储库):
cmake/sdl2
然后在您的CMakeLists.txt中添加以下行:
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
注意:如果CMake在Windows中找不到SDL2库,我们可以如下指定CMake选项list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main)
:
SDL2_PATH
有关更多详细信息,请阅读cmake .. -DSDL2_PATH="/path/to/sdl2"
文件。
SDL2 CMake模块支持其他相关的库:SDL2_image,SDL2_ttf,SDL2_mixer,SDL2_net和SDL2_gfx。
您可以在此处找到使用这些模块的示例/样本和项目的列表:README.md
使用Windows中具有MinGW-w64的SDL2-2.0.9的编译版本,以下配置对我有效:
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)
详细说明
通过阅读find_package(SDL2 REQUIRED)
add_executable(sdl-test ${SOURCES})
target_link_libraries(sdl-test
mingw32
SDL2::SDL2main
SDL2::SDL2
)
文件,我了解到SDL2提供了几个目标:
SDL2Targets.cmake
(SDL2::SDL2main
)lib/libSDL2main.a
(SDL2::SDL2
)lib/libSDL2.dll.a
(SDL2::SDL2-static
)每个都定义了lib/libSDL2-static.a
,这意味着我们不需要为SDL2手动指定INTERFACE_INCLUDE_DIRECTORIES
。
但是仅将include_directories
和SDL2::SDL2main
添加为SDL2::SDL2
是不够的。 g ++编译器可能会抱怨“对WinMain的未定义引用”。
通过检查编译器选项,我发现SDL2库添加在target_link_libraries
选项之前。为了使-lmingw32
选项在SDL2库之前出现,我们还必须将-lmingw32
指定为第一个mingw32
。这将使此配置起作用。
我用于构建它的命令是:
target_link_libraries
这里唯一的小问题是在最终生成的编译器选项中,$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .
选项是重复的。但是,由于它不会影响链接过程,因此我暂时将其忽略。
在我回答问题时,SDL2提供了sdl2-config可执行文件(据我了解,开发人员称他为“实验性”)。在“安装” SDL2之后,您可以尝试从终端使用-lmingw32
查看其输出。
然后您可以在其makefile中添加对其的调用:
sdl2-config --cflags --libs
这里有一个问题-如果我只放置一个不带路径的可执行文件名称,例如
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})
我收到错误消息“没有这样的文件”,即cmake不在当前路径中搜索,并且我现在不知道如何正确编写它。
另外一个注意:在我的makefile中,我不使用execute_process(COMMAND sdl2-config --libs <...>
选项,因为cmake查找正确地包含了它们,并且我不需要显式指定它们。
我遇到了同样的问题,其他解决方案均无效。但是我最终通过遵循以下解决方案使其工作:--cflags
简而言之,问题是SDL2库在我的CMakeLists.txt中未正确链接。通过将其写入文件,它可以工作(在另一个线程中有更多解释):
How to properly link libraries with cmake?