Premake5の拡張
📌 はじめに
Premakeは定義ファイルからVisualStudioやXcodeなどのプロジェクトファイルを生成するコマンドラインツールです.最新版は premake5
です.開発規模が大きくなってくると取り扱うファイルも増え,追加忘れやソリューション上のフォルダ構成がエクスプローラ上と違うとか,カスタムビルドを設定するものが多いと非常に面倒です.また,ソリューション構成やターゲットが増えるほど管理が大変になり,定義ファイル上で手軽に変更できるのはPremake
の良いところだと思います.とはいえ,実際に実務で使う場合には拡張が必須だと思います.ここでは,Premake
自体のビルドと拡張,あとは定義ファイルについて少し書いておこうと思います.備忘録的な内容となっています.また環境はWindowsです.
📌 Premake
公式は以下です.
📌 ドキュメント
📌 はじめてのpremake
まずは以下を参照することをオススメします.
📌 拡張について
以下が参考になります.
📌 Premake のビルド
以下からフォークやクローンします.
ビルドの方法については BUILD.txt
に書いてあります.Windowsの場合はVisualStudioのコマンドプロンプト上で次のコマンドを実行します.
nmake -f Bootstrap.mak windows
Visual Studio のコマンドプロンプトはスタートメニューから開くか,次のようなバッチファイルを用意すると比較的楽です.
@echo off
set VSPROMPT_2015="%VS140COMNTOOLS%vsvars32.bat"
set VSPROMPT_2017="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat"
set VSPROMPT_2017C="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
set VSPROMPT_2019="C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
set VSPROMPT_2019C="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
set VSPROMPT=
if exist %VSPROMPT_2015% (
echo found %VSPROMPT_2015%
set VSPROMPT=%VSPROMPT_2015%
)
if exist %VSPROMPT_2017C% (
echo found %VSPROMPT_2017C%
set VSPROMPT=%VSPROMPT_2017C%
)
if exist %VSPROMPT_2017% (
echo found %VSPROMPT_2017%
set VSPROMPT=%VSPROMPT_2017%
)
if exist %VSPROMPT_2019C% (
echo found %VSPROMPT_2019C%
set VSPROMPT=%VSPROMPT_2019C%
)
if exist %VSPROMPT_2019% (
echo found %VSPROMPT_2019%
set VSPROMPT=%VSPROMPT_2019%
)
call %VSPROMPT%
Visual Studio 2017 から VS14XCOMNTOOLS
といった環境変数がなくなっています.
このバッチファイルは以下のVisual Studio に対応しています.
- Visual Studio 2015 (v140)
- Visual Studio 2017 Community (v141)
- Visual Studio 2017 Professional (v141)
- Visual Studio 2019 Community (v142)
- Visual Studio 2019 Professional (v142)
例えば,vscmd.bat
という名前でバッチファイルを作成したとすれば通常のコマンドプロンプトで
vscmd.bat
nmake -f Bootstrap.mak windows
とします.これで bin/release/premake5.exe
が出来上がります.premake の定義ファイルは Lua ファイルで,premake内でも Lua スクリプトを使って処理しています.以下のコマンドを実行すると Lua スクリプトを premake5.exe
に埋め込みます.
.\bin\release\premake5 embed
devenv .\build\bootstrap\premake5.sln /Build Release
これは premake
を使ってプロジェクトファイルを作成して,そのプロジェクトファイルを使ってビルドすると Lua スクリプトが埋め込まれた premake
が出来上がるという面白い仕組みになっています.
📌 拡張
ここでは新しくプロパティシートを追加する importprops
関数を追加します.premake は Lua スクリプトで処理しているので,Luaファイルを変更します.基本的に新しい関数の定義は src/_premake_init.lua
で api.register
で登録します.
api.register {
name = "importprops",
scope = "config",
kind = "list:path",
tokens = true
}
次に,実装です.Visual Studio の処理は主に modules/vstudio/vs2010_vcxproj.lua
にあります.プロパティシート関連は m.propertySheets()
の部分です.
function m.propertySheets(cfg)
p.push('<ImportGroup Label="PropertySheets" %s>', m.condition(cfg))
p.w('<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists(\'$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\')" Label="LocalAppDataPlatform" />')
p.pop('</ImportGroup>')
end
ここに,今回 importprops
の処理を追加します.
function m.propertySheets(cfg)
p.push('<ImportGroup Label="PropertySheets" %s>', m.condition(cfg))
p.w('<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists(\'$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\')" Label="LocalAppDataPlatform" />')
if cfg.importprops and #cfg.importprops > 0 then
for i = 1, #cfg.importprops do
local prop = project.getrelative(cfg.project, cfg.importprops[i])
p.w('<Import Project="%s" />', prop);
end
end
p.pop('</ImportGroup>')
end
これで実装は完了です.Luaスクリプトを更新したので,以下のコマンドで再ビルドします.
.\bin\release\premake5 embed
devenv .\build\bootstrap\premake5.sln /Build Release
これで importprops
が使えます.
使用例
filter { "platforms:x64", "configurations:Debug" }
importprops "props/Debug_x64.props"
リポジトリ
importprops
を追加した premake
のリポジトリは以下です.
vscmd.bat
や build.bat
, make.bat
を追加しています.
make.bat
@echo off
call vscmd.bat
nmake -f Bootstrap.mak windows
pause
build.bat
@echo off
call vscmd.bat
.\bin\release\premake5 embed
devenv .\build\bootstrap\premake5.sln /Build Release
pause
📌 Tips
OR
filter { "platforms:x64", "configurations:Debug or Release" }
...
外部プロジェクト
externalproject "Hoge"
location <Hoge.vcxprojがある場所>
kind "StaticLib"
language "C++"
グループ
フォルダを追加します.
group "libs"
externalproject "Hoge"
location "hoge.vcxproj"
kind "StaticLib"
language "C++"
依存関係
プロジェクト Foo
がライブラリ Hoge
に依存している場合
project "Foo"
links { "Hoge" }
group "libs"
externalproject "Hoge"
location <Hoge.vcxprojがある場所>
kind "StaticLib"
language "C++"
共有DLLを使わない
project "Foo"
flags { staticruntime "On" }
プリコンパイル済みヘッダー
project "Foo"
pchheader "stdafx.h"
pchsource "stdafx.cpp"
Discussion