Tatara

第34章
複数のディレクトリに
またがるプロジェクト

ある程度の大きさのプログラムは、すぐに1つのディレクトリに収まらなくなります。ソースはある場所に、それが取り込むファイルはその隣に、ほかのプログラムと共有するヘッダーは別の場所に、そしてオブジェクト・ファイルはそれらとは別に置くこともあります。この章では、A:\TATARA\EXAMPLES\DIRSにある例、DIRSを作ります。ファイルが3つのディレクトリに分かれている例で、TATARAがそれぞれをどのように見つけるかをたどります(13章)。そのあとで、同じプログラムを別の方法でも作ります。別のディレクトリから作る方法、TATARAに相対パスのディレクトリを書く方法、そしてオブジェクト・ファイルとリンク・ファイルを専用のディレクトリに置く方法です。

34.1 この例

DIRSは3行を表示します。それぞれの行は別々のインクルード・ファイルにあり、そのファイルを見つけた探し方の規則を示しています。

A:\TATARA\EXAMPLES\DIRS>dirs 
Rule 1: beside the file that asked. 
Rule 1 again, one level deeper. 
Rule 3: found through TATARA.
 

TATARAは、インクルード・ファイルを次の3つの場所でこの順に探します(13.2節)。

  1. INCLUDEの行があるファイルのディレクトリ
  2. カレント・ディレクトリ
  3. TATARAに書いたそれぞれのディレクトリ

図34.1に、この例のファイルと、DIRSから作るときにそれぞれを見つける規則を示します。

PIC

図 34.1: DIRSのファイルと、各インクルード・ファイルを見つける規則。

34.2 ソース

モジュールはSRC\MAIN.ASです。

; SRC\MAIN.AS - a program whose parts are in three directories. 
; 
; AN INCLUDE IS LOOKED FOR IN THREE PLACES, IN THIS ORDER: 
; 
;   1. the directory of the file doing the including 
;   2. the current directory 
;   3. each directory named in the TATARA environment variable 
; 
; Rule 1 comes first so that a file always finds the header sitting 
; beside it, whatever directory you happen to be standing in when you 
; run the build. Neither line below depends on where that is. 
 
                include ascii.inc       ; CHR_CR and CHR_LF, for the messages 
                include msxdos.inc      ; rule 3: TATARA names the 
                                        ;   directory it is in 
 
                cseg 
 
start:          ld      de,text 
                call    prtstr 
                ld      de,deeper 
                call    prtstr 
                ld      de,sysmsg 
                call    prtstr 
                system  _TERM0 
 
prtstr:         ld      c,_STROUT 
                jp      BDOS            ; and BDOS returns to the caller 
 
; THE MESSAGES COME AFTER THE CODE. Each include below holds a DB, 
; and MSX-DOS starts a .COM at 0100h: text there would be run as 
; instructions. 
 
                include inc\text.inc    ; rule 1, with a separator: 
                                        ;   relative to THIS file 
                include sysmsg.inc      ; rule 3 as well, from the OTHER 
                                        ;   directory in TATARA 
 
                end     start
 

このソースは4つのファイルを、2つのグループに分けて取り込んでいます。

inc\text.incは名前にディレクトリを含みますが、ドライブも先頭の\もないので相対パスです(13.4節)。規則1はこれをMAIN.ASから見た位置、つまりSRC\INCで探します。SRC\INC\TEXT.INCは最初のメッセージを持ち、MSG.INCを取り込みます。

; SRC\INC\TEXT.INC - reached as inc\text.inc from SRC\MAIN.AS, so 
; rule 1 found it: a name with a separator in it is still relative to 
; the file that asked for it. 
; 
; The include below has no directory at all, and rule 1 finds it 
; beside THIS file rather than beside MAIN.AS. 
 
                include msg.inc 
 
text:           db      "Rule 1: beside the file that asked.",CHR_CR,CHR_LF,"$"
 

このINCLUDEについての規則1はTEXT.INCのディレクトリなので、MSG.INCもSRC\INCで見つかります。

; SRC\INC\MSG.INC - a bare name, included from TEXT.INC, which lives 
; in this directory. 
; 
; IF THE SEARCH STARTED IN THE CURRENT DIRECTORY, THIS WOULD NOT BE 
; FOUND: the build runs two levels up, and there is no MSG.INC there. 
 
deeper:         db      "Rule 1 again, one level deeper.",CHR_CR,CHR_LF,"$"
 

LIB\SYSMSG.INCは、そのどちらのディレクトリにも、カレント・ディレクトリにもありません。見つかるのは、BUILD.BATがLIBをTATARAに入れているからです。

; LIB\SYSMSG.INC - not beside MAIN.AS, and not in the directory the 
; build runs from. BUILD.BAT puts this directory in TATARA, which is 
; rule 3, and that is how a project keeps its shared headers in one 
; place instead of a copy per program. 
 
sysmsg:         db      "Rule 3: found through TATARA.",CHR_CR,CHR_LF,"$"
 

34.3 作って実行する

