スポンサーリンク

DxLibを使ったプログラムをcmakeでビルドする方法 ~外部ライブラリをリンクするには?~

記事内に広告が含まれています。

そしてまた、DxLibの使い方を紹介したこともありました。ですが、考えてみれば、それはcmakeをどうにゅうするまえだったとおもいます。

そのため、cmakeからDxLibを使う方法は解説したことがありませんでした。

ということで今回は、DxLibを使いたいときは、どのようなcmakeスクリプトを書けばいいかを解説します。

スポンサーリンク

この記事で作る環境

この記事では後ろの方に、CMakeLists.txtを書いていますが、そのスクリプトが正しく動作するための環境は以下の手順で作ります。

  1. DxLibをダウンロードする
  2. 以下のようなディレクトリ構造を作る
.
├───CMakeLists.txt
├───DxLib
│     └───.hファイルや.aファイル
└───src
       ├───CMakeLists.txt
       └───Main.cpp

DxLibは、公式サイトから「DXライブラリ Windows版 Gnu C++( MinGW )用」をダウンロードしてきます。そして、その中から必要なファイルだけを上記ディレクトリ構造の中のDxLibディレクトリ以下に置いておきます。

今回解説するのは、軽量化パッケージや3Dモデル機能無しパッケージではありません。あくまでも、通常版(と呼んでいいのだろうか?)を想定しています。ですが、基本的な方法は

その必要なファイルとは、「プロジェクトに追加すべきファイル_GCC(MinGW)用」の中に置かれているディレクトリの内の一つ(僕は12_1_0を選びました)の中に入っているファイルをすべてコピーします。

つまり、ディレクトリで示すと、(僕の場合は12_1_0を使うので、)「DxLib_GCC\プロジェクトに追加すべきファイル_GCC(MinGW)用\12_1_0」の中身と、上記プロジェクトの中にあるDxLibの中身が同一となるようにするということです。

後述しますが、DxLibは必ずしもプロジェクト内のディレクトリに置く必要はありません。しかし、説明に都合が良いので、今回はプロジェクト内のディレクトリにDxLibを置くことにします。

cmakeスクリプトの書き方

上の節で説明したような環境を作れたら、cmakeスクリプトを以下のように書きます。

  1. target_include_directoriesで、ヘッダファイルの置かれているディレクトリを指定する
  2. target_link_directoriesで、ライブラリの置かれているディレクトリを指定する
  3. target_link_librariesで、リンクしなければならないライブラリを指定する

ヘッダファイルは、今回の場合はDxLib以下に置くことにしたので、DxLibを指定することになります。ライブラリファイル(.aファイル)も含めて、必要なファイルはすべて、DxLibディレクトリにコピーしたことを前提していましたから、target_link_directoriesで指定するディレクトリもDxLibです。

3つ目のtarget_link_librariesでリンクしなければならないライブラリとは、公式サイトの使い方解説に記載されているライブラリ群です。

そのとき、-lを書いてはいけないことに注意する必要があります。公式サイトのものは、指定しなければならないオプションということで、-lが先頭についています。しかし、cmakeでは、-lは必要ありませんので、それを削除して、ライブラリを指定する必要があります。

cmakeスクリプトに書かなければならない関数は、基本的にはそれだけです。

また、cmakeスクリプトに限らず、プログラム一般に言えることですが、変数をどう使うかとか、どのタイミングで関数を呼び出すか、あるいは、独自関数を定義するのか、等々と考えていけば、色々な派生形態が考えられます。

しかし、基本的にはここで解説した3つのことを正しく実行出来てさえいたら、DxLibは使えます。

必要事項を確認できたので、次の節で、cmakeスクリプトの例を書いてみます。

スクリプト例

もう一度確認ですが、ディレクトリ構成は次のようになっているのでした(前々節の再掲です)。

.
├───CMakeLists.txt
├───DxLib
│     └───.hファイルや.aファイル
└───src
       ├───CMakeLists.txt
       └───Main.cpp

このDxLibディレクトリは、公式サイトからダウンロードしてきたDxLibに入っている「プロジェクトに追加すべきファイル_GCC(MinGW)用\12_1_0」の中身と、同じになっているのでした。

そして、srcDxLibを利用するMain.cppが入っています。このMain.cppは、例えば公式サイトに置かれているサンプルプログラムなどのように、DxLibを利用するプログラムです。今回はcmakeの書き方解説であって、プログラムはあまり記事のテーマに関係ないので、そのサンプルプログラムをコピペさせていただくことにします。

