커스텀 eglibc 를 사용하도록 하려면?
글쓴이: mandugukbap / 작성시간: 목, 2013/02/07 - 9:37오후
기존 eglibc 대신 제가 약간 수정한 후 직접 컴파일한 eglibc를 사용하게 하고자 합니다.
1. eglibc에 testfunc()라는 테스트 함수를 작성해 넣은 후 컴파일 (make) 하고 /temp/myusr에 설치하였습니다. (make install).
2. test-codes-1.c 라는 파일을 작성하고 아래와 같은 Makefile을 만들어 컴파일 했습니다.
TARGET = test-codes-1 OBJ = $(TARGET).o SRC = $(TARGET).c CC = gcc CFLAGS = -g LDFLAGS = -nostdlib -nostartfiles -static GLIBCDIR = /temp/myusr/lib STARTFILES = $(GLIBCDIR)/crt1.o $(GLIBCDIR)/crti.o `gcc --print-file-name=crtbegin.o` ENDFILES = `gcc --print-file-name=crtend.o` $(GLIBCDIR)/crtn.o LIBGROUP = -Wl,--start-group $(GLIBCDIR)/libc.a $(GLIBCDIR)/libresolv.a -lgcc -lgcc_eh -Wl,--end-group -Wl,--verbose -Wl,--dynamic-linker=$(GLIBCDIR)/libresolv-2.15.so -Wl,-rpath=$(GLIBCDIR) -Wl,-Map,test.map #LIBGROUP = -Wl,--start-group $(GLIBCDIR)/libc.a $(GLIBCDIR)/libresolv.a -lgcc -lgcc_eh -Wl,--end-group $(TARGET): $(OBJ) $(CC) $(LDFLAGS) -o $@ $(STARTFILES) $^ $(LIBGROUP) $(ENDFILES) $(OBJ): $(SRC) $(CC) $(CFLAGS) -c $^ clean: rm -f *.o *.~ $(TARGET) test.map
3. test-codes-1.c 는 다음과 같습니다.
#include "/temp/myusr/include/stdio.h" #include "/temp/myusr/include/sys/socket.h" #include "/Storage/jkim_temp/myusr/include/netinet/in.h" ... (생략) .... #include "/temp/myusr/include/netdb.h" main(argc, argv) int argc; char **argv; { char hostname[100]; struct hostent *hp; strcpy(hostname, "google.com"); hp = gethostbyname(hostname) testfunc(); }
정말 의미 없는 코드입니다. 코드에 대한 코멘트는 답변 없이 감사히 읽기만 하겠습니다.
여기서 testfunc()라는 함수는 제가 컴파일한 라이브러리에만 있고 OS 설치시 설치된 라이브러리에는 없는게 분명합니다. 그런데 이 함수가 잘 실행되고 "Hello!!! This lib works"같은 테스트 메세지가 잘 출력됩니다.
문제는 그 위의 gethostbyname()의 경우입니다. 제가 컴파일한 라이브러리에 gethostbyname() 호출시 임시 메세지가 화면에 출력되도록 만들어 보았는데 그런 메세지가 출력되지 않습니다.
즉, testfunc()는 분명 제가 수정/컴파일한 라이브러리에서 불러 오는듯 한데 gethostbtname()은 원래 라이브러리에서 불러 오는 것 같다는 것입니다.
어떻게 해야 제가 만드는 프로그램들이 제가 컴파일한 라이브러리를 사용하도록 할 수 있을까요?
Forums:
참고로...
컴파일시 이런 warning이 뜨는군요.
/test-codes-1/test-codes-1.c:30: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
refresh
refresh
위의 Makefile 대신에 다음처럼 컴파일을 시도해
위의 Makefile 대신에 다음처럼 컴파일을 시도해 보았습니다. (libresolv.a)
gcc test-codes-1.c -o test-codes-1 -Wall -I/temp/myusr/include -L/temp/myusr/lib -Xlinker --start-group /temp/myusr/lib/libresolv.a -Xlinker --end-group
컴파일은 되고 testfunc()라는 제가 삽입한 함수가 호출됩니다. 그런데 역시나 gethostbyname()함수는 오리지널 Glibc에서 불러오는 것 같습니다.
다음은 shared object를 이용해 보았습니다. (libresolv.so)
gcc test-codes-1.c -o test-codes-1 -Wall -I/temp/myusr/include -L/temp/myusr/lib -Xlinker --start-group /temp/myusr/lib/libresolv.so -Xlinker --end-group
그러면 test-codes-1.c:(.text+0x9f): undefined reference to 'testfunc' 라는 에러 메세지가 뜹니다.
nm을 이용해서 .a 라이브러리와 .so 라이브러리를 리스팅 해 보면
.a의 경우: 000000e0 T testfunc
.so의 경우: 000028e0 t testfunc
로 나타납니다. 즉, .a는 testfunc가 global이라는 거고 .so에서는 로컬이라는 건데 뭐 때문에 이런 차이가 생기는 걸까요?
약간의 힌트를 첨가해 보았는데 위의 원글을 참고하셔서 제가 컴파일한 커스텀 라이브러리를 오리지널 라이브러리 대신에 사용할 수 있는 방법을 좀 알려 주시면 감사 드리겠습니다.
답변 감사 드립니다. 김정균님. 사실
답변 감사 드립니다. 김정균님.
사실 LD_LIBRARY_PATH를 제일 먼저 사용해 보았습니다만 결과가 다르지 않았습니다. LD_LIBRARY_PATH를 먼저 지정하고 컴파일 시도시에는 segmentation fault가 나오고, 위에 주신대로 커맨드를 실행할 경우 마찬가지로 제가 만든 테스트 함수를 찾을 수 없다고 나옵니다.
rpath는 경우는 본문에 올린 Makefile의 내용에 나와 있듯이 계속해서 쓰고 있습니다.
혹시 다른 힌트가 있으시면 정말 감사 드리겠습니다.
참고로 현재 상태로는 static이든
참고로 현재 상태로는 static이든 dynamic이든 상관 없습니다. 어떻게든 제가 테스트하는 코드가 제가 직접 컴파일한 glibc (더 정확히는 libresolv 및 소켓 관련 lib)을 사용하게 할 수만 있으면 됩니다.
정적, 동적 라이브러리가 문제가 된다면 나중에 따로 풀 수 있으리라고 믿습니다.
부디 도움 부탁 드립니다.
keep-alive
keep-alive
댓글 달기