2009-06-03 3 views
2

연결 문제가 있습니다. 공유 라이브러리 libfoo.so에 링크해야합니다. read 함수에 의존합니다.이 파일은 read.c에 자신을 정의하고 싶습니다.nm보고 기호가 정의되었지만 ldd보고 기호가 정의되지 않았습니다.

나는 컴파일하고 모든 것을 함께 연결하지만, 런타임에 나는 기호를보고 나노

/home/bar/src/libfoo.so: undefined symbol: sread. 

$nm baz | grep sread 
    00000000000022f8 t sread 

을 정의되어 있지만 LDD는 심볼이
$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so) 

을 정의되지보고 오류를 얻을

무엇을 제공합니까? libfoo.so가 공유 라이브러리라는 사실을 알고 있습니까?

+0

아마 모든 공유 객체와 실행 파일이 제목을 비추도록 전체 링크를 게시해야합니다. – lothar

답변

13

먼저 'read'라는 함수 정의는 모든 UNIXen의 표준 libc 함수이기 때문에 나쁜 아이디어 (TM)입니다. 이렇게하면 프로그램의 동작이 정의되지 않습니다.

두 번째로 libbaz.so에 정의한 read 함수의 결과는 출력에 't'으로 표시됩니다. 즉,이 함수는 로컬입니다 (libbaz.so 외부에서는 볼 수 없음). 전역 기능은 'T'nm으로 표시됩니다.

'static int read(...)'을 read.c에 정의 할 때 사용 했습니까? libbaz.so을 컴파일하고 링크 할 때 명령 줄에 링커 스크립트 인 attribute((visibility(hidden))) 또는 -fvisibility=hidden을 사용 했습니까?

+0

함수의 이름이 실제로 읽히지 않는다. 나는 단순하게 만들려고 노력했다. Ahh ... 당신이 맞습니다. -Wl, - 내보내려는 두 개를 제외한 모든 심볼을 로컬로 유지하는 파일을 포함하는 version-script를 사용하고 있습니다. 나는 분명히 read 함수를 익스포트 할 필요가있다. – codehippo

-1

공유 라이브러리를 빌드 할 때 모두 동일한 라이브러리 또는 다른 (공유) 라이브러리에서 정의되지 않은 기호를 해결해야합니다. 링커는 이 아니며은 라이브러리의 정의되지 않은 심볼을 응용 프로그램의 심볼로 해결합니다.

+0

나는 baz가 실제로 공유 라이브러리임을 명확히해야한다. 그래서 이것은 읽기 기능 만 포함하는 공유 라이브러리를 만들어야한다는 것을 의미합니까? 이 공유 라이브러리 (libread.so)와 공유 라이브러리 libfoo.so에서 정의되지 않은 심볼을 해결하도록 링커에 알리는 명확한 방법이 있습니까? – codehippo

+2

당신은 꽤 잘못 생각합니다 : 런타임 로더는 심볼이 동적 테이블에서 "내 보낸"경우 (예 : 실행 파일이 -rdynamic로 링크 된 경우) 공유 실행 파일의 심볼로 공유 라이브러리의 정의되지 않은 심볼을 행복하게 해결합니다. . –

+0

@codehippo 당신은 baz가 공유 라이브러리이고 그 이름이 그 가정으로 이어지지 않는다고 말하지 않았습니다. – lothar

1

위의 오류는 C 코드를 G ++로 컴파일하고 링크 할 때도 발생할 수 있습니다. G ++은 이름 맹 글링을 수행하기 때문에 실제 기호는 "_Zsds_ [function_name] _"과 같을 수 있으므로 링커가 맹 글링되지 않은 이름을 검색 할 때 질식합니다.

Wikipedia에 설명 된 작업에 따라 문제가 해결되었다는 것을 제외하면 오늘 같은 행동이 발생했습니다. 기본적으로 C++ 컴파일러로 컴파일 된 C 코드는 심볼 테이블에 "mangled"이름을 가지므로 C 스타일의 심볼 해석이 실패하게됩니다.

관련 문제