5. Miscellaneous

5.1. nm 명령

nm(1)명령은 주어진 라이브러리의 심볼의 리스트를 보고한다. 이것은 정적, 공유 라이브러리에서 모두 동작한다. 주어진 라이브러리에서, nm(1)은 정의된 심볼의 이름, 각각의 심볼의 값, 심볼의 타입을 나열한다. 이것은 또한 라이브러리에서 가능하다면(-l옵션을 보라), 심볼이 소스코드의 어디에서 정의되었는지 알려준다(파일이름과 줄 번호를 표시함으로서).

심볼타입은 더 많은 설명을 요구한다. 타입은 한글자로써 표시된다; 소문자는 타입이 지역적이라는 것이고, 대문자는 타입이 전역적(외부적)이라는 것을 의미한다. 보통의 심볼타입들은 다음과 같다. T (코드섹션에서 보통의 정의), D (초기화 데이터 섹션), B (초기화되지 않은 데이터 섹션), U (정의되지 않음; 심볼이 라이브러리에의해 사용되지만 라이브러리에 의해 정의되지 않았다), W (약함; 다른 라이브러리가 이 심볼을 정의한다면, 그 정의가 이 정의를 오버라이드 할 수 있다).

당신이 함수의 이름을 알지만, 어떤 라이브러리에서 정의되있는지 기억하지 못한다면, grep으로 라이브러리를 찾으면서 nm의 ``-o''옵션(각각의 줄의 파일 이름을 앞에 붙인다)을 사용할 수 있다. bash에서 당신은 /lib, /usr/lib와 /usr/lib, /usr/local/lib의 하부 디렉토리에서 ``cos''를 다음과 같이 찾을 수 있다.
nm -o /lib/* /usr/lib/* /usr/lib/*/* \
      /usr/local/lib/* 2> /dev/null | grep 'cos$' 

nm에 대해 더 많은 것을 알고 싶으면 info:binutils#nm에 ``정보'' 문서가 있따.

5.2. 특별함수 _init, _fini

두개의 특별한 함수가 초기화와 종결화의 모둘을 돕는다:_init와 _fini. ``_init''함수가 라이브러리에 의해 내보내진다면, 라이브러리가 처음에 열어질때 불릴것이다(dlopen()이나 공유라이브러리의 형태로). C 프로그램에서, 이것은 당신이 _init이란 이름이 붙은 어떤 함수를 정의했다는 것을 의미한다. 이것에 대한 _fini함수가 있는데, 이것은 클라이언트가 라이브러리 사용을 끝낼때 불리는 함수이다(0나 프로그램의 정상종료를 가져오는 dlclose()의 형태로). 이 함수의 C 프로토타입은 다음과 같다:
  void _init(void);
  void _fini(void);

``.o''파일을 gcc에서 컴파일 할 때, ``-nostartfiles''옵션을 넣어라. 이것은 C컴파일러가 .so파일에 대해 시스템 시작 라이브러리를 링크하도록 해준다. 그렇지 않으면, 당신은 ``multiple=definition''에러를 만날 것이다. Jim Mischel과 Tim Gentry이 _init, _fini함수에 대한 논의에서 글을 쓰는데 도움을 줬을 뿐만 아니라 이런 제안을 해준것에 의해 감사한다.

5.3. 공유 라이브러리는 스크립트가 될 수 있다

GNU 로더가 특별한 스크립트 언어를 통해 보통의 라이브러리 형식대신 텍스트 파일의 형태로 공유 라이브러리를 유지하게 하는것은 의미가 없다. 이것은 간접적으로 다른 라이브러리를 합치게 됨으로서 유용하다. 예를들어, 나의 시스템중 하나에서 돌아가는 /usr/lib/libc.so의 리스트가 있다:
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )

이것에 대해 더 많은 정보를 얻기위해 ld링커 스크립트를 보아라(ld명령어). 일반적인 정보는 info:ld#Options와 info:ld#Commands에서 얻을수 있고, info:ld#Option Commands에서 명령어의 정보를 얻을수 있다.

5.4. GNU libtool

만약 당신이 다른 많은 시스템에 포팅할 응용프로그램을 제작한다면, 당신은 라이브러리를 만들고 설치하기 위해 GNU libtool를 사용하는것을 고려해야 할 것이다. GNU libtool은 스크립트를 지원하는 일반적인 라이브러리이다. Libtool은 일관적이고 포팅가능한 인터페이스속에 공유라이브러리의 복잡도를 줄여준다. Libtool은 오브젝트 파일을 만들고, (정적, 공유)라이브러리를 링크하고, 실행파일을 링크하고, 실행파일을 디버그하고, 라이브러리를 설치하고, 실행파일을 설치하는데 포팅가능한 인터페이스를 제공한다. 이것은 또한 libltdl을 포함하는데, 동적 적재 프로그램의 포팅가능한 감싸는 역할을 한다. 더 많은 정보를 위해서 http://www.gnu.org/software/libtool/manual.html의 문서를 참고하라.

5.5. 공간을 위해 심볼을 제거하기

생성된 파일에 포함되는 모든 심볼은 디버깅에 유용하지만, 너무 많은 공간을 차지한다. 만약 공간이 필요하다면, 그것들의 일부를 지워라.

최선의 접근법은 오브젝트 파일을 정상적으로 생성하고, 디버깅과 검사를 먼저한다(이것들을 가지고 디버깅, 검사를 하는것은 매우 편하다). 그리고나서, 프로그램을 완전히 검사했으면, strip(1)을 사용해서 심볼들을 지워라. strip(1) 명령은 심볼을 지우는데 많이 편리하게 해준다; 자세한것은 그것의 문서를 참조하라.

다른, GNU ld욥션의 다른 것으로는 ``-S''와 ``-s''가 있다; ``-S''는 출력파일에서 (모든 심볼이아닌)디버거 심볼 정보를 빠뜨린다. ``-s''옵션은 출력파일에 모든 심볼 정보를 써 넣는다. ``-Wl, -S''와 ''-Wl,-s''로서 gcc를 통해 이 옵션을 쓸 수 있다. 당신이 항상 심볼을 제거하고, 이 옵션이 불필요한것이라면, 그냥 편하게 느껴라. 하지만, 이것은 덜 유연한 방법일 것이다.

5.6. 매우 작은 실행화일들

당신은 Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux문서가 유용하다는 것을 알것이다. 이것은 매우작은 프로그램들이 어떻게 만드는지 설명한다. 사실, 일반적인 상황에서 이런 트릭을 사용할 필요는 없다. 하지만 이것은 ELF가 어떻게 동작하는지 보여주는 좋은예이다.

5.7. C++초기화 속도 높이기

KDE 개발자는 많이 재 배치를 해야하게때문에 큰 GUI C++응용프로그램이 시작하는데 오래걸린다는 것을 안다. 이것에 여러가지 해결책이 있다. 더 많은 정보를 위해 Making C++ ready for the desktop (by Waldo Bastian)를 참고하라.