문제

컴파일러에 문제가있어 라이브러리에서 사용하고 싶은 함수에 대한 '정의되지 않은 참조'가 있다고 말합니다. 문제에 대한 정보를 공유하겠습니다.

  • 나는 C에 대한 GCC로 크로스 컴파일하고 있습니다.
  • 프로토 타입이 포함 된 다른 헤더가 포함 된 포함 된 헤더를 통해 액세스하는 라이브러리 기능을 호출하고 있습니다.
  • -i를 사용하여 헤더 디렉토리를 포함 시켰으며 그것이 발견되고 있다고 확신합니다.
  • 먼저 .O 파일을 작성한 다음 별도의 명령으로 연결합니다.

그래서 내 생각은 라이브러리 파일을 포함하는 순서 일지 모르지만 주문하는 올바른 방법이 무엇인지 잘 모르겠습니다. .o 파일 전후에 헤더 폴더를 포함 시켰습니다.

어떤 사람들은 링커가 어떻게하는지에 대한 설명이 좋을 것이라고 제안합니다.

감사!


답변에 대한 응답

  • 라이브러리 파일이 없습니다.
  • 라이브러리 파일에 대한 나의 이해는 단지 헤더 및 소스 파일 모음이지만 소스에서 만든 .O 파일 모음 일 것입니다!
  • 라이브러리 개체 파일이 생성되지 않아야 할 것입니다. 예, 포함과 도서관의 차이점을 이해하지 못하는 것 같습니다.

모든 응답에 감사드립니다! 나는 도서관에 대해 많은 것을 배웠다. 모든 응답을 받아 들인 답변으로 넣고 싶습니다 :-)

도움이 되었습니까?

해결책

.o 파일을 생성하기 위해 라이브러리에서 .c 파일을 컴파일하지 않는 것 같습니다. 링커는 라이브러리를 컴파일하여 생성 된 .o 파일에서 프로토 타입의 구현을 찾습니다.

빌드 프로세스가 라이브러리 .C 파일을 컴파일합니까?

실제로 소스 코드 인 경우 왜 "라이브러리"라고 부릅니까?

다른 팁

헤더는 기능 선언 및 기능 정의를 제공합니다. 링커를 허용하려면 함수의 구현 (정의되지 않은 참조를 제거)을 찾으려면 컴파일러 드라이버 (GCC)에 기능이 -L 플래그를 사용하는 특정 라이브러리를 연결하도록 요청해야합니다. 예를 들어 -lm은 수학 라이브러리를 연결합니다. 함수의 매뉴얼 페이지는 일반적으로 기능을 찾기 위해 지정 해야하는 라이브러리를 지정해야합니다.

링커에서 지정된 라이브러리를 찾을 수없는 경우 -L 스위치 (예 : -l/usr/local/lib)를 사용하여 라이브러리 검색 경로를 추가 할 수 있습니다. Library_Path 환경 변수를 통해 라이브러리 경로에 영구적으로 영향을 줄 수 있습니다.

다음은 문제를 디버깅하는 데 도움이되는 추가 세부 사항입니다. 컨벤션에 의해 라이브러리 파일의 이름은 lib로 접두사를 붙이고 (정적 형태로) .a 확장자가 있습니다. 따라서 시스템의 기본 수학 라이브러리 (-LM과 연결된 것)의 정적으로 연결된 버전은 일반적으로 /usr/lib/libm.a에 있습니다. 주어진 라이브러리가 정의하는 기호를 보려면 라이브러리 파일에서 NM- 정의 전용을 실행할 수 있습니다. 내 시스템에서 libm.a에서 명령을 실행하면 다음과 같은 출력이 제공됩니다.

e_atan2.o:
00000000 T atan2

e_asinf.o:
00000000 T asinf

e_asin.o:
00000000 T asin

컴파일러가 사용하는 라이브러리 경로와 기본적으로로드하는 라이브러리를 확인하려면 -V 옵션으로 GCC를 호출 할 수 있습니다. 다시 내 시스템에서 이것은 다음과 같은 출력을 제공합니다.

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o

라이브러리와 헤더 개념을 혼합 한 것을 두려워합니다. 도서관이 있다고 가정 해 봅시다 libmylib.a 기능이 포함되어 있습니다 myfunc() 그리고 해당 헤더 mylib.h 그것은 프로토 타입을 정의합니다. 소스 파일에서 myapp.c 직접 또는 직접 또는 다른 헤더를 포함하는 헤더를 포함합니다. 예를 들어:

/* myapp.h
** Here I will include and define my stuff
*/
...
#include "mylib.h"
...

소스 파일은 다음과 같습니다.

/* myapp.c
** Here is my real code
*/
...
#include "myapp.h"
...
/* Here I can use the function */
myfunc(3,"XYZ");

이제 얻을 수 있도록 컴파일 할 수 있습니다 myapp.o:

gcc -c -I../mylib/includes myapp.c

-나는 단지 GCC에 헤더 파일이 어디에 있는지 알려주고 라이브러리 자체와 관련이 없습니다!

이제 응용 프로그램을 실제 라이브러리와 연결할 수 있습니다.

gcc -o myapp -L../mylib/libs myapp.o -lmylib

주목하십시오 -L 스위치는 GCC에 라이브러리가 어디에 있는지, -l 코드를 라이브러리에 연결하도록 지시합니다.

이 마지막 단계를 수행하지 않으면 설명한 문제가 발생할 수 있습니다.

더 복잡한 다른 경우가있을 수 있지만 귀하의 질문에 따르면 이것이 문제를 해결하기에 충분하기를 바랍니다.

Makefile 및 귀하가 호출하려는 라이브러리 기능을 게시하십시오. 간단한 GCC MakeFiles조차도 일반적으로 다음과 같은 선이 있습니다.

LIBFLAGS =-lc -lpthread -lrt -lstdc++ -lShared -L../shared

이 경우 표준 C 라이브러리를 연결하는 것을 의미합니다.

링커가 라이브러리를 찾을 수있는 경로를 추가해야한다고 생각합니다. GCC/LD에서는 -l로 -L로이를 수행 할 수 있으며 -L로 라이브러리를 수행 할 수 있습니다.

-ldir,-library-path = dir

표준 검색 디렉토리 이전의 검색 디렉토리 DIR (이 옵션은 해당 디렉토리를 검색하는 -L 옵션보다 우선합니다).

-larch, -library = 아카이브

링크 할 파일 목록에 아카이브 파일 아치를 포함시킵니다.


답변에 대한 응답 - 라이브러리에는 .A 라이브러리 파일, 단지 .h 및 .c가 없으므로 -L은 Abtoriate가 아닙니다.

그러면 먼저 라이브러리를 만들어야 할 수도 있습니까?

gcc -c mylib.c -o mylib.o
ar  rcs libmylib.a      mylib.o

새로운 버전의 GCC로 프로그램을 구축 할 때이 문제가 발생했습니다. -std = gnu89 옵션으로 GCC를 호출하여 문제가 해결되었습니다. 분명히 이것은 인라인 함수 선언 때문이었습니다. 이 솔루션을 찾았습니다 https://gcc.gnu.org/gcc-5/porting_to.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top