노무현 대통령 배너


2006. 8. 10. 10:00

리눅스 개발환경의 개요도

출처: http://kelp.or.kr/korweblog/stories.php?story=02/04/26/3308863

리눅스 개발환경의 개요도
글쓴이 : 조형기 (2002년 04월 26일 오전 01:48) 읽은수: 9,889 [ 임베디드강좌/초보 인쇄용 페이지 ]
리눅스의 개발 환경 개요도

- 들어가기 -

리눅스를 잘 알지 못할 당시 나는 리눅스에는 왜 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) 를 비롯하여 많은 바이너리 도구들이 포함되어 있다.
www.gnu.org 에서 내리는 간단한 요약을 적어 본다.

The GNU Binutils are a collection of binary tools. The main ones are:

ld - the GNU linker. ( 현재 holelee 님이 열심히 강좌 중이지요, 다음 차례가 ld 네요.
저도 유심히 읽고 있습니다. 좋은 내용입니다. )

as - the GNU assembler. ( 임베디드 리눅스를 하면서 어셈블리어는 필수겠죠 ? 저는 잘 못합니다.
저번에 강좌란을 맡을 때 공부 좀 했는데 영 ... 하하하 )

But they also include:

addr2line - Converts addresses into filenames and line numbers. (모른다)

ar - A utility for creating, modifying and extracting from archives. (정적 라이브러리를 만드는
유틸리티이다. 다음과 같이 만든다.
# ar rs libxxx.a a.o b.o c.o
s 옵션을 넣으면 ranlib 를 실행하지 않아도 된다. )

c++filt - Filter to demangle encoded C++ symbols. (모른다.)

gprof - Displays profiling information. (프로파일러 , 음 이것도 binutils에 있구나.)

nlmconv - Converts object code into an NLM. (모른다.)

nm - Lists symbols from object files. (오브젝트 파일의 심볼들을 나열해 준다.)

objcopy - Copys and translates object files. (오브젝트 파일을 복사, 변환한다.)

objdump - Displays information from object files. (오브젝트 파일을 덤프하여 여러가지
정보를 보여준다. 어셈블리어도 보여준다.)

ranlib - Generates an index to the contents of an archive. (정정 라이브러리를 만들고 나서 인덱스
파일을 라이브러리 처음에 생생시켜 준다.)

readelf - Displays information from any ELF format object file. (ELF 포맷의 오브젝트 파일의 정보를 디스플레이한다.)

size - Lists the section sizes of an object or archive file. (#size any_program 이라고 명령하면
text , data , bss, dec 등의 섹션
크기를 출력해 준다. )

strings - Lists printable strings from files. (파일로부터 출력 가능한 스트링을 나열해 준다.)

strip - Discards symbols. (심볼들을 제거한다. 프로그램의
사이즈를 조금이라도 줄일려고 임베디드
에선 많이 사용한다. 유영창님의 그
처절한 체험수기를 봐라!)

windres - A compiler for Windows resource files. (모른다.)


이런 바이너리 유틸리티를 능숙하게 다루는 것이 임베디드 리눅스 프로그래머에겐 필수 인 것 같다.
그래서 나도 시간나는 데로 틈틈히,열심히 매뉴얼들을 읽고 있다. 시스템 프로그래밍의 기본이 아니겠는가 ?
여기에 보충하는 기사를 추천하여 주겠다.
현재 2002년 1월 부터 6월 까지 '마이크로 소프트웨어'라는 잡지에 운영체제 오딧세이라는
기사가 연재되고 있다. 거기보면 '방준영' 이라는 사람이 실행파일 포맷에 대하여 기사를 실고 있다.
아주 좋은 기사들인것 같다. 관심있으면 읽어 분들은 읽어 보시기 바랍니다.
그리고 저는 khexedit 라는 바이너리 편집기를 즐겨 사용합니다. 궁금하고 이상한 것이 있으면 바로
바로 펼쳐서 프로그램의 실체를 들여다 보지요. 근데 아직 아무것도 안 보인답니다. 허허허


2) GCC
GNU의 불후의 명작!
여기에 대해서는 holelee 님이 아주 잘 설명하였습니다. gcc이야기(1~5) 참조!

3) GDB - 역시 GNU의 불후의 명작!
나는 명령라인에서 디버깅하는 것이 아직 어렵게 느껴진다. 그래서 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
3) kdbg
이것들은 gdb가 진짜 디버거이고 , ddd와 kdbg는 gdb의 윈도우용 프론트 엔드일 뿐이다.
그러나 막강한 기능들을 가지고 있을 것이다. 주로 ddd를 많이 쓰는 것 같다.
리니오의 CTO의 세미나를 들을 기회가 있었는데, 그도 리니오도 ddd 를 좋아 하는 것 같았다.
그리고 국내의 미지도 ddd를 좋아하는 것 같다. 나도 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 - 실행시키는 프로그램의 수행 시간을 측정해 준다.
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는 무엇인가 ? 숙제다!................ 농담이다.
m4는 매크로 프리 프로세서라는 것이다. aotoconf에서 내부적으로(?) 사용하는
것이다. 더는 모른다. 숨이 차다.



