Compilation 我如何编译这个鸡肉方案代码?
显然我的头发太宽了。因此,这里的问题再次简化,并与示例源代码 我正在尝试编译一个包含多个文件的Chicken Scheme项目: test-a.scm:Compilation 我如何编译这个鸡肉方案代码?,compilation,compiler-errors,include,scheme,chicken-scheme,Compilation,Compiler Errors,Include,Scheme,Chicken Scheme,显然我的头发太宽了。因此,这里的问题再次简化,并与示例源代码 我正在尝试编译一个包含多个文件的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) (declare (unit test-b)) (module test-b * (import
#!/usr/bin/csi -script
(declare (unit test-a))
(declare (uses test-b))
(load "test-b.scm")
(use test-b)
(test-syntax)
(declare (unit test-b))
(module test-b *
(import scheme chicken)
(define-syntax test-syntax
(syntax-rules ()
((_)
(print "In test-syntax")))))
test-b.scm:
#!/usr/bin/csi -script
(declare (unit test-a))
(declare (uses test-b))
(load "test-b.scm")
(use test-b)
(test-syntax)
(declare (unit test-b))
(module test-b *
(import scheme chicken)
(define-syntax test-syntax
(syntax-rules ()
((_)
(print "In test-syntax")))))
根据我的建议,我应该这样做:
csc -c test-b.scm
csc -c test-a.scm
csc test-a.o test-b.o -o test
我实际上得到的是:
语法错误(导入):无法从未定义的模块导入
注意事项:
- 我在叫宏
- 我有一个
子句,但csc找不到我的源代码(declare)(uses
也不起作用csc test-a.scm test-b.o-o test
- 如果我删除
,程序将无法在csi中工作load
- 如果我删除
,程序将无法在csi中工作使用
- 我需要这个项目在csi工作
包含一个单元声明。这是不正确的;总有一个文件需要编译才能拥有test-a.scm
C函数。这个文件没有单元声明。如果你仔细研究你链接的手册页面,它会说“在本例中,main()
是主模块,因为它没有单元声明”foo.scm
- 由于您决定使用模块,您需要编译
如下:test-b.scm
。当导入libr时,csc-c-j test-b test-b.scm
开关将导致编译器发出模块库-j
,这就是编译器在编译test-b.import.scm
时要查找的ary丢失,它会抱怨模块未定义。在解释器中,这没有问题,因为您在导入它定义的模块之前加载了文件test-a.scm
- 您正在使用
,即使是在程序的编译版本中也是如此。这意味着在任何情况下,它都将读取和评估load
文件(如果缺少该文件,则会进行投诉)test-b.scm
- 您正在使用
,这将在运行时需要该库。这用于加载和导入由动态链接库定义的模块use
csc -c test-b.scm
csc -c test-a.scm
csc test-a.o test-b.o -o test
测试a.scm
#!/usr/bin/csi -script
;; Declare that this uses test-b, so that its toplevel is initialised
(declare (uses test-b))
;; No (declare (unit test-a)) because this file should generate main().
;; Because we tell the compiler what to link together and we want to
;; avoid passing all the .scm files on the csi command line, we can load
;; the test-b.scm file here, but only when interpreting:
(cond-expand
((not compiling) (load "test-b.scm"))
(else))
;; Only import the module; we take care of loading the code above,
;; or in the linking step when compiling. If we had (use test-b),
;; the library would be searched for at runtime.
;; Alternatively, (use test-b) here, but add (register-feature! 'test-b)
;; to test-b.scm, which prevents the runtime from attempting to load test-b.
(import test-b)
(test-syntax)
#!/usr/bin/csi -script
(cond-expand
(compiling (declare (uses test-b)))
(else (load "test-b.scm")))
(import test-b)
(test-syntax)
测试b.scm(未更改)
要编译它:
csc -c -j test-b test-b.scm
csc -c test-a.scm
csc test-a.o test-b.o -o test
我意识到这需要知道的东西很多,而且也很棘手,有些东西,比如使用加注册功能!
根本没有什么意义。我们正在尝试在CHICKEN 5中降低这一点,我们还将在wiki中添加一个常见问题,因为这确实不明显,而且有点常见问题
您链接的手动页面已经很长时间没有更改了:例如,它完全忽略了模块的存在。这就是为什么您无法对其进行编译,-j
开关丢失,因为手动页面中的示例文件没有定义模块
编辑:
这可以稍微清理一下,因为declare
仅由编译器执行。因此,我们也可以将其移动到cond expand
中:
测试a.scm
#!/usr/bin/csi -script
;; Declare that this uses test-b, so that its toplevel is initialised
(declare (uses test-b))
;; No (declare (unit test-a)) because this file should generate main().
;; Because we tell the compiler what to link together and we want to
;; avoid passing all the .scm files on the csi command line, we can load
;; the test-b.scm file here, but only when interpreting:
(cond-expand
((not compiling) (load "test-b.scm"))
(else))
;; Only import the module; we take care of loading the code above,
;; or in the linking step when compiling. If we had (use test-b),
;; the library would be searched for at runtime.
;; Alternatively, (use test-b) here, but add (register-feature! 'test-b)
;; to test-b.scm, which prevents the runtime from attempting to load test-b.
(import test-b)
(test-syntax)
#!/usr/bin/csi -script
(cond-expand
(compiling (declare (uses test-b)))
(else (load "test-b.scm")))
(import test-b)
(test-syntax)
谢谢,这非常有用。但是我可以问一个后续问题吗?为什么我会遇到类似未定义的对blah_toplevel的引用
?我已经生成了导入文件,并且正在链接.o文件。无可否认,我正在编译的文件比示例稍微复杂一点。blah_toplevel
是“主要问题”“单元的入口点。它不是实际的Cmain()
,但所有使用blah
初始化该单元的单元都会调用它。如果缺少它,可能您有(声明(使用blah))
在一些源文件中,但您忘记实际将其链接到blah
?另一种可能的解释是您有(声明(单元blah2))
在blah的源文件中,这样它就不会声明与其他人期望的相同的单元名称。在没有实际查看源代码的情况下,很难说出确切的原因。我试图邀请您进行聊天,但我认为它不起作用。如果我给您我的项目文件,您能告诉我为什么我会出现奇怪的错误吗?我不仅仅是你可以把它们放在一个粘贴箱里吗?或者,试着把文件(如果它们不是太大!)发送到chicken用户的mailinglist并在那里寻求帮助。我也读过这个列表,所以除非有人比我强,否则我可以在那里做出回应。