각 컴파일러별로 컴파일 하는 방법에 대해서 짚어보도록 하겠습니다.
Makefile은 이렇습니다. (아래의 Makefile은 sample.c을 컴파일 하고, sample을 만듭니다.)
CC = gcc CFLAGS = -O2 -I/usr/local/include LIBS = -L/usr/local/lib -ltcl8.4 -lm .c.o: $(CC) -c $(CFLAGS) $*.c sample: sample.o $(CC) -o $@ sample.o $(LIBS)
-I와 -L에는 각각 tcl.h가 있는 디렉토리와 libtcl 8.4.so가 있는 디렉토리를 지정합니다. SunOS, FreeBSD등 일부의 UNIX에서는 「libtcl84.a」가 있을수도 있어, 이 경우는 「-ltcl8.4」대신 「-ltcl84」이라고 지정합니다. 몇개의 UNIX 계열 OS에서는, 링크타임에 「-lm」등 이외의 몇개 라이브러리도 링크할 필요가 있습니다. 예를 들면 Solaris라면「-lnsl -lsocket」, Linux라면 「-ldl」, HP-UX라면 「-ldld」입니다.
CC = gcc CFLAGS = -O2 -I/usr/local/include -I/usr/X11R6/include LIBS = -L/usr/local/lib -ltk8.4 -ltcl8.4 \ -L/usr/X11R6/lib -lX11 -lm .c.o: $(CC) -c $(CFLAGS) $*.c sampletk: sampletk.o $(CC) -o $@ sample.o $(LIBS)
이 경우에는 Tk의 라이브러리와 X윈도우 시스템 라이브러리를 링크할 필요가 있습니다.
CC = gcc SHLD = gcc -shared CFLAGS = -O2 -fPIC -I/usr/local/include LIBS = .c.o: $(CC) -c $(CFLAGS) $*.c libsample.so: sample.o $(SHLD) -o $@ sample.o $(LIBS)
공유 라이브러리를 만들 때 compiler나 linker의 옵션은 OS의 컴파일러에 따라 달라집니다. 여기에서는 만국 공통 컴파일러인 gcc을 사용하고 있으므로, 어느 OS에서도 거의 동일합니다. 보통 gcc을 사용할 경우는, 컴파일러의 옵션에 「-fPIC」를 지정해주고, linker의 옵션에 「-shared」를 지정해줍니다. 휴렛 펙커드의 HP-UX등 일부의 OS에서는, -shared에서 연동하는 모든 object module이 반드시 로케이션(location) 독립이 (-fPIC을 붙여서 컴파일 컴파일 한 것) 아니면 안됩니다. 또한, 완성되는 공유 라이브러리의 확장자는, 그 OS의 표준에 준 할 필요가 있습니다. 대부분의 OS(SunOS, Solaris, IRIX, Linux, FreeBSD등)는 위와 같이 「.so」 그러나, HP-UX의 「.sl」과 같은 예외도 있습니다. 한편, gcc가 아닌, 시스템(system)의 cccompiler를 사용할 경우는 컴파일러 옵션을 해당 메뉴얼에서 찿아보시면 됩니다. 일례를 들면, 실리콘 그래픽스의 IRIX에서는 컴파일러 옵션의 linker에서「-shared」를 빼줍니다. FreeBSD는 cccompiler의 스위치(switch)는 gcc과 같아서 linker의 옵션을 「-ld -Bshareable -x」라고 지정해줍니다. HP-UX로는 컴파일러 옵션에 「+z」 또는 「+Z」를 붙입니다. Linux의 cccompiler는 gcc 컴파일러이기 때문에, 어느쪽을 사용해도 동일합니다.
이번은, Microsoft Visual C++의 CL.EXE와 LINK.EXE를 사용하며, NMAKE에서 사용가능한 Makefile의 예입니다.
여기에서는 sampletk.c을 컴파일하고, sampletk.exe를 만듭니다.
CC = cl TCLROOT = C:\TCL CFLAGS = /nologo /O2 /I"$(TCLROOT)\include" LDFLAGS = /nologo LIBS = "$(TCLROOT)\lib\tcl84.lib" "$(TCLROOT)\lib\tk84.lib" .c.obj: $(CC) $(CFLAGS) -c $*.c sampletk.exe: sampletk.obj $(CC) /o $@ $(LDFLAGS) sampletk.obj $(LIBS)
위의 예로 만들어지는 프로그램은, 통합 개발 환경에서 말하는 것의 「콘솔 어플리케이션(Console Application)」이 됩니다. Tk을 사용하지 않을 경우에는 tk84.lib을 링크하지 않아도 됩니다.
Makefile은 아래와 같습니다. Tcl/Tk 인터프리터의 소스 파일인 winMain.c을 개조해서 다른 버전의 wish를 만들 경우는 아래와 같이 됩니다. 여기에서는 sampletk.c을 컴파일하고, sampletk.exe를 만듭니다.
CC = cl TCLROOT = C:\TCL CFLAGS = /nologo /O2 /I"$(TCLROOT)\include" LDFLAGS = /nologo /SUBSYSTEM:WINDOWS LIBS = "$(TCLROOT)\lib\tcl84.lib" "$(TCLROOT)\lib\tk84.lib" .c.obj: $(CC) $(CFLAGS) -c $*.c sampletk.exe: sampletk.obj $(CC) /o $@ $(LDFLAGS) sampletk.obj $(LIBS)
Makefile은 다음과 같습니다. 여기에서는 sample.c을 컴파일하고, libsample.dll 을 만듭니다.
SHLD = cl /LD TCLROOT = C:\TCL CFLAGS = /nologo /O2 /I"$(TCLROOT)\include" LDFLAGS = /nologo LIBS = "$(TCLROOT)\lib\tcl84.lib" "$(TCLROOT)\lib\tk84.lib" .c.obj: $(CC) $(CFLAGS) -c $*.c libsample.dll: sample.obj $(SHLD) /o $@ $(LDFLAGS) sample.obj $(LIBS)
CL.EXE의 DLL을 만드는 옵션은 「/LD」입니다.
Borland C++은 무료 컴파일러가 제공되므로 http://borland.co.kr/products/downloads/download_cbuilder.html# 에서 쉽게 구하실수 있습니다. Tcl/Tk의 확장은 BC++에서도 쉽게 할수 있습니다. 단, Tcl/Tk 인터프리터에 대해서 딸려오는 라이브러리가 Visual C++용이므로, BC++용으로의 변환과정이 필요합니다.
우선, BC++의 유틸리티 implib을 사용하여, Tcl과 Tk의 BC++용 라이브러리를 만듭니다.
implib -a tcl84bcc.lib C:\tcl\bin\tcl84.dll implib -a tk84bcc.lib C:\tcl\bin\tk84.dll
-a 는, VC++ compiler가
의 함수이름의 머리에 자동적으로 「_」를 붙이는 처리에 호환성을 가지게 하는 스위치로 필수적입니다. 변환한후 이 tcl84bcc.lib 와 tk84bcc.lib를 적당한 디렉토리, 여기에서는 C:\tcl\lib에 둡니다.
TCLROOT = C:\TCL CC = bcc32 CFLAGS = -O2 -I"$(TCLROOT)\include" LIBS = "$(TCLROOT)\lib\tcl84bcc.lib" "$(TCLROOT)\lib\tk84bcc.lib" .c.obj: $(CC) $(CFLAGS) -c $? sampletk.exe: sampletk.obj $(CC) -e$@ sample.obj $(LIBS)
Makefile은 아래와 같습니다. 한편, BC++에서는 tcl.h에서 정의되어 있는 매크로 DLLEXPORT 가 통하지 않으므로,
이라고 VC++에 맞게 쓸 필요가 있습니다.
TCLROOT = C:\TCL CC = bcc32 SHLD = bcc32 -tWD CFLAGS = -O2 -I"$(TCLROOT)\include" LIBS = "$(TCLROOT)\lib\tcl84bcc.lib" "$(TCLROOT)\lib\tk84bcc.lib" .c.obj: $(CC) $(CFLAGS) -c $*.c libsample.dll: sample.obj $(SHLD) -e$@ sample.obj $(LIBS)