diff options
| author | Chi Huu Huynh <[email protected]> | 2023-11-23 09:21:25 +0000 |
|---|---|---|
| committer | Chi Huu Huynh <[email protected]> | 2023-11-23 09:21:25 +0000 |
| commit | ca57b9c9215da434522e35179feba029c3e9e6e1 (patch) | |
| tree | d85fbbab4cec99a41c79bdb559c4234d8f364233 | |
| parent | 45cacaf1760d36db7f1f7f121ee25b966a0a3037 (diff) | |
Fix Proto
Code is now similar to rule `verilator`
| -rw-r--r-- | xmake/rules/protobuf/proto.lua | 206 | ||||
| -rw-r--r-- | xmake/rules/protobuf/xmake.lua | 19 |
2 files changed, 190 insertions, 35 deletions
diff --git a/xmake/rules/protobuf/proto.lua b/xmake/rules/protobuf/proto.lua index 7e43e9bdd..e6f351810 100644 --- a/xmake/rules/protobuf/proto.lua +++ b/xmake/rules/protobuf/proto.lua @@ -22,6 +22,8 @@ import("core.base.option") import("lib.detect.find_tool") import("private.utils.batchcmds") +import("core.project.depend") +import("private.action.build.object", {alias = "build_objectfiles"}) import("module_parser") -- get protoc @@ -89,8 +91,7 @@ function load(target, sourcekind) target:add("includedirs", sourcefile_dir, {public = public}) end --- generate build commands -function build_proto_cmd(target, batchcmds, sourcefile_proto, opt, sourcekind) +function buildcmd_pfiles(target, batchcmds, sourcefile_proto, opt, sourcekind) -- get protoc local protoc = _get_protoc(target, sourcekind) @@ -123,9 +124,6 @@ function build_proto_cmd(target, batchcmds, sourcefile_proto, opt, sourcekind) sourcefile_cx_grpc = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename_grpc}) end - -- add includedirs - target:add("includedirs", sourcefile_dir, {public = public}) - local protoc_args = { path(sourcefile_proto), path(prefixdir and prefixdir or path.directory(sourcefile_proto), function (p) return "-I" .. p end), @@ -140,38 +138,188 @@ function build_proto_cmd(target, batchcmds, sourcefile_proto, opt, sourcekind) -- add commands batchcmds:mkdir(sourcefile_dir) - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.proto %s", sourcefile_proto) + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.proto %s to %s", sourcefile_proto, sourcekind) batchcmds:vrunv(protoc, protoc_args) end --- build batch jobs -function build_sourcefiles_proto(target, batchjobs, sourcebatch, opt, sourcekind) +function buildcmd_cxfiles(target, batchcmds, sourcefile_proto, opt, sourcekind) - -- get the root directory of protobuf - local proto_rootdir - if #sourcebatch.sourcefiles > 0 then - local sourcefile = sourcebatch.sourcefiles[1] - local fileconfig = target:fileconfig(sourcefile) - if fileconfig then - proto_rootdir = fileconfig.proto_rootdir - end + -- get protoc + local protoc = _get_protoc(target, sourcekind) + + -- get c/c++ source file for protobuf + local prefixdir + local autogendir + local public + local grpc_cpp_plugin + local fileconfig = target:fileconfig(sourcefile_proto) + if fileconfig then + public = fileconfig.proto_public + prefixdir = fileconfig.proto_rootdir + -- custom autogen directory to access the generated header files + -- @see https://github.com/xmake-io/xmake/issues/3678 + autogendir = fileconfig.proto_autogendir + grpc_cpp_plugin = fileconfig.proto_grpc_cpp_plugin + end + local rootdir = autogendir and autogendir or path.join(target:autogendir(), "rules", "protobuf") + local filename = path.basename(sourcefile_proto) .. ".pb" .. (sourcekind == "cxx" and ".cc" or "-c.c") + local sourcefile_cx = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename}) + local sourcefile_dir = prefixdir and path.join(rootdir, prefixdir) or path.directory(sourcefile_cx) + + local grpc_cpp_plugin_bin + local filename_grpc + local sourcefile_cx_grpc + if grpc_cpp_plugin then + grpc_cpp_plugin_bin = _get_grpc_cpp_plugin(target, sourcekind) + filename_grpc = path.basename(sourcefile_proto) .. ".grpc.pb.cc" + sourcefile_cx_grpc = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename_grpc}) + end + + -- add includedirs + target:add("includedirs", sourcefile_dir, {public = public}) + + -- add objectfile + local objectfile = target:objectfile(sourcefile_cx) + table.insert(target:objectfiles(), objectfile) + + local objectfile_grpc + if grpc_cpp_plugin then + objectfile_grpc = target:objectfile(sourcefile_cx_grpc) + table.insert(target:objectfiles(), objectfile_grpc) + end + + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.proto %s sourcefile %s", sourcefile_proto, sourcefile_cx) + batchcmds:compile(sourcefile_cx, objectfile, {configs = {includedirs = sourcefile_dir}}) + if grpc_cpp_plugin then + batchcmds:compile(sourcefile_cx_grpc, objectfile_grpc, {configs = {includedirs = sourcefile_dir}}) end + -- add deps + local depmtime = os.mtime(objectfile) + batchcmds:add_depfiles(sourcefile_proto) + batchcmds:set_depcache(target:dependfile(objectfile)) + if grpc_cpp_plugin then + batchcmds:set_depmtime(math.max(os.mtime(objectfile_grpc), depmtime)) + else + batchcmds:set_depmtime(depmtime) + end +end + +-- build batch jobs +function build_cxfiles(target, batchjobs, sourcebatch, opt, sourcekind) -- load moduledeps opt = opt or {} - local moduledeps, moduledeps_files = module_parser.load(target, sourcebatch, table.join(opt, {proto_rootdir = proto_rootdir})) - local sourcefiles_total = #sourcebatch.sourcefiles - -- generate jobs - for i = 1, sourcefiles_total do - local sourcefile = sourcebatch.sourcefiles[i] - local moduleinfo = moduledeps_files[sourcefile] or {} - moduleinfo.job = batchjobs:newjob(sourcefile, function (index, total) - -- make build job - local batchcmds_ = batchcmds.new({target = target}) - build_proto_cmd(target, batchcmds_, sourcefile, {progress = (index * 100) / total}, sourcekind) - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) - end) + -- get protoc + local protoc = _get_protoc(target, sourcekind) + + local sourcefiles = sourcebatch.sourcefiles + for _, sourcefile_proto in ipairs(sourcefiles) do + local dependfile = target:dependfile(sourcefile_proto) + depend.on_changed(function() + -- get c/c++ source file for protobuf + local prefixdir + local autogendir + local public + local grpc_cpp_plugin + local fileconfig = target:fileconfig(sourcefile_proto) + if fileconfig then + public = fileconfig.proto_public + prefixdir = fileconfig.proto_rootdir + -- custom autogen directory to access the generated header files + -- @see https://github.com/xmake-io/xmake/issues/3678 + autogendir = fileconfig.proto_autogendir + grpc_cpp_plugin = fileconfig.proto_grpc_cpp_plugin + end + local rootdir = autogendir and autogendir or path.join(target:autogendir(), "rules", "protobuf") + local filename = path.basename(sourcefile_proto) .. ".pb" .. (sourcekind == "cxx" and ".cc" or "-c.c") + local sourcefile_cx = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename}) + local sourcefile_dir = prefixdir and path.join(rootdir, prefixdir) or path.directory(sourcefile_cx) + + local grpc_cpp_plugin_bin + local filename_grpc + local sourcefile_cx_grpc + if grpc_cpp_plugin then + grpc_cpp_plugin_bin = _get_grpc_cpp_plugin(target, sourcekind) + filename_grpc = path.basename(sourcefile_proto) .. ".grpc.pb.cc" + sourcefile_cx_grpc = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename_grpc}) + end + + local protoc_args = { + path(sourcefile_proto), + path(prefixdir and prefixdir or path.directory(sourcefile_proto), function (p) return "-I" .. p end), + path(sourcefile_dir, function (p) return (sourcekind == "cxx" and "--cpp_out=" or "--c_out=") .. p end) + } + + if grpc_cpp_plugin then + local extension = target:is_plat("windows") and ".exe" or "" + table.insert(protoc_args, "--plugin=protoc-gen-grpc=" .. grpc_cpp_plugin_bin .. extension) + table.insert(protoc_args, path(sourcefile_dir, function (p) return ("--grpc_out=") .. p end)) + end + + os.mkdir(sourcefile_dir) + if opt.progress then + progress.show(opt.progress, "${color.build.object}compiling.proto %s", sourcefile_proto) + end + os.vrunv(protoc, protoc_args) + + end, { + dependfile = dependfile, + files = {sourcefile_proto}, + changed = target:is_rebuilt() + }) + end + + -- do build + local sourcebatch_cx = { + rulename = "c++.build", + sourcekind = "cxx", + sourcefiles = {}, + objectfiles = {}, + dependfiles = {} + } + for _, sourcefile_proto in ipairs(sourcefiles) do + -- get c/c++ source file for protobuf + local prefixdir + local autogendir + local public + local grpc_cpp_plugin + local fileconfig = target:fileconfig(sourcefile_proto) + if fileconfig then + public = fileconfig.proto_public + prefixdir = fileconfig.proto_rootdir + -- custom autogen directory to access the generated header files + -- @see https://github.com/xmake-io/xmake/issues/3678 + autogendir = fileconfig.proto_autogendir + grpc_cpp_plugin = fileconfig.proto_grpc_cpp_plugin + end + local rootdir = autogendir and autogendir or path.join(target:autogendir(), "rules", "protobuf") + local filename = path.basename(sourcefile_proto) .. ".pb" .. (sourcekind == "cxx" and ".cc" or "-c.c") + local sourcefile_cx = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename}) + local sourcefile_dir = prefixdir and path.join(rootdir, prefixdir) or path.directory(sourcefile_cx) + + local grpc_cpp_plugin_bin + local filename_grpc + local sourcefile_cx_grpc + if grpc_cpp_plugin then + grpc_cpp_plugin_bin = _get_grpc_cpp_plugin(target, sourcekind) + filename_grpc = path.basename(sourcefile_proto) .. ".grpc.pb.cc" + sourcefile_cx_grpc = target:autogenfile(sourcefile_proto, {rootdir = rootdir, filename = filename_grpc}) + end + + -- add objectfile + local objectfile = target:objectfile(sourcefile_cx) + table.insert(sourcebatch_cx.sourcefiles, sourcefile_cx) + table.insert(sourcebatch_cx.objectfiles, objectfile) + table.insert(sourcebatch_cx.dependfiles, sourcefile_proto) + + local objectfile_grpc + if grpc_cpp_plugin then + objectfile_grpc = target:objectfile(sourcefile_cx_grpc) + table.insert(sourcebatch_cx.sourcefiles, sourcefile_cx_grpc) + table.insert(sourcebatch_cx.objectfiles, objectfile_grpc) + table.insert(sourcebatch_cx.dependfiles, sourcefile_proto) + end end - module_parser.build_batchjobs(moduledeps, batchjobs, opt.rootjob) + build_objectfiles(target, batchjobs, sourcebatch_cx, opt) end diff --git a/xmake/rules/protobuf/xmake.lua b/xmake/rules/protobuf/xmake.lua index 294d1f8be..0f1e8e445 100644 --- a/xmake/rules/protobuf/xmake.lua +++ b/xmake/rules/protobuf/xmake.lua @@ -25,11 +25,15 @@ rule("protobuf.cpp") on_load(function(target) import("proto").load(target, "cxx") end) - before_buildcmd_file(function (target, batchcmds, sourcefile_proto, opt) - import("proto").build_proto_cmd(target, batchcmds, sourcefile_proto, opt, "cxx") + -- generate build commands + before_buildcmd_file(function(target, batchcmds, sourcefile_proto, opt) + import("proto").buildcmd_pfiles(target, batchcmds, sourcefile_proto, opt, "cxx") + end) + on_buildcmd_file(function(target, batchcmds, sourcefile_proto, opt) + import("proto").buildcmd_cxfiles(target, batchcmds, sourcefile_proto, opt, "cxx") end) before_build_files(function (target, batchjobs, sourcebatch, opt) - import("proto").build_sourcefiles_proto(target, batchjobs, sourcebatch, opt, "cxx") + import("proto").build_cxfiles(target, batchjobs, sourcebatch, opt, "cxx") end, {batch = true}) @@ -40,9 +44,12 @@ rule("protobuf.c") on_load(function(target) import("proto").load(target, "cc") end) - before_buildcmd_file(function (target, batchcmds, sourcefile_proto, opt) - import("proto").build_proto_cmd(target, batchcmds, sourcefile_proto, opt, "cc") + before_buildcmd_file(function(target, batchcmds, sourcefile_proto, opt) + import("proto").buildcmd_pfiles(target, batchcmds, sourcefile_proto, opt, "cc") + end) + on_buildcmd_file(function(target, batchcmds, sourcefile_proto, opt) + import("proto").buildcmd_cxfiles(target, batchcmds, sourcefile_proto, opt, "cc") end) before_build_files(function (target, batchjobs, sourcebatch, opt) - import("proto").build_sourcefiles_proto(target, batchjobs, sourcebatch, opt, "cc") + import("proto").build_cxfiles(target, batchjobs, sourcebatch, opt, "cc") end, {batch = true}) |
