컴파일시 왜 "undefined reference error"가 나는지요?

aeronova의 이미지

안녕하세요,
제가 liblip라는 library를 사용할 일이 있어서 소스를 받아서 make install 과정까지 마쳤습니다.
(제 환경은 DevCpp + MinGW + Gygwin + Windows XP 입니다.)
설치하니 /usr/local/include와 /usr/local/lib에 각각 header와 liblip.a가 위치하였습니다.
문제는 이제 설치된 liblip.a를 사용하여 간단한 예제를 컴파일 하는 것이 잘 되지 않았습니다.

g++ -I"/usr/local/include" -L"/usr/local/lib" -lm -lglpk -llip liblipex.cpp

위와 같이 컴파일하니 수 많은 에러가 발생하는데 모두 undefined reference error였습니다.
대강 아래와 같이 말입니다.
C:\DOCUME~1\gtg106p\LOCALS~1\Temp/ccQbcaaa.o:liblipex.cpp:(.text+0x3c7): undefin
ed reference to `SLipIntBasic::ComputeLocalLipschitz(int, int, double*, double*)'
C:\DOCUME~1\gtg106p\LOCALS~1\Temp/ccQbcaaa.o:liblipex.cpp:(.text+0x466): undefin
ed reference to `SLipIntBasic::Value(int, int, double*, double*, double*, int*)'
 
.....
 
collect2: ld returned 1 exit status

음... 설치 과정에서 에러도 없었고 library 경로도 정확히 표시해주었는데 이런 문제가 생기니 난감합니다.
어떻게 해결해야 할지 모르겠구요.ㅜㅜ
꼭 사용해야 하는 library라서 어떻게 좀 문제를 해결해야 하는데, 조언 좀 주시면 감사하겠습니다.
cinsk의 이미지

일단 nm(1) 등을 써서 undefined symbol이라고 나온 symbol이 지정한 라이브러리에 포함되어 있는지 확인하기 바랍니다. (http://kldp.org/node/68410/ 참고)

그리고 라이브러리를 지정한 순서가 제대로 되어 있는지 확인 바랍니다.
gcc는 써 준 순서대로 라이브러리 또는 오브젝트 파일을 링크합니다. 예를 들어 b.o가 라이브러리 util에 있는 함수를 쓴다고 할 때, 다음과 같이 하면 undefined symbol 에러가 납니다:

$ gcc a.c -lutil b.o

다음과 같이 해야 합니다:

$ gcc -a.c b.o -lutil

마찬가지로 util 라이브러리가 snippet 라이브러리에 있는 함수를 쓴다면 반드시 -lutil이 -lsnippet의 앞에 있어야 합니다.

때때로 라이브러리가 잘 못 설계되거나 기타 다른 이유로 인해, 순서를 바꾸지 못한다거나 할 경우도 있습니다. 이 경우 링커 옵션을 써서 undefined symbol이 나오지 않을 때까지 지정한 라이브러리를 계속 뒤지도록 할 수 있기는 합니다. 예를 들어 util과 snippet 두 라이브러리에 있는 함수들은 계속 찾아보도록 지정하고 싶다면 다음과 같이 합니다:

$ gcc a.c -Wl,-\(,-lutil,-lsnippet,-\)

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

aeronova의 이미지

친절한 답변 감사합니다. 알려주신 gcc의 -Wl 옵션으로 알아서 찾아보게 시켰는데 ld가 glpk를 찾지 못한다면서 중단되었습니다 (liblip가 libglpk에 의존합니다). 정말 이상합니다. -L로 지정한 디렉토리에 분명히 libglpk.a가 있거든요.ㅜㅜ

그나저나 undefined reference란 결국 함수가 "선언"만 되었고 "정의"는 되지 않았다는 말 같은데, 보통 선언은 헤더에 하고 정의를 따로 *.cpp에 하는 것에 비추어 보면 왜 이런 현상이 발생하는지 선뜻 이해가 되지 않습니다. 결국 undefined reference란 소리는 컴파일시 헤더 부분만 고려되었다는 뜻인가요?

undefined reference 문제가 보통 library를 link하는 순서의 조작으로 간단히 해결가능했으면 좋겠습니다...

It's better to burn out than to fade away. -- Kurt Cobain.

kslee80의 이미지

undefined reference 가 발생하는 원인 중에 가장 많은 것이
라이브러리의 링크를 제대로 하지 못하는 경우죠.

말씀하신대로 undefined reference 는 함수가 선언되고 사용되었지만,
실제로 그 함수의 정의가 없기 때문에 발생하는 것이고...
대부분의 라이브러리들은 함수의 선언은 .h 파일에,
함수의 정의는 컴파일된 상태로 라이브러리 파일에 포함되기 때문에
사용하는 함수가 포함된 라이브러리 파일을 링크하지 않는다면 바로 만나게 되죠.

라이브러리에 포함된 함수가 아닌 직접 정의한 함수에서 undefined reference 가 난다면
1. 함수 사용시나 정의시의 오타
2. C++ 의 경우는, 함수 사용시에 전달되는 인자의 타입 불일치
에 의한 경우가 많죠.

benedict의 이미지

제목의 IDE 환경을 사용중이며 똑같은 에러를 겪었습니다.
그리고, 에러는 혼신의 노력과 구글링으로 해결되었습니다.
암만 봐도 이상없는데... 했었죠... 해결은 역시였습니다.

프로젝트 특성-> Paths and Symbols-> Source Location에서 빠져있는 부분이 보이길래 추가해서 해결하였습니다.
도움되시기를 바라며 글 남깁니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.