xmake中将proto文件生成C/C++文件然后再编译链接进项目

📅 2026/8/26 16:04:37
xmake中将proto文件生成C/C++文件然后再编译链接进项目
前几天在玩CMake的时候想让CMake来生成pkgconfig的配置文件pc文件尝试了很久都没成功借助DeepSeek也没搞出来。于是研究起了xmake不用不知道一用真觉得xmake比CMake好用多了最主要是的语法简洁没有CMake怪异语法和晦涩的生成表达式xmake完全使用的Lua的语言规则。还有一个非常重要的工具就是VSCode有xmake插件可以像CMake插件一样流畅的工作。举一下简单的示例创建一个xmake工程xmake create hello:$ xmake create hello create hello...[]: .gitignore[]: src\main.cpp[]: xmake.lua create ok!xmake.luaadd_rules(mode.debug,mode.release)-- 添加debug和release模式target(hello)-- 目标为helloset_kind(binary)-- 生成可执行文件如果是static为静态库shared为动态库add_files(src/*.cpp)-- 添加要编译的源文件日常项目中可能会有多目录的情况比如一个目录为库一个目录为依赖这个库的可执行文件顶层xmake.luaincludes(mylib)includes(app)mylib的xmake.luatarget(mylib)set_kind(static)add_files(*.c)add_includedirs(.,{publictrue})app的xmake.luatarget(mylib)set_kind(binary)add_files(*.c)add_deps(mylib)感觉入门非常容易。如果在项目中使用了protobuf则可以使用内置的protobuf规则有“protobuf.c”规则也有“protobuf.cpp”规则。app/xmake.luaadd_requires(libprotobuf-c)-- 查找PBC的依赖库target(app)set_kind(binary)add_rules(protobuf.c)add_files(pb/*.proto,{proto_publictrue})-- 这里需要导出proto 的头文件搜索目录add_packages(libprotobuf-c)-- 将PBC的依赖库添加到目标但是“protobuf.c”是查找的是protoc-c程序可以查看xmake/rules/protobuf/proto.lua源码-- get protocfunction_get_protoc(target,sourcekind)-- find protoc-- see https://github.com/xmake-io/xmake/issues/4659localenvsos.joinenvs(target:pkgenvs(),os.getenvs())localprotoctarget:data(protobuf.protoc)ifnotprotocandsourcekindcxxthenprotocfind_tool(protoc,{envsenvs})ifprotocandprotoc.programthentarget:data_set(protobuf.protoc,protoc.program)endend-- find protoc-clocalprotoc_ctarget:data(protobuf.protoc-c)ifnotprotoc_candsourcekindccthenprotoc_cfind_tool(protoc-c,{envsenvs})orprotocifprotoc_candprotoc_c.programthentarget:data_set(protobuf.protoc-c,protoc_c.program)endend-- get protocreturnassert(target:data(sourcekindcxxandprotobuf.protocorprotobuf.protoc-c),protoc not found!)end在MinGW下会报错$ xmake error: protoc not found!protoc-c已经过时了官方建议使用protoc程序它会调用protoc-gen-c来生成C代码。从上面的源码可以看到在会先使用target:data(“protobuf.protoc-c”)获取生成C语言文件的protoc程序如果没有设置则查找protoc-c找到了再使用target:data_set(“protobuf.protoc-c”, protoc_c.program)设置数据。我们可以手动设置这个数据避免查找protoc-c。app/xmake.luaadd_requires(libprotobuf-c)-- 查找PBC的依赖库target(app)-- 目标appset_kind(binary)-- 可执行文件add_rules(protobuf.c)-- 添加规则add_files(pb/*.proto,{proto_publictrue})-- 添加proto文件这里需要导出proto 的头文件搜索目录add_files(*.c)-- 添加C源文件add_packages(libprotobuf-c)-- 将PBC的依赖库添加到目标on_load(function(target)target:data_set(protobuf.protoc-c,protoc)-- 手动设置PB的C生成器end)这样就可以正常使用了生成C代码不用手动设置。xmake会先使用protobuf规则将proto文件生成C/C源文件和头文件再编译C/C源文件。笔者曾经写过一篇博文C语言使用Protobuf进行网络通信里面介绍了如何定义宏来方便快捷的处理Protobuf的网络消息最终为了方便宏处理对protobuf-c库进行了一点小调整也就是需要使用自己修改过源码生成的protoc-gen-c程序。假如自己编译生成的protoc-gen-c程序在app/pb目录中则需要在处理proto文件前将app/pb目录的路径添加到PATH环境变量中去才能优先使用自己的程序app/xmake.luaadd_requires(libprotobuf-c)-- 查找PBC的依赖库target(app)-- 目标appset_kind(binary)-- 可执行文件add_rules(protobuf.c)-- 添加规则add_files(pb/*.proto,{proto_publictrue})-- 添加proto文件这里需要导出proto 的头文件搜索目录add_files(*.c)-- 添加C源文件add_packages(libprotobuf-c)-- 将PBC的依赖库添加到目标on_load(function(target)target:data_set(protobuf.protoc-c,protoc)-- 手动设置PB的C生成器-- 需要使用vformat手动展开变量$(scriptdir)构成绝对路径localcustom_dirvformat($(scriptdir)/pb)-- 获取当前 PATHlocalcurrent_pathos.getenv(PATH)or-- 根据操作系统选择路径分隔符localsep(os.host()windows)and;or:-- 将自定义目录添加到 PATH 最前面确保优先级最高localnew_pathcustom_dir..sep..current_path-- 设置PATH变量os.setenv(PATH,new_path)end)如本文对你有帮助欢迎点赞收藏