将单声道编译为静态库

Posted

技术标签:

【中文标题】将单声道编译为静态库【英文标题】:Compiling mono as static library 【发布时间】:2012-05-29 23:52:11 【问题描述】:

我想在 Windows 上将 libmono 编译为静态库。

目标平台是 Windows x86。构建环境:Windows 7 64 位,VC++ Express 2010

我已经做了什么。

1) 已下载单声道 2.10.8 源。 2) 从 msvc 文件夹中打开 mono.sln 并确保一切都在编译。 3) 然后我做了一些改变: 3.1) 常规->项目默认值->配置类型:静态库(.lib) 3.2) 常规->项目默认值->使用 MFC:使用标准 Windows 库 3.3) C/C++->代码生成->运行时库:多线程 (/MT) 4) 构建它并且 VC++ 2010 成功创建了 mono-2.0.lib 5) 在我自己的项目(我想嵌入单声道)的链接器输入中添加它: 5.1) 常规->项目默认值->配置类型:应用程序 (.exe) 5.2) General->Project Defaults->Use of MFC: Use MFC in a Ststic Library 5.3)C/C++->代码生成->运行时库:多线程(/MT)

它似乎工作得近乎完美,但有一些可怕的问题:Mysterious behavior of Dictionary<TKey, TSource>

一切都做对了吗? 我应该指定任何其他编译器选项或预处理器指令吗?

P.S.: libmono 命令行是:

/I"..\libgc\include" /I"..\" /I"..\mono\" /I"..\mono\jit" /I"..\mono\eglib\src" /I"..\mono\eglib\src" /I"..\eglib\src" /Zi /nologo /W1 /WX- /O1 /Ob1 /Oi /Oy- /D "NDEBUG" /D "i386" /D "TARGET_X86" /D "i386" /D "WIN32" /D "_WIN32" /D "WIN32" /D "_WINDOWS" /D "WINDOWS" /D "HOST_WIN32" /D "TARGET_WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "GC_NOT_DLL" /D "HAVE_CONFIG_H" /D "WINVER=0x0500" /D "_WIN32_WINNT=0x0500" /D "_WIN32_IE=0x0501" /D "WIN32_THREADS" /D "FD_SETSIZE=1024" /D "default_codegen" /D "MONO_ASSEMBLIES=0" /D "_UNICODE" /D "UNICODE" /GF /Gm- /EHsc /MT /GS /Gy /fp:精确 /Zc:wchar_t /Zc:forScope /Fp".\Release/libmono.pch" /Fa"Win32\obj\libmono\" /Fo"Win32\obj\libmono\" /Fd"Win32\obj\libmono\vc100.pdb" /Gd /TC /analyze- /errorReport:queue

UPD:

我发现这个讨论与我的问题http://mono.1490590.n4.nabble.com/Mono-static-library-td3546774.html

它仍然是真实的吗? 我可以使用 SGen 代替 Boehm 吗?如果是,任何提示都非常感谢。 如果是的话,我可以使用 mono 作为静态库并使用 sgen 吗?

【问题讨论】:

这是一个奇怪的问题,考虑到您之前的问题显示了您如何通过静态链接运行单声道来击中您的脚。 ***.com/questions/10717406/… 【参考方案1】:

我现在一切都清楚了。

Hans Passant 对 Mysterious behavior of Dictionary<TKey, TSource> 的回答表明静态链接不起作用。

对这个问题的回答表明还没有选择另一个 GC 的可能性: Compiling Mono from Visual Studio with sgen support

总结一下,现在windows上唯一的解决办法就是动态链接

【讨论】:

这很奇怪。我会否决这个答案。但是,作为 OP,您“有点”有权改变规则并改变您自己的问题。那好吧。 这是你的权利,但我认为它回答了所有问题。 1) 所做的一切都是正确的; 2)我不应该添加任何其他标志,因为一切都是正确的; 3) Boehm 使用 DllMain 的情况仍然是实际的; 4) 我还不能在 Windows 上使用 SGen 代替 Boehm。每个问题都有答案,答案都包含在这里。我当然认为。 好吧,除了问题标题可能是“将单声道编译为静态库”。我谦虚地提出,“windows 上唯一的解决方案是动态链接”不能被视为真正的答案。无论如何,无需辩护,I defended you in my first comment :) 我没有百分百看懂,因为我的英文还不够完善)谢谢)【参考方案2】:

