이 글은 KELP의 조형기님 글을 가져와서 수정한 것입니다.
- 들어가기 -
리눅스를 잘 알지 못할 당시 나는 리눅스에는 왜 Visual C++가 없는지에 대해 불평하였다. 그런 편리한 IDE환경이 없는지에 대해서 참으로 불만이었다. 어쩔 수 없이 이상한 에디터 vi를 배우기 시작했고, 명령 라인에서 gcc 를 구동하기 시작했었다. 그러다 명령 라인에서 gcc 를 계속 두들기니까... 뭐 편한 거 없나 ? 하고 살펴보고, 즉시 make 를 공부했다. 지금까지 이런 과정을 거치면서 리눅스의 전통적인 아니 유닉스의 전통적인 개발 환경과 개발 방법이 아주 매력적이라는 사실을 알게 되었다.
사실 알고 보면 Visual C++의 느낌표를 누르면 이러한 과정이 내부에서 일어나는 것이다. 우리 눈 앞에 안 보일 뿐이다. 나는 이 사실을 깨달았을때 Visual C++/MFC에 정이 뚝 떨어졌다. 지금도 어쩔 수 없는 초보이지만, 그러기에 나름대로 유닉스의 개발환경에 대하여 알아 본다.
- 개요도 -
이번에는 리눅스의 개발 환경이 전체적으로 어떻게 구성되어 있나 살펴보는 것이다. 우선 분류를 하여 나열해 보겠다.
[1] GNU Toolkit
1) Binutils
2) GCC
3) GDB
4) C, C++ library
[2] 디버깅 도구
1) GDB
2) DDD
3) kdbg
4) ldd
5) strace
6) ltrace
7) checker
[3] 시간측정, 성능평가도구
1) time
2) gprof
3) calls
[4] 자동 컴파일링 도구
1) make
2) m4
3) Automake
4) Autoconf
[5] 인터페이스 만들기 도구
1) Xt
2) Motif/Lesstif
3) Xaw3D
4) Tcl/Tk
5) QT
6) GTK+
[6] 버전 관리 도구
1) CVS
2) RCS
3) SCCS
[7] 파일 패치 & 들여쓰기
1) patch
2) diff
3) indent
한눈에 들어오니까 참 좋다. 이것을 보고 있으면 마음이 편안해진다. 빠진 내용이 있으면 피드 백을 해 주기 바란다. 여기에 나열되어 있는 모든 것들을 어느 정도 안다면 글쎄 유닉스/리눅스 초보는 분명 아닐 것이다. 위에서 [1] 항목은 분류항목으로 있기에 좀 그렇지만 대표적이라서 그냥 넣어 두었다.
- 본론 -
그럼 이제 하나하나 항목에 대해서 대충 알아보자. 이 내용들은 필자의 기반 지시과 '러닝 리눅스' 라는 책을 참고하였다. 이 책을 지은 '메트 웰시'라는 작자는 보통 사람은 아닌 것 같다. (www.linuxdoc.org 의 핵심 관리자이다.)
[1] GNU toolkit
1) Binutils - 여기에는 어셈블러(as), 링커(ld) 를 비롯하여 많은 바이너리 도구들이 포함되어 있다.
ld - GNU 링커.
as - GNU 어셈블러. ( 임베디드 리눅스를 하면서 어셈블리어는 필수겠죠?)
addr2line - 주소를 파일명과 라인 수로 변경.
ar - 정적 라이브러리를 만드는 유틸리티. (예 $ ar rs libxxx.a a.o b.o s옵션을 넣으면 ranlib 를 실행하지 않아도 된다.)
c++filt - Filter to demangle encoded C++ symbols.
gprof - 프로파일 정보 출력(프로파일러)
nlmconv - 오브젝트 코드를 NLM으로 변경
nm - 오브젝트 파일의 심볼들을 나열.
objcopy - 오브젝트 파일을 복사 및 변환
objdump - 오브젝트 파일을 덤프하여 여러가지 정보를 보여줌. 어셈블리어도 보여줌
ranlib - 정정 라이브러리를 만들고 나서 인덱스 파일을 라이브러리 처음에 생성 시켜줌
readelf - ELF 포맷의 오브젝트 파일의 정보 출력
size - 오브젝트 또는 문서 파일의 정보 출력, text , data , bss, dec 등의 섹션 크기를 출력 (예 $ size any_program)
strings - 파일로부터 출력 가능한 스트링 나열
strip - 심볼 제거, 프로그램의 사이즈를 조금이라도 줄일려고 임베디드에선 많이 사용.
windres - 윈도우즈용 파일을 위한 컴파일러
** 이런 바이너리 유틸리티를 능숙하게 다루는 것이 임베디드 리눅스 프로그래머에겐 필수이다.
** 그래서 나도 시간나는 데로 틈틈히,열심히 매뉴얼들을 읽고 있다. 시스템 프로그래밍의 기본이다.
2) GCC - gcc에 대한 안내를 보라.
3) GDB - 나는 명령라인에서 디버깅하는 프로그램. DDD라는 프로그램도 있다.
4) c, c++ library - glibc 가 표준 C언어 라이브러이다.
현재 나의 리눅스 머신에는 /lib/libc-2.2.2.so 라는 공유라이브러리로 존재한다.
c++ 표준 라이브러리는 /usr/lib/libstdc++-3-libc6.2-2-2.10.0.so 라는 공유라이브러리로 존재한다.
c library는 시스템 유틸리티들이 다 사용하기 때문에, c++ library 는 그렇지 않으니까, /usr/lib에 존재한다.
물론 위의 두 개다 /usr/lib에 정적 라이브러리들로도 다 있다.
표준 라이브러리의 소스는 www.gnu.org의 GNU Software 란에 다 있다.
[2] 디버깅 도구
1) gdb - 진짜 디버깅 툴
2) ddd - GDB의 윈도우용 프론트 엔드
3) kdbg - GDB의 윈도우용 프론트 엔드
막강한 기능들을 많이 가지고 있다. 위의 프로그램 중에서는 ddd를 가장 많이 사용하는 것 같다.
kdbg는 kde기반에서 나온것 같은데, kdevelop이라는 QT용 IDE툴의 기본 디버거로 들어가 있다.
4) ldd - 공유 라이브러리 의존성을 출력해 준다. 불필요한 라이브러리는 제거하는 것이 좋다.
5) strace / ltrace - 뭔가 추적하는 것이다.
strace는 사용하는 시스템 콜을 추적하여 주는 것이고,
ltrace는 라이브러리 호출을 추적하여 주는 것이다.
지금 당장, hello world c언어 소스를 컴파일하여 실행하여 보라.
그리고 strace/ltrace 를 실행하고 유심히 살펴보라. 감이 올 것이다!
$ strace ./hello
$ ltrace ./hello
6) checker - 프로그램 코딩중 메모리 할당 루틴에서 문제가 있는 것 같으면, 사용하는 것이다.
컴파일하기 전에 -lchecker 라는 옵션을 주는 것을 잊지 말자.
그리면 문제가 있는 메모리 할당 루틴을 checker 가 검사하여 원인을 보고 하여 줄 것이다.
[3] 시간 측정, 성능 평가 도구
1) time - 프로그램의 수행 시간을 측정해 준다. 시스템 유틸리티이지만, 같은 이름의 라이브러리 함수가 있다.(man 2 time)
2) gprof - 바이너리 유틸리티에 포함되어 있다. 이것은 프로파일러이다.
즉, 코드 안에서 병목 현상을 일으키는 곳을 파악할 수 있다.
각 함수가 얼마나 자주 호출되는지, 각 함수에서 소요된 시간 등 실행한 프로그램의 목록을 보여주는 도구이다.
컴파일 할때 -pg 옵션을 주고 해야 한다. 컴파일 후 실행하라.
정상적으로 종료하면, 현재 디렉토리에 gmon.out 이라는 파일을 내어 놓는다.
이 파일안에 실행 프로파일 정보가 들어 있으며 gprof를 사용하여 통계값을 볼 수 있다.
$ gprof 프로그램명 gmon.out
3) calls - c 소스 코드 안에서의 호출 관계를 계층 구조로 보여 준다.
호출된 모든 함수의 인덱스를 만들거나 프로그램 구조에 대한 계층 구조 보고서를 작성할 때 좋다.
$ calls hello.c
[4] 자동 컴파일링 도구
1) make - 조금이라도 덩치 있는 프로그램을 작성해 보았다면 필요성을 절실히 느낄 것이다.
make를 사용할 줄 모른다면, 남이 작성한 파일을 보고 수정할 수 있으면 된다.
그러다 보면 자신만의 makefile을 만들수 있을 것이다.
2) m4 / automake / autoconf - 플랫폼에 독립적인 프로그램을 배포할 때 필요한 것들이다.
make 파일을 작성하는 것이 또 지루한 작업이기 때문에 그것을 자동으로 해주는 툴이 automake이다.
autoconf는 configure 라는 스크립트를 자동으로 작성해 주는 툴이다.
우리가 프로그램을 설치할때 리눅스에서, 가장 먼저, ./configre 하지 않는가?
그 configure 스트립트를 만들어 주는 것이 autoconf 이다.
configure 라는 스트립트는 여러가지를 시스템에서 찾아보고, 알맞은 makefile을 만들어 주는 것이다.
그후에 make 명령을 이용해서 컴파일을 시키는 것이다.
m4는 매크로 프리 프로세서라는 것이다. aotoconf에서 내부적으로 사용하는 것이다.
[5] 인터페이스 만들기 도구
1) Xt - X library의 기본 툴킷이다.
2) Motif / Lesstif - 유닉스상에서 전통적으로 인기있는 윈도우 툴킷이지만 상용이다.
오픈소스의 다음 세대(QT, GTK+)들에게 대세를 빼았기었다. 그리고 Lesstif 가 나왔지만 대세는 홀러간 뒤었다.
3) Xaw3D - 표준 아데나(Athena)위젯의 변형 버전으로써 마치 모티프와 같은 스타일의 3D 효과를 준다.
4) Tcl/Tk - 창, 버튼, 스크롤바 등 기존의 프로그램에서 사용하고 있는 X 기반의 완전한 인터페이스를 만들 수 있다.
5) Qt - 트롤 테크(Troll Tech)가 만든 C++ GUI 툴킷이다.
나는 QT로 윈도우 프로그래밍을 즐긴다. 왜냐면, 예쁘기 때문이다. 나는 뭐니뭐니 해도 예쁜게 좋다.
gtk기반의 어플리케이션은 알고리즘이나 성능을 좋더라도, 보기에 좋지는 않다.
6) GTK+ - 원래 김프라는 이미지 처리 프로그램을 위해 만든 C GUI 툴킷이다.
[6] 버전 관리 도구
1) CVS - (Concurrent Versioning system) 거의 표준으로 자리 잡고 있다. 인터넷으로 전세계 개발자들이
함께 개발할 수 있게끔 해주는 멋진 도구이다. 거의 모든 오픈 소스 프로젝트들이 CVS로 개발되고 있다.
2) RCS - (Revision control system) CVS와 비슷하다. RCS로는 한 그룹내에서 개발할때 사용한다.
3) SCCS - (Source Code Control System) 카네기 멜론 대학에서 개발된 것이다.
[7] 파일 패치 & 들여 쓰기
1) patch - 정기적으로 갱신되는 프로그램이 있고 프로그램이 매우 많은 소스 파일로 이루어져 있으며
한 버전에서 다음 버전으로 갱신하려고 상황에 맞게 파일을 변환시켜주는 프로그램이다.
매번 전체 소스 배포 파일을 내놓는 것이 적절치 않을 때에 주로 사용한다.
방법은 각 버전마다 변경된 부분만을 patch로 갱신하는 것이다.
2) diff - patch보다 작은 규모의 업그레이드에 유용하게 사용된다.
<사용법>
$ patch -pNUM〈 patchfile
$ diff [option] from-file to-file
< 예제1. 소스가 단순 파일 하나일 때 >
hello1.c 가 있고, 다음 버전인 hello2.c 가 있다고 하자.
우선 hello.patch 라는 패치 파일을 만들어 내려면 다음과 같이 한다.
$ diff -c hello1.c hello2.c > hello.patch
이렇게 만든 패치 파일을 배포하며, 이 패치 파일을 다운 받은 사용자는 다음과 같이 하여 hello1.c 소스에 패치를 가한다.
$ patch〈 hello.patch
< 예제2. 소스가 디렉토리 구조일 때 >
hello1 라는 디렉토리가 있고, 다음 버전인 hello2라는 디렉토리가 있다고 하자.
우선 hello.patch 라는 패치 파일을 만들기 위해서는 다음과 같이 한다.
$ diff -cr hello1 hello2 > hello.patch ( 옵션 -r 은 recursive를 의미 )
이렇게 만든 패치 파일을 배포하며, 이 패치 파일을 다운 받은 사용자는 다음과 같이 hello1 디렉토리 구조에 패치를 가한다.
$ patch -p0〈 hello.patch (-pNUM 에 대한 옵션은 맨페이지 참고)
3) indent - 코드를 예쁘게 들여쓰기를 해준다. 다음과 같이 사용할 수 있다.
$ indent hello.c 출처 : 엠파스블로그 > 입으로 하는 행동, 손으로 하는 생각. > 테마 : Programming? |
0