グラフィック系のライブラリを用いたC言語のプログラムをコンパイルする際のCMakeLists.txtの記述について(gccのコマンド付き)

グラフィック系のライブラリを用いたC言語のプログラムをコンパイルする際のCMakeLists.txt(CMakeのコンパイル設定ファイル)の記述についてまとめてみます(gccでコンパイルするという人にも役立つ記事となっております)。

#検証環境
以下の環境にて検証を行っております。

* [Ubuntu](https://ubuntulinux.jp/) 14.04 LTS<br>
  * CMake 2.8
  * [CLion](https://www.jetbrains.com/clion/) 1.0.3(CMake 3.2 使用)

#X Window System(X11) (+Xpm)を使用する場合
##gccのコマンド

|パターン|コマンド|
|:-----------:|:------------:|
| X Window System(X11)のみ | `gcc -Wall -o <実行ファイル名> <ソースファイル名> -lX11` |
| X Window System(X11) + Xpm | `gcc -Wall -o <実行ファイル名> <ソースファイル名> -lX11 -lXpm` |

##CMakeLists.txtの記述
###全体の記述

|CMakeLists.txtの記述|内容|
|:-----------:|:------------:|
|`find_package(X11)`|X Window System(X11)のパッケージを参照します。|

###コンパイル対象ごとの記述

|CMakeLists.txtの記述|gccのオプション|内容|
|:-----------:|:------------:|:------------:|
|`add_executable(<実行ファイル名> <ソースファイル名>)`|`-o <実行ファイル名> <ソースファイル名>`|実行ファイル名とソースファイル名の対応関係を登録します。|
|`target_link_libraries(<実行ファイル名> Xpm)`|`-lXpm`|実行ファイルとXpmのライブラリをリンクさせます__(Xpmを使用する場合のみ)__。|
|`target_link_libraries(<実行ファイル名> ${X11_LIBRARIES})`|`-lX11`|実行ファイルとX Window System(X11)のライブラリをリンクさせます。|

##余談
* Xpmを[Ubuntu](https://ubuntulinux.jp/)で使う場合、`sudo apt-get install libxpm-dev`でライブラリをインストールせねばなりません。
* Xpmを使用する場合、`X11/xpm.h`をインクルードしておけば、(`X11/Xlib.h`等のインクルードなしで、)X Window System(X11)の関数を使用することができます。

#GTK2を使用する場合
##gccのコマンド
gccでコンパイルする際には、どちらのパターンでも構いませんが、この記事では、パターン1の記述を元に説明していきます。

|パターン|コマンド|
|:-----------:|:-----------:|
|1|`gcc -Wall -o <実行ファイル名> <ソースファイル名> $(pkg-config --cflags gtk+-2.0) $(pkg-config --libs gtk+-2.0)`|
|2|`gcc -Wall -o <実行ファイル名> <ソースファイル名> $(pkg-config --cflags --libs gtk+-2.0)`|

##CMakeLists.txtの記述
###全体の記述

|CMakeLists.txtの記述|gccのオプション|内容|
|:-----------:|:------------:|:------------:|
|`find_package(GTK2)`||GTK2のパッケージを参照します。|
|`include_directories(${GTK2_INCLUDE_DIRS})`|`$(pkg-config --cflags gtk+-2.0)`|GTK2のインクルードパスを指定します。|

###コンパイル対象ごとの記述

|CMakeLists.txtの記述|gccのオプション|内容|
|:-----------:|:------------:|:------------:|
|`add_executable(<実行ファイル名> <ソースファイル名>)`|`-o <実行ファイル名> <ソースファイル名>`|実行ファイル名とソースファイル名の対応関係を登録します。|
|`target_link_libraries(<実行ファイル名> ${GTK2_LIBRARIES})`|`$(pkg-config --libs gtk+-2.0)`|実行ファイルとGTK2のライブラリをリンクさせます。|

#math.h や tgmath.hを使用する場合
##gccのコマンド

|コマンド|
|:-----------:|
|`gcc -Wall -o <実行ファイル名> <ソースファイル名> -lm`|

##CMakeLists.txtの記述
###コンパイル対象ごとの記述

|CMakeLists.txtの記述|gccのオプション|内容|
|:-----------:|:------------:|:------------:|
|`add_executable(<実行ファイル名> <ソースファイル名>)`|`-o <実行ファイル名> <ソースファイル名>`|実行ファイル名とソースファイル名の対応関係を登録します。|
|`target_link_libraries(<実行ファイル名> m)`|`-lm`|実行ファイルとmath.h や tgmath.hのライブラリをリンクさせます。|

##余談
* tgmath.hは、C99で定められた計算用ライブラリで、インクルードすると、math.h と complex.hも同時にインクルードされます。<br>複素数も扱えるようになるという画期的なライブラリですが、扱い方が少々難しい印象があります......。

#OpenGL + glutを使用する場合
##gccのコマンド

|パターン|コマンド|
|:-----------:|:-----------:|
|(`glut`で始まる関数を除く)`glu`で始まる関数が使われていない|`gcc -Wall -o <実行ファイル名> <ソースファイル名> -lGL -lglut`|
|(`glut`で始まる関数を除く)`glu`で始まる関数が使われている|`gcc -Wall -o <実行ファイル名> <ソースファイル名> -lGL -lGLU -lglut`|

##CMakeLists.txtの記述
###全体の記述

|CMakeLists.txtの記述|内容|
|:-----------:|:------------:|
|`find_package(GLUT)`|glutのパッケージを参照します。|
|`find_package(OpenGL)`|OpenGLのパッケージを参照します。|

###コンパイル対象ごとの記述

|CMakeLists.txtの記述|gccのオプション|内容|
|:-----------:|:------------:|:------------:|
|`add_executable(<実行ファイル名> <ソースファイル名>)`|`-o <実行ファイル名> <ソースファイル名>`|実行ファイル名とソースファイル名の対応関係を登録します。|
|`target_link_libraries(<実行ファイル名> ${GLUT_LIBRARY})`|`-lglut`|実行ファイルとglutのライブラリをリンクさせます。|
|`target_link_libraries(<実行ファイル名> ${OPENGL_LIBRARY})`|`-lGL -lGLU`|実行ファイルとOpenGLのライブラリをリンクさせます。|

##余談
* OpenGL + glutを[Ubuntu](https://ubuntulinux.jp/)で使う場合、`sudo apt-get install freeglut3-dev libglew-dev libxmu-dev`でライブラリをインストールせねばなりません。
* Linux上でOpenGLを動かすと、処理が遅くなる問題があるようです(参照：[Ubuntu の OpenGLの速度の問題(他のOSとの画像生成の速度比較) - 田中法博ゼミナール(長野大学 企業情報学部)](http://wwws.nagano.ac.jp/circle/tanaka/2010/09/ubuntu-openglos.html),[一部のUbuntu環境ではNVIDIAのグラフィックカードの性能を引き出せない | スラド Linux](http://wwws.nagano.ac.jp/circle/tanaka/2010/09/ubuntu-openglos.html))。

#これらを記述したCMakeLists.txtの例
__プロジェクトCG__というC言語のプロジェクトがあり、その中に以下のコンパイル対象があるとします。

|実行ファイル名|ソースファイル名|内容|
|:-----------:|:------------:|:------------:|
|CG1|CG1.c|X Window System(X11) + Xpm使用。|
|CG2|CG2.c|GTK2 と math.h使用。|
|CG3|CG3.c|OpenGL + glut使用。|

その際、CMakeLists.txtは次のようになります。

```CMakeLists.txt
cmake_minimum_required(VERSION 2.8) #実行できるCMakeのバージョンをver 2.8以降に設定
project(CG C) #プロジェクトCGをC言語のプロジェクトとして生成(Cと書かないと、C++のプロジェクトになります)

add_definitions(-Wall) #警告を全て表示するように設定
find_package(X11)
find_package(GTK2)
find_package(GLUT)
find_package(OpenGL) 
include_directories(${GTK2_INCLUDE_DIRS})

#実行ファイルCG1(X Window System(X11) + Xpm使用)
add_executable(CG1 CG1.c)
target_link_libraries(CG1 Xpm)
target_link_libraries(CG1 ${X11_LIBRARIES})

#実行ファイルCG2(GTK2 と math.h使用)
add_executable(CG2 CG2.c)
target_link_libraries(CG2 m)
target_link_libraries(CG2 ${GTK2_LIBRARIES})

#実行ファイルCG3(OpenGL + glut使用)
add_executable(CG3 CG3.c)
target_link_libraries(CG3 ${GLUT_LIBRARY})
target_link_libraries(CG3 ${OPENGL_LIBRARY})
```

#関連記事
* [C言語 - X Window System(X11)のプログラムを正常に終了させる方法 - Qiita](http://qiita.com/SUZUKI_Masaya/items/e73791e20d78be640729)