리눅스 상에서 오픈소스를 이용해서 개발환경을 구축하는 방법에 대해서 설명하고 있다.
임베디드 리눅스의 개발에서는 호스트가 리눅스인 환경에서 개발하게 되는 경우가 많다. 물론 vmware 를 사용해서 개발할 수도 있지만, 아무래도 실제환경과 vmware 의 환경과는 차이(usb, serial)가 있다.
나의 경우는 윈도우에서 개발했던 버릇이 있어서 리눅스에서의 개발환경이 많이 서먹하다. 하지만, 이번 기회를 계기로 익숙해져 보려고 한다.
여기서 언급하고 있는 것은 기존의 윈도우에서 사용했던 소스 분석툴인 source insight 를 대체할만한 방법이다.
참고로 여기서는 Redhat 9 를 기준으로 설명할 것이다.

  1. vi
  2. ctags
  3. cscope
  4. taglist
  5. screen

위의 순서대로 설명하겠다.

vi

자세한 설명은 [vi] 문서를 참고하기 바란다. 여기서는 몇가지 유의할 점에 대해서 설명할 것이다.
Redhat 9 에 기본으로 설치되어 있는 vi 의 경우, 'syntax on' 명령어가 적용되지 않는 관계로 최신버전을 다운로드 받아서 따로 설치했다.
다음 .vimrc 파일의 내용이다.

  set tabstop=2
  set shiftwidth=2
  set expandtab
  set softtabstop=2
  set visualbell
  set nobackup
  set cindent
  set autoindent
  set smartindent
  set incsearch
  set number
  set visualbell
  syntax on
  filetype on
  set backspace=eol,start,indent
  set history=1000
  set hlsearch
  set ignorecase
  set showmatch

ctags

Redhat 9 에 기본적으로 설치되지 않기 때문에, 따로 다운로드 해서 설치했다.
http://ctags.sourceforge.net 에서 최신버전을 다운로드 한다.

#tar xzf ctags-5.6.tar.gz
#cd ctags-5.6
#./configure --prefix=/usr/local/ctags
#make
#make install

위와 같이 설치한다. ctags 는 C 언어 소스 코드의 함수, 구조체등을 tag(태그) 로 구성한다. 어떤 함수는 어느 파일의 몇 번째 라인에 있고, 어떤 구조체는 어느 파일의 몇 번째 라인에 있다와 같은 정보를 담고 있는 데이터베이스를 생성한다. 여기서는 리눅스 커널을 대상으로 데이터베이스를 만들어 본다. 데이터베이스를 생성하기 위해서 커널이 있는 곳으로 이동한 뒤에,

#cd /usr/src/linux
#ctags -R

실행한다. 만일 ctags 가 설치된 상태라면, 커널에서 기본적으로 지원한다.

#make tags

제대로 실행이 되었다면, 'tags' 라는 파일이 생성되었을 것이다. 이 파일을 vi 에서 읽어들이기 위해, ~/.vimrc 파일에 다음을 추가한다.

set tags=/usr/src/linux/tags

예를 들어 task_struct 라는 구조체의 정의를 보고 싶다면, 아래와 같이 실행한다.

#cd /usr/src/linux
#vi -t task_struct

task_struct 구조체에서 'mm_segment_t' 라는 하부 구조체의 정의를 보고 싶다면,

volatile long state;  /* -1 unrunnable, 0 runnable, >0 stopped */
288   unsigned long flags;  /* per process flags, defined below */
289   int sigpending;
290   mm_segment_t addr_limit;  /* thread address space:
291             0-0xBFFFFFFF for user-thead
292             0-0xFFFFFFFF for kernel-thread
293            */

커서를 'mm_segment_t' 에 놓고 'Ctrl + ]' 를 누르면, 'mm_segment_t' 가 정의된 곳으로 이동한다. 다시 돌아오려면, 'Ctrl + t' 를 누르면 된다.
원하는 tag 로 바로 이동하기 위해서는 vi 의 명령모드에서

:ta task_struct

