Использование SDL2 с CMake
Я пытаюсь использовать CLion для создания проекта SDL2.
Проблема заключается в том, что заголовки SDL не могут быть найдены при использовании # include.
Мой файл 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.
Ответы
Ответ 1
Не устанавливайте путь к SDL2 вручную. Используйте правильную команду поиска, которая использует 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 не найден, вы должны добавить путь к CMAKE_PREFIX_PATH
в CMAKE_PREFIX_PATH
, где CMake ищет установленное программное обеспечение.
Если вы можете использовать Pkg-config, его использование может быть проще, см. Как использовать SDL2 и SDL_image с cmake
Если вам удобнее использовать файл FindSDL2.cmake, аналогичный файлу FindSDL.cmake, предоставленному CMake, см. Https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/
Ответ 2
Это сообщение в блоге показывает, как вы можете это сделать: Использование SDL2 с 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 и переконфигурировали, тогда все должно работать.
Затем вы можете включить заголовки SDL2, просто написав #include "SDL.h"
.
Ответ 3
У вас нет ошибки CMake, генерирующей ваш файл make. Но я думаю, что ваша проблема в том, что заголовок SDL находится в подпапке под названием "SDL2".
Измените свой CMakeLists.txt, чтобы включить
C:/SDL/SDL2-2.0.3/include/SDL2
Вместо
C:/SDL/SDL2-2.0.3/include
Ответ 4
Используя модуль SDL2 CMake, который я разработал, вы можете легко интегрировать библиотеку SDL2 в современный и переносимый подход.
Вы должны просто скопировать модуль в cmake/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 не нашел библиотеку SDL2 (в Windows), мы можем указать параметр 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
Ответ 5
к моменту моего ответа SDL2 снабжен исполняемым файлом sdl2-config (как я понимаю, разработчики называют его "экспериментальным" ).
После "make install" SDL2 вы можете попробовать позвонить ему из терминала с помощью
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})
Здесь у меня есть проблема - если я ставил только исполняемое имя без пути, например
execute_process(COMMAND sdl2-config --libs <...>
Я получаю сообщение об ошибке "Нет такого файла", т.е. cmake не ищет в текущем пути, и я не знаю, как его правильно записать.
Еще одно уведомление: в моем make файле я не являюсь пользователем --cflags
, потому что наборы cmake включены правильно, и мне не нужно явно указывать их.
Ответ 6
У меня была такая же проблема, и ни одно из других решений не сработало. Но, наконец, я заработал, следуя этому решению: Как правильно связать библиотеки с помощью 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)
Ответ 7
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)
Ответ 8
Вы также можете вставить исходный репозиторий 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
, возможно, раньше.)
Ответ 9
Выделим шаги, как я смог в конечном итоге сделать это с помощью модуля FindSDL2.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)
После этого запуск 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})
Надеюсь, это поможет кому-то в ближайшем будущем.
Ответ 10
С скомпилированной версией SDL2-2.0.9 с MinGW-w64 в Windows у меня работает следующая конфигурация:
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
, что означает, что нам не нужно вручную указывать include_directories
для SDL2.
Но только при добавлении SDL2::SDL2main
и SDL2::SDL2
, как target_link_libraries
недостаточно. Компилятор g++ может жаловаться на "неопределенную ссылку на" WinMain "".
-lmingw32
параметры компилятора, я обнаружил, что библиотеки -lmingw32
добавляются до -lmingw32
. Чтобы опция -lmingw32
появилась перед библиотеками SDL2, мы также должны указать mingw32
в качестве первого target_link_libraries
. Который заставит эту конфигурацию работать.
Команда, которую я использовал для его построения:
$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .
Единственная небольшая проблема здесь в окончательно сгенерированных опциях компилятора, опция -lmingw32
дублируется. Но поскольку это не влияет на процесс компоновки, я пока проигнорировал это.