我在使用Windows中的mkbundle静态链接Mono时遇到了麻烦。在我试图找出发生了什么的时候,我碰到了一堵墙。当您将静态标志传递给Windows中的mkbundle时,它会在mono目录中查找monosgen-2.0-static.lib文件。该目录由以下行定义:
string monoPath = GetEnv("MONOPREFIX", @"C:\Program Files (x86)\Mono");
安装mono 5.1.1后该目录的内容是:
首先我注意到文件命名约定与mkbundle正在寻找的不同(monosgen-2.0应该是mono-2.0-sgen)。我可以改变这个很好,但我怀疑 - 给定文件名 - 截图中显示的mono-2.0-sgen.lib文件不是静态编译的,因为当我尝试运行我的捆绑应用程序时,它首先不能找到sgen dll,然后什么时候可以找不到别的。
此时我想知道mkbundle是否在Windows上正式运行,如果它确实是我做了一些根本错误的事情?我看过旧帖子在Windows中寻求帮助设置mkbundle并自己发布了有关此问题。大多数人指向使用mingw而不是cl.exe。我应该使用它吗?
此代码段的来源如下所示。您可以在https://github.com/mono/mono/blob/master/mcs/tools/mkbundle/mkbundle.cs找到完整的源代码。
if (style == "windows")
{
Func<string, string> quote = (pp) => { return "\"" + pp + "\""; };
string compiler = GetEnv("CC", "cl.exe");
string winsdkPath = GetEnv("WINSDK", @"C:\Program Files (x86)\Windows Kits\8.1");
string vsPath = GetEnv("VSINCLUDE", @"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC");
string monoPath = GetEnv("MONOPREFIX", @"C:\Program Files (x86)\Mono");
string[] includes = new string[] {winsdkPath + @"\Include\um", winsdkPath + @"\Include\shared", vsPath + @"\include", monoPath + @"\include\mono-2.0", "." };
// string[] libs = new string[] { winsdkPath + @"\Lib\winv6.3\um\x86" , vsPath + @"\lib" };
var linkLibraries = new string[] { "kernel32.lib",
"version.lib",
"Ws2_32.lib",
"Mswsock.lib",
"Psapi.lib",
"shell32.lib",
"OleAut32.lib",
"ole32.lib",
"winmm.lib",
"user32.lib",
"libvcruntime.lib",
"advapi32.lib",
"OLDNAMES.lib",
"libucrt.lib" };
string glue_obj = "mkbundle_glue.obj";
string monoLib;
if (static_link)
monoLib = LocateFile (monoPath + @"\lib\monosgen-2.0-static.lib");
else {
Console.WriteLine ("WARNING: Dynamically linking the Mono runtime on Windows is not a tested option.");
monoLib = LocateFile (monoPath + @"\lib\monosgen-2.0.lib");
LocateFile (monoPath + @"\lib\monosgen-2.0.dll"); // in this case, the .lib is just the import library, and the .dll is also needed
}
var compilerArgs = new List<string>();
compilerArgs.Add("/MT");
foreach (string include in includes)
compilerArgs.Add(String.Format ("/I {0}", quote (include)));
if (!nomain || custom_main != null) {
compilerArgs.Add(quote(temp_c));
compilerArgs.Add(quote(temp_o));
if (custom_main != null)
compilerArgs.Add(quote(custom_main));
compilerArgs.Add(quote(monoLib));
compilerArgs.Add("/link");
compilerArgs.Add("/NODEFAULTLIB");
compilerArgs.Add("/SUBSYSTEM:windows");
compilerArgs.Add("/ENTRY:mainCRTStartup");
compilerArgs.AddRange(linkLibraries);
compilerArgs.Add("/out:"+ output);
string cl_cmd = String.Format("{0} {1}", compiler, String.Join(" ", compilerArgs.ToArray()));
Execute (cl_cmd);
}