Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protobuf编译依赖分析 #2225

Closed
shuax opened this issue Mar 30, 2022 · 19 comments
Closed

protobuf编译依赖分析 #2225

shuax opened this issue Mar 30, 2022 · 19 comments

Comments

@shuax
Copy link
Contributor

shuax commented Mar 30, 2022

你在什么场景下需要该功能?

当proto文件本身存在依赖关系时,编译proto顺序不一定正确。

import "base.proto"

描述可能的解决方案

扫描一下import关系

描述你认为的候选方案

或者不要一边编译proto一边编译c,可以等所有proto编译完成以后再编译c。

其他信息

No response

@waruqi
Copy link
Member

waruqi commented Mar 30, 2022

给个完整复现的例子和编译输出。

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

for x in range(1, 100):
	f = open("proto/{}.proto".format(x), "w")
	f.write('syntax = "proto3";')
	if x==1:
		f.write('import "99.proto";')

生成99个proto文件
编译报错

[  0%]: compiling.proto proto\1.proto
[  0%]: compiling.proto proto\10.proto
[  0%]: compiling.proto proto\11.proto
[  0%]: compiling.proto proto\12.proto
[  0%]: compiling.proto proto\13.proto
[  0%]: compiling.proto proto\14.proto
[  4%]: compiling.proto proto\15.proto
[  4%]: compiling.proto proto\16.proto
[  4%]: compiling.proto proto\17.proto
[  4%]: compiling.proto proto\18.proto
error: 1.pb.cc
***.gens\test\windows\x64\release\rules\protobuf\proto\1.pb.h(32): fatal error C1083: 无法打开包括文件: “99.pb.h”: No such file or directory

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

上传个完整 demo

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

test.zip

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

试了好几次,没测出啥问题,一切正常

[ 66%]: compiling.proto proto/63.proto
[ 67%]: compiling.proto proto/24.proto
[ 68%]: compiling.proto proto/61.proto
[ 69%]: compiling.proto proto/7.proto
[ 70%]: compiling.proto proto/19.proto
[ 71%]: compiling.proto proto/85.proto
[ 72%]: compiling.proto proto/78.proto
[ 73%]: compiling.proto proto/45.proto
[ 74%]: compiling.proto proto/39.proto
[ 75%]: compiling.proto proto/81.proto
[ 76%]: compiling.proto proto/41.proto
[ 77%]: compiling.proto proto/20.proto
[ 78%]: compiling.proto proto/65.proto
[ 79%]: compiling.proto proto/98.proto
[ 80%]: compiling.proto proto/58.proto
[ 81%]: compiling.proto proto/3.proto
[ 82%]: compiling.proto proto/1.proto
[ 84%]: compiling.proto proto/22.proto
[ 84%]: compiling.proto proto/67.proto
[ 85%]: compiling.proto proto/43.proto
[ 86%]: compiling.proto proto/83.proto
[ 98%]: archiving.release libtest.a
[100%]: build ok!

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

能让1.proto最先编译,99.proto最后编译吗

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

这是并行的控制不了,要想解析 import 做依赖并行编译是可以,不过要做不少改动,暂时没空搞。。你可以参考

local moduledeps = module_parser.load(target, sourcebatch, opt)
-- build moduledeps
local moduledeps_files = module_parser.build(moduledeps)
-- compile module files to object files
local count = 0
local sourcefiles_total = #sourcebatch.sourcefiles
for i = 1, sourcefiles_total do
local sourcefile = sourcebatch.sourcefiles[i]
local moduledep = assert(moduledeps_files[sourcefile], "moduledep(%s) not found!", sourcefile)
moduledep.job = batchjobs:newjob(sourcefile, function (index, total)
local opt2 = table.join(opt, {configs = {force = {cxxflags = {
interfaceflag,
{outputflag, modulefiles[i]},
"/TP"}}}})
opt2.progress = (index * 100) / total
opt2.objectfile = sourcebatch.objectfiles[i]
opt2.dependfile = sourcebatch.dependfiles[i]
opt2.sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
objectbuilder.build_object(target, sourcefile, opt2)
-- add module flags to other c++ files after building all modules
count = count + 1
if count == sourcefiles_total and not cachedir then
for _, modulefile in ipairs(modulefiles) do
target:add("cxxflags", {referenceflag, modulefile}, {force = true, expand = false})
end
end
end)
end

