最近在使用Premake4进行项目配置生成makefile之类。
比较而言,Premake4比cmake还是感觉简单一点,至少lua语法简单,premake4的配置文件比较简单易读,而cmake的配置文件就比较复杂,而且又是自己定义的一套东西,用起来实在比较烦。
Premake4还有一个比较好用的特性,可以直接用 **/*.cpp 指定项目包含所有目录下的cpp文件,而不用单个指定。这样每次增加一个文件不用老等编译了才想起来忘记了增加文件到配置中。算是给懒人的一个福利吧。
当然,Premake4也有自己的缺陷,目前还不支持自定义规则,所以如果项目中有用到什么自动生成源文件的特性就比较麻烦了,比如这次说到的protobuf要用protoc编译.proto文件生成.pb.cc和.pb.h文件,另外QT也有类似的需求,就我之前某项目中,也使用了tolua++生成过c++的lua接口文件。
但是,Premake4虽然还不支持自定义规则,但是总算有一个prebuildcommands可以用,于是研究了一下,自制了一个.proto文件的"编译规则":
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最开始的时候,调用
dofile "protobuf.lua"
然后在项目定义的时候,使用
protobufs { "**/*.proto" }
就可以了。
当然,还有一点要注意的,我的系统是mac,但脚本在linux下应该也能同样运行,但是windows下面的话,可能就需要做一点改动了。