我正在使用mkbundle并尝试创建一个使用Isis2的小程序IdaTester的嵌入式版本。该系统反过来使用Mono中依赖MonoPosixHelper
的功能我的问题是mkbundle无法识别依赖项,我最终得到一个仍然需要动态链接〜/ bin / lib / libMonoPosixHelper.so的可执行文件,当我将此可执行文件移动到我的系统时会导致问题没有安装Mono。实际上,捆绑包缺少应该静态链接的东西之一。
我的可执行文件确实有效,但前提是我确保只在具有“正确位置”动态库的计算机上运行它。这违背了嵌入式可执行文件的目的......我希望能够将这个程序作为一种服务器交给他们,他们可以把它放在任何地方并作为二进制文件启动,显然如果他们需要安装库来实现这一点,服务器不是完全独立的!
我看到如何强制mkbundle包含程序所依赖的任何dll文件,但是MonoPosixHelper不作为dll存在;这是一个仅限Linux的库,仅作为共享库存在。有没有人知道一种“强制”捆绑静态嵌入它的方法?
如果这有帮助,我的小编译脚本如下:
mcs -debug+ IdaTester.cs Isis.cs -r:System.dll -r:Microsoft.CSharp.dll -r:Mono.Posix.dll
mkbundle --static -o IdaTester IdaTester.exe --deps
然后我运行IdaTester;这适用于可以找到libMonoPosixHelper库的平台,但是如果在尚未安装libMonoPosixHelper的平台上运行时尝试动态加载该库,则会在运行时失败...
答案 0 :(得分:3)
需要将libMonoPosixHelper.so与应用程序一起分发,并更改dll映射以使其正常工作。
问题的背景 - 在运行时加载库
libMonoPosixHelper不是静态链接,而是作为P / Invoke调用进行搜索和加载,例如下面的示例:
[DllImport ("MonoPosixHelper")]
static extern int zipClose (ZipHandle handle, string globalComment);
也就是说,它仅在运行时请求,而不是在编译时请求,因此不能提前链接。
修复它 - 分发libMonoPosixHelper.so
需要四个步骤。
执行各项操作:
<强> 1。将libMonoPosixHelper复制到您将用于分发程序的目录。
libMonoPosixHelper通常位于lib文件夹中,只需将其复制到您将制作tarball的文件夹中。
cp $MONO_ROOT/lib/libMonoPosixHelper.so ~/MY_PROGRAM/
<强> 2。更新DllMap配置文件以避免硬编码位置。
这是避免硬编码路径问题的关键位。我们需要嵌入一个配置文件,其中mkbundle没有指定路径。为此,首先找到单声道配置文件,并将其复制到本地目录
cp $MONO_ROOT/etc/mono/config ~/MY_PROGRAM/config
现在我们需要更改此文件以删除dll的特定路径,使用您喜欢的编辑器打开它并更改路径以避免使用特定的前缀:
<dllmap dll="MonoPosixHelper" target="MACHINE_SPECIFIC/lib/libMonoPosixHelper.dylib" os="!windows" />
到
<dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dylib" os="!windows" />
第3。使用mkbundle
嵌入配置文件将以下选项添加到mkbundle命令以嵌入新编辑的配置文件:
--config MY_PROGRAM/config
<强> 4。将libMonoPosixHelper.so的路径添加到安装机器上的LD_LIBRARY_PATH。
现在,您可以压缩mkbundled可执行文件libMonoPosixHelper.so以及任何其他文件以进行分发。解压缩并在机器上运行时,dlopen现在将像任何其他dll一样查找libMonoPosixHelper.so。因此,只需将包含分布式版本的libMonoPosixHelper的任何目录添加到其LD_LIBRARY_PATH环境变量中
答案 1 :(得分:1)
据我所知,我可以选择的最佳选择是构建一个非共享的Mono库,其中包含与MonoPosixHelper.so中当前相同的方法,或者提供MonoPosixHelper.so的副本作为组件安装在与我的服务器相同的文件夹中。两者似乎都不理想:前者迫使我“进入”Mono发行版,这会产生一个长期维护问题,而后者迫使我进入更复杂的发行和安装模式。但似乎一旦生成共享库,您就无法静态链接到该库的版本; Linux加载器不会像处理更多标准库那样将库这样的东西视为库。
相反,如果我从相同的.o文件生成标准库,加载器将很乐意静态链接它,并且因为mxbundle最终运行cc并因此使用标准ld,该选项对我有用。所以我想这就是我的问题的答案。