libiconv 질문입니다.

lovejin0309의 이미지

GNU 의 libiconv 를 크로스 컴파일 해서 arm 타겟 보드에 올렸습니다.

크로스 컴파일 후 생성되는 iconv 바이너리는 정상적으로 동작합니다.

그런데 제가 다음과 같이 샘플 코드를 작성해 보면 iconv_open() 부분쪽에서 오류가 발생합니다. 리턴값을 ic 로 받아서 그 값을 출력해 보았는데 -1 로 뜹니다.

#include <iconv.h>
#include <stdio.h>
main()
{
   FILE *fp;
   iconv_t ic;
   char *p_in_buf;
   char *p_out_buf;
   char *p_in_tmp;
   char *p_out_tmp;
   int i, itmp;
   size_t in_left,out_left;
 
   p_in_buf=(char *)malloc(10000);
   p_out_buf=(char *)malloc(10000);
   ic= iconv_open("EUC-KR","UTF-8");
   printf("%d\n",ic);
 
   iconv(ic,NULL,NULL,NULL,NULL);
   fp=fopen("test.utf8","r");
   i=0;
   while( (itmp=fgetc(fp)) != EOF){
     *(p_in_buf+i)=(unsigned char)itmp;
     i++;
   }
   *(p_in_buf+i)=0;
   in_left=strlen(p_in_buf);
   out_left=10000;
   p_out_tmp=p_out_buf;
   iconv(ic,(char **)&p_in_buf, &in_left, &p_out_buf, &out_left);
printf(" in_left=%d out_left=%d str=%s \n", in_left, out_left, p_out_tmp);
   iconv_close(ic);
   fclose(fp);
 
}

아무래도 라이브러리를 타겟 보드에 심은후 환경 설정을 잘못한 것 같습니다. 어느쪽을 살펴봐야 할까요?

cinsk의 이미지

자세히는 잘 모르겠지만, 혹시 관련 conversion file이 설치가 되어 있지 않은지 검사바랍니다. 설치되어 있지 않으면 localedef 명령을 써서 설치할 수 있습니다. glibc-x.y.z/INSTALL 파일을 읽어 보시기 바랍니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

lovejin0309의 이미지

원인을 찾았습니다.

glibc 의 iconv 관련 함수들이 더미 함수였고 무조건 -1을 리턴하도록 되어 있었습니다.

lovejin0309의 이미지

libiconv 설치 문서입니다.

================================================================================
libiconv 포팅 문서

이 문서는 문자 인코딩을 담당하는 라이브러리인 libiconv 를 arm 에 포팅하는 과정에
대해 설명하는 문서입니다.

ChangeLog
2006.07.14
1. 초안 작성

================================================================================

목차
1. 작성자 정보
2. 준비작업
3. 원하는 인코딩만 선택하기
4. Configure
5. 설치
6. 환경 변수 셋팅
7. 응용 프로그램 컴파일

1. 작성자 정보
작성자 : 김유석
연락처 : poplinux@yahoo.co.kr, sixline13_1@hotmail.com

2. 준비 작업
2.1 소스 구하기
1) libiconv 소스
문자를 표현하는 인코딩 셋은 시스템에 따라 여러가지가 있다. 인코딩 셋과
인코딩 셋 간에는 서로 호환이 안되는 때문에 서로 인코딩 셋을 변환해 주는
기능이 필요하다. iconv 는 인코딩 셋을 변환하는 기능을 가진 라이브러리이다.

iconv 는 glibc 에 기본으로 들어 있다. 하지만 크기가 크기 때문에 임베디드
제품에서는 빼는 경우가 많다. glibc 를 재 컴파일 할 수도 있지만 그보다는
GNU iconv 를 사용하는 것을 추천한다.

GNU iconv 는 http://www.GNU.org 에서 구할 수 있다.

파일명은 다음과 같다.

libiconv-1.9.2.tar.gz

2) gperf 소스
gperf 는 해쉬 테이블을 만들어 주는 바이너리인데 사실 정확한 기능과 사용
법은 잘 모르겠다. 하지만 libiconv 를 컴파일 하는 과정에 필요하므로 설치
해야 한다.

