我需要编译一个包含多个源文件的Chicken Scheme项目,但是我遇到了错误 .
根据the manual和this SO answer,我需要在我的来源中添加 (declare)
. 为什么编译器不能只看到我正在导入其他源代码超出我,但是meh .
问题是,即使我把 (declare)
放入,编译器也会抱怨 (import)
和 (use)
.
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
编译说:
语法错误(导入):无法从未定义的模块导入
和
未绑定变量:使用
如果我只删除"infinity.general"的 import
和 use
声明,则文件将编译 . 但是,我有两个问题:
-
在没有
import
和use
条款的情况下,生成的.o
文件是否真的有效?或者它会抱怨在运行时丢失代码? -
csi
要求我的代码包含(import)
和(use)
声明,而csc
要求它不包含(import)
和(use)
声明 . I, however, require that my code works in both csi and csc!
我该如何解决这个问题?
1 回答
声明用于确定依赖关系:编译器需要知道以什么顺序(以及如果有的话)调用特定的顶层,以确保在使用该单元的任何全局变量之前初始化正确的代码 . 当所有内容单独编译时,编译器将不知道何时插入对toplevels的调用 . 传递给
csc
的-uses
开关是多余的:csc -uses foo
相当于将(declare (uses foo))
放在源代码中 . 据我所知,传递-uses foo.o
对 filefoo.o
没有任何作用 .在您的代码段中,您使用的是
load
,这不是在编译时包含代码的正确方法:load
将在运行时读取和评估目标文件 . 相反,你应该完全省略load
:declare
已经处理了依赖;你只需将它们连接在一起 .此外,使用文件名作为模块/单元名称并不常见,尽管它应该可行 .
你需要保留
import
表达式,否则程序不应该发生奇怪的事情 . 当您静态链接所有内容时,您不需要use
. 如果您使用的是动态链接,则会出现运行时错误 .你得到的关于
unbound variable: use
的错误是因为你在begin-for-syntax
块中使用use
. 根据your other SO question,您可能只需要(import-for-syntax chicken)
.看起来你正在快速接近这个问题:你正在编写一个完整的程序,同时试图让它运行编译和解释,而不首先了解系统的工作原理 .
在这一点上,首先尝试一个由两个文件组成的小项目可能是个好主意 . 然后,您可以弄清楚如何编译可执行代码的可执行文件,该代码也适用于解释器 . 然后,使用这些知识来构建实际程序 . 如果在任何时候出现问题,你可以随时回到最小的情况,并找出你在做什么不同的事情 .
这也有助于获得支持,因为您可以提供完整但最小的文件集,人们可以更快地告诉您哪里出错,或者您是否发现了错误 .