2013-03-01 3 views
3

저는 Zed Shaw의 Learn C를 사용하여 C 프로그래밍을 배우려 고 노력하고 있습니다. ex26에서 소프트웨어를 설치하는 데 사용되는 "devpkg"프로그램을 만들었습니다. 이 연습에서는 Apache Portable Runtime 라이브러리를 설치해야합니다. 나는이 프로그램은 다음 메이크 파일을 사용하여 컴파일 할 수 없었다이 연습의 코드를 작성 후 :Library Linking

PREFIX?=/user/local 
    CFLAGS=-g -Wall -I${PREFIX}/apr/include/apr-1 -I{PREFIX}/apr/include/apr-util-1 
    LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1 

    all: devpkg 

    install: all 
      install -d${DESTDIR}/${PREFIX}/bin/ 
      install devpkg ${DESTDIR}/${PREFIX}/bin/ 

    clean: 
      rm -f *.o 
      rm -f devpkg 
      rm -f *.dSYM 

이 메이크 내가 4 월 라이브러리 함수의 모든했다 "$ devpkg 만들"을 사용하는 경우와 같이 작동하지 않았다 선언했다. 사이드 노트로 우분투 가상 머신에서 이것을 실행하고 있습니다. 텍스트에서 주어진 해결책은 config 파일을 변경 한 다음 링커가 적절한 라이브러리를 찾을 수 있도록 "ldconfig"를 실행하는 것입니다.
필자는 ldconfig의 매뉴얼 페이지가 올바르게 기능을 제대로 활용하는지 이해하지 못합니다. ldconfig를 올바르게 실행하려면 어떻게해야합니까?

또한 일부 파고 후에 "LDFLAGS"대신 "LDLIBS"를 사용하여 makefile에서 문제가 해결된다는 참조를 발견했습니다. 나는 메이크 파일을 수정하고 프로그램을 컴파일했다.

C 컴파일러가 APR 라이브러리에 올바르게 링크 할 수있게 해주는 "LDFLAGS"와 "LDLIBS"의 차이점은 무엇입니까? makefile을 올바르게 생성하는 방법을 더 잘 이해할 수있는 편리한 명령 목록이 있습니까?

감사합니다. GNU Make Manual에서

+2

'/ usr/local'이 아닌'/ user/local'이 맞습니까? –

+0

네가 맞습니다. 그러나 나는 여기에 오타를 만들었고 그것은 makefile에 없다. – user2073935

답변

3

, 섹션 암시 적 규칙의 10.2 카탈로그 : 하나의 오브젝트 파일
n을 연결

링커를 실행하여 n.o에서 자동으로 만들어 (보통이라고 ld)를 C 컴파일러를 통해 실행합니다. 정확한 레시피는 '$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)'입니다.

보시다시피, LDFLAGS은 오브젝트 파일보다 앞에 있고 LDLIBS은 이후입니다. 때로는 그 순서가 중요 할 수 있습니다 - 분명히 그것은 당신의 경우에 않습니다.

편집 주석 : make의 암시 적 규칙 지원을 사용하는 것이 편리 할 수도 있지만 거의 항상 길 아래로 혼란스러워집니다. 나는 완전한 makefile을 작성하길 강력히 권합니다 - 앞으로 일어날 일을 잘 이해하고 미래의 이런 종류의 문제를 피하는 데 도움이 될 것입니다.

+0

감사합니다. 지금 받으십시오. 나에게 GNU make 매뉴얼을 알려준 점에 대해서도 감사한다. 나는 makefile을 다시 쓰려고 노력할 것이다. – user2073935

3

"LDFLAGS"를 "LDLIBS"로 변경하는 대신이 답변을 추가하고 싶습니다. 위의 해결책은 내 경우에는 효과가 있었지만 다른 사람들이 유용하거나 흥미로 웠던이 스레드를보기 전에 대안 (덜 직접적인) 솔루션을 발견했습니다. 내가 많이보고 있었다 컴파일 할 때 "정의되지 않은 참조"오류 예 :

CC=gcc 
PREFIX?=/usr/local 
CFLAGS=-g -Wall -I$(PREFIX)/apr/include/apr-1 -I$(PREFIX)/apr/include/apr-util-1 
LDFLAGS=-L$(PREFIX)/apr/lib -lapr-1 -laprutil-1 -pthread 
OBJECTS=bstrlib.o db.o shell.o commands.o devpkg.o 

all: devpkg 

devpkg: $(OBJECTS) 
    $(CC) $(CFLAGS) $(OBJECTS) -o devpkg $(LDFLAGS) 

install: all 
    install -d $(DESTDIR)/$(PREFIX)/bin/ 
    install devpkg $(DESTDIR)/$(PREFIX)/bin/ 

clean: 
    rm -f *.o 
    rm -f devpkg 
    rm -rf *.dSYM 

그때 추가했다 :

/MyCode/LCTHW/devpkg/devpkg.c:18: undefined reference to `apr_pool_initialize' 

많은 시행 착오 후, 나는 (여전히 LDFLAGS를 사용하여) 따라서 메이크 변경 .conf 파일은 /etc/ld.so.conf에 있습니다.즉, 4 월 도서관에 다음

/usr/local/apr/lib 

과 경로를 포함하는 d를

sudo ldconfig 

그래서 시스템이 새의 .conf 파일을 선택할 것입니다 실행하고 어디 라이브러리를 찾을 알고있다. 필자가 읽은 바에 따르면 라이브러리가/usr/local/lib에 저장되지 않았기 때문에이 마지막 단계가 필요했던 것 같습니다. .conf 파일을 제거하고 ldconfig를 다시 실행하여 프로그램을 컴파일해도 런타임에 라이브러리를 찾지 못합니다 (내 makefile 또는 OP로 컴파일되었는지 여부에 관계 없음).

내 솔루션을 완전히 이해하지는 못했지만 오류없이 프로그램을 컴파일하고 실행할 수있었습니다. 다행히도이 솔루션은 다른 사람들에게도 흥미로울 것이며 어쩌면 지식이 풍부한 누군가가 왜 더 효과적인지 설명 할 수있을 것입니다.