2016-08-16 71 views
3

我需要编译一个包含多个源文件的Chicken Scheme项目,但我收到错误。如何编译多个Chicken Scheme文件?

根据the manualthis SO answer,我需要把(declare)在我的来源。为什么编译器不能只是看到我正在导入另一个源超出了我,但是meh。

问题是,即使我把(declare)写入,编译器也会抱怨(import) s和(use) s。

infinity.filesystem.scm:

(use bindings filepath posix) 
(declare (uses infinity.general.scm)) 
(load-relative "infinity.general.scm") 

(module infinity.filesystem (with-open-file make-absolute-path with-temporary-directory with-chdir) 
(import scheme filepath posix infinity.general) 
(begin-for-syntax 
    (use bindings chicken) 
    (import infinity.general)) 

...etc... 

infinity.general.scm:

(declare (unit infinity.general.scm)) 
(require-extension srfi-1 srfi-13 format data-structures ansi-escape-sequences basic-sequences) 
(module infinity.general (bind+ format-ansi repeat-string join-strings pop-chars! inc! dec! 
          take* drop* take-right* drop-right* ends-with? take-where) 
(import scheme chicken srfi-1 srfi-13 data-structures ansi-escape-sequences basic-sequences bindings ports format) 

...etc... 

命令:

$ csc -uses bindings.o -uses infinity.general.o -c infinity.filesystem.scm -o infinity.filesystem.o 

编译器说:

语法错误(进口):无法从不确定的模块导入

绑定变量:使用

如果我只是删除importuse声明为 “infinity.general” ,文件编译。不过,我有两个问题:

  1. 将产生的.o文件实际工作,在没有importuse条款?还是会抱怨在运行时丢失代码?
  2. csi要求我的代码包含(import)(use)声明,而csc要求它没有声明。 但是,我要求我的代码在csicsc中都可以使用!

我该如何解决这个问题?

回答

2

为什么编译器不能看到我导入其他源超出了我,但是meh。

声明用于确定依赖性:编译器需要知道什么样的顺序(如果有的话)来调用特定的顶层,以确保从该单位可以是正确的代码之前的任何全局变量的初始化用过的。当一切都被单独编译时,编译器不知道何时将调用插入toplevels。您传递给csc-uses开关是多余的:csc -uses foo等同于将(declare (uses foo))置入源代码中。据我所知,通过-uses foo.o不会对文件foo.o做任何事情。

在您的代码段,你使用load,这是不包括在编译时间码的正确方法:load将读取和评估在运行时的目标文件。相反,您应该完全省略loaddeclare已经处理了依赖关系;你只需要将它们连接在一起。

而且,这不是很普遍使用的文件名作为模块/单元的名称,但它应该工作。

如果我只是删除“infinity.general”的导入和使用声明,该文件编译。但是,我有两个问题:

1)在没有导入和使用子句的情况下,生成的.o文件是否会真正起作用?还是会抱怨在运行时丢失代码?

您需要保留import表达式,否则程序不应编译。如果它编译,有一些奇怪的事情发生。当您将所有内容静态链接在一起时,您不需要use。如果你使用动态链接,你会得到一个运行时错误。

您收到的关于unbound variable: use的错误是因为您在begin-for-syntax区块中使用了use。根据your other SO question,您可能只需要(import-for-syntax chicken)

2)csi要求我的代码包含(导入)和(使用)声明,而csc要求它没有。然而,我要求我的代码同时适用于csi和csc!

看起来您正在接近这个过快:您正在编写一个完整的程序,同时试图使其运行编译和解释,而无需先了解系统的工作原理。

在这一点上,首先尝试一个由两个文件组成的小项目可能是一个好主意。然后你可以找出如何编译一个可以在解释器中工作的代码。然后,使用这些知识来构建实际的程序。如果在任何时候出现问题,您可以随时回到最低限度的情况,找出不同的做法。

这也将有助于获得支持,因为您将能够呈现一个完整的,但最小的一组文件,并且人们能够更快地告诉您错误的位置,或者您是否已经找到错误。

+0

但是,如果我省略了“加载”,解释器将如何知道在哪里可以找到我的包含? –

+0

使用文件名作为单位名称的FYI是我的一个错字。我的意思是使用“无限一般”等等。 –

+1

您可以使用'include'而不是'load',它在文件上将源文件包含在另一个文件的位置。它在解释器*和*编译器中工作。但我不确定你会这样做,因为它基本上与在C文件中使用'#include'other-file.c“'相同。另一种选择是只有在解释器中运行'cond-expand'才能'加载',否则将编译的对象链接在一起。 – sjamaan