构建多个二进制版本,每个版本针对不同的共享库
我想创建一个 go 可执行文件,通过它的本机接口与 xen 进行通信。为此有一个 C 共享库(实际上是 2 个),我用 cgo 创建了一个简单的 go 包装器。
问题是我想要定位 3 个 xen 版本(3.2、3.4、4.0),每个版本都有不同的共享库。库本身提供了基本相同的 API,但是 C 头文件中定义的结构体的大小和形状不同,因此相同的编译后的 go 二进制文件不能与这些不同的共享库一起使用。
我想要一个包含“main”的 go 二进制文件和一个 go pkg(xen 的包装器)。
我正在考虑 2 个解决方案:
我可以构建 3 个不同版本的已编译 pkg,以及 3 个不同版本的主二进制文件,每个版本都与相应的 pkg 版本链接。此解决方案需要手动构建 makefile,以便我可以传递正确的路径等
我可以构建一个瘦 C 包装器作为共享库,并针对 3 个版本的 xen C 绑定构建 3 个版本。然后,这个 C 包装器将导出一个稳定的 C 接口,然后由一个 go pkg 使用。然后我可以将正确的 C 包装器共享库部署到主机并在运行时解析它
是否有其他方法来处理这个问题?我更喜欢使用纯 (c)go 代码,但我不喜欢维护复杂 makefile 的额外负担。
编辑:关于为什么我在 makefile 中手动处理它感到不舒服的更多细节:
例如 _obj 目录的名称在 Make.inc 和 company 中被硬编码,并且这些 makefile 依赖于一些生成的 .c 文件,其中包含有关名称的特殊信息共享库的,在构建下一版本的 pkg 之前我必须清理它。我的 makefile 的片段:
all:
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=3.0
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=3.4
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=4.0
其中 Makefile.common 基本上是一个普通的 pkg makefile,它使用 TARG=$(XENVERSION)/vimini/xen,因为我无法在包名称中对版本进行编码,因为我必须修改源中的导入。
通过对包目录中的版本进行编码,我可以使用 GCIMPORTS=-I../../pkg/xen/_obj/$(XENVERSION) 从主 cmd 的 Makefile 中选择正确的版本。
当然,我可以推出我自己的 makefile,它调用 6c 和 6l、cgo 等,但我更喜欢利用现有的 make 基础设施,因为它似乎有一些智慧。
I want to create a go executable which communicates with xen through it's native interface. There is a C shared library (actually 2) for this purpose and I created a simple go wrapper with cgo.
The problem is that I want to target 3 xen versions (3.2, 3.4, 4.0), each of which has a different shared library. The library itself provides basically the same API, but the sizes and shape of the structs defined in the C header are different, and thus the same compiled go binary cannot be used with these different shared libraries.
I want to have a go binary holding the 'main' and a go pkg which is the wrapper for xen.
I was thinking about 2 solutions:
I could build 3 different versions of the compiled pkg and also 3 different versions of the main binary each linked with the corresponding pkg version. This solution requires building manually the makefiles so that I can pass the correct paths etc
I could build a thin C wrapper as a shared library and build it in 3 versions against the 3 versions of xen C bindings. This C wrapper would then export a stable C interface which is then used by one single go pkg. Then I can deploy the correct C wrapper shared library to the hosts and have it resolve at runtime
Is there any other way to handle that ? I would prefer using pure (c)go code but I don't like the additional burden of maintaining complicated makefiles.
EDIT: More details about why I feel uncomfortable about handling that manually in the makefiles:
For example the name of the _obj dir is hardcoded in Make.inc and company, and these makefiles rely on some generated .c files containing special information about the name of the shared library, which I have to cleanup before building the next version of the pkg. A snipped of my makefile:
all:
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=3.0
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=3.4
rm -f _obj/_*
$(MAKE) -f Makefile.common XENVERSION=4.0
where Makefile.common basically is a normal pkg makefile which uses TARG=$(XENVERSION)/vimini/xen
, as I cannot encode the version in the package name because I'd have to modify the imports in the source.
By encoding the version in the package directory I can use GCIMPORTS=-I../../pkg/xen/_obj/$(XENVERSION)
to select the right une from the main cmd's Makefile.
Of course I could roll out my own makefile which invokes 6c and 6l, cgo etc, but I prefer to leverage the existing make infrastructure since it seems that there is some wisdom in it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你尝试过这种方法吗?
特定于架构和操作系统的代码
它可以轻松地适应使用 $XENVER 环境多变的。
Have you tried this approach?
Architecture- and operating system-specific code
It could easily be adapted to use a $XENVER environment variable.