gperf 는 GNU 의 프로젝트이므로 http://www.GNU.org 에서 구할 수 있다.

파일명은 다음과 같다.

gperf-3.0.2.tar.gz

gperf 의 설치법은 생략하겠다.

3. 원하는 인코딩만 선택하기
GNU iconv 는 많은 인코딩 셋을 지원하기 때문에 그대로 컴파일 할 경우에는
라이브러리 크기가 아주 커지는 단점이 있다. 임베디드 시스템은 극히 일부의
인코딩 셋만 필요로 하는 경우가 많으므로 자신이 사용할 인코딩 셋을 제외한
나머지 인코딩 셋은 삭제 해야 한다.

인코딩 셋은 삭제하기 위해서는 다음 파일들을 수정해야 한다.

./lib/encoding.def
./lib/aliases.gperf
./lib/aliases.h
./lib/converters.h
./lib/loop_unicode.h

Step 1.
encoding.def 파일에는 각종 인코딩 셋에 대한 내용이 정의 되어 있다. 이
중에서 필요 없는 부분을 삭제해야 한다.

가령 다음과 같이 세 가지 인코딩 셋 정보가 있고 그 중 UTF-8 만을 사용할
것이라면.

원본)

DEFENCODING(( "UTF-8", /* IANA, RFC 2279 */
/*"UTF8", JDK 1.1 */
),
utf8,
{ utf8_mbtowc, NULL }, { utf8_wctomb, NULL })

DEFENCODING(( "UCS-2", /* glibc */
"ISO-10646-UCS-2", /* IANA */
"csUnicode", /* IANA */
),
ucs2,
{ ucs2_mbtowc, NULL }, { ucs2_wctomb, NULL })

DEFENCODING(( "UCS-2BE", /* glibc */
"UNICODEBIG", /* glibc */
"UNICODE-1-1", /* IANA */
"csUnicode11", /* IANA */
),
ucs2be,
{ ucs2be_mbtowc, NULL }, { ucs2be_wctomb, NULL })

수정본)

DEFENCODING(( "UTF-8", /* IANA, RFC 2279 */
/*"UTF8", JDK 1.1 */
),
utf8,
{ utf8_mbtowc, NULL }, { utf8_wctomb, NULL })

수정본에서 볼 수 있듯이 UTF-8 부분만 남기고 지워야 한다.

encoding.def 에는 많은 종류의 인코딩 셋이 정의 되어 있는데 그 중
유니코드들을 삭제할 경우에는 loop_unicode.h 파일도 같이 수정해야 한다.
loop_unicode.h 에 보면 유니코드를 참조 하는 부분이 있음을 알 수 있다.
그 부분들을 주석처리 해 줘야 한다. 어느 부분을 주석처리해야 하는지는
make 를 실행할 때 나오는 에러 메시지를 참조하면 된다.

Step 2.
encoding.h 에 정의되어 있는 인코딩 셋은 동시에 aliases.gperf 파일에도
정의되어 있다. encoding.h 파일과 aliases.gperf 파일을 동시에 열어서
encoding.h 에서 특정 인코딩 셋을 지우게 되면 aliases.gperf 파일도 편집
하자. (해당 줄을 지우기만 하면 된다.)
주의할 점은 aliases.gperf는 내용 중간에 비는 줄을 만들어서는 안된다는
점이다.

UTF-32LE, ei_utf32le
UTF-7, ei_utf7

UNICODE-1-1-UTF-7, ei_utf7
CSUNICODE11UTF7, ei_utf7
C99, ei_c99

위와 같이 중간에 한 줄을 비우게 되면 Step 3 에서 aliases.h 파일을 만들
때 에러가 발생하게 되므로 주의하자.

Step 3.
aliases.gperf 까지 모두 편집이 끝났으면 aliases.h 파일을 만들어야 한다.
aliases.h 파일은 수동으로 일일히 편집해서 만드는게 아니라 위에서 이야기한
"gperf" 라는 유틸리티를 이용해서 생성한다. (사실 gperf 가 정확히 어떤일을
해 주는 유틸리티인줄은 잘 모르겠다.)