rem BUILD.BAT - EXAMPLE: DIRS 
rem 
rem Sources in SRC, headers beside them in SRC\INC, shared headers in 
rem LIB. The build runs from HERE and nothing is copied anywhere. 
rem 
rem TATARA holds the directories rule 3 looks in - the same idea as 
rem PATH, and the same shape: several may be separated by semicolons. 
rem It is set for the build and cleared afterwards so that nothing 
rem outside this example inherits it. 
rem 
rem THE PATH BELOW IS ABSOLUTE and names this example. MSX-DOS gives a 
rem batch file no way to ask where it is, so change this line if you 
rem put the tree somewhere else. 
 
set TATARA=a:\tatara\include;a:\tatara\examples\dirs\lib 
 
echo === Assembling SRC\MAIN.AS 
tatara /q src\main.as dirs.tro 
 
echo === Linking 
tanren /q /o:dirs.com dirs.tro 
 
set TATARA= 
 
echo === Done. Type DIRS to run it.
 

TATARAには、セミコロンで区切った2つのディレクトリが入っています(13.3節)。バッチ・ファイルはDIRSから実行し、ソースをsrc\main.asと指定します。オブジェクト・ファイルとプログラムはDIRSに書き出されます。

A:\TATARA\EXAMPLES\DIRS>build 
=== Assembling SRC\MAIN.AS 
=== Linking 
=== Done. Type DIRS to run it. 
A:\TATARA\EXAMPLES\DIRS>dirs 
Rule 1: beside the file that asked. 
Rule 1 again, one level deeper. 
Rule 3: found through TATARA.
 

/Qなしで実行すると、プログラムが当然そうあるべきように、0100hのコードから始まることがTANRENの表示でわかります。

A:\TATARA\EXAMPLES\DIRS>tanren /o:dirs.com dirs.tro 
... 
1 modules, 7 records, ends at EOF. 
Wrote DIRS.COM, 0100-0183 (132 bytes), entry 0100.
 

34.4 試してみること

次のどれもDIRSから始め、特に書いていなければTATARAはBUILD.BATと同じように設定します。

34.4.1 TATARAからLIBを外す

TATARAにインクルード用のディレクトリしかないと、SYSMSG.INCはどこからも見つかりません。

A:\TATARA\EXAMPLES\DIRS>set tatara=a:\tatara\include 
A:\TATARA\EXAMPLES\DIRS>tatara src\main.as nolib.tro 
... 
ERROR: cannot open SYSMSG.INC 
    included from SRC\MAIN.AS(36)
 

メッセージは、書いたとおりのファイル名と、それを求めたMAIN.ASの行を示します。

34.4.2 TATARAに相対パスのディレクトリを書く

TATARAのディレクトリも、ほかのパスと同じように相対パスで書けます。

A:\TATARA\EXAMPLES\DIRS>set tatara=a:\tatara\include;lib 
A:\TATARA\EXAMPLES\DIRS>tatara src\main.as rel.tro 
... 
ended at SRC\MAIN.AS(39)
 

libはカレント・ディレクトリから見た位置なので、これがうまくいくのはDIRSから作るときだけです。BUILD.BATは絶対パスを使っているので、どこから作ってもTATARAの意味は変わりません。

34.4.3 別のディレクトリから作る

規則1はカレント・ディレクトリに左右されません。SRCの中からアセンブルしても、MAIN.ASはINC\TEXT.INCとMSG.INCを見つけ、残りはTATARAが見つけます。

A:\TATARA\EXAMPLES\DIRS>cd src 
A:\TATARA\EXAMPLES\DIRS\SRC>tatara main.as ..\dirs2.tro 
... 
ended at MAIN.AS(39) 
A:\TATARA\EXAMPLES\DIRS\SRC>cd .. 
A:\TATARA\EXAMPLES\DIRS>tanren /o:dirs2.com dirs2.tro 
... 
Wrote DIRS2.COM, 0100-0183 (132 bytes), entry 0100. 
A:\TATARA\EXAMPLES\DIRS>dirs2 
Rule 1: beside the file that asked. 
Rule 1 again, one level deeper. 
Rule 3: found through TATARA.
 

34.4.4 オブジェクト・ファイルを分けて置く

大きなプロジェクトでは、オブジェクト・ファイルと、それを指定するリンク・ファイルを、専用のディレクトリに置くことがよくあります。OBJ\DIRS.LNKはそのようなリンク・ファイルです。

; DIRS.LNK - the link, kept with the object files. 
main 
/o:dirs3.com
 

TATARAはオブジェクト・ファイルをOBJに書き出し、TANRENはリンク・ファイルを与えられると、まずその隣でMAIN.TROを探します(23.1節)。

A:\TATARA\EXAMPLES\DIRS>tatara /q src\main.as obj\main.tro 
A:\TATARA\EXAMPLES\DIRS>tanren @obj\dirs 
... 
1 modules, 7 records, ends at EOF. 
Wrote DIRS3.COM, 0100-0183 (132 bytes), entry 0100. 
A:\TATARA\EXAMPLES\DIRS>dirs3 
Rule 1: beside the file that asked. 
Rule 1 again, one level deeper. 
Rule 3: found through TATARA.
 

DIRS3.COMはOBJではなく、カレント・ディレクトリのDIRSに書き出されます。/O:は名前を書いたとおりに使うからです(21.2節)。プログラムを別の場所に置くには、/o:bin\dirs3.comのように、名前にパスを含めてください。