統合開発環境である xcode を使わずに、cmake を使ってプロジェクトを作成し、xcodebuild を使ってビルドを行います。これにより CMakeLists.txt さえ書けばビルドできるようになるのでプロジェクトの管理が楽になります。
当然ですが、ビルドするには正規ライセンスのmacosが必要になるのでmacが必要になります。しかしコマンドラインで完結できるようになるのでmacをsshで操作すればよくなり、macを極力触らないで良くなります。
また、このページではコマンドが長く読みづらいため改行を入れています。実際に使うときは1行にするかバックスラッシュを使ってください。
iOS向けのプロジェクトはあくまでもXcodeプロジェクトという扱いであり、mac向けのプロジェクトと基本は同じ使い方になります。また、cmake ios で検索をすると ios.toolchain を使ったサンプルを見かけますが実際にはツールチェインは使う必要はなくcmake単体でプロジェクトの生成ができます。
cmake .. -G Xcode
-DCMAKE_MACOSX_BUNDLE=YES
-DCMAKE_SYSTEM_NAME=iOS
-DCMAKE_OSX_SYSROOT=iphoneos
-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=チームID
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0
名前 | 値 | 意味 |
---|---|---|
CMAKE_OSX_SYSROOT | iphoneos | iOS向けのSDKを使う |
CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM | 開発アカウントのチームID | |
CMAKE_OSX_DEPLOYMENT_TARGET | 11.0など | デプロイターゲットバージョン |
cmake_minimum_required(VERSION 3.10.2)
project(myappli)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
if (APPLE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE INTERNAL "" FORCE)
# $(OTHER_CFLAGS) は Xcodeのデフォルトのコンパイルオプションを
# 引き継ぐための文字列です。
# -x objective-c++ は .cpp を Objective-C++として扱う
set(CMAKE_CXX_FLAGS
"$(OTHER_CFLAGS) ${CMAKE_CXX_FLAGS} -x objective-c++")
# オープンソースのサブプロジェクトを使うときに問題になりやすいので
# BitcodeはOFFにします。
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE
"NO" CACHE INTERNAL "")
# resourcesフォルダのファイルとフォルダを列挙し
# 結果をRESOURCE_FILESに格納する
file(GLOB RESOURCE_FILES "../resources/*")
add_executable(
myappli MACOSX_BUNDLE
src/main.cpp # -x objective-c++ で .mm として扱われる
${RESOURCE_FILES} # リソースも実行ファイルに追加する
)
set_target_properties(
myappli PROPERTIES
MACOSX_BUNDLE TRUE
OUTPUT_NAME myappli
MACOSX_BUNDLE_GUI_IDENTIFIER "バンドルID"
MACOSX_BUNDLE_LONG_VERSION_STRING "1"
MACOSX_BUNDLE_SHORT_VERSION_STRING "1"
MACOSX_BUNDLE_BUNDLE_VERSION 1
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
# RESOURCE_FILESにRESOURCEプロパティをつけると
# アプリ内でリソースとして扱われる。
RESOURCE "${RESOURCE_FILES}"
)
endif() # APPLE
以下のパラメータはiOS向けのビルド時に必須となるパラメータです。これらのパラメータが無いと正しい環境設定がされないのでキャッシュに入れてグローバル変数にしておくと良い。
set(CMAKE_MACOSX_BUNDLE YES CACHE INTERNAL "" FORCE)
set(CMAKE_SYSTEM_NAME iOS CACHE INTERNAL "" FORCE)
set(CMAKE_OSX_SYSROOT "iphoneos" CACHE INTERNAL "" FORCE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE INTERNAL "" FORCE)
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0などのターゲット" CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "チームID" CACHE STRING "" FORCE)
oggをビルドしていたら "No 16 bit type found on this platform!" というエラーが出た。CMAKE_TRY_COMPILE_TARGET_TYPEにSTATIC_LIBRARYを指定しておくと良い。そうしないとcmakeの不具合なのかConfigure時にinclude pathなど正しいコンパイラオプションが渡されないためstdint.hなどが見つけれずConfigureが失敗する。
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE INTERNAL "" FORCE)
ipaファイルを作る場合は後述のアーカイブを行うため通常はビルドを単体で行うことはありませんが、コンパイルが通るかだけのテストなどで使うこともできます。
xcodebuild
-allowProvisioningUpdates
-project myappli.xcodeproj
-sdk iphoneos
-scheme myappli
ipaファイルを作るには「アーカイブ」→「エクスポート」の順に行う必要があります。また、アーカイブは必ずクリーンな環境でビルドされるためcleanを行う必要はありません。
そのため、ビルドとほぼほぼ同じコマンドライン引数が必要になります。これにより「tmp.xcarchive」フォルダにアーカイブデータが作成されます。
xcodebuild
-allowProvisioningUpdates
-project myappli.xcodeproj
-sdk iphoneos
-scheme myappli
-archivePath tmp.xcarchive
archive
先のアーカイブデータを使いipaファイルをエクスポートします。その際に後述の adhoc.plist が必要になります。
xcodebuild
-exportArchive
-archivePath tmp.xcarchive
-exportPath myappli.adhoc
-exportOptionsPlist ../adhoc.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC
"-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<true/>
<key>method</key>
<string>ad-hoc</string>
<key>signingStyle</key>
<string>automatic</string>
</dict>
</plist>
cmakeのソースコードは cmake/Sources/cmGlobalXCodeProject.cpp が担当ソースになっています。