[5] 인터페이스 만들기 도구

1) Xt - X library의 기본 툴킷이다. www.kldp.org에서 이만용님의 글을 찾아 읽어 보라.

2) Motif / Lesstif - 유닉스상에서 전통적으로 인기있는 윈도우 툴킷이었는데, 상용이라서 오픈소스의
다음세대(QT, GTK+)들에게 대세를 빼았기었다. 그리고 Lesstif(이름이 재밌지 않은가?)
라는 오픈소스 구현체가 나왔는데 대세는 홀러간 뒤었다.

3) Xaw3D - 표준 아데나(Athena)위젯의 변형 버전으로써 마치 모티프와 같은 스타일의 3D 효과를 준다.


4) Tcl/Tk (티씨엘 티케이 라고 읽자) - 창, 버튼, 스크롤바 등 기존의 프로그램에서 사용하고 있는
X 기반의 완전한 인터페이스를 만들 수 있다.


5) Qt - 노르웨이 회사인 트롤 테크(Troll Tech)가 만든 C++ GUI 툴킷이다.
나는 QT로 윈도우 프로그래밍을 즐긴다. 왜냐면, 예쁘기 때문이다. 나는 뭐니뭐니 해도
예쁜게 좋더라. gtk기반의 어플리케이션은 알고리즘이나 성능을 좋더라도 어쨋든 보기에는 구리다.
반박하고 싶은 사람이 있더라도 개인적인 취향이라 생각해 달라.
그리고 나는 개인적으로 C++ 언어(객체 지향 언어)를 사모한다.

6) GTK+ - 원래 김프라는 이미지 처리 프로그램을 위해 만든 C GUI 툴킷이다.
공부해 본적은 있는데... 조금 하다가 시간이 없어서 말았다.
혹자는 소스코드가 훨씬 심플, 간결하다고 하였다. 현재 마소에서 GTK+ 연재를 하고 있다.


[6] 버전 관리 도구

1) CVS - (Concurrent Versioning system) 거의 표준으로 자리 잡고 있다. 인터넷으로 전세계 개발자들이
함께 개발할 수 있게끔 해주는 멋진 도구이다. 거의 모든 오픈 소스 프로젝트들이 CVS로 개발되고 있다. 필수다 .!
아직 모르는가? 뭐 하는가 ! 공부하지 않고!
이러는 필자도 현재 개발하는 프로젝트를 CVS로 하지 않아 참 고생하고 있다. 필요성을 절실히
느낀다. 필요는 공부의 어머니!

2) RCS - (Revision control system) CVS와 많은 것이 비슷하다. 하지만 RCS로는 인터넷에 연결된 그런 분산
개발보다는 한 그룹내에서 개발할때 사용한다.

3) SCCS - (Source Code Control System) 카네기 멜론 대학에서 개발된 것이다. 그외네는 잘 모른다.
써 본적도 없고.... 들은 바도 없다. 그냥 비교하기 위해 나열해 보았다.




[7] 파일 패치 & 들여 쓰기

1) patch - 정기적으로 갱신되는 프로그램이 있고 프로그램이 매우 많은 소스 파일로 이루어져 있으며
2) diff 매번 전체 소스 배포 파일을 내놓는 것이 적절치 않을 때가 있다. 이 때, 가장 좋은 방법이
각 버전마다 변경된 부분만을 patch(펄의 창시자인 래리 월이 만든)로 갱신하는 것이다.
즉, patch 는 한 버전에서 다음 버전으로 갱신하려고 상황에 맞게 파일을 변환시켜주는
프로그램이다. diff 와 함께 사용된다.

<사용법>
patch -pNUM 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
어떤가 ? 쓸만하지 않은가 ?


- 마무리 -

여기까지 리눅스의 개발환경에 대하여 알아 보았다. 지루하고 쓴 것 같다. 그래도 마음은 후련하다.
숲이 보이는가?
어느정도 정리가 된 것 같다는 생각이 든다. 아마 기억이 희미해져 가면 이 글을 나 또한 읽을 것이다.
인간은 망각하는 존재이기에... 신이 주신 재악이자 축복이다. 이리저리 따져 보면 축복인 것 같다.
다음에는 프로그래밍 언어들에 대한 글과 임베디드 리눅스 커리큘럼에 대한 짧은 글을 쓰겠습니다.

'Utilities' 카테고리의 다른 글

리눅스 디버깅 기술 마스터하기 (한글)  (0) 2006.08.10
디버깅을 익히자!  (0) 2006.08.10
CVS 사용  (0) 2006.07.26
[본문스크랩] vi 편집기 사용법  (0) 2006.07.21
DDD를 이용한 디버깅  (0) 2006.07.20