임베디드시스템설계강의자료 3 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과
Outline n Shell n 리눅스명령어 n vi editor n - 2 - Young-Jin Kim
vi 편집기 v vi 소개 Ø Bill Joy 에의해 BSD 유닉스용으로개발 Ø System V 와유닉스의대부분버전에서기본유틸리티로채택 Ø vi 는 visual editor 의약어이다. Ø A 2009 survey of Linux Journal readers found that vi was the most widely u sed text editor among respondents, beating gedit, the second most widely used editor by nearly a factor of two (36% to 19%). - 3 - Young-Jin Kim
vi 편집기 } 실행방법 : vi 명령어뒤에파일이름 } vi 실행시시작하는모드는명령모드 } 편집기모드 } 입력모드혹은편집모드 글자를입력할수있는모드 } 모드변환방법 - 명령모드에서 a,a,i,o,o 등을입력했을때 } 명령모드혹은 ESC 모드 커서이동및기타명령어처리 } 모드변환방법 - 실행모드혹은입력모드에서 ESC 키를눌렀을때 } 실행모드혹은콜론모드 내용바꾸기및기타 } 모드변환방법 - 명령모드에서콜론 (:) 을입력했을때 입력모드 입력명령 ESC 명령모드 : 실행완료 실행모드 - 4 - Young-Jin Kim
vi 편집기 } 입력모드전환 a : 커서위치의다음칸부터입력하기 (append) A : 커서가있는줄의끝부터입력하기 i : 커서위치부터입력하기 I : 커서가있는줄의맨앞에서부터입력하기 o : 커서바로아래에줄을만들고입력하기 (open line) O : 커서바로위에줄을만들고입력하기 s : 커서가있는글자를지우고입력하기 S : 커서가있는행을지우고입력하기 - 5 - Young-Jin Kim
vi 편집기 } 커서이동 h : 왼쪽, j : 위로, k : 아래로, l : 오른쪽 ( 방향키사용가능 ) - 글자단위 w : 다음단어로, b : 이전단어로 - word 단위 ^ : 맨왼쪽의첫글자, $ : 마지막글자의끝 - 행단위 ^F: 한화면아래로, ^B: 한화면위로, ^D: 반화면아래로, ^U: 반화면위로 gg: 파일의맨처음줄로 G : 파일의맨마지막줄로 :n : 파일의 n번째줄로 (e.g. n이 1이면첫번째줄로 ) H : 화면상에처음줄로 M : 화면상의중간줄로 L : 화면상의마지막줄로 - 6 - Young-Jin Kim
vi 편집기 } 삭제기능 x : 커서위치의글자삭제 X : 커서바로앞의글자삭제 dw : 한단어를삭제 D : d$ 커서위치부터줄의끝까지삭제 dd : 커서가있는줄을삭제 } 복사및붙여넣기 yw : 커서위치부터단어의끝까지복사하기 y0 : 커서위치부터줄의처음까지복사하기 y$ : 커서위치부터줄의끝까지복사하기 yy : 커서가있는줄을복사하기 nyy : 커서가있는줄을포함하여 n 줄을복사하기 (e.g. 5yy이면 5줄복사 ) p : 커서의다음위치에붙여넣기 P : 커서가있는위치에붙여넣기 - 7 - Young-Jin Kim
vi 편집기 } 기타 u : 작업취소하기 (undo) U : 그줄에행해진작업모두취소하기. : 조금전에했던명령을반복하기 ~ : 대소문자전환 / 검색어 : 아래방향으로찾기 ( 검색 )? 검색어 : 위쪽방향으로찾기 n : 다음찾기 - 8 - Young-Jin Kim
vi 편집기 } 치환관련실행 :%s/old/new/g old를 new 로치환 :%s/char/_&_/g 문서처음부터마지막까지의 char 를 _char_ 로치환 :.,$s/char/_&_/g 현재 ( 커서위치 ) 부터마지막까지의 char 를 _char_ 로치환 :%s/aaa//g aaa를삭제 :%s/\n\n/\n/g 빈줄두줄을한줄로바꾸기 } 파일관련실행 :w 현재파일에저장 :w 파일명 파일명 으로저장 :q 일반적인종료 :q! 변경사항을무시하고강제종료 :wq 현재파일에저장하고종료 :e 파일명 파일명 의파일을불러들여편집 :r 파일명 파일명 의파일을읽어서삽입 :! 명령어 외부명령어실행 - 9 - Young-Jin Kim
vi 편집기 } 사용자정의 } 사용자가작업환경을제어하기위해사용 / 사용하지않음으로설정할수있는많은매개변수가존재 } 옵션들은기본값을가지고있지만, 조정을통해서설정할수있다 } 현재시스템의설정내용보기 } :set all - 10 - Young-Jin Kim
vi 편집기 } vi 환경설정 } vi 편집기의매개변수를새로운값으로편집하여사용자정의될수있고사용자가이의값을바꿀수있다 } set 명령을사용 } 환경옵션변수 키 autoindent(ai) number(nu) ts=4 smartindent sm shiftwidth=4 동작이전줄과같은형식으로새줄을정렬 à 정렬없앨때는 noai 사용줄번호를표시 à 줄없앨때는 nonu 사용탭크기를 4 만큼지정 tab-자동맞춤을해줌새로입력한괄호의짝표시자동들여쓰기너비 } 설정파일사용 } 사용자홈디렉토리에서 vi.exrc 편집후, 위표내용삽입 } source.exrc 수행 à 위환경설정이적용됨 - 11 - Young-Jin Kim
- 12 - Young-Jin Kim
} gcc (GNU project C and C++ compiler) compile 실행개요 } gcc 소스파일명 -o 실행파일명 include 헤더파일명 I{include 할헤더파일디렉토리 } D{define 할 macro} l{ 라이브러리이름 } L{ 라이브러리디렉토리 } } 예 ) gcc -o test test.c I/usr/ajou/include lm L/usr/lib à 최종의실행파일 test 가만들어짐 } -l: object library 를읽어들임예 ) lmyarchive à libmyarchive.a( 또는 libmyarchive.so) 라는 library 파일과같이 linking 을수행함 (library 파일이름은기본적으로 lib 로시작하니깐그것을빼고지정 ) } -L: library search 를 linker 에게넘겨줌 } gcc 옵션 } -E: cpp 의전처리결과표시 (-save-temps 에서중간생성파일명.i 를읽는것을더추천 ) } -S: 전처리후 cc 에의해어셈블까지하고멈추며어셈블리파일을생성 ( 파일명.s) } -c: as 에의해컴파일후링크를하지않고오브젝트파일까지생성 ( 파일명.o) } -static: 정적라이브러리를이용한 static linking 지시 } -shared: 공유라이브러리를사용한 dynamic linking 지시 } -print-search-dirs: 컴파일러가 library 와실행파일을검색하는 path 를보임 cf. cpp -v: include 를위해검색하는 path 를보임 - 13 - Young-Jin Kim
} Make 기능및목적 } 컴파일을자동화하는프로그램 } 실행파일을만드는과정 ( 빌드 ) 을정의하면필요한작업만을수행하여실행파일생성 } 입력파일간의의존성을파악하여어느부분이새롭게컴파일되어야하는지를자동적으로판단해서필요한명령어를이용해서그들을재컴파일 } 다중모듈프로그램의재사용을유지하고, 프로그램수정에대한재번역을최소화 } gmake gnumake 는 make 보다발전된것임 } Make 사용 } 입력파일이변경되면자동적으로결과파일이변경되기를원할때나명령어방식으로처리되는모든곳에유용하게사용가능 } 파일의상호의존관계를나타내는목록파일 () 이필요 } GNUmakefile, makefile, 중하나가 default 로사용하는파일임 } 보통 의이름으로파일작성을함 } 을참조하여파일을최신버전으로컴파일및링크 - 14 - Young-Jin Kim
} 의기본형태 } 타겟 (target) Target : Prerequisites(Dependencies) [TAB]Recipe(Command) } 프로그램에의해생성해내고자하는파일의이름또는수행하고자하는액션 (action) 의이름 } 선행조건 (prerequisites) } 타겟을만들어내거나수행하기위해미리갖춰야하는조건. target 이어떤파일에종속적인가를지정 } 선행조건에해당하는파일이존재하는경우에는, 타겟파일이선행조건파일보다더최신일경우, 선행조건이만족한것으로판단함 } 레시피 (recipe) } 선행조건이만족될때 make 가수행할명령 } 리눅스명령어및쉘스크립트사용가능 } 각 command 앞은반드시 TAB 으로띄워줘야함 - 15 - Young-Jin Kim
} Make 의규칙처리 } 규칙의처리는다음과같은딱 2 개의동작으로이루어짐 1. 선행조건이없거나모두만족되면, 레시피들을실행 2. 만족되지않은선행조건이있으면, 해당선행조건에해당하는규칙을찾아서처리한다음원래규칙을처리 (1) CC = gcc (2) OBJS = MySocket.o MyClient.o (3) TARGET = MyClient (4) (5).SUFFIXES :.c.o (6) (7) all : $(TARGET) (8) (9) $(TARGET): $(OBJS) (10) $(CC) -o $@ $(OBJS) (11) (12) clean : (13) rm -f $(OBJS) $(TARGET) 예제의 makefile 구조 : -(7) 의 all 은단순히 $(TARGET) 이라는선행조건만있고, 레시피는없음 -(9) 의 $(TARGET) 은, $(OBJS) 라는선행조건을가지고있고, (10) 의레시피하나를가지고있음 - (12) 의 clean 은선행조건없이하나의레시피를가지고있음 - 16 - Young-Jin Kim
} Make 수행설명 } make 는 을읽어들여서, 변수들과규칙들을구성 } CC, LIBS, OBSJ, SRCS 그리고 TARGET 등의변수들, all, $(TARGET), clean 규칙들이정의됨 } 첫번째로만나는규칙, 즉, all 을처리 } all 은 $(TARGET) 이라는선행조건을가지는데, $(TARGET) 즉 MyClient 라는파일이존재하지않으므로, 이선행조건은만족되지않은것으로간주되고, make 는 $(TARGET) 규칙을찾아서이를먼저처리 } $(TARGET) 은다시 $(OBJS) 를선행조건으로가지므로같은방식으로 $(OBJS) 규칙을찾아처리 } $(OBJS) 는 MySocket.o MyClient.o 이며관련된규칙은 내에존재하지않음 } (5) 에서.SUFFIXES :.c.o 라고선언했기때문에, make 는확장자가.c.o 인파일들에대해서는별도의규칙이제공되지않는범위내에서, 자신이가지고있는확장자규칙을사용 } make 가가지고있는.c 와.o 확장자규칙은.c (C 소스파일 ) 를컴파일해서.o ( 목적파일 ) 를만들어내는레시피를가짐 } MySocket.o 가컴파일되고, 그결과로 $(TARGET) 의선행조건중 MySocket.o 는처리된것으로간주됨 } 마찬가지로, MyClient.o 도 MyClient.c 로부터컴파일됨 } 이제 $(OBJS) 에해당하는파일들이모두존재하므로, 결과적으로 $(TARGET) 의모든선행조건이만족되므로드디어 (9) 의 $(TARGET) 규칙의레시피가실행됨 } 2 개의목적파일들로부터최종타겟인 MyClient 를 linking 수행하여만들어냄 } 이제 all 의선행조건이만족되었으므로 all 의 recipe 수행함 } all 은아무런레시피를가지고있지않고, 여기에개입할만한내장규칙들도없기때문에, 드디어 make 는 all 의처리를완료하면서실행을종료함 $ make gcc -c -o MySocket.o MySocket.c gcc -c -o MyClient.o MyClient.c gcc -o MyClient MySocket.o MyClient.o - 17 - Young-Jin Kim
} 주석및라인변경 } 빈라인은무시 } 라인에 # 이나오면그라인은무시 ( 주석 ) } 하나의라인이길어질경우 \ ( 역슬래시 ) 를추가하여라인은바꿀수있다. #all: test 무시 ( 주석 ) test : main.o foo.o bar.o gcc o test main.o \ 연결 foo.o \ 연결 bar.o main.o : io.h main.c gcc c main.c io.h 가변경되거나 main.c 내용이변경되면, 아래의레시피를수행한다. 즉, main.c 를컴파일하여 main.o 를만든다. foo.o : io.h foo.c gcc c foo.c bar.o : io.h bar.c gcc c bar.c - 18 - Young-Jin Kim
} 매크로 (Macros) } make에서지원하는기능 } 일련의반복되는특정코드를간단하게표현 } Macro makes happy } 정해진 Macro } 미리정해놓은매크로들 } make p 확인가능 } CC = cc (=gcc) } CFLAGS = gcc 명령어의옵션세팅 } CXX = g++ } CPPFLAGS = g++ 명령어의옵션세팅 } LD = ld } LDLFAGS = ld 명령어의옵션세팅 - 19 - Young-Jin Kim
} 매크로 (Macros) 사용법 } 매크로작성은등호 (=) 사용 } = 표시이후에아무런문자열이없는매크로정의에는 NULL 할당 } 작성된매크로를참고하기위해서는매크로앞에 $ 를붙여사용 } 기존매크로에내용을추가하기위해서는 += 와같은방식사용 } 일련의반복되는특정코드를간단하게표현 } 매크로정의순서는상관없음 } 같은이름의매크로는 makefile 내에서한번이상정의될수있으며이런경우맨마지막에정의한매크로만사용됨 - 20 - Young-Jin Kim
} 매크로 (Macros) 사용법 } Command line( 명령행 ), makefile 내, 환경변수등에중복정의된경우에는다음의우선순위가적용된다. } 매크로적용우선순위 } 명령행에서정의한매크로 } 에서정의된매크로 } 현재쉘의환경변수 } make 내부에정의된매크로 - 21 - Young-Jin Kim
} 매크로 (Macros) 사용법 } 명령행에서매크로 } make 명령행에서매크로정의가능 Target 을지정 $make test DIR=/usr/project } 명령행에서정의가여러단어들로구성되어있을경우해당부분을 나 로묶어주어야한다. $make test DIR=/usr/project/usr/project/lib } 매크로를 make 명령이전에정의가능 $ DIR=/usr/project make test - 22 - Young-Jin Kim
} 매크로 (Macros) 사용법 } 내부매크로 (1) } 임의로설정해서사용할수없는매크로 } $* - 확장자가없는현재의목표파일 (Target) main.o : io.h main.c [TAB] gcc c $*.c ß------------- $* = main } $< - 현재타켓보다최근에변경된현재필요항목의이름 ( 소스파일 ) main.o : io.h main.c [TAB] gcc c $< - 23 - Young-Jin Kim
} 매크로 (Macros) 사용법 } 내부매크로 (2) } $@ - 현재타켓의이름 test : main.o foo.o bar.o [TAB] gcc o $@ $*.c ß------------$@ = test } $^ - 현재타겟보다최근에변경된필요항목들의리스트 test : main.o foo.o bar.o [TAB] gcc c $@ $^ - 24 - Young-Jin Kim
} 확장자규칙 (Suffix Rule) } make가파일의확장자를보고, 그에따라적절한연산을수행시키는규칙 } 어떤확장자에대한규칙이정의되어있더라도,.SUFFIXES 리스트에도함께정의되어야효력이있다. } 오브젝트파일이존재하지않으면, make는이를작성하기위한.c,.s 소스파일을찾는다. } make는.suffixes 리스트의확장자순서에따라파일을검색한다. } 내부에미리정의되어있는확장자리스트.SUFFIXES:.out.a.ln.o.c.cc.C.cpp.p.f.F.r.y.l.s.S.mod.sym.def.h.info.dvi.tex.texinfo.texi.txinfo.w.ch.web.sh.elc.el - 25 - Young-Jin Kim
} 확장자규칙 (Suffix Rule).c.o: [TAB] $(CC) c $< -o $@ } 확장자규칙에의해서 make 는파일들간의확장자를자동으로인식해서필요한작업을수행 } 확장자가.c 파일은컴파일되어확장자가.o 파일로됨. - 26 - Young-Jin Kim
} 예제 io.h main.c foo.c bar.c main.o foo.o bar.o test - 27 - Young-Jin Kim
} 예제 SRCS 에서는 OBJS 에서.o 가.c 로바뀌게된다. 다음과같이변경되는것이다. SRCS = main.c read.c write.c 매크로와확장자규칙사용 매크로와확장자규칙비사용 all: test test : main.o foo.o bar.o gcc o test main.o foo.o bar.o main.o : io.h main.c gcc c main.c foo.o : io.h foo.c gcc c foo.c bar.o : io.h bar.c gcc c bar.c CC = gcc CFLAGS = -O2 -g OBJS = main.o foo.o bar.o SRCS = $(OBJS:.o=.c) TARGET = test all: $(TARGET) $(TARGET) : $(OBJS) $(CC) -o $@ $(OBJS) dep: gccmakedep $(SRCS) clean : rm -f $(OBJS) $(TARGET) } 좀더읽을거리 : http://forum.falinux.com/zbxe/index.php?document_srl=405822&mid=gcc - 28 - Young-Jin Kim
} include } 에서 include 가사용되면, 현재읽고있는 makefile 의 reading 잠시중단하고 include 된 makefile 을 reading 함 } 사용법 } include file_name } include a.mk b.mk c.mk à listed file 이순차적으로 reading 됨 } 해당경로에 makefile 이없을경우, warning message 발생 } 을모두 reading 하고 remake 시도후실패화면 error message 발생 } Include 는반드시줄의처음에서시작해야하면다음에공백문자혹은탭문자가나와야한다. Include 앞에공백이나탭이있어서는안된다. } Include 의효과는 file_name 의모든행을현재의 로옮겨적는것과동일. - 29 - Young-Jin Kim
} 헤더파일의존성관계 } make 는소스에숨겨져있는의존관계를살펴보기위해파일의내부를들여다볼수없다. } #include 지시자가소스파일에있는지알수있는방법이없으므로, 헤더파일이변경되었을경우, 다시오브젝트파일을생성할방법이없다. } 이러한한계를극복하기위하여대부분 에서는의존관계를직접지정한다. - 30 - Young-Jin Kim
} 헤더파일의존성관계 } 헤더파일의존성관계생성 } GNU 컴파일어 (gcc) 에서제공하고있는 M 옵션을이용하게되면, 의존파일의리스트를만들어낼수있게된다. gcc M $(SRCS) >.depend } 의존관계를만들고 include문을통하여.depend 파일을 에 include 시킨다. Include.depend } gcc를사용하는경우, gccmakedep 명령을이용하면의존관계를쉽게만들어낼수있다. (gccmakedep를사용하기위해서는 xutils-dev 설치필요 ) - 31 - Young-Jin Kim
} 프로젝트관리 } 재귀적 (recursive) make } 대부분의프로젝트에서는여러개의소스파일을계층구조의디렉토리에넣어두고 make 에서사용할수있도록한다. } 각하위디렉토리에별도의 makefile 을두고최상위 makefile 에서 이들 make 를재귀적으로실행하여연결한다. Make C <DIR> - 32 - Young-Jin Kim
} 재귀적 make 예제 subsystem: cd subdir; $(MAKE) # (1) #subsystem: $(MAKE) -C subdir # (2) # (1) 과 (2) 는동일한명령을수행 # 우리가만들시스템의타겟이 subsystem # 우선 subdir 이라는곳으로가서, 거기에있는 # 을동작시키게된다. MAKE 라는것 # 은그냥 make 라는명령어를표시하는매크 # 로일뿐이다. SUFFIXES :.c.o CC = gcc CFLAGS = -O2 g all : DataBase Test #<- 요기에집중 DataBase: cd db ; $(MAKE) # db 로이동해서 make 실행 Test: cd test ; $(Make) # db 로이동해서 make 실행 Make 실행화면 $make cd db ; make make[1]: Entering directory`/home/raxis/test/src gcc -O2 -g -c DBopen.c -o DBopen.o gcc -O2 -g -c DBread.c -o DBread.o gcc -O2 -g -c DBwrite.c -o DBwrite.o make[1]: Leaving directory `/home/windows/test/src cd test ; make make[1]: Entering directory `/home/raxis/test/test gcc -O2 -g -c test.c -o test.o make[1]: Leaving directory `/home/windows/test/test' 여기서, make 뒤의대괄호의 1 이라고나타난것은현재의레벨을의미한다. 원래디렉토리의레벨이 0 이고, 여기서는레벨이하나더내려갔으므로 1 이라고표시된것이다. - 33 - Young-Jin Kim
} 프로젝트관리 } 컴파일러옵션과 #ifdef 지시자 } #ifdef 나 ifndef 와같은전처리지시자를사용하는조건부컴파일은소프트웨어발전과함께불가피한선택이되고있음 [Makeflie 의내용 ] CFLAGS = -DTEST [Source Code 의내용 ] #ifdef TEST test_print(); #endif } Make 파일이름지정 } -f 옵션을사용하여원하는이름의입력파일을지정할수있음 make f./test.mk } -f 옵션이없으면, make 는 GNUmakefile, makefile 및 의순서로입력을찾음 ( 입력파일로위해서 을사용하는것을추천 ) - 34 - Young-Jin Kim