5

複数のソース ファイルを含む Chicken Scheme プロジェクトをコンパイルする必要がありますが、エラーが発生します。

マニュアルこの SO answerによると、ソースに sを入れる必要があり(declare)ます。他のソースをインポートしていることをコンパイラが認識できない理由はわかりませんが、まあ。

問題は、s を入れても、コンパイラがs とs(declare)について文句を言うことです。(import)(use)

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...

指示:

$ csc -uses bindings.o -uses infinity.general.o -c infinity.filesystem.scm -o infinity.filesystem.o

コンパイラは次のように述べています。

構文エラー (インポート): 未定義のモジュールからインポートできません

非バインド変数: 使用

「infinity.general」のimportand宣言を削除するだけで、ファイルはコンパイルされます。useただし、これには2つの問題があります。

  1. and句がない場合、結果の.oファイルは実際に機能しますか? それとも、実行時に欠落しているコードについて文句を言うでしょうか?importuse
  2. csi私のコードには宣言が含ま(import)れている必要がありますが、含まれていない必要があります。ただし、コードが!の両方で機能する必要があります。(use)csccsicsc

どうすればこれを解決できますか?

4

1 に答える 1

3

他のソースをインポートしていることをコンパイラが認識できない理由はわかりませんが、まあ。

宣言は依存関係を決定するために使用されます。コンパイラーは、特定のトップレベルを呼び出す順序 (もしあるとしても) を知る必要があり、そのユニットのグローバルを使用する前に正しいコードが初期化されるようにする必要があります。すべてが個別にコンパイルされている場合、コンパイラはトップレベルへの呼び出しを挿入するタイミングを認識できません。-uses渡すスイッチcscは冗長です:ソースコードcsc -uses fooを入れるのと同じです。私が知る限り、ファイル(declare (uses foo))を渡す-uses foo.oことは何もしません。 foo.o

コード スニペットで を使用していますがload、これはコンパイル時にコードを含める正しい方法ではありませんload。実行時にターゲット ファイルを読み取って評価します。load代わりに、 を完全に省略してくださいdeclare。依存関係はすでに処理されています。それらをリンクするだけです。

また、ファイル名をモジュール/ユニット名として使用することはあまり一般的ではありませんが、機能するはずです。

「infinity.general」の import および use 宣言を削除するだけで、ファイルはコンパイルされます。ただし、これには2つの問題があります。

1) import 句と use 句がない場合、結果の .o ファイルは実際に機能しますか? それとも、実行時に欠落しているコードについて文句を言うでしょうか?

式を保持する必要がありimportます。そうしないと、プログラムがコンパイルされません。コンパイルできる場合は、何か奇妙なことが起こっています。useすべてを静的にリンクする場合は必要ありません。動的リンクを使用している場合、実行時エラーが発生します。

発生するエラーは、ブロックでunbound variable: use使用しているためです。他のSOの質問に従って、おそらく必要になるだけです。usebegin-for-syntax(import-for-syntax chicken)

2) csi ではコードに (インポート) および (使用) 宣言が含まれている必要がありますが、csc では含まれていない必要があります。ただし、私のコードは csi と csc の両方で動作する必要があります。

あなたはこれにあまりにも早く近づいているようです: システムがどのように機能するかを最初に理解することなく、完全なプログラムを作成し、同時にそれをコンパイルして解釈して実行しようとしています。

この時点で、最初に 2 つのファイルで構成される小さなプロジェクトで実験することをお勧めします。次に、インタープリターでも機能するコードから機能する実行可能ファイルをコンパイルする方法を理解できます。次に、この知識を使用して実際のプログラムを作成します。いつでも何かが壊れた場合は、いつでも最小限のケースに戻って、何が違うのかを理解することができます。

これは、完全ではあるが最小限のファイルのセットを提示できるため、サポートを受けるのにも役立ちます。また、人々は、どこが間違っていたのか、またはバグを見つけたかどうかをはるかに迅速に伝えることができます。

于 2016-08-16T06:51:14.747 に答える