link시에 라이브 러리에 있는데 자꾸 없다라는 메세지의 원인은
글쓴이: cbycby / 작성시간: 목, 2004/07/01 - 7:34오후
현재 Microwindows 를 이용해서 Embedded Target 시스템용 UI를 테스트 하고 있는 중에 문제가 발생하였습니다. :cry:
아래를 보면, libmwengine.a 파일에 보면 분명히 GdDrawImageFromFile 이라는 함수가 들어 있습니다.
[korone@koronelinux lib]$ nm libmwengine.a | grep DrawImage 00000e70 T GdDrawImage U GdDrawImage 000016a8 T GdDrawImageFromBuffer 000017d8 T GdDrawImageFromFile 00000000 T GdDrawImageToFit
이를 아래와 같이 컴파일 하는데...
아래는 Makefile 내용중 일부입니다.
중략 ... MWINLIBS = \ $(MWINPATH)/lib/libmwin.a \ $(MWINPATH)/lib/libmwinlib.a\ $(MWINPATH)/lib/libmwengine.a \ $(MWINPATH)/lib/libmwdrivers.a \ $(MWINPATH)/lib/libmwfonts.a \ $(MWINPATH)/lib/libmwimages.a \ $(MW_CORE_LIBS) FT2LIB = $(FT2PATH)/objs/.libs/libfreetype.a PIMWLIBS = gui01_main.o ../../mwgui/libpimwgui.a INC=-I../../common -I../../lib -I../../mwgui -I$(MWINPATH)/include -I$(FT2PATH)/include #LIBS=$(MWINLIBS) $(FT2PATH)/objs/.libs/libfreetype.a gui01_main.o ../../mwgui/libpimwgui.a LIBS=$(MWINLIBS) $(FT2LIB) $(PIMWLIBS) 중략 ... @sh -c 'for i in $(OUT); do echo making $$i...; $(CXX) $(CFLAGS) $(INC) $(LFLAGS) -o $$i $$i.cc $(LIBS); if [ $$? -ne 0 ]; then exit 1; fi; done'
이와 같이 컴파일 하는데...
대체 분명 컴파일 시에도 libmwengine.a 를 포함시켰는데... 왜 자꾸
Quote:
undefined reference to `GdDrawImageFromFile(_mwscreendevice*, int, int, int, int, char*, int)'
라는 에러가 나타나는 것일까요?
이것때문에 일이 안되네요... :(
Forums:
c의 header를 특별한 guard없이 c++파일에서 직접inclu
c의 header를 특별한 guard없이 c++파일에서 직접
include한것으로 짐작이 되네요.
GdDrawImageFromFile를 정의한 header를 foo.h라고 하면
extern "C" {
#include "foo.h"
}
이런 식으로 c++파일에서 include 하세요.
답변 감사합니다.
지금 테스트 해봐야겠습니다. :D
http://www.korone.net QT 커뮤니티 사이트
음... 답변해 주신대로 해 보았는데도 안되네요...
C 헤더를 include 한 곳 마다 extern "C" { }; 로 내부를 처리했는데도 결과가 마찬가지네요...
대체 이일을 어찌해야 할까요?
다른 방법으로 해결책 알고 계신분 있나요?
이것때문에 오늘 아무것도 못했어요 ㅜ.ㅡ
http://www.korone.net QT 커뮤니티 사이트
Re:
직접 작성한 코드들중에 해당 함수를 사용한 부분이 있는지요?
그렇다면 저 프로토타입에 '완벽하게' 들어맞는지를 확인해야 합니다.
라이브러리에 포함된 함수가 저 함수를 부를때,
해당 함수가 프로토타입을 잘못 맞춰서 부르는 경우도
저런 문제가 생길수 있습니다.
C 와 틀리게 C++ 은 함수 프로토타입 체크가 엄격해서,
약간만이라도 틀리면 바로 undefined 에러를 만나게 됩니다.
(물론, undefined 에러가 나는 이유는..
C++ 은 Overloading 을 지원하는 언어이기 때문이죠.)
만약에 두번째 문제라면 많이 골치아퍼집니다;;
라이브러리들의 소스를 구해서 잘못 맞춘 프로토타입을 다 맞춰준 다음
재컴파일해서 사용하거나,
아니면 C++ 을 사용한 코드들을 모두 다 C 로 바꿔야 할겁니다.;
컴파일 과정에서 나온 에러인지 링크 과정에서 나온 에러인지명확히 해주
컴파일 과정에서 나온 에러인지 링크 과정에서 나온 에러인지
명확히 해주세요.
전자라면 kslee80님 답변이 설득력이 있네요
-- 아쉬운 하루 되세요 --
[quote]컴파일 과정에서 나온 에러인지 링크 과정에서 나온 에러인지
링크과정에서 나오는 에러입니다.
흠... 또 문제들을 살펴 보아야겠군요...
기존 몇몇 라이브러리들이 링크가 잘 되는것으로 봐서는(전체 5개중 1개만 그러한 증상을 일부 라이브러리의 문제인것으로 보이는데...
http://www.korone.net QT 커뮤니티 사이트
저두 지금 동일한 현상에 시달리고 있습니다.사실은 이런 경우가 발
저두 지금 동일한 현상에 시달리고 있습니다.
사실은 이런 경우가 발생하면, 링크시에 나열하는 라이브러리나 오브젝트 파일의 위치를 바꾸면 더 많은 undefined reference에러가 발생하거나 사라지는 기묘한(?) 현상이 발생하더군요.
몇번의 시행착오를 거쳐 겨우 해결되어서 문제없이 링킹을 하다가... 어느날 좀 많은 부분의 코드가 추가되거나 수정되면서 또 유사한 문제가 발생하곤 했어요...
위의 님들께서 말씀하신대로 extern "C"라던지 extern선언부, 그리고 프로토타입 missmatch 등등 안해 본게 없지만 다 마찬가지였습니다.
링킹시 .a파일을 오브젝트 파일처럼 링킹도 해 보고, -l라이브러리로 링킹도 해보고 다 해봤지만(물론 -L로 위치지정도 확인했구요), 여간해서 잘 사라지질 않더군요... 자리만 요목조목 잘 끼워맞춰서 넘어가면 다행이긴 하지만, 여간 찜찜하지 않더라고요.
왜냐면 다음번 업데이트에 또 문제가 발생할지도 모르니까요...
어쨌든 이부분을 완전히 해결할려면 사용하시는 덩치 큰 라이브러리를 동적라이브러리로 만드셔야 합니다. 그러면 이런 문제는 완전히 사라집니다.
(유추하건대... 링킹시에 사용하는 offset범위를 초과하거나 링커의 오류인걸로 추측은 하지만, 정확한 원인은 모르겠네요. 아무튼 실행시에 주소가 결정되는 동적라이브러리라면 이런문제를 고려하지 않아도 되겠지요.)
하지만, 저두 임베디드 쪽 작업을 하는데, 동적라이브러리를 사용하는 거 자체를 부담스러워 하는 경우에는 다른 방법이 없나 고민하게 되지요.
오늘도 그 고민을 하다가 우연히 저랑 비슷한 고민을 하신 분이 계신거 같아서 이렇게 몇자 적습니다......
예전에 누가 올려둔 글묶음입니다..도움이 되실지 모르겠네요.
http://bbs.kldp.org/viewtopic.php?t=535&highlight=undefined+reference
저두 동일한 현상에 시달린 적이 있습니다.그때 해결방법은 yeppig
저두 동일한 현상에 시달린 적이 있습니다.
그때 해결방법은 yeppiguy님의 말씀대로
링크시에 나열하는 라이브러리나 오브젝트 파일의 위치를 바꾸면
이방법을 사용 했었습니다.그리고, 프로젝트의 자체 라이버러리를 통합하는 과정을 거쳤던 기억이 있습니다.
여러개로 쪼개어진 라이버러리를 하나로 묶어 버리는 작업을 했었던... --> 이게 삽잘이었을까요..
누군가 더 좋은 해결 방법이 있으면.. 제발 알려 주세요.
>>>행복한 웃음<<<
[quote="yeppiguy"]사실은 이런 경우가 발생하면, 링크시에
이 문제가 발생하는 가장 큰 이유는 library module 이나 object file들이 서로 상호 참조를 하는 구조로 작성되었을 때 입니다. 또는 link 순서를 잘못 적어준 경우에도 발생합니다.
간단하게 예를 들면
위와 같이 libTestA에서 libTestB를 참조하고(funcC()), 다시 libTestB에서 libTestA를 참조(funcB())하는 경우와 같을 때 발생합니다.
위와 같이 link를 하면 funcB()가 없다고 에러가 나죠...
간단하게 해결하려면 물론 다음과 같이 하면 해결은 되나 좋은 방법은 아니죠.
상용 toolchain 중에서는 link시에 library가 모두 resolve 될 때까지 계속 recursive하게 library를 search하는 경우도 있지만(diab compiler가 이러던것 같았는데...) gnu ld의 경우 link시의 적어준 순서데로 왼쪽부터 오른쪽으로 한번씩만 search를 하여 link합니다.
일반적으로 module을 layering하여 각각의 layer마다 따로 library를 만들고 이를 link 시에 상위 layer먼저 적어주기 때문에 이런 현상이 발생하지 않습니다.
library를 만들때 이와 같이 여러 library들이 상호 참조하는 구조는 바람직하지 않습니다.
이런 경우 link시에 에러 출력결과를 보고 에러 출력된 소스파일내에 관련 함수를 호출하는 곳을 찾아
- library간에 상호 참조하는 경우인지
- 아니면 link시에 library순서를 잘못 쓴것인지
원인을 찾아보고 그렇게 되지 않도록 수정하여야 합니다.
아니면 속편하게 gnu ld의 -( xxx -) option을 사용하면 recursive search가 가능합니다.
자세한 사항은 gnu ld manual을 참조하세요.
http://www.fsf.org/software/binutils/manual/ld-2.9.1/html_mono/ld.html
Re: link시에 라이브 러리에 있는데 자꾸 없다라는
위의 코드는 틀림없이(:)) C library의 Header에 extern "C"이 선언이 안되어 C++ 코드에서 mangling이 일어나서 링크 오류가 발생하는 것입니다.
확인 방법은 일단
nm -A *.o *.a | grep GdDrawImageFromFile
모든 오브젝트와 라이브러리에서 T로 된것과 U 로 된 것이 제대로 존재하는지 확인하면 됩니다.
nm -AC *.o *.a | grep GdDrawImageFromFile
로도 해보세요.
-A 옵션은 이런 오류를 찾는데 아주 유용합니다.
---
http://coolengineer.com
위의 것은 c, c++ 문제가 아니라 link시 option 순서가 문제
위의 것은 c, c++ 문제가 아니라 link시 option 순서가 문제일 확률이 가장 높습니다.
LIBS=$(MWINLIBS) $(FT2LIB) $(PIMWLIBS)
로 되어 있는데 PIMWLIBS에 gui01_main.o 가 포함 되어 있네요.
아마 gui01_main.o에서 에러나는 함수를 참조하는 것 같은데 다음과 같이 하면 해결 될 겁니다.
LIBS=gui01_main.o $(MWINLIBS) $(FT2LIB) $(PIMWLIBS)
물론 PIMWLIBS에서는 gui01_main.o를 빼야죠.
댓글 달기