보통 배포되는 패키지는 Shared LIbrary (.so) 형식으로 라이브러리가 빌드되곤 한다. .so 형식으로 빌드되는 것은 여러모로 편리할 때가 있는 반면 여러모로 불편할 때도 분명 있다. 이를테면 왠지 라이브러리 자체를 수정하고 싶을때, 최신 버젼 라이브러리가 깔려 있는데 특별한 용도로 이전 버전 라이브러리를 사용해야 할때, 배포에 관한 문제가 있을 때, 이런 때는 Shared Library로 라이브러리가 배포되는 것은 어딘가 석연치 않다. 참고 사이트 : Program Library HOWTO (kldp의 Wiki에 번역되어 있는 문서이다. linux 상의 library들의 종류, Build 방법 등이 나와 있다.)
neon과 libmcrypt 패키지의 예 닫기.
(뭐 이유야 어쨌든..) neon(0.25.4)과 libmcrypt(2.5.7)의 소스상에서 Static Library로 Build 하도록 수정했던 과정을 간략하게 적어보고자 한다. (사실 Object들을 ar로 묶기만 하면 간단한 일이다;) 두 라이브러리 모두 빌드할때는 libtool이라는 스크립트를 사용한다. 각각 소스상의 최상위 디렉토리에 위치하고 있고, 각각의 버젼은 아래와 같다.
(libmcrypt의 경우) ltmain.sh (GNU libtool) 1.4.3 (1.922.2.111 2002/10/23 02:54:36)(neon의 경우) ltmain.sh (GNU libtool) 1.5.16 (1.1220.2.235 2005/04/25 18:13:26) Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
음 뭐 libtool의 버젼이 각각 다르긴 하다. 그것이 원인이 되는 것인지는 몰라도, 각각 빌드되는 모양도 역시 조금 다르다. 우선 libmcrypt부터 살펴본다. 우선 빌드하면 아래와 같이 빌드된다.
... if /bin/sh ../libtool --mode=compile gcc -DHAVE_CONFIG_H -DLIBDIR=\"/usr/local/lib/libmcrypt/\" -I. -I. -I.. -I. -I.. -I../modules/algorithms -I../modules/modes -g -O2 -MT mcrypt_extra.lo -MD -MP -MF ".deps/mcrypt_extra.Tpo" \ -c -o mcrypt_extra.lo `test -f 'mcrypt_extra.c' || echo './'`mcrypt_extra.c; \ then mv ".deps/mcrypt_extra.Tpo" ".deps/mcrypt_extra.Plo"; \ else rm -f ".deps/mcrypt_extra.Tpo"; exit 1; \ fi gcc -DHAVE_CONFIG_H -DLIBDIR=\"/usr/local/lib/libmcrypt/\" -I. -I. -I.. -I. -I.. -I../modules/algorithms -I../modules/modes -g -O2 -MT mcrypt_extra.lo -MD -MP -MF .deps/mcrypt_extra.Tpo -c mcrypt_extra.c -fPIC -DPIC -o mcrypt_extra.lo ... 그리고 빌드된 후에 보면,
elenoa# ls -la mcrypt_extra* -rw-r--r-- 1 root root 9016 Jan 18 2007 mcrypt_extra.c -rw-r--r-- 1 root root 10296 Jul 23 10:23 mcrypt_extra.lo lrwxrwxrwx 1 root root 15 Jul 23 10:24 mcrypt_extra.o -> mcrypt_extra.lo elenoa# .lo와 .o가 생성되어 있고, .o가 .lo의 Symbolic Link로 이루어져 있다. 빌드된 Object는 .lo로 만들어져 있는 것이다. 자, Makefile.in을 고쳐서 Static Library를 Build하게 해보자.
Build 될때 Shared Library가 Build 되는 부분은 아래와 같다.
(.la를 생성하는 부분인듯 하다) /bin/sh ../libtool --mode=link gcc -g -O2 -o libmcrypt.la -rpath /usr/local/lib -version-info 8:7:4 -version-info 8:7:4 -export-symbols libmcrypt.sym mcrypt_extra.lo mcrypt.lo bzero.lo xmemory.lo mcrypt_modules.lo win32_comp.lo mcrypt_threads.lo mcrypt_symb.lo ../modules/modes/cbc.lo ../modules/modes/cfb.lo ../modules/modes/ctr.lo ../modules/modes/ecb.lo ../modules/modes/ncfb.lo ../modules/modes/nofb.lo ../modules/modes/ofb.lo ../modules/modes/stream.lo ../modules/algorithms/cast-128.lo ../modules/algorithms/gost.lo ../modules/algorithms/rijndael-128.lo ../modules/algorithms/twofish.lo ../modules/algorithms/arcfour.lo ../modules/algorithms/cast-256.lo ../modules/algorithms/loki97.lo ../modules/algorithms/rijndael-192.lo ../modules/algorithms/saferplus.lo ../modules/algorithms/wake.lo ../modules/algorithms/blowfish-compat.lo ../modules/algorithms/des.lo ../modules/algorithms/rijndael-256.lo ../modules/algorithms/serpent.lo ../modules/algorithms/xtea.lo ../modules/algorithms/blowfish.lo ../modules/algorithms/enigma.lo ../modules/algorithms/rc2.lo ../modules/algorithms/tripledes.lo(.so를 생성하는 부분인듯 하다) gcc -shared mcrypt_extra.lo mcrypt.lo bzero.lo xmemory.lo mcrypt_modules.lo win32_comp.lo mcrypt_threads.lo mcrypt_symb.lo ../modules/modes/cbc.lo ../modules/modes/cfb.lo ../modules/modes/ctr.lo ../modules/modes/ecb.lo ../modules/modes/ncfb.lo ../modules/modes/nofb.lo ../modules/modes/ofb.lo ../modules/modes/stream.lo ../modules/algorithms/cast-128.lo ../modules/algorithms/gost.lo ../modules/algorithms/rijndael-128.lo ../modules/algorithms/twofish.lo ../modules/algorithms/arcfour.lo ../modules/algorithms/cast-256.lo ../modules/algorithms/loki97.lo ../modules/algorithms/rijndael-192.lo ../modules/algorithms/saferplus.lo ../modules/algorithms/wake.lo ../modules/algorithms/blowfish-compat.lo ../modules/algorithms/des.lo ../modules/algorithms/rijndael-256.lo ../modules/algorithms/serpent.lo ../modules/algorithms/xtea.lo ../modules/algorithms/blowfish.lo ../modules/algorithms/enigma.lo ../modules/algorithms/rc2.lo ../modules/algorithms/tripledes.lo -Wl,-soname -Wl,libmcrypt.so.4 -Wl,-retain-symbols-file -Wl,libmcrypt.sym -o .libs/libmcrypt.so.4.4.7그리고 위의 내용을 토대로
(응?) Makefile 상에서 libmcrypt.la를 빌드하는 내용을 찾았는데,
(Makefile.in의 249라인 부터) libmcrypt.la: $(libmcrypt_la_OBJECTS) $(libmcrypt_la_DEPENDENCIES) $(LINK) -rpath $(libdir) $(libmcrypt_la_LDFLAGS) $(libmcrypt_la_OBJECTS) $(libmcrypt_la_LIBADD) $(LIBS) ...헉헉.. 거의 다 왔다. 대략 Build된 Object파일은 libmcrypt_la_OBJECTS 와 libmcrypt_la_LIBADD 로 들어오는 것 같고, 그러니까, Makefile.in에 이렇게 추가해 주면 되겠다.
... libmcrypt.a: $(libmcrypt_la_LIBADD) $(libmcrypt_la_OBJECTS) @rm -f $@ $(AR) cru $@ $(libmcrypt_la_LIBADD) $(libmcrypt_la_OBJECTS) $(RANLIB) $@ ... ar은 Object들을 묶어서 Library를 만들어주는 Archive 관련 유틸리티이고, ranlib는 Object 관련 파일에 Index를 생성해주는 유틸리티이다. 대부분 automake를 사용한 프로그램들의 Makefile에는 AR과 RANLIB로 정의되어 있다.
configure를 하고 나면, make libmcrypt.a로 Static Library를 Build 할 수 있게 된다.
(뭐 이렇게 쓰고 나니 전혀 쓸모가 없다;) neon의 경우에는.. 뭐 거의 동일하다. make시에 나오는 메시지는 약간 다르고,
... /bin/sh ..//libtool --quiet --mode=compile gcc -DHAVE_CONFIG_H -D_LARGEFILE64_SOURCE -DNE_LFS -I/usr/kerberos/include -I../ -g -O2 -c ne_request.c -o ne_request.lo ... 빌드된 후에도,
elenoa# ls -la ne_request.* -rw------- 1 root root 46123 Jan 18 2007 ne_request.c -rw------- 1 root root 12503 Jan 18 2007 ne_request.h -rw-r--r-- 1 root root 305 Jul 23 11:01 ne_request.lo -rw-r--r-- 1 root root 41744 Jul 23 11:01 ne_request.o elenoa# 어, 정말 많이 다르다. .lo를 열어보면,
eleno# cat ne_request.lo # ne_request.lo - a libtool object file # Generated by ltmain.sh - GNU libtool 1.5.16 (1.1220.2.235 2005/04/25 18:13:26) # # Please DO NOT delete this file! # It is necessary for linking the library.
# Name of the PIC object. pic_object=none
# Name of the non-PIC object. non_pic_object='ne_request.o'
elenoa#
음 상당히 많이 생소하다.
어쨌든 확실한건 .lo는 위와 같은 description이 들어있는 파일로 생성되어 있고, .o가 진짜 Object 파일로 구성되어 있는데, neon도 libmcrypt와 같은 경로로 libneon.la를 생성하는 부분을 검색해보면,
(Makefile.in의 69라인부터) libneon.la: $(OBJECTS) $(LINK) -rpath $(libdir) $(NEON_LINK_FLAGS) -o $@ $(OBJECTS) $(LIBS) ...이렇게 되어 있고, Makefile상에서 OBJECTS가 어떻게 들어오는지 확인해보면,
(Makefile의 38라인부터) NEON_BASEOBJS = ne_request.lo ne_session.lo \ ne_basic.lo ne_string.lo \ ne_uri.lo ne_dates.lo ne_alloc.lo \ ne_md5.lo ne_utils.lo \ ne_socket.lo ne_auth.lo \ ne_redirect.lo ne_compress.lo
NEON_DAVOBJS = $(NEON_BASEOBJS) \ ne_207.lo ne_xml.lo \ ne_props.lo ne_locks.lo \ ne_xmlreq.lo
OBJECTS = $(NEON_DAVOBJS) ne_acl.lo ne_stubssl.lo
.lo 파일들이 OBJECTS에 들어가 있는데, 보다시피 우리가 필요한 Object들은 .o 파일들이다. 따라서, 위의 서술된 Object들의 각각의 .o파일들을 입력해줘야 하는데, Makefile.in에 아래와 같이 추가해주면 되겠다.
... libneon.a: $(OBJECTS) @rm -f $@ $(AR) cru $@ $(OBJECTS:.lo=.o) $(RANLIB) $@ ... 그러니까 $(OBJECTS:.lo=.o)로 명시하게 되면 OBJECTS 안의 .lo 확장자들이 .o 확장자로 치환된다.
(뭐 좋은 다른 방법들도 많겠다.) 그리고 나서 역시 configure 후에 make libneon.a 하게 되면, 간단히 Static Library를 얻을 수 있겠다.
neon과 libmcrypt 패키지의 예 닫기.