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_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を使用できる場合は、その使用がより簡単になる可能性があります。 cmakeでSDL2およびSDL_imageを使用する方法
CMakeが提供するFindSDL.cmakeに似たFindSDL2.cmakeファイルを使用したほうが快適な場合は、 https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/を参照してください
メイクファイルを生成するCMakeエラーはないようです。しかし、あなたの問題は、SDLヘッダーが「SDL2」という名前のサブフォルダーにあることだと思います。
CMakeLists.txtを変更して含める
C:/SDL/SDL2-2.0.3/include/SDL2
の代わりに
C:/SDL/SDL2-2.0.3/include
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)
私が開発した 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が(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
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への未定義の参照」について不平を言っているかもしれません。
コンパイラオプションを調べると、-lmingw32
オプションの前にSDL2ライブラリが追加されていることがわかりました。 -lmingw32
オプションをSDL2ライブラリよりも前にするには、最初のmingw32
としてtarget_link_libraries
も指定する必要があります。これにより、この構成が機能します。
ビルドに使用したコマンドは次のとおりです。
$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .
ここでの唯一の小さな問題は、最終的に生成されたコンパイラオプションにあり、-lmingw32
オプションが重複しています。しかし、リンクプロセスには影響しないため、今のところ無視しました。
FindSDL2.cmakeモジュールを使用して最終的にこれを達成することができた方法のステップを強調表示します。
SET(SDL2_SEARCH_PATHS
_行を見つけ、コピーしたSDL2の開発ディレクトリを新しい行として追加します:"/Program Files (x86)/SDL2-2.0.9" # Windows
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})
_
これが近い将来誰かに役立つことを願っています。
私の答えの時までに、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 <...>
「No such file」というエラーが表示されます。つまり、cmakeは現在のパスを検索せず、今では適切に書き込む方法がわかりません。
もう1つ注意してください。cmakeはインクルードを正しく検出し、明示的に指定する必要がないため、メイクファイルでは--cflags
オプションを使用しません。
私は同じ問題を抱えていて、他の解決策はどれもうまくいきませんでした。しかし、私は最終的にこの解決策に従って動作するようになりました: ライブラリを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)