英文:
Proper way to gen multiple Thrift files for Go
问题
所以我有以下文件
/src/baseService.thrift
/baseTypes.thrift
/baseSecurity.thrift
我希望将所有这些Thrift定义创建为一个库。因此,每个文件的顶部如下:
baseService.thrift
==================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
import "baseTypes.thrift"
baseTypes.thrift
================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
baseSecurity.thrift
===================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
import "baseTypes.thrift"
问题是,如何将所有这些文件创建为一个lib包?对于java/cpp/js,这样做是可以的,但是当我尝试为go构建时却不行。
使用Thrift,你不能使用thrift gen:baz *.thrift
,你必须逐个处理文件。对于其他语言,我们只需执行以下操作:
for f in `find *.thrift`; do
thrift -o myGenDir --gen go $f"
done
(为每种语言替换适当的gen命令)
对于Python来说,这很好,因为它将每个生成的文件放在基于文件名的自己的目录中[即foo/bar/{filename}/ttypes.py]。对于Java来说,它将所有文件都放在foo/bar/中,但每个类名都是唯一的。对于cpp,它将所有文件都倒入到gen目录中,但每个Thrift文件都有唯一的名称[因此是{filename.h},{filename.cpp}]。然而,对于Go来说,它将所有内容都倒入到foo/bar中,如下所示:
/foo/bar/constants.go
/foo/bar/service.go
/foo/bar/service-remote/
/foo/bar/baz/ [对于命名空间为foo.bar.baz的任何内容]
/foo/bar/ttypes.go
问题是,ttypes.go和(可能)constants.go会被最后一个在for循环中生成的文件覆盖。有没有办法解决这个问题?对于其他语言来说,这是可以的-似乎对于Go来说是一个疏忽。我漏掉了什么。我们有很多Thrift文件,其中包含很多内容-我不想将同一级别的所有内容合并到一个Thrift文件中。
英文:
So I have the following files
/src/baseService.thrift
/baseTypes.thrift
/baseSecurity.thrift
I want all of these thrift definitions to be created into one library. The top of each file is thus:
baseService.thrift
==================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
import "baseTypes.thrift"
baseTypes.thrift
================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
baseSecurity.thrift
===================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar
import "baseTypes.thrift"
The problem is, how to I create all of these into one lib package? It works fine for java/cpp/js but when I try to build for go it's a no go.
With thrift, you can't do a thrift gen:baz *.thrift
, you have to do the files one at a time. For the other languages, we just do a:
for f in `find *.thrift`; do
thrift -o myGenDir --gen go $f"
done
(substitute appropriate gen command for each lang)
For Python this is fine because it puts every gen'd file in it's own dir based on the filename [ i.e. foo/bar/{filename}/ttypes.py]. For Java it dumps all of the files in foo/bar/ but every class name is unique. For cpp, it dumps it all into the gen dir, but uniquely named per thrift file [so {filename.h}, {filename.cpp}]. For Go, however, it dumps everything into foo/bar like so:
/foo/bar/constants.go
/foo/bar/service.go
/foo/bar/service-remote/
/foo/bar/baz/ [for anything that has a namespace of foo.bar.baz]
/foo/bar/ttypes.go
The problem is, the ttypes.go and (presumably) constants.go are getting overwritten by whatever is gen'd last in the for loop. Is there a way around this? It works for the other languages - seems like it's an oversight for Go. What am I missing. We've got lots of Thrift files with lots of stuff in them - I'd rather not have to combine everything that's at the same package level into one thrift file.
答案1
得分: 10
问题是,ttypes.go和(可能)constants.go被最后一个在for循环中生成的内容覆盖了。
是的,这是真的。
有没有办法解决这个问题?
最(跨语言)可移植的建议是不要这样做。相反:
- 将不同的IDL文件放入不同的命名空间
- 将属于一个命名空间的所有内容放入一个IDL文件中
Thrift编译器为Go提供了一些编译器开关,可能会在一定程度上帮助你(你可以在命令提示符上输入thrift --help
来获取所有语言的所有可用选项)
go (Go):
package_prefix= 生成文件的包前缀。
thrift_import= 覆盖thrift包的导入路径(默认值:git.apache.org/thrift.git/lib/go/thrift)
package= 包名称(默认值:从thrift文件名推断)
这些选项的使用方式如下:
thrift -gen go:package=mypack,package_prefix=myprefix
对于其他语言也是有效的,似乎对Go来说是一个疏忽。
这可能是你的印象,但我建议你不要尝试,如果你对跨语言兼容性感兴趣的话。其他语言的行为也是一样的。举个例子:最近我修复了(或者更准确地说是解决了)一个问题与Erlang测试相关的问题,我不得不对抗这个非常相同的问题。
英文:
> The problem is, the ttypes.go and (presumably) constants.go are getting overwritten by whatever is gen'd last in the for loop.
Yes, that's true.
> Is there a way around this?
The most (cross-language) portable recommendation is to not do this. Instead:
- put different IDL files into different namespaces
- put everything belonging to one namespace into exactly one IDL file
The Thrift compiler offers a few compiler switches for Go that may help you at least partially, (you get all available options for all languages by typing thrift --help
on the command prompt)
go (Go):
package_prefix= Package prefix for generated files.
thrift_import= Override thrift package import path (default:git.apache.org/thrift.git/lib/go/thrift)
package= Package name (default: inferred from thrift file name)
These options are used like in
thrift -gen go:package=mypack,package_prefix=myprefix
> It works for the other languages - seems like it's an oversight for Go.
It might be your impression but I'd recommend not to try it, if you are interested in cross-language compatibility. The behaviour is the same with other languages. Just as an example: I recently fixed (or better: worked around) a problem with the Erlang tests, where I had to fight exactly this very same issue.
答案2
得分: 0
最近我也遇到了同样的问题。不同命名空间中的每个 IDL 都无法正常工作。代码看起来很糟糕,到处都是不同的命名空间,你必须记住它们,为每个小事情添加/删除命名空间很烦人。
我只定义了一个命名空间,所以我采用了这种方法。基本上,对象在不同的文件中,但它们被写成它们在一个文件中的样子。所以没有导入,没有跨文件引用,没有在每个文件中都有命名空间。我将命名空间放在一个单独的文件中。然后我的脚本将所有内容合并成一个大的 thrift 文件并进行编译。它确实要求你按正确的顺序放置所有内容,但对我需要的语言(Go、C# 和 Java)来说,它可以正常工作。
对我来说,这看起来也像是一个疏忽。没有理由只为了 Go 而这样做。也许有一天我会发送一个合并请求,使其行为更符合其他语言。
英文:
Had the same problem recently. Every IDL in different namespaces just doesn't work. Code looks bad, different namespaces everywhere that you have to remember, annoying to add/remove namespaces for every little thing.
I only define a single namespace so I come with this. Basically, objects are in different files but they're written as they're in a single file. So no imports, no cross-file references, no namespaces in every file. I put namespaces in a separate file. Then my script joins everything into one big thirft file and compiles it. It does require you to put everything in the right order but it works for languages I need - Go, C# and Java worked fine.
For me it too looks like an oversight. There is no reason for it to be like that just for Go. Maybe some day I will send a merge request with behaviour that better matches other languages.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论