다음과 같이 실행하면 된다.
이번에는 function 이라고 하는 이름의 변수를 찾아보도록 하자! vi 에서

:ta function

총 100 개가 넘는 결과가 나왔다. 결과를 하나씩 보기 위해서는 ':tn' 을 입력하면 된다. 반대는 ':tp' 이다.
총 검색결과는 한 눈에 보고 원하는 결과를 선택할 수도 있다. ':ts function' 입력하면 아래와 같이 출력된다.

  # pri kind tag               file
  1 F C m    function          drivers/hotplug/acpiphp.h
               struct:acpiphp_func
               u8  function; /* pci function# */
  2 F   m    function          drivers/hotplug/cpqphp.h
               struct:controller
               u8 function;
  3 F   m    function          drivers/hotplug/cpqphp.h
               struct:pci_func
               u8 function;

여기서 원하는 곳의 숫자를 입력하면 그쪽으로 이동한다.
다음은 좀더 ctags 를 편리하게 사용하기 위한 설정이다. .vimrc 파일에 추가한다.

set complete // 태그 자동 완성 기능
set tagbsearch // 검색 속도 향상

ctags 의 명령어 목록을 정리했다.

명령 설명
:ta keyword keyword 와 일치하는 태그 위치로 이동한다
Ctrl + ] 커서가 위치한 keyword 의 정의로 이동한다
Ctrl + t 이전 위치로 이동한다
:ts keyword keyword 와 일치하는 태그 목록을 출력하고 선택한다
:tj keyword ts 와 동일하지만 목록이 한 개인 경우에는 해당 태그로 이동하고, 두 개 이상이면 목록을 출력한다
:ta keyword keyword 가 포함된 태그를 검색한다
:tn 다음 태그로 이동한다
:tp 이전 태그로 이동한다
tags 이동한 태그 히스토리 목록을 출력한다

cscope

cscope 를 사용하는 가장 큰 목적은 찾는 함수가 있을 때, 어디서 함수를 호출 했는지를 찾을 때, 아주 유용하게 사용할 수 있다.
이것 역시 기본적으로 Redhat 9 에 설치가 되어 있지 않기 때문에, 따로 다운로드 받아서 설치해야 한다. http://cscope.sourceforge.net 에서 최신버전을 다운 받는다.

#tar xzf cscope-15.6.tar.gz
#cd cscope-15.6
#./configure --prefix=/usr/local/cscope
#make; make install

설치 후에, .bash_profile 파일에 앞에서 설치한 경로를 path 로 설정해야 한다.
ctags 와 마찬가지로 데이터베이스를 생성해주어야 한다. 여기서는 kernel 을 대상으로 데이터베이스를 만들어 볼 것이다.

#cd /usr/src/linux
#find ./ -name *.[chS] -print > cscope.files
#/usr/local/cscope/bin/cscope

데이터베이스 생성이 완료되면, 'Ctrl + d' 를 입력하여 빠져나온다. cscope.out 파일이 생성되었을 것이다.
이제 본격적으로 vi 와 연동해서 사용해보자!
vi 를 실행시킨 후에, 앞서 만든 데이터베이스를 연결시켜야 한다.

:cs add /usr/src/linux/cscope.out
:cs show

별다른 에러 메세지가 없다면, 성공이다. 이제 struct task_struct 를 검색해보자! vi 상태에서 다음을 입력해보자!!

:cs find 0 task_struct

아래와 비슷한 결과가 출력될 것이다.

