MakefileからCMakeLists.txtへ移植メモ


Linuxで動かしていたMakefileをWindowsでも使えるようにCMake対応したときのメモ

<!--
##CMakeLists.txtが生成するMakefileの基本的な構造
```
  (1.変数の設定)
-------------------
  (2.ターゲットと実行)
```
-->

cmakeを実行すると、
Linuxの場合、Makefileが生成され、
Windowの場合、Projectファイルが生成される。

#1.変数の設定を置き換える

```diff:
- CC = gcc
- CXX = g++
⇑デフォルトコンパイラが自動的に設定されるので削除する
⇓デフォルトコンパイラから変更する場合
+ set(CMAKE_C_COMPILER   ◯◯◯  ...      )
+ set(CMAKE_CXX_COMPILER ◯◯◯  ...      )
```

```diff:
- INCDIR=./include
+ set(INCDIR ./include)
```

正規表現で置換する場合は以下のようにする。

```:
^ ⇒ set(
= ⇒ 
$ ⇒ )
```

###文字列を加える
```diff:
- INCDIR+=/usr/include /usr/local/include
+ set(INCDIR ${INCDIR} /usr/include /usr/local/include)
```


###パスが違うとき
```diff:
- HOGE=/usr/local/hoge
+ if(WIN32)
+   set(HOGE C:/Foo/hoge)
+ else()
+   set(HOGE /usr/local/hoge)
+ endif()
```

###オプション -I ⇒ include_directories()
```diff:
- -I$(INCDIR)
+ include_directories(${INCDIR})
```

###オプション -L ⇒ link_directories()
```diff:
- -L$(LIBDIR)
+ link_directories(${LIBDIR})
```
###オプション -l ⇒ target_link_libraries()
```diff:
- -l$(LIBS)
+ target_link_libraries(${PROJECT_NAME} ${LIBS})
```
add_executableの後に記述する。


###CXXFLAGS = -std=c++11 -Wall
```diff:
- CXXFLAGS = -std=c++11 -Wall
+ set(CMAKE_CXX_FLAGS -std=c++11 -Wall)
```

###アスタリスクで複数のファイル指定をする場合
```diff
- HEADERS += $(INCDIR)/*.h
+ file(GLOB HEADERS ${INCDIR}/*.h)
```

<!--
target_include_directories
target_link_libraries
-->



#2.ターゲットと実行を置き換える
```diff:
- HOGE: hoge.o
+ add_executable(HOGE hoge.cpp)
```
※オブジェクトファイル関連は削除します。

ここまでやったら、とりあえずビルドしてエラーログに従う。
##ビルドコマンド
###Linux
```:Terminal
$ mkdir build
$ cd build
$ cmake ..
$ make
```

###Windows
```:Powershell
> mkdir build
> cd build
> cmake ..
> cmake --build . --target ALL_BUILD --config Release -- /nologo /verbosity:minimal
```

Visual Studioのバージョンを指定する場合

```
cmake -G"Visual Studio 14" ..
```



|ビルド番号|年式|
|:--|:--|
|Visual Studio 12|2013|
|Visual Studio 14|2015|
|Visual Studio 15|2017|
|Visual Studio 16|2019|

<!--
⇓MS Buildを使う場合
> 
> msbuild /P:Configuration=Release

msbuildが見つからない場合は環境変数を登録してください。

2015年以前
C:\Windows\Microsoft.NET\Framework\3.5\MSBuild.exe
                                   ~~~(環境依存)


2017年以降
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe
                                               ~~~~                      ~~~~

⇓登録したくない場合

例1
> $msbuild = 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe'
> $msbuild  ◯◯◯.vcxproj /P:Configuration=Release

例2
> $msbuild = 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe'
> $msbuild  ◯◯◯.vcxproj /P:Configuration=Release

-->



##エラー解消
###デバッグの基本
変数の中身表示する

```
message("HOGE" ${HOGE})
```
##記法を修正
>Parse error.  Expected "(", got newline with text

```diff
- $(変数名)
+ ${変数名}
```
ファイルが見つからない
>Cannot find source file

```diff:
- ./
+ ${PROJECT_SOURCE_DIR}/

```
>現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐ ために、ファイルを Unicode 形式で保存してください。

ソースコードをutf-8として読み込ませるために追加。

```
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
```

>LINK : fatal error LNK1104: ファイル〇〇〇.libを開くことができません。

##適切なパスを指定

```
target_link_libraries(△△△ 〇〇〇.lib)
```
を追加。△△△はターゲットファイル名。
なお、ライブラリディレクトリはtarget_link_directoriesではなく、

```
link_directories()
```
で追加することができる。

##リンクエラーを修正

><font color="Red"> error LNK2038: 'RuntimeLibrary' の不一致が検出されました。値 'MT_StaticRelease' が MD_DynamicRelease の値</font>

↑長々と上記のエラーが表示される場合は

```
if(MSVC)
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_DEBUG            ${CMAKE_C_FLAGS_DEBUG})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_MINSIZEREL       ${CMAKE_C_FLAGS_MINSIZEREL})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE          ${CMAKE_C_FLAGS_RELEASE})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO   ${CMAKE_C_FLAGS_RELWITHDEBINFO})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG          ${CMAKE_CXX_FLAGS_DEBUG})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_MINSIZEREL     ${CMAKE_CXX_FLAGS_MINSIZEREL})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE        ${CMAKE_CXX_FLAGS_RELEASE})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
endif(MSVC)
```
を最上位のCMakeLists.txtへ追加する。

##参考
https://qiita.com/nullpo24/items/716bad137f1264b776f5