Next: コンポーネントの組み込みのサブクラス, Previous: コンポーネント, Up: コンポーネント [Contents][Index]
すべてのコンポーネントはその型にかかわらず、次の属性(attribute)を持っています。コンポーネント名以外の属性は任意です。
コンポーネント名(component name)は文字列またはシンボルであり、シンボルはasdf:coerce-name
によって小文字の文字列に変換されます。コンポーネント名には総称関数component-name
でアクセスできます。
:pathname
属性を上書きしない限り、コンポーネント名はUNIXスタイルの相対パスとしてそのままパス名指定子に使われるでしょう。(→ パス名指定子)
:version
)この属性は任意であり、コンポーネントのバージョンを指定します。バージョンは、一般的にはドットで区切られた整数の文字列で、例えば‘1.0.11’などです。(→ バージョン指定子) コンポーネントのバージョンには総称関数component-version
でアクセスできます。
ASDFが、:depends-on
で指定された依存コンポーネントの:version
オプションについて調べる時に、コンポーネントのバージョンをversion-satisfies
で問い合わせるかもしれません。例えばシステム定義に:depends-on (((:version "mydepname" "1.0.11"))
という記述がある時は、mydepname
コンポーネントのバージョンが1.0.11
以上であるかどうか確認されることになります。:version
オプションについてはdefsystemの文法を、version-satisfies
関数については関連する関数を参照してください。
一般的には、バージョン番号が問題になるのはsystem
型のコンポーネントだけであることに注意してください。ライブラリの作者が、システムに含まれる様々なファイルにバージョン番号を付けて自ら同期させるというような使い方は、おそらくまったく有用ではないでしょう。
:if-feature
)defsystem
内で処理系に応じてファイルを含めたり除外したりする時は、伝統的にはリーダーマクロ#+
が使われていました。例えばポータブルなCのFFIであるCFFIには、システム定義に次のような一行があります:
#+sbcl (:file "cffi-sbcl")
しかしこの方法には、どの処理系もシステム全体を読み込むことができないという欠点があります。例えば、新しくarchive-op
というオペレーションを作り、システムのすべてのソースファイルをまとめたアーカイブを作ろうとしたとしましょう。この時、上の例のcffi-sbcl.lispはSBCL以外の処理系では不可視であり、archive-op
を実行してもアーカイブに収集されないという問題が起きます。
この問題を解決するため、ASDF 3からコンポーネントに:if-feature
オプションが導入されました。このオプションの値はフィーチャー表現であり、つまり、#+
と同じ文法を使います。フィーチャー表現が満たされないとき、そのコンポーネントはコンパイル、ロード、リンクの際に無視されます。なお、「同じ文法」と述べましたが、このフィーチャー表現は標準のリーダーで読まれるので、シンボルを使う際には:
を前置して明示的にキーワードにしなくてはなりません。#+
に続くフィーチャー表現は暗黙にキーワードパッケージを使いますから、その点は異なることになります。
例えば(:file "foo-sbcl" :if-feature (:and :x86 (:or :sbcl :cmu :scl)))
という記述は、x86マシン上のSBCL、CMUCL、Scieneer CLにおいてのみ、foo-sbcl.lispのコンパイル、ロードがなされるという意味です。先に述べた通り、(:file "foo-sbcl" :if-feature (and x86 (or sbcl cmu scl)))
と書くことはできません。
:in-order-to
)この属性には、当該コンポーネントに関するアクションが別のアクションに依存していることを記述します。任意の属性ですが、しばしば必要になります。
依存関係はオペレーションとコンポーネントのペアについて指定します。例えば次のように記述したとしましょう:
:in-order-to ((compile-op (load-op "a" "b") (compile-op "c")) (load-op (load-op "foo")))
このとき、このコンポーネントに対してcompile-op
を実行する前に、ASDFはa
とb
に対してload-op
を実行し、さらにc
に対してcompile-op
を実行しなければなりません。また、load-op
を実行する前に、foo
がロードされていなければなりません。
文法はおおむね次のようになります。
(this-op {(other-op required-components)}+) required-components := component-name | (required-components required-components) component-name := simple-component-name | (:version simple-component-name minimum-version-object) simple-component-name := string | symbol
[付記]
これはACLのdefsystemと同等の機能です。mk-defsystemはやや一般性に欠けていて、次のような暗黙の依存関係
すべてのソースファイルxについて、(load x)は(compile x)に依存する
を導入していました。:depends-on
引数でbがaに依存すると指定したとき、それが実際に意味しているのは
(compile b)は(load a)に依存する
ことだったのです。しかし、これは不十分な機能でした。McCLIMのように、何らかのファイルがコンパイルされる前に、まずはすべてロードされなければならないようなシステムを記述できなかったのです。
[付記終わり]
ASDFでは、与えられたアクションがどのアクションに依存しているかを(component-depends-on operation component)
で問い合わせることができます。このフォームが返すリストは
((load-op "a" "b") (compile-op "c") (load-op "d") ...)
のような形式です。
component-depends-on
メソッドは、特定のコンポーネント・オペレーションのクラスについて定義することも可能です。その際、(デフォルトの依存関係を完全に上書きしたいのでなければ)自分のメソッドの結果と(call-next-method)
の返り値をappend
して返す必要があります。
この結合は、CLISPのことを考えなければ、メソッドコンビネーションのlist
を使って透過的に実現できるでしょうが、我々はCLISPもサポートする必要があるので、この仕様を使っていません。あなたにCLISPをハックする時間があれば、この部分の修正はきっと歓迎されることでしょう。
コンポーネント(通常はシステム)に特定のバージョン以降を要求したい場合は、ここでも:version
オプションが使えます。この場合、:in-order-to ((load-op (load-op "other-system'')))
の代わりに:in-order-to ((load-op (load-op (:version "other-system" "1.2.3"))))
などと記述することになるでしょう。
:pathname
)この属性の指定は任意であり、たいていは省略されるでしょう。その場合、コンポーネント名が(相対パスとして)使われます。
パス名がどのように解釈されるかについては、パス名指定子を参照してください。
また、「トップレベル」のシステムを定義するdefsystem
マクロは、システム直下のコンポーネントがファイルシステム上のどこにあるか決めるために、追加の処理をします。詳しくはdefsystemでシステムを定義するを参照してください。
componentに対応するパス名を返します。ソースファイルのようなコンポーネントに対しては、ファイルのパス名を返すでしょう。以下に例を挙げます:
CL-USER> (asdf:component-pathname (asdf:find-system "xmls")) #P"/Users/rpg/lisp/xmls/"
CL-USER> (asdf:component-pathname (asdf:find-component (asdf:find-system "xmls") "xmls")) #P"/Users/rpg/lisp/xmls/xmls.lisp"
:properties
)この属性は任意です。
[訳者補足]
この属性は廃止予定であり、ASDF 2との後方互換性のためだけに存在します。また、その名に反して、:properties
オプションにはプロパティリストではなく連想リストを指定します。昔のASDFでは独自の属性が必要な時にcomponent-property
で読み書きしていた、という点だけ知っていれば十分でしょう。
[訳者補足終わり]
システムをパッケージングするにあたって、ASDFの組み込みの属性に指定した情報に加えて、ファイルやシステムについての他の情報が必要になることはしばしばあります。ASDFシステムからベンダーのパッケージを作るプログラムは、これらのシステムを満たすために「プレースホルダ―」情報を作る必要があります。ASDFシステムを作る方は、その付加的な情報を直接読み書きすることがあるでしょう。
(component-property component property-name)
はsetf
のプレースとしても使用可能で、この情報を読み書きすることができます。property-nameの同一性はeql
で判定されるので、シンボルやキーワード等を使いましょう。
• コンポーネントの組み込みのサブクラス | ||
• 新しいコンポーネント型を定義する |