如何编译多个鸡方案文件? [英] How to compile multiple Chicken Scheme files?
问题描述
我需要编译一个包含多个源文件的Chicken Scheme项目,但我收到错误。
根据手册和这个SO回答,我需要把(declare) / code> s在我的来源。为什么编译器不能只是看到我正在导入其他来源不只是我,但是嗯。
问题是,即使如果我把(declare)
插入,编译器会提示(import)
s和(使用)
。
infinity.filesystem.scm:
(使用bindings filepath posix)
pre>
(declare(uses infinity.general.scm))
(load-relativeinfinity.general.scm)
(module infinity.filesystem(with-open-file make-absolute-path with-temporary-directory with-chdir)
(import scheme filepath posix infinity.general)
-syntax
(使用绑定鸡)
(import infinity.general))
... etc ...
infinity.general.scm:
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
编译器说:
语法错误(import):无法从未定义的模块导入
和
未绑定的变数:use
如果我只是删除
import
和使用
infinity.general的声明,文件编译。但是,我有两个问题:
- 会生成
.o
文件实际工作,在没有import
和使用
子句?
csi
要求我的代码包含(import)
和(使用)
声明,而csc
要求它不。 然而,我需要我的代码在csi
和csc
! li>
如何解决这个问题?
解决方案
为什么编译器不能只看到我正在导入其他源不在我身上,而是meh。
声明用于确定依赖性:编译器需要知道以什么顺序(并且如果有的话)调用特定的toplevel,以确保在该单元的任何全局变量之前初始化正确的代码使用。当一切都单独编译时,编译器不知道何时将调用插入toplevels。
-uses
切换您传递给csc
是多余的:csc -uses foo
等效于在源代码中插入(declare(uses foo))
。传递-uses foo.o
不会对文件执行任何操作foo.o
在您的代码片段中,您使用
加载
,这不是正确的方式在编译时包含代码:load
将在运行时读取和评估目标文件。相反,您应该完全省略load
:declare
已经处理了依赖关系;您只需要将它们链接在一起。
此外,使用文件名作为模块/单元名称不是很常见,虽然它应该工作。
如果我只是删除infinity.general的导入和使用声明,文件将被编译。但是,我有两个问题:
1)在没有import和use子句的情况下,生成的.o文件实际上是否工作?
您需要保留
import
表达式,否则程序不应该编译。如果它编译,有一些奇怪的事情。当您将所有内容链接到静态时,不需要use
。
您得到的错误
未绑定的变量:use
是因为您在begin-for-syntax
块中使用使用
。你可能只需要(import-for-syntax chicken)
,根据您的其他SO问题。
2)csi要求我的代码包含(import)和(use)声明,而csc要求它不是。然而,我需要我的代码工程在csi和csc!
看起来你的接近这太快:正在编写一个完整的程序,同时试图使其运行编译和解释,而不首先建立对系统如何工作的理解。
此时,可能是一个好主意,首先尝试一个由两个文件组成的小项目。然后你可以弄清楚如何编译一个可执行文件,该代码在解释器中也有效。然后,使用这些知识来构建实际的程序。
这也将有助于获得支持,因为您将能够提供一个完整,但最小的文件集,人们将能够更快地告诉你哪里你错了,或者你是否发现了一个错误。
I need to compile a Chicken Scheme project containing multiple source files, but I'm getting errors.
According to the manual and this SO answer, I need to put
(declare)
s in my sources. Why the compiler can't just see that I'm importing the other source is beyond me, but meh.The problem is, even if I put the
(declare)
s in, the compiler complains about the(import)
s and(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...
Command:
$ csc -uses bindings.o -uses infinity.general.o -c infinity.filesystem.scm -o infinity.filesystem.o
Compiler says:
Syntax error (import): cannot import from undefined module
and
unbound variable: use
If I just remove the
import
anduse
declarations for "infinity.general", the file compiles. However, I have two problems with this:
- Will the resulting
.o
file actually work, in the absence ofimport
anduse
clauses? Or will it complain about missing code at runtime?csi
requires that my code contains(import)
and(use)
declarations, whereascsc
requires that it does not. I, however, require that my code works in bothcsi
andcsc
!How can I solve this, please?
解决方案Why the compiler can't just see that I'm importing the other source is beyond me, but meh.
Declares are used to determine dependencies: the compiler needs to know in what order (and if at all) to invoke a particular toplevel, to ensure the right code is initialized before any of the globals from that unit can be used. When everything is being compiled separately, the compiler wouldn't know when to insert calls to toplevels. The
-uses
switch you pass tocsc
is redundant:csc -uses foo
is equivalent to putting(declare (uses foo))
in the source code. Passing-uses foo.o
doesn't do anything with the filefoo.o
as far as I can tell.In your code snippet, you're using
load
, which is not the correct way to include code at compile-time:load
will read and evaluate the target file at run time. Instead, you should omit theload
completely: thedeclare
already takes care of the dependency; you just need to link them together.Also, it's not very common to use filenames as module/unit names, though it should work.
If I just remove the import and use declarations for "infinity.general", the file compiles. However, I have two problems with this:
1) Will the resulting .o file actually work, in the absence of import and use clauses? Or will it complain about missing code at runtime?
You'll need to keep the
import
expressions, or the program shouldn't compile. If it does compile, there's something strange going on. You don't needuse
when you link everything together statically. If you're using dynamic linking, you will get a runtime error.The error you get about
unbound variable: use
is because you're usinguse
in abegin-for-syntax
block. You'll probably just need to(import-for-syntax chicken)
, as per your other SO question.2) csi requires that my code contains (import) and (use) declarations, whereas csc requires that it does not. I, however, require that my code works in both csi and csc!
It looks like you're approaching this too quickly: You are writing a complete program and at the same time trying to make it run compiled and interpreted, without first building an understanding of how the system works.
At this point, it's probably a good idea to experiment first with a tiny project consisting of two files. Then you can figure out how to compile an executable that works from code that also works in the interpreter. Then, use this knowledge to build the actual program. If at any point something breaks, you can always go back to the minimal case and figure out what you're doing differently.
This will also help in getting support, as you would be able to present a complete, but minimal set of files, and people will be able to tell you much quicker where you went wrong, or whether you've found a bug.
这篇关于如何编译多个鸡方案文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!