ここには 4 つの (!) 問題があります。
test-a.scm
ユニット宣言が含まれています。これは正しくありません。main()
C関数を持つためにコンパイルする必要があるファイルは常に1つです。それがユニット宣言のないファイルです。リンクしたマニュアルページをより詳しく調べると、「この場合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
いますが、実行時にライブラリが必要になります。これは、動的にリンクされたライブラリによって定義されたモジュールをロードおよびインポートするためのものです。
したがって、これを解決するには、次のようにします。
テスト 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)
test-b.scm (変更なし)
(declare (unit test-b))
(module test-b *
(import scheme chicken)
(define-syntax test-syntax
(syntax-rules ()
((_)
(print "In test-syntax")))))
そして、それをコンパイルするには:
csc -c -j test-b test-b.scm
csc -c test-a.scm
csc test-a.o test-b.o -o test
これは知っておくべきことが非常に多く、トリッキーでもあり、use
プラスのようないくつかのことはregister-feature!
単にあまり意味がありません. 私たちは CHICKEN 5 でこれを簡単にしようと試みています。また、よくある質問を wiki に追加する予定です。
リンクしたマニュアル ページは長い間変更されていません。たとえば、モジュールの存在を完全に無視しています。そのため、コンパイルできませんでした-j
。マニュアル ページのサンプル ファイルではモジュールが定義されていないため、スイッチがありませんでした。
編集:
declare
とにかくコンパイラによってのみ尊重されるため、これは少しきれいにすることができます。したがって、それを にも移動できcond-expand
ます。
テスト a.scm
#!/usr/bin/csi -script
(cond-expand
(compiling (declare (uses test-b)))
(else (load "test-b.scm")))
(import test-b)
(test-syntax)