我将跳过您问题的详细信息,因为我怀疑是 XY problem。

如果您想创建一个静态链接到单声道运行时的应用程序,只需使用mkbundle.exe

 mcs Main.cs
 mkbundle --static --deps -z Main.exe -o Main
 ldd Main

结果

sehe@mint12:~/Projects/SODemo/SODemo$ mkbundle --static --deps -z Main.exe -o Main
OS is: Linux
Note that statically linking the LGPL Mono runtime has more licensing restrictions than dynamically linking.
See http://www.mono-project.com/Licensing for details on licensing.
Sources: 1 Auto-dependencies: True
   embedding: /home/sehe/Projects/SODemo/SODemo/Main.exe
   compression ratio: 44,62%
   embedding: /usr/lib/mono/4.0/mscorlib.dll
   compression ratio: 34,99%
   embedding: /usr/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll
   compression ratio: 37,49%
   embedding: /usr/lib/mono/gac/Mono.Security/4.0.0.0__0738eb9f132ed756/Mono.Security.dll
   compression ratio: 40,12%
   embedding: /usr/lib/mono/gac/System.Configuration/4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
   compression ratio: 40,12%
   embedding: /usr/lib/mono/gac/System.Xml/4.0.0.0__b77a5c561934e089/System.Xml.dll
   compression ratio: 34,06%
   embedding: /usr/lib/mono/gac/System.Security/4.0.0.0__b03f5f7f11d50a3a/System.Security.dll
   compression ratio: 39,32%
   embedding: /usr/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll
   compression ratio: 34,16%
   embedding: /usr/lib/mono/gac/Mono.Posix/4.0.0.0__0738eb9f132ed756/Mono.Posix.dll
   compression ratio: 40,01%
Compiling:
as -o temp.o temp.s 
cc -o Main -Wall `pkg-config --cflags mono-2` temp.c -lz `pkg-config --libs-only-L mono-2` -Wl,-Bstatic -lmono-2.0 -Wl,-Bdynamic `pkg-config --libs-only-l mono-2 | sed -e "s/\-lmono-2.0 //"` temp.o
Done
sehe@mint12:~/Projects/SODemo/SODemo$ ldd Main
    linux-vdso.so.1 =>  (0x00007fff7b1ff000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ffe95d0f000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffe95a8b000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ffe95882000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffe9567e000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ffe95461000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffe950bf000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffe95f52000)

注意生成的可执行文件大小为:5.8Mb 用于普通程序。但它完全独立的。

另见

Monotouch 链接器http://docs.xamarin.com/ios/advanced_topics/linker 这会优化所有未使用的引用

Sebastian Poulliot 的博客http://spouliot.wordpress.com/

【讨论】:

感谢您对捆绑包的这次游览,但这与我的需要和我的问题完全不同。为什么称它为 XY 问题?我已经尝试过了。它对我不起作用。所以我要求更正描述尝试的步骤。我不需要将托管程序集捆绑到我的可执行文件中。我需要静态链接到 libmono。如果不清楚,我同意编辑我的问题,但现在我看不到。 @ILya 你的问题很清楚。目标不是。请注意,生成的可执行文件 静态链接到 libmono。另请注意,您可以重复练习 without --deps 将单个程序集编译为本机库而不是完整的 exe。这有帮助吗? 我不需要编译任何程序集 =) 可以说我想要 mono.exe 但有附加功能并且没有单独的 mono-2.0.dll,即我可以以某种方式使用的单个文件可执行文件“C:\myapp\mymono.exe D:\dot-net-assembly.exe”。我已经有一个可以工作的,除了 dot-net-assembly.exe 中使用的 Dictionary 类随机抛出奇怪的异常。这是由 GC 问题引起的。如果您有兴趣,请查看我自己的答案以获取详细信息。 啊哈。这就像单声道嵌入但静态链接。嗯。考虑一下 Exactly =) 不幸的是,由于 GC 设计,它无法实现

以上是关于将单声道编译为静态库的主要内容,如果未能解决你的问题,请参考以下文章

在树莓派上将 libffi 编译为静态库

使用 Visual Studio 2010 将 libexif 编译为静态库 - 然后从 Visual C++ 项目链接

Linux下静态库与动态库

linux下的静态库与动态库详解

linux上静态库的创建和使用

静态库:从头文件中隐藏私有成员