IT

ar 오류 File format not recognized

심량 2014. 12. 5. 15:55

잘못 써진 ar 옵션이 적혀있는 Makefile이 기존(linux kernel v2.6.18-194)에는 별 문제도 없이 잘 컴파일되어 문제인지도 모르고 있다가 컴파일 환경이 바뀌면서(linux kernel v2.6.32-504.1.3/v3.13.0-24) 'File format not recognized' 란 오류를 뱉어내는 문제를 겪게 되었습니다. file 명령을 써보고 objectdump나  g++ -v 명령이나 g++ -dumpmachine 명령을 내려보거나 libtool을 시스템에서 제대로 찾니 못찾니나 곁다리지만 바이너리와 gdb간의 구조(32 or 64bit) 등 갖은 시도를 해봤지만 딱히 해결책이 보이지 않았습니다... 알고 나니 저런 근본적인 문제가 아니라 황당하긴 했지만요..

혹시나 저런 부분을 확인하지 않고 이 글을 읽으시는 부분은 '갖은 시도'를 먼저 검색해보고 나서 보시기 바랍니다. 이 글에서는 굳이 저 상황에 대해 따로 설명하지 않습니다. ar 옵션을 잘못 사용한 내용에 관한 글입니다.

 

Makefile에는 관련 내용이 다음과 같이 정의되어 있었습니다.

LIB_CMD=ar
LIB_FLAGS=rau
OBJ=1.o 2.o 3.o 4.o 5.o 6.o 7.o 8.o 9.o
...
libabcd.a :  Makefile
  @echo Building Library $@
  @$(LIB_CMD) $(LIB_FLAGS) -o libabcd.a  $(OBJ)

 

정말로 온갖... 시도를 다 해보다 해결책을 못찾아 포기하고 이참에 ar 사용법이나 익혀보자는 엉뚱한 생각이 들었습니다.

 

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ar.html 페이지의 글과, 리눅스에 저장된 ar man 페이지를 참고해봤습니다. 저 페이지에는 사용되는 형태를 간단하게 보여주는 예시가 있습니다.

ar -d [-v] archive file...

ar -m [-v] archive file...
ar -m -a [-v] posname archive file...
ar -m -b [-v] posname archive file...
ar -m -i [-v] posname archive file...

ar -p [-v] [-s] archive [file...]

ar -q [-cv] archive file...


ar -r [-cuv] archive file...

ar -r -a [-cuv] posname archive file...
ar -r -b [-cuv] posname archive file...
ar -r -i [-cuv] posname archive file...

ar -t [-v] [-s] archive [file...]

ar -x [-v] [-sCT] archive [file...]

위 예에서 archive는 이미 ar로 묶여있는 libabcd.a 파일을 가리키고 file은 합칠 1.o와 같은 파일, posname은 archive인 libabcd.a 파일 안에 있는 m.o n.o 와 같은 파일들을 가리킵니다.

 

뭐 자세한 사용 설명은 'ar 사용법' 정도로 검색해보시기 바랍니다.

각 옵션들 설명을 보고 직접 테스트를 해보면서 문제가 되었던 부분을 찾게 되었습니다.

그것은 바로 옵션이었고 그것도 rau 중에 a라는 옵션이었습니다.

$ ar rcu libTest.a 1.o 2.o 4.o 5.o
$ ar tv libTest.a 
rw-r--r-- 0/0  19608 Dec  5 14:41 2014 1.o
rw-r--r-- 0/0  15776 Dec  5 14:41 2014 2.o
rw-r--r-- 0/0  15672 Dec  5 14:41 2014 4.o
rw-r--r-- 0/0  16168 Dec  5 14:41 2014 5.o

일반적으로는 위와 같이 파일을 묶습니다. 다만 archive 파일 안에 포함된 파일의 순서가 중요한 경우에는 a, b, i 의 옵션을 필요에 따라 사용합니다. 위에 인용한 페이지에도 언급되어 있지만 간단하게 설명하면 a는 지정된 파일 위치 다음에(after), b는 이전에(before), i는 b와 동일한 기능을 합니다. 똑같은 걸 왜 만들었는지는 모르겠습니다. 배포판에 따라 옵션이 다르다던가.. 하는 이유일런지? 어쨌든 중요하지 않습니다.

 

위에서 합쳐놓은 libTest.a 파일을 가지고 설명을 하면 이 파일엔 1.o, 2.o, 4.o, 5.o 파일이 포함되어 있습니다. 미처 3.o를 못 넣었는데 꼭 2.o와 4.o 사이에 넣고 싶다고 합시다. 그러면 ar ra 2.o libTest.a 3.o 라는 명령을 내리거나 ar rb 4.o libTest.a 3.o 라는 명령을 내리면 꼭 2.o와 4.o 사이에 3.o가 들어갑니다.

 

돌아온 길이 멀지만(나중에 기억 안날 때 다시 도움 받으려고 나름 자세하게? 남기는 중) 어쨌든 저 Makefile 내용에 보면 rau라고 해서 a 옵션은 지정되어 있지만 어느 곳에 넣을 것인지가 지정되어 있지 않습니다. 바로 위에 소개된 경우의 2.o나 4.o라는 기준이 있어야 그 파일의 앞에다 넣든 뒤에다 넣든 할텐데 그런 부분이 되어 있지 않아서 거창한 'File format not recognized' 라는 문제가 발생했습니다... make 매크로로 자동화된 위치이고 굳이 순서가 필요해보이지 않아서 과감하게 a 옵션을 삭제했더니 정상적으로 잘 묶입니다.

 

혹시나 이런 문제가 아닌데 이 글을 찾아 오신 분들은 제가 이 글 첫 부분에 언급한 '갖은 시도' 를 키워드로 해서 검색하시기 바랍니다. 잘 나와 있습니다.