Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compilation 我如何编译这个鸡肉方案代码?_Compilation_Compiler Errors_Include_Scheme_Chicken Scheme - Fatal编程技术网

Compilation 我如何编译这个鸡肉方案代码?

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

显然我的头发太宽了。因此,这里的问题再次简化,并与示例源代码

我正在尝试编译一个包含多个文件的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 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
我实际上得到的是:

语法错误(导入):无法从未定义的模块导入

注意事项:

  • 我在叫宏
  • 我有一个
    (declare)(uses
    子句,但csc找不到我的源代码
  • csc test-a.scm test-b.o-o test
    也不起作用
  • 如果我删除
    load
    ,程序将无法在csi中工作
  • 如果我删除
    使用
    ,程序将无法在csi中工作
  • 我需要这个项目在csi工作
如何在不破坏与csi的兼容性的情况下进行编译?

这里有四个(!)问题:

  • test-a.scm
    包含一个单元声明。这是不正确的;总有一个文件需要编译才能拥有
    main()
    C函数。这个文件没有单元声明。如果你仔细研究你链接的手册页面,它会说“在本例中,
    foo.scm
    是主模块,因为它没有单元声明”
  • 由于您决定使用模块,您需要编译
    test-b.scm
    如下:
    csc-c-j test-b test-b.scm
    。当导入libr时,
    -j
    开关将导致编译器发出模块库
    test-b.import.scm
    ,这就是编译器在编译
    test-a.scm
    时要查找的ary丢失,它会抱怨模块未定义。在解释器中,这没有问题,因为您在导入它定义的模块之前加载了文件
  • 您正在使用
    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
是“主要问题”“单元的入口点。它不是实际的C
main()
,但所有使用
blah
初始化该单元的单元都会调用它。如果缺少它,可能您有
(声明(使用blah))
在一些源文件中,但您忘记实际将其链接到
blah
?另一种可能的解释是您有
(声明(单元blah2))
在blah的源文件中,这样它就不会声明与其他人期望的相同的单元名称。在没有实际查看源代码的情况下,很难说出确切的原因。我试图邀请您进行聊天,但我认为它不起作用。如果我给您我的项目文件,您能告诉我为什么我会出现奇怪的错误吗?我不仅仅是你可以把它们放在一个粘贴箱里吗?或者,试着把文件(如果它们不是太大!)发送到
chicken用户的
mailinglist并在那里寻求帮助。我也读过这个列表,所以除非有人比我强,否则我可以在那里做出回应。