最近在使用Premake4進(jìn)行項(xiàng)目配置生成makefile之類。
比較而言,Premake4比cmake還是感覺(jué)簡(jiǎn)單一點(diǎn),至少lua語(yǔ)法簡(jiǎn)單,premake4的配置文件比較簡(jiǎn)單易讀,而cmake的配置文件就比較復(fù)雜,而且又是自己定義的一套東西,用起來(lái)實(shí)在比較煩。
Premake4還有一個(gè)比較好用的特性,可以直接用 **/*.cpp 指定項(xiàng)目包含所有目錄下的cpp文件,而不用單個(gè)指定。這樣每次增加一個(gè)文件不用老等編譯了才想起來(lái)忘記了增加文件到配置中。算是給懶人的一個(gè)福利吧。
當(dāng)然,Premake4也有自己的缺陷,目前還不支持自定義規(guī)則,所以如果項(xiàng)目中有用到什么自動(dòng)生成源文件的特性就比較麻煩了,比如這次說(shuō)到的protobuf要用protoc編譯.proto文件生成.pb.cc和.pb.h文件,另外QT也有類似的需求,就我之前某項(xiàng)目中,也使用了tolua++生成過(guò)c++的lua接口文件。
但是,Premake4雖然還不支持自定義規(guī)則,但是總算有一個(gè)prebuildcommands可以用,于是研究了一下,自制了一個(gè).proto文件的"編譯規(guī)則":
function protobufs(pat)
local list = {}
if type(pat) == "string" then
list[1] = pat;
elseif type(pat) == "table" then
list = pat;
end
local proj = project();
for _,pat in ipairs(list) do
local protofiles = os.matchfiles(pat);
for _,protofile in ipairs(protofiles) do
local basename = path.getbasename(protofile);
local sourcedir = proj.basedir.."/"..path.getdirectory(protofile);
local sourcefile = proj.basedir.."/"..protofile;
local targetdir = "$(OBJDIR)/proto/"..path.getdirectory(protofile);
local targetfile = targetdir.."/"..basename..".pb.cc";
prebuildcommands {
"@mkdir -p "..targetdir,
"@test "..sourcefile.." \\\n"
.."\t\t\t -ot "..targetfile.." || \\\n"
.."\t\t( echo protoc "..protofile.." && \\\n"
.."\t\tprotoc --cpp_out "..targetdir.."\\\n"
.."\t\t\t"..sourcefile.."\\\n"
.."\t\t\t".." -I"..sourcedir.." ) \\\n"
}
files {
path.join(targetdir, basename..".pb.h"),
path.join(targetdir, basename..".pb.cc"),
}
includedirs { targetdir }
end
end
end
使用方法呢,就是把上面的代碼保存到protobuf.lua里面,然后在premake4.lua最開(kāi)始的時(shí)候,調(diào)用
dofile "protobuf.lua"
然后在項(xiàng)目定義的時(shí)候,使用
protobufs { "**/*.proto" }
就可以了。
?
當(dāng)然,還有一點(diǎn)要注意的,我的系統(tǒng)是mac,但腳本在linux下應(yīng)該也能同樣運(yùn)行,但是windows下面的話,可能就需要做一點(diǎn)改動(dòng)了。