CMake 2.8.10 における個人的なメモです。まだ慣れていないので誤りがあるかもしれません。随時追加していくので書きかけの部分があります。
CMake 変数
変数名 | 内容 | 展開 | 外部コマンド |
---|---|---|---|
CMAKE_SYSTEM |
システム名(フル) | Darwin-10.8.0 | uname -a |
CMAKE_SYSTEM_NAME |
システム名 | Darwin | uname -n |
CMAKE_SYSTEM_VERSION |
システムバージョン | 10.8.0 | uname -r |
CMAKE_SYSTEM_PROCESSOR |
システムプロセッサー | i386 | uname -p |
同様に CMAKE_HOST_SYSTEM_*
という変数もある。
変数名 | 内容 | 例 |
---|---|---|
CMAKE_<LANG>_COMPILER_ABI |
コンパイラの ABI(?) | 空 |
CMAKE_<LANG>_COMPILER_ID |
コンパイラのベンダー名 | GNU |
CMAKE_<LANG>_COMPILER_VERSION |
コンパイラのバージョン | 4.2.1 |
CMAKE_<LANG>_FLAGS_DEBUG CMAKE_<LANG>_FLAGS_RELEASE CMAKE_<LANG>_FLAGS_MINSIZEREL CMAKE_<LANG>_FLAGS_RELWITHDEBINFO |
コンフィグレーション別のフラグ設定 | -O3 -DNDEBUG |
CMAKE_INTERNAL_PLATFORM_ABI |
システムの ABI(?) | 空 |
CMAKE_LIBRARY_ARCHITECTURE |
ターゲットアーキテクチャのライブラリディレクトリ名。 |
変数名 | 内容 | 例 |
---|---|---|
CMAKE_OSX_SYSROOT |
多分、CMAKE_XCODE_SELECT によって自動検出される。定義すればコンパイラフラグ -isysroot [sdk path] などが追加される。Xcode 4.3 以降ではどうなるか不明。 |
/Developer/SDKs/MacOSX10.6.sdk |
CMAKE_OSX_ARCHITECTURES |
定義すればコンパイラフラグに -arch [arch] が追加される。複数の場合は値をセミコロンで区切る。 |
x86_64 |
CMAKE_OSX_DEPLOYMENT_TARGET |
定義すればコンパイラフラグに -mmacosx-version-min=[version] が追加される。 |
10.6 |
基本的な CMake コマンド
file()
ファイル操作を行うコマンド。
サブコマンド | 動作 |
---|---|
file(WRITE ファイル名 "文字列") |
文字列をファイルに出力します。(新規または上書き) |
file(APPEND ファイル名 "文字列") |
文字列をファイルに出力します。(追記) |
file(STRINGS ファイル名 変数) |
ファイルの内容を取得します。 |
file(GLOB 変数 [相対パス] [パターン]) |
相対パスまたはパターンのファイルまたはディレクトリを検索して変数(リスト)に出力します。 |
file(GLOB_RECURSE 変数 [相対パス] [パターン]) |
相対パスまたはパターンのファイルまたはディレクトリを再帰的に検索して変数(リスト)に出力します。 |
file(RENAME 旧ファイル名 新ファイル名) |
旧ファイル名から新ファイル名にリネーム(ムーブ)します。 |
file(REMOVE ファイル1 ファイル2 …) |
ファイルを削除します。 |
file(REMOVE_RECURSE ファイル1 ファイル2 …) |
ファイルまたはディレクトリを再帰的に削除します。 |
file(MAKE_DIRECTORY ディレクトリ1 ディレクトリ2 …) |
ディレクトリを作成します。 |
少し特殊な file(COPY)
と file(INSTALL)
もあります。前者はステータス表示なし、後者はステータス表示ありです。ファイルには複数のファイルを指定できます(リストでの指定も可)。install()
は make install
時に動作しますが、file(INSTALL)
は CMake コマンド実行時に動作します。
file(COPY ファイル DESTINATION ディレクトリ [FILE_PERMISSIONS パーミッション] [DIRECTORY_PERMISSIONS パーミッション] [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS] [FILES_MATCHING] [PATTERN パターン] [EXCLUDE] [REGEX 正規表現] [EXCLUDE] [PERMISSIONS パーミッション] )
PATTERN
は複数指定可能ですが、1回の PATTERN
に対して指定できるパターンは1種類なので複数のパターンを指定したい場合は都度 PATTERN
を使用することになります。EXCLUDE
はその前にあるパターンもしくは正規表現に該当するファイルを除外します。
パーミッションの種類
install()
や file(COPY|INSTALL)
で使用します。ユーザー_権限
という書式で、例えば所有者対して実行を許可する場合は OWNER_EXECUTE
になります。
- ユーザー:
OWNER
、GROUP
、WORLD
- 権限:
READ
、WRITE
、EXECUTE
外部コマンドの実行 execute_process()
外部コマンドの出力結果を変数に入れたいときなどに使う。
http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command:execute_process
書式
execute_process (COMMAND コマンド1 COMMAND コマンド2 OUTPUT_VARIABLE 変数名 OUTPUT_STRIP_TRAILING_WHITESPACE)
COMMAND
は複数指定可能。これらはパイプで繋がれるようになっている。複数のコマンドを別に実行(sh で言う ;
を使う場合)することは恐らくできないので execute_process()
で追加する。CMake コマンド部分では改行することも可能。OUTPUT_STRIP_TRAILING_WHITESPACE
は最後の改行を取り除く。OUTPUT_VARIABLE
以外にもエラーコードを格納する変数や入出力ファイルの指定なども可能。
シングルクオートはシンタックスエラーになる可能性がある。また、CMake コマンド用のバックスラッシュと外部コマンド用のバックスラッシュが混在するので外部コマンド用のバックスラッシュは \\
になる。
例えば otool
と awk
を併用し、実行ファイルのリンクを変数に配列(リスト)として登録する場合は以下、以下のような方法が考えられる。
execute_process ( COMMAND otool -L ${EXECUTABLE} # awk の正規表現のバックスラッシュは「\」ではなく「\\」になる COMMAND awk "NR >= 2 && $1 !~ /(\\/usr\\/lib|\\/System|@executable_path)\\// { printf \"%s;\", $1 }" OUTPUT_VARIABLE FOO # ↑この時点では「var1;var2;var3;(var4)」という状態になっていて、「var4」は空の状態 ) # list (REMOVE_ITEM <list> <value>) で空の要素を取り除く list (REMOVE_ITEM FOO "") # 最後の要素だけであれば list(REMOVE_AT <list> <index>) でも取り除くことができる #list (REMOVE_AT FOO -1) # 再度変数にセットして「ver4」を取り除いてもいいかもしれない #set (FOO ${FOO})
awk
の出力をもう少しまともに書けば空の要素を取り除く作業は必要ないと思う。list(REMOVE_ITEM)
と list(REMOVE_AT)
の違いは前者が値による削除、後者がインデックスによる削除。
※作業状態によっては「空の要素が含まれるリストは作成できない」といったポリシー違反が発生するのでセミコロンの位置を前に移して cut
カットコマンドなどで削除する必要があるかもしれません。
ループ foreach() … endforeach()
http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command:foreach
書式
# パターン1 foreach(ループ変数 引数1 引数2) コマンド1 コマンド2 endforeach(ループ変数) # パターン2 foreach(ループ変数 ${リスト}) コマンド1 コマンド2 endforeach(ループ変数) # パターン3 foreach(ループ変数 IN LISTS リスト名) コマンド1 コマンド2 endforeach(ループ変数)
リストに関しては二種類の方法があり、変数を展開して引数にする方法と純粋にリストとして渡す方法がある。前者の場合は恐らくスペースを含む要素があった場合に正しく動作しない可能性がある(試してない)。後者の場合は空の要素が含まれているとエラーになる。
CMake で Info.plist を作成する
Info.plist を手動で作成する場合、CMake のテンプレートを利用することができます。${CMAKE_ROOT}/Modules/MacOSXBundleInfo.plist.in
を使用します。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> <key>CFBundleGetInfoString</key> <string>${MACOSX_BUNDLE_INFO_STRING}</string> <key>CFBundleIconFile</key> <string>${MACOSX_BUNDLE_ICON_FILE}</string> <key>CFBundleIdentifier</key> <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleLongVersionString</key> <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> <key>CFBundleName</key> <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> <key>CSResourcesFileMapped</key> <true/> <key>LSRequiresCarbon</key> <true/> <key>NSHumanReadableCopyright</key> <string>${MACOSX_BUNDLE_COPYRIGHT}</string> </dict> </plist>
MacOSXBundleInfo.pist.in には既に変数が記述されているので呼び出し元になる CMake ファイルに以下の変数をセットしておくだけ。
- MACOSX_BUNDLE_COPYRIGHT
- MACOSX_BUNDLE_INFO_STRING
- MACOSX_BUNDLE_BUNDLE_NAME
- MACOSX_BUNDLE_GUI_IDENTIFIER
- MACOSX_BUNDLE_EXECUTABLE_NAME
- MACOSX_BUNDLE_ICON_FILE
- MACOSX_BUNDLE_BUNDLE_VERSION
- MACOSX_BUNDLE_LONG_VERSION_STRING
- MACOSX_BUNDLE_SHORT_VERSION_STRING
MACOSX_BUNDLE_SHORT_VERSION_STRING
に関しては string(SUBSTRING)
を使って MACOSX_BUNDLE_LONG_VERSION_STRING
の値から取得してもいいかもしれません。
string (SUBSTRING "${PROJECT_VERSION}" 0 3 MACOSX_BUNDLE_SHORT_VERSION_STRING)
あとは configure_file()
をかければ変数が展開されて Info.plist が作成されます。
configure_file ("${CMAKE_ROOT}/Modules/MacOSXBundleInfo.plist.in" "${BUNDLE_CONTENTS_DIR}/Info.plist")
execute_process()
で defaults
コマンドを使って出力する方法もあります。