显然我的previous question太广了 . 所以这里的问题是再次,简化,以及示例源代码 .
我正在尝试编译包含多个文件的Chicken Scheme项目:
test-a.scm:
#!/usr/bin/csi -script
(declare (unit test-a))
(declare (uses test-b))
(load "test-b.scm")
(use test-b)
(test-syntax)
test-b.scm:
(declare (unit test-b))
(module test-b *
(import scheme chicken)
(define-syntax test-syntax
(syntax-rules ()
((_)
(print "In test-syntax")))))
根据official manual,我应该这样做:
csc -c test-b.scm
csc -c test-a.scm
csc test-a.o test-b.o -o test
我真正得到的是:
语法错误(导入):无法从未定义的模块导入
注意事项:
-
我正在调用一个宏 .
-
我有
(declare (uses
条款,但csc找不到我的来源 . -
csc test-a.scm test-b.o -o test
也不起作用 . -
如果删除
load
,程序将无法在csi中运行 . -
如果我删除
use
,程序将无法在csi中运行 . -
我需要程序在csi中工作 .
如何, without breaking compatibility with csi ,我能编译吗?
1 回答
这里有四个(!)问题:
test-a.scm
包含单位声明 . 这是不正确的;总有一个文件需要编译才能具有main()
C函数 . 那是没有单位声明的文件 . 如果您研究更紧密地链接的手册页,它会说“在这种情况下foo.scm
是主要模块,因为它没有单位声明” .由于您决定使用模块,因此需要按如下方式编译
test-b.scm
:csc -c -j test-b test-b.scm
.-j
开关将使编译器发出模块库test-b.import.scm
,这是编译器在编译test-a.scm
时要查找的内容 . 当缺少导入库时,它会抱怨模块未定义 . 在解释器中它没有问题,因为在导入它定义的模块之前你是load
文件 .您正在使用
load
,即使在程序的编译版本中也是如此 . 这意味着它将在每种情况下读取和评估test-b.scm
文件(并在其丢失时进行投诉) .您正在使用
use
,这将在运行时需要库 . 这用于加载和导入由动态链接库定义的模块 .所以,要解决这个问题,你可以这样做:
test-a.scm
test-b.scm (不变)
并且,编译它:
我知道这有很多东西要知道,也很棘手,有些像
use
加上register-feature!
只是试图在鸡5中不那么繁琐,而且我们显而易见并且有点像常见问题解答 .您链接的手册页没有't been changed in a long time: it completely ignores the existence of modules, for example. That'为什么你无法编译它,
-j
开关丢失了,因为手册页中的示例文件没有定义模块 .编辑:
这可以稍微清理一下,因为
declare
无论如何都只能被编译器尊重 . 所以我们也可以将它移到cond-expand
中:test-a.scm