对 proto 做类似的处理,c++ modules 里面,就是解析了源码 import 构建依赖图 然后进行依赖编译的。

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

我是说复现这个问题,最好用第一个去依赖最后一个proto,并不是真的要控制顺序。

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

我是说复现这个问题,最好用第一个去依赖最后一个proto,并不是真的要控制顺序。

在没做依赖构建支持之前,是控制不了让 1.proto 先去编译的,也就没法复现,一切都是随机的。。而支持了依赖构建,这个问题就等于解了,也就没必要复现了。。

而且也不用复现,我大体知道什么问题,就是刚说的要支持 import 解析构造 .proto 之间的依赖关系,来处理编译顺序才行。。目前没时间支持。

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

不用before_buildcmd_file一个一个处理,而是before_buildcmd_files一次性把所有proto处理了,再编译cpp,行得通吗。

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

不用before_buildcmd_file一个一个处理,而是before_buildcmd_files一次性把所有proto处理了,再编译cpp,行得通吗。

现在就是先处理的 proto ,再编译的 cpp,问题是就算换成 before_buildcmd_files,那一批 proto 之间的依赖关系,你还是要处理,避免不了

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

不用before_buildcmd_file一个一个处理,而是before_buildcmd_files一次性把所有proto处理了,再编译cpp,行得通吗。

现在就是先处理的 proto ,再编译的 cpp,问题是就算换成 before_buildcmd_files,那一批 proto 之间的依赖关系,你还是要处理,避免不了

实际上编译proto并不会出错,而是生成的c文件有依赖关系编译才出错的。

@shuax
Copy link
Contributor Author

shuax commented Mar 31, 2022

试了下before_buildcmd_files,能用,但是并行不起来,编译特别慢,不好用,

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

不用before_buildcmd_file一个一个处理,而是before_buildcmd_files一次性把所有proto处理了,再编译cpp,行得通吗。

现在就是先处理的 proto ,再编译的 cpp,问题是就算换成 before_buildcmd_files,那一批 proto 之间的依赖关系,你还是要处理,避免不了

实际上编译proto并不会出错,而是生成的c文件有依赖关系编译才出错的。

目前是在 proto rule 生成完 .c 然后直接阻塞编译的,跟 add_files 没啥关系,所以还是依赖 proto 的处理顺序

@waruqi
Copy link
Member

waruqi commented Mar 31, 2022

试了下before_buildcmd_files,能用,但是并行不起来,编译特别慢,不好用,

那是因为不走并行了,恰巧顺序处理对了而已。但是 os.files 遍历的 proto file 列表顺序 依赖系统,也是未定义的

@Ocrosoft
Copy link

Ocrosoft commented Apr 2, 2022

确实是个问题,我也遇到了,特别是在机器卡的时候就会找不到依赖头文件。

@shuax
Copy link
Contributor Author

shuax commented Apr 2, 2022

确实是个问题,我也遇到了,特别是在机器卡的时候就会找不到依赖头文件。

我现在是手动编译proto,先用着吧。

@waruqi
Copy link
Member

waruqi commented Apr 3, 2022

改进了下, 更新到 dev 再试试,xmake update -s dev

@shuax
Copy link
Contributor Author

shuax commented Apr 3, 2022

可以了,感谢作者。

@waruqi waruqi closed this as completed Apr 3, 2022
@waruqi waruqi added this to the v2.6.5 milestone Apr 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants