英文:
go build multiple binary versions each against a different shared library
问题
我想创建一个能够通过其本地接口与xen通信的go可执行文件。为此,有一个C共享库(实际上有两个),我使用cgo创建了一个简单的go包装器。
问题是我想要针对3个xen版本(3.2、3.4、4.0)进行目标设置,每个版本都有一个不同的共享库。这个库本身基本上提供了相同的API,但在C头文件中定义的结构体的大小和形状是不同的,因此同一个编译后的go二进制文件不能与这些不同的共享库一起使用。
我想要一个包含“main”函数的go二进制文件和一个用于xen的go包装器。
我考虑了两种解决方案:
-
我可以构建3个不同版本的编译后的包以及3个不同版本的主二进制文件,每个都链接到相应的包版本。这个解决方案需要手动构建makefile,以便我可以传递正确的路径等。
-
我可以构建一个薄的C包装器作为共享库,并针对3个xen C绑定的版本构建它的3个版本。然后,这个C包装器将导出一个稳定的C接口,由一个单独的go包使用。然后,我可以将正确的C包装器共享库部署到主机上,并在运行时解析它。
还有其他处理这个问题的方法吗?我更喜欢使用纯(c)go代码,但我不喜欢维护复杂的makefile所带来的额外负担。
编辑:关于为什么我对在makefile中手动处理这个问题感到不舒服的更多细节:
例如,_obj目录的名称在Make.inc和company中是硬编码的,而这些makefile依赖于一些包含有关共享库名称的特殊信息的生成的.c文件,在构建下一个版本的包之前,我必须清理它们。我的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基本上是一个普通的包makefile,它使用TARG=$(XENVERSION)/vimini/xen
,因为我不能在包名中编码版本,否则我将不得不修改源文件中的导入。
通过在包目录中编码版本,我可以使用GCIMPORTS=-I../../pkg/xen/_obj/$(XENVERSION)
来选择正确的一个。
当然,我可以编写自己的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.
答案1
得分: 1
你尝试过这种方法吗?
它可以很容易地适应使用$XENVER环境变量。
英文:
Have you tried this approach?
Architecture- and operating system-specific code
It could easily be adapted to use a $XENVER environment variable.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论