※何かこだわりがあるのなら、別にサンプルプログラムでなくても構いませんが、ほとんどの場合では動作確認が確実にできるようなプログラムの方が好ましいと思います。ですので、ここは公式サイトのサンプルプログラムを使うことをお勧めします。

このような構成のときは、特殊な事情が無い限りは、上記のディレクトリ構成の中に記載した通り、2つのCMakeLists.txtを書くことになると思います。それは、プロジェクトのルートに置くCMakeLists.txtと、srcの中に置くsrc/CMakeLists.txtの2つです。

ルートに置く方は特に難しいことは無いと思います。

とりあえず、

  1. cmakeの最小バージョンの指定(cmake_minimum_required※1
  2. プロジェクト名の設定(project
  3. このサブディレクトリ※2もビルドに必要だぞと伝える(add_subdirectory

※1. 例えば、cmakeのバージョンが3.12より前のバージョンでは、C++の規格を指定するcxx_std_20などが利用できません。そのため、そのスクリプトを正常に実行するのに必要なバージョンを明記した方が好ましいと、僕は思います(僕が使っているcmakeは3.25.1でしたが、最低バージョンの記載が無いと警告が表示されますし)。

※2. そのCMakeLists.txtが置かれているディレクトリの下に置かれているディレクトリのこと。今回の場合なら、例えばDxLibやsrcがサブディレクトリになります。

とりあえず、CMakeLists.txtには、これら3つの関数を書いておけば問題ないと思います(DxLibを使うだけなら)。

そしてこの記事での本題は、(src/ディレクトリ以下に配置された)src/CMakeLists.txtの方です。こちらは例えば、次のようになると思います。

src/CMakeLists.txt

# ソースファイルの名前を指定
set( SOURCE Main.cpp )

# 生成する実行ファイルの名前を指定
set( OUTPUT out )

# DxLibが置かれているディレクトリを指定
set( DXLIB_DIR ${PROJECT_SOURCE_DIR}/DxLib )

add_executable( ${OUTPUT} ${SOURCE} )

target_include_directories( ${OUTPUT} PUBLIC ${DXLIB_DIR} )
target_link_directories( ${OUTPUT} PUBLIC ${DXLIB_DIR} )

# コンパイルフラグに-DDX_GCC_COMPILEを付けてなければならないことに注意
target_compile_options( ${OUTPUT} PUBLIC
  -Wall
  -target x86_64-w64-windows-gnu
  -DDX_GCC_COMPILE )

# C++標準規格の指定( cxx_std_20はcmake3.12以降で指定可能 )
target_compile_features( ${OUTPUT} PUBLIC cxx_std_20 )

# リンクするライブラリの指定
# 公式サイトによると、この順番で指定しなければ、正しくリンクされないことがあるらしい
set( DXLIB_LIBRARY_LIST DxLib;DxUseCLib;DxDrawFunc;jpeg;png;zlib;tiff;theora_static;vorbis_static;vorbisfile_static;ogg_static;bulletdynamics;bulletcollision;bulletmath;opusfile;opus;silk_common;celt )
target_link_libraries( ${OUTPUT} PUBLIC ${DXLIB_LIBRARY_LIST} )

このCMakeLists.txtは、環境によって変わります。しかし、基本的にはディレクトリ設定を変更すれば済みます。

そのことを説明するために、次の節で、ディレクトリ構成を変えてみて、CMakeLists.txtを変更してみます。

スポンサーリンク

ディレクトリ構成を変えてみた場合

以上のようにDxLibだけでなく、他のライブラリも使おうとすると(、かつ、プロジェクト内にそのライブラリ本体を置こうとすると)、使用しているライブラリの数だけルートにディレクトリが増えていくことになります。それではルートディレクトリが見づらくなってしまいます。

ということで、ディレクトリ構成を次のように変更したとしましょう。赤字部分が、前節からの変更箇所です。

.
├───CMakeLists.txt
├───include
│     └───DxLib
│            └───.hファイル
├───lib
│     └───DxLib
│            └───.aファイル
└───src
       ├───CMakeLists.txt
       └───Main.cpp

DxLibのヘッダとライブラリファイルを、それぞれinclude/以下のDxLibディレクトリ、lib/以下のDxLibディレクトリに置くように修正しました。

これなら、新しく使うライブラリが増えて(、かつ、そのライブラリもプロジェクト内に配置する場合)も、プロジェクトのルートが見づらくなることはありません。

この場合、src/CMakeLists.txtは、例えば次のようになります。こちらも、赤字部分が変更箇所になります。

src/CMakeLists.txt

# ソースファイルの名前を指定
set( SOURCE Main.cpp )

# 生成するファイル名の指定
set( OUTPUT out )

# DxLibが置かれているディレクトリを指定
set( INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include )
set( LIB_DIR ${PROJECT_SOURCE_DIR}/lib )
set( INCLUDE_DXLIB_DIR ${INCLUDE_DIR}/DxLib )
set( LIB_DXLIB_DIR ${LIB_DIR}/DxLib )

add_executable( ${OUTPUT} ${SOURCE} )

target_include_directories( ${OUTPUT} PUBLIC ${INCLUDE_DXLIB_DIR} )
target_link_directories( ${OUTPUT} PUBLIC ${LIB_DXLIB_DIR} )

# コンパイルフラグに-DDX_GCC_COMPILEを付けてなければならない
target_compile_options( ${OUTPUT} PUBLIC
  -Wall
  -target x86_64-w64-windows-gnu
  -DDX_GCC_COMPILE )

# C++標準規格の指定( cxx_std_20はcmake3.12以降で指定可能 )
target_compile_features( ${OUTPUT} PUBLIC cxx_std_20 )

# リンクするライブラリの指定
# 公式サイトによると、この順番で指定しなければ、正しくリンクされないことがあるらしい
set( DXLIB_LIBRARY_LIST DxLib;DxUseCLib;DxDrawFunc;jpeg;png;zlib;tiff;theora_static;vorbis_static;vorbisfile_static;ogg_static;bulletdynamics;bulletcollision;bulletmath;opusfile;opus;silk_common;celt )
target_link_libraries( ${OUTPUT} PUBLIC ${DXLIB_LIBRARY_LIST} )

そんなに大きな変更は無く、ディレクトリを指定している部分が変わっただけですね。

まとめ

最終的に、環境に応じて、次のことを記述する必要があるということでした。

  1. ヘッダファイルの置かれているディレクトリの指定(target_include_directories
  2. ライブラリの置かれているディレクトリの指定(target_link_directories
  3. リンクしなければならないライブラリの指定(target_link_libraries

リンクしたいライブラリファイルが置かれているディレクトリを指定して、リンクしたいライブラリを指定するという流れですね。

もしも、ライブラリファイルの置かれているディレクトリを指定できていなかったり、リンクしたいライブラリを指定できていなかったりすると、エラーになるのでご注意ください。また、ライブラリをリンクする順番が、DxLibの使い方解説に書かれている通りでなければ、リンクエラーとなることがあるそうだとも紹介しました。

基本的には以上を守れば良いものの、そのようなcmakeスクリプトには様々なパターンが考えられるということも、お伝えしました。

その「以上を守れてさえいれば良い」ということと「cmakeスクリプトには色々な派生形態が考えられる」ということを、DxLibをひとまとめにして扱うパターン、DxLibをヘッダファイルとライブラリファイルに分けて扱うパターンの2パターンで、実際にCMakeLists.txtを書くことで解説しました。

理解しないといけないことがかなり少ないので、この記事が無くても、皆さんは普通にcmakeでDxLibを使えるような気もします。そういう意味で、この記事に需要があるのかどうか不安なので、もし役に立ったとか、役に立ちそうだと思っていただけたら、Twitterの方でいいねをするなどの方法で僕に知らせていただけると、とても有難いです(もちろん、気が向いたらで構いません)。

というわけで、DxLibを利用するプロジェクトを、cmakeでビルドできるようになりました。

これからも、もっとDxLibを使って遊んでいきたいですね。

皆さんも良いDxLib生活を~。ではでは~。

 

P.S. この記事を書いて初めて知ったんですが、cmake_minimum_required関数って、ただバージョンチェックをしてるだけじゃなくて、cmake_policyという関数も呼び出しているらしいですね。その関数は、スクリプトが、指定されたバージョンの書式に則って書かれているかを検査するらしいです(リファレンスを適当に読んだだけなので、間違っているかもしれません)。

タイトルとURLをコピーしました