我在 MacOSX 上运行 Mathematica 8,试图将最简单的程序编译为 C。任何与 C 相关的东西在 Mathematica 中都不起作用。我安装了 GCC 4.2;我什至用 XCode 重新安装了多次。这是我正在做的事情以及我遇到的错误:
首先,我总是评估命令
Needs["CCompilerDriver`"]
如果我将编译目标设置为C,
c = Compile[ {{x}}, x^2 + Sin[x^2], CompilationTarget -> "C"];
我收到一条错误,内容为: Compile::nogen :无法从编译的函数创建库。
如果我尝试创建一个库,
demoFile = FileNameJoin[{$CCompilerDirectory,"SystemFiles","CSource","createDLL_demo.c"}];
lib = CreateLibrary[{demoFile},"testLibrary"]
我收到一条消息$失败。 Wolfram 说这是因为我没有安装 C 编译器。我发现这很难相信,因为当我跑步时
CCompilers[]
它告诉我我已经安装了 GCC: {{"Name" -> "GCC", “编译器”-> CCompilerDriver'GCCCompiler`GCCCompiler, “编译器安装”->“/usr/bin”,“编译器名称”->自动}}
更重要的是,终端说我也安装了 GCC!任何帮助将不胜感激。我真的很想将 Mathematica 编译为 C。
在这个答案中我将收集一些类似问题的调试步骤,以供将来参考。 请随意编辑/改进它们。
如果在 Mathematica 8 中无法编译为 C 代码,
检查您是否安装了支持的 C 编译器并且它可以工作(显而易见)。
请注意,编译器不一定必须位于
PATH
中,至少在 Windows/Visual Studio 上不需要。检查 Mathematica 是否识别编译器
<< CCompilerDriver`
CCompilers[]
将列出 Mathematica 已知的编译器。
检查 Mathematica 执行了哪些命令来编译生成的 C 代码:
Compiler`$CCompilerOptions = {"ShellCommandFunction" -> Print};
Compile[{{x}}, x^2, CompilationTarget -> "C"];
请注意,使用
"ShellCommandFunction" -> Print
命令将不会被执行,因此您需要在完成此步骤后将 Compiler`$CCompilerOptions
重新设置为 {}
以允许再次执行命令。Compiler`$CCompilerOptions = {"ShellOutputFunction" -> Print};
Compile[{{x}}, x^2, CompilationTarget -> "C"];
最后两个步骤有望为您提供足够的线索来继续。 通过此信息,您可以检查是否将正确的库/包含路径传递给编译器(对于 gcc/icc,请查看指定库路径的
-L
选项和指定包含路径的 -I
选项)。 然后检查这些路径中是否存在所需的包含文件和库文件。
如果你得到 Compile::nogen,你可以通过在 Compile 表达式中设置 ShellOutputFunction->Print 来查看编译器输出:
c = Compile[ {{x}}, x^2 + Sin[x^2],
CompilationTarget -> {"C", "ShellOutputFunction"->Print}];
一般来说,通过将 CompilationTarget->"C" 更改为 CompilationTarget->{"C", options} ,可以将选项传递给底层 CreateLibrary 调用。 设置 Compiler`$CCompilerOptions 也可以,但这种技术的优点是不设置全局变量。
遗憾的是,您看到的唯一错误是 $Failed,这并不是很有帮助;我想知道是否有一些文件或目录权限问题?
我在 Linux 上运行而不是 Mac,所以我不确定我的设置是否“足够接近”。 在我的机器上,您的
Compile
命令成功并在我的主目录中生成一个文件 .Mathematica/ApplicationData/CCompilerDriver/BuildFolder/blackie-desktop-5077/compiledFunction1.so
。 有什么方法可以找到与您的用户 ID 关联的 .Mathematica
目录,并查看它是否存在并且可以由 mathematica 写入吗?
此外,您还可以通过在调用
/usr/bin/gcc
之前和之后检查 Compile
的文件访问时间来检查“gcc”是否正在被访问。 从操作系统 shell 中,您可以执行 ls -lu /usr/bin/gcc
或从 Mathematica 执行 Import["!ls -lu /usr/bin/gcc", "Text"]