Cscope tag: task_struct
   #   line  filename / context / line
   1     11  arch/alpha/kernel/proto.h <<GLOBAL>>
             struct task_struct;
   2    231  arch/arm/kernel/process.c <<GLOBAL>>
             static struct task_struct *task_struct_head;
   3    240  arch/arm/kernel/process.c <<GLOBAL>>
             struct task_struct *alloc_task_struct(void )
   4    242  arch/arm/kernel/process.c <<GLOBAL>>
             struct task_struct *tsk;
   5     10  arch/arm/kernel/ptrace.h <<GLOBAL>>
             extern void __ptrace_cancel_bpt(struct task_struct *);
   6     11  arch/arm/kernel/ptrace.h <<GLOBAL>>
             extern int ptrace_set_bpt(struct task_struct *);
   7     34  arch/arm/mm/alignment.c <<GLOBAL>>
             do_bad_area(struct task_struct *..._struct *mm, unsigned long addr,
   8     37  arch/arm/mm/fault-armv.c <<GLOBAL>>
             extern void do_bad_area(struct t...ruct *tsk, struct mm_struct *mm,
   9     44  arch/arm/nwfpe/fpmodule.c <<GLOBAL>>
             typedef struct task_struct* PTASK;
  10    158  arch/i386/kernel/vm86.c <<GLOBAL>>

원하는 숫자를 입력하면, 소스 코드로 이동한다. 이때 숫자를 입력했음에도 불구하고 소스 코드로 이동하지 않는다면, vi 를 /usr/src/linux 로 이동한 후에 실행하고, 다시 시도해본다. 아래 표에 나와 있는 명령어를 이용해서 좀 더 폭 넓은 검색을 할 수 있다.

검색 유형 설명
0 또는 s C 심볼을 검색한다
1 또는 g 정의를 검색한다
2 또는 d 이 함수에 의해 호출되는 함수들을 검색한다
3 또는 c 이 함수를 호출하는 함수들을 검색한다
4 또는 t 텍스트 문자열을 검색한다
5 또는 e 확장 정규식을 사용해서 검색한다
7 또는 f 파일 이름을 검색한다
8 또는 i 이 파일을 인클루드 하는 파일을 검색한다

taglist

taglist 는 vi 내에서 현재 소스 코드의 태그를 보여주는 vi 플러그인으로서, 편집중인 소스 코드의 매크로, 함수, 구조체 등을 일목요연하게 볼 수 있으며, 각각을 이동할 수 있다.
http://www.vim.org/scripts/script.php?script_id=273 에서 다운 받을 수 있다.

#cd
#mkdir .vim
#mv taglist_42.zip .vim
#cd .vim
#unzip taglist_42.zip

위와 같이 설치를 하고, 다음을 입력한다.

#cd /usr/src/linux
#vi -t task_struct

vi 를 실행한 이후에

:Tlist

를 입력하면, 두 개의 창으로 나뉘어진 것을 볼 수 있다. 왼쪽은 해당 소스 파일의 태그 목록 창이고, 오른쪽은 소스 코드 창이다.
서로 좌우 창을 이동하기 위해서는 'Ctrl + w,w' 를 입력하면 된다.

screen

방대한 소스코드 트리를 여기저기 뒤적거리다 보면, 자연스레 터미널 창이 늘어나게 된다. 그럼 자연스레 몇개만 띄워도 꽉차는 모니터 해상도를 원망하게 된다.
많은 터미널 창을 이리저리 옮겨다니다보면, 나중에 헤깔릴 때도 많다. 이런 고민을 해결해줄 프로그램이 있는데, 바로 screen 이다.

이를 사용하면, 하나의 터미널 창을 마치 여러개의 창을 띄워놓은 것과 같은 효과를 발휘한다. 직접 확인해보자!
먼저 터미널 창을 하나 띄우고 screen 을 실행한다.

#screen

화면이 지워지고, 아래와 같은 메세지가 출력된다.

Screen version 4.00.03jw4 (FAU) 2-May-06
 
Copyright (c) 1993-2002 Juergen Weigert, Michael Schroeder
Copyright (c) 1987 Oliver Laumann
 
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License along with
this program (see the file COPYING); if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to
screen@uni-erlangen.de
 
To use byobu (formerly screen-profiles), exit screen and run 'byobu'.
 
[Press Space or Return to end.]

스페이스 나 엔터키를 누르면 모두 지워지고, 프롬프트만 덩그러니 남아있다. 아주 간단한 명령어를 실행하자!

#ls
MPlayer-1.1         XP_WOW.iso                     king.avi
MPlayer-1.1.tar.gz  debian-6.0.6-i386-netinst.iso  sketchbook
W2K3AIO_KO.iso      essential-20071007.tar         win31.mp3
#

여기서 'Ctrl + ac' 를 키보드로 입력한다. 방금 전의 화면이 사라지고, 다시 프롬프트만 덩그러니 남았다. 이번에는 ifconfig 명령을 내려보자.

#ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1184 (1.1 KB)  TX bytes:1184 (1.1 KB)

여기서 다시 'Ctrl + ac' 를 다시 입력한다. 또다시 프롬프트만 남았다. 과연 지금껏 입력했던 것들은 어디로 간 것일까?
이 상태에서 'Ctrl + an' 을 입력해보자!
처음 입력했던 ls 명령어가 보인다. 또다시 'Ctrl + an' 을 입력해보면, ifconfig 명령어가 보인다. 마치 세션을 이리저리 옮겨다니는 듯 하다. 이제 더이상 여러 개의 터미널 창을 띄울 필요가 없어졌다.

단축키 설명
Ctrl + a' 화면 하단에 새로운 가상 터미널을 선택할 수 있는 입력 프롬프트가 나옴
Ctrl + a'' 현재 생성되어 있는 모든 가상 터미널이 나열되며 커서로 선택할 수 있음
Ctrl + a[N] N번째 가상 터미널로 이동
Ctrl + aa 바로 이전 가상 터미널로 이동
Ctrl + ac 새로운 가상 터미널 생성
Ctrl + ad 현재의 가상 터미널을 닫음
Ctrl + an 다음 가상 터미널로 이동
Ctrl + ap 이전 가상 터미널로 이동

screen 은 여러 파일을 수정할 때 유리하다. 파일 버퍼 간 전환은 vim 내에서 :b[N] 명령으로 하면 되지만 때로는 여러 개의 창을 사용하고 싶을 때가 있을 것이다. 가령 한 창에서는 파일을 수정하고 다른 창에서는 컴파일하고 디버깅하는 용도로 말이다.
screen 의 또 다른 장점은 세션을 유지한다는 점이다. telnet 이나 ssh 를 사용해 원격으로 소스를 수정하고 있었는데 갑자기 네트워크 불량으로 접속이 종료되면 대책이 없을 것이다.
물론 vim 은 .swp 파일에 주기적으로 백업을 하지만 .swp 파일의 내용이 항상 화면과 동기화되는 것은 아니다. 이럴 때 screen 을 사용하는 중이었다면 걱정할 필요가 없다.
사용자가 갑자기 접속을 잃었더라도 screen 의 세션은 그대로 유지되므로 고뇌에 찬 비명이나 한숨대신 다시 접속해 단지 다음 명령만 내려주면 접속을 잃었을 때의 화면이 그대로 복구된다.

#screen -r 또는 screen -r [세션명]

앞서 설명한 것처럼, 원격으로 작업도중 네트워크 연결이 끊어졌을 경우에 간단히 복구(?)하여 작업을 이어 진행할 수 있다.
이런 경우 외에도 회사에서 작업하던 터미널(세션)을 집에 가서 그대로 받아 작업도 가능하다. 이또한 세션으로 가능하다.

screen 프로그램 자체를 exit(종료) 하지 않는 이상, 터미널 창을 종료한다고 해서 세션이 종료되지는 않는다.
아래 명령어를 실행하여 현재 사용 중인 세션 목록을 볼 수 있다.

#screen -list
There is a screen on:
        14377.pts-1.lucas       (2014년 04월 13일 12시 39분 33초)       (Dettached)
1 Socket in /var/run/screen/S-root.

새로운 터미널 창을 하나 열고, 사용하고 싶은 세션 이름을 아래처럼 실행하면 되면 세션 그대로를 받아 작업이 가능하다.
유의할 것은 해당 세션의 상태가 'Dettached' 어야 한다는 것이다.

#screen -r 14377.pts-1.lucas
  • computer/programming/오픈소스를_이용한_개발환경_구축하기.txt
  • Last modified: 3 years ago
  • by likewind