본문으로 바로가기

Tcl로 Makefile 구현

category 카테고리 없음 2024. 7. 3. 14:45

이번 글은 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