Tcl로 Makefile 구현

admin의 아바타

이번 글은 Tcl의 구문을 이용해 Makefile과 비슷한 스크립트를 기술하는 방법에 대해서 간단히 구현해 봅니다.

make 프로시져

아래의 코드는 make룰을 정의하기 위한 프로시져입니다. make.tcl등의 이름으로 저장하세요.

proc make {target source procedure} {
   if {[regexp {^\. } $target]} {
      proc $target {name} [format {
         set targetsuffix %s
         set sourcesuffix %s
         if {
            ! [file exists $name$targetsuffix] ||
            [file mtime $name$sourcesuffix] > [file mtime $name$targetsuffix]
         } {
            eval {%s}
         }
      } $target $source $procedure]
   } else {
      proc $target {} [format {
         set target %s
         foreach source {%s} {
            regexp {^(. +)(\. [a-z]+)$} $source fullname name suffix
            if {[info procs $source] ! = ""} {
               $source
            } elseif {[info procs $suffix] ! = ""} {
               $suffix $name
            }
            if {
               ! [file exists $target] ||
               ! [file exists $source] ||
               [file mtime $source] > [file mtime $target]
            } {
               eval {%s}
            }
         }
      } $target $source $procedure]
   }
}

사용법

앞의 코드를 읽어들이면(source), 아래와 같이 Tcl의 구문을 이용해 Makefile의 기능과 비슷한 동작을 할수 있습니다.

source make.tcl

make target.exe {source1.obj source2.obj} {
    exec ilink32 -Tpd -c -x -Lc:\borland\bcc55\lib c0d32.obj+source1.obj+source2.obj, target.exe, , import32.lib+cw32.lib,
}

make . obj . c {
    exec bcc32 -c -tWD -Ic:\borland\bcc55\include -o$name.obj $name.c
}

target.exe

make 프로시져는 make의 룰을 정의합니다. 첫번째 인자로 타겟(target) 파일의 이름을, 두번째 인자는 타겟이 의존하는 원시파일, 세번째 인자는 타겟을 구축하기 위한 커맨드를 입력합니다. 두번째 인자는 복수의 파일명을 포함하며 Tcl 리스트로 위와같이 구현가능합니다. 또 두번째 인자와 세번째 인자는 확장자를 상관하지 않습니다. 개별 파일명에 정의된 make룰이 존재하지 않는 경우, 확장자로 정의된 룰이 적용됩니다. 세번째 인자의 커맨드는 원시파일이 하나라도 새롭게 생신된 것이 있을때 실행됩니다. 위의 Tcl로 구현된 Makefile은 실제 아래의 Makefile과 동일한 결과를 가져옵니다.

all: target.exe

taget.exe: source1.obj source2.obj
    ilink32 -Tpd -c -x -Lc:\borland\bcc55\lib c0d32.obj+source1.obj+source2.obj, target.exe, , import32.lib+cw32.lib,

. c.obj:
    bcc32 -c -tWD -Ic:\borland\bcc55\include -o$*.obj $*. c