다음과 같이 aliases.h를 만들어 주자.

gperf -m 10 aliases.gperf > aliases.h

주의할 점은 꼭 버전 3.0 이상의 gperf를 사용해야 한다는 점이다. 그 이하
버전을 사용할 경우에는 에러 메시지를 볼 수 있을 것이다.

Step 4.
우리가 이렇게 고생해가면서까지 libconv 를 컴파일 하는 것의 주 목적은
크기를 줄이는데 있다. 하지만 여기까지만 진행한 상태에서 컴파일을 하면
크기가 전혀 줄어들지 않은 iconv 라이브러리를 확인할 수 있을 것이다.
그 이유는 converters.h에서 사용하지 않는 인코딩셋 정보까지 인클루드
하기 때문인데 다음 파일을 수정해서 필요 없는 부분을 지원 버리자.

./lib/converters.h

여기까지 진행하면 원하는 인코딩만 선택할 수 있게 된다.

4. Configure
구슬이 서말이어도 꾀야 보배라고, 준비 작업을 열심히 해 놓고 컴파일을 하지
않으면 아무런 의미가 없다. 다음과 같이 configure를 실행하자.

./configure --host=arm-linux --build=i686-linux LD=${CROSS_COMPILE}/arm-linux-ld \
CC=${CROSS_COMPILE}/arm-linux-gcc STRIP=${CROSS_COMPILE}/arm-linux-strip \
CXX=${CROSS_COMPILE}/arm-linux-c++ F77=${CROSS_COMPILE}/arm-linux-g77 \
AR=${CROSS_COMPILE}/arm-linux-ar RANDLIB=${CROSS_COMPILE}/arm-linux-randlib \
--prefix=/home/poplinux/usr --enable-static=no --enable-shared=yes

위 내용은 컴파일을 해 본 사람들은 알 수 있을 것이다. 자세한 설명은 피한다.

configure 가 무사히 끝나면 컴파일을 하자.

make
make install

여기까지 아무 이상없이 진행되었다면 iconv 라이브러리는 현재 디렉토리의 ./usr/lib
에 설치가 되었을 것이다.

5. 설치
iconv 라이브러리는 작업 디렉토리의 ./usr/lib에 설치되었을 것이다. 이
파일들을 타겟 시스템의 /usr/lib 로 복사하자. (자세한 설명 생략)

6. 환경 변수
동적 라이브러리를 설치했으면 이제 동적 라이브러리가 어디 있는지를 타겟시스템에
알려 주어야 한다. 동적 라이브러의 패스는 $LD_LIBRARY_PATH 환경 변수로 지정 한다.
LD_LIBRARY_PATH 를 셋팅한 파일을 찾아서 다음과 같이 수정한다.


export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib

7. 응용 프로그램 컴파일
iconv 라이브러리를 컴파일하고 타겟 시스템에 심는 것까지 모두 성공했다면
응용 프로그램을 만들어서 돌려 봐야 한다. 자고로 고기랑 뒷다마는 씹어야 제
맛이다.

다음과 같은 상태라고 가정하자.

개발용 호스트
iconv 라이브러리 경로

/home/poplinux/usr/lib
/home/poplinux/usr/include

이럴 경우 다음과 같이 make file 을 만들어 준다.

CROSS_COMPILE=/usr/local/hybus-arm-linux-R1.1/bin/
CC=$(CROSS_COMPILE)arm-linux-gcc
LD=$(CROSS_COMPILE)arm-linux-ld
STRIP=$(CROSS_COMPILE)arm-linux-strip
LDFLAGS=-L/home/poplinux/usr/lib -liconv -I/home/poplinux/usr/include

arm:event_client.c
${CC} -g -o event_client event_client.c ${LDFLAGS}

x86:event_client.c
gcc -g -o event_client event_client.c

clean:
rm event_client

위와 같이 make file을 작성하고 컴파일 하면 잘 돌아간다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.