05. gcc, make, gdb.

Slides:



Advertisements
Similar presentations
SPARCS 10 이 가 영 기본 UNIX 명령어. 일단 로그인 ! Linux login 시 계정을 입력하거나 root 를 입력 Root -> # 일반 사용자 -> $ 패스워드 : echo 기능을 꺼서 볼 수 없다. 대소문자 구분 패스워드 처음 설정 시 : ~$ passwd.
Advertisements

쉘 스크립트와 cron coearth, george.
(금) 김 희 준 Makefile (금) 김 희 준
Power C++ 제6장 포인터와 문자열.
시작부터 끝까지 진지한 궁서체로 진행하는 완벽한 주입식의 하드코어한 리눅스/장난감 세미나
제3장 C 프로그래밍 환경.
Linux University of Seoul Computer Science Park Jong wook
리눅스 실습 정성훈.
컴퓨터 네트워크 실습.
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
개발 환경 개발 환경 개요 PXA270과 타겟 시스템 툴체인 환경 구축 JTAG 유틸리티 미니컴 Make 유틸리티
크로스 컴파일 환경 구축.
제 8 장  파서 생성기 YACC 사용하기.
Makefile의 이해 ㈜FALinux 박진호.
Chapter 11 The C Shell.
제16장 QT/Embedded.
Kernel Porting Lecture #7.
제4장 Cross Compiler 설치.
임베디드 프로그래밍 Lecture #
공학기초설계 Youn-Hee Han 강의 소개 & MinGW & gcc 공학기초설계 Youn-Hee Han
1 유닉스 시스템 프로그래밍 개요.
 13장. 배시쉘 프로그래밍.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
제9장 C 프로그래밍 환경 창병모
[beginning] Linux & vi editor
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
작 성 자: 김선영 메 일: sunyzero (at) gmail (dot) com 버 전: 1.30
버퍼 오버플로우에 대한 대책과 발전된 공격 안전한 함수 사용 버퍼 오버플로우에 취약한 함수 사용하지 않기
MicroC/OS-II Lab. 경희대학교 컴퓨터공학과 조 진 성.
Autotools Autoconf, automake Further Study
Linux/UNIX Programming
-Part3- 제5장 전처리기와 파일 분할 컴파일
컴퓨터 네트워크 실습.
Embedded System Porting (2)
C 7장. 배열과 문자열 #include <stdio.h> int main(void) { int num;
작 성 자: 김선영 메 일: sunyzero (at) gmail (dot) com 버 전: 1.30
7장. 셸 스크립트 프로그래밍.
IS lab. 김건영 Awk, Posting list IS lab. 김건영
제15장 전처리 및 비트연산.
Internet Protocol and Programming
정보검색 환경세팅 및 쉘스크립트 맛보기 IS lab. 김건영.
Beginning Linux Programming
1장. 프로그래밍 언어, C 프로그래밍.
Geek-OS Project 정영진
커널 모듈 프로그래밍 (Kernel Module Programming)
HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버
제 3 장 상수와 변수
1주차: 프로그래밍언어란 무엇인가? C 언어란? C 프로그래밍을 위한 준비
Linux/UNIX Programming
Mips cross compile OS LAB.
제4장 유닉스 쉘 숙명여대 창병모 2011 가을.
제13장 전처리 및 기타기능.
C언어 프로그래밍의 이해 Ch13. 선행처리기와 주석문.
쉽게 풀어쓴 C언어 Express 제15장 전처리 및 비트연산 C Express Slide 1 (of 29)
4장 서버 구축을 위해 알아야 할 핵심 개념과 명령어
Internet Protocol and Programming
작은 분야의 일을 훌륭하게 해내는 자그마한 도구들을 개발자들에게 제공하고 개발자들은 이 도구들을 창의적으로 결합하여 사용하자.
운영체제 RaspberryPi Sejin Oh.
Lecture Notes on Computer Networks 주 홍 택 컴퓨터공학과 계명대학교
editing program files with vi 기본적인 Linux commands
누구나 즐기는 C언어 콘서트 제2장 기초 사항 IT응용시스템공학과 김형진 교수.
Telnet 을 활용한 Linux 메뉴얼 오두환.
Command line tools 한국어 정보의 전산 처리
GDB - GNU Debugger 김진용.
Internet Protocol and Programming
제4장 유닉스 쉘 숙명여대 창병모
제8장 C 쉘 창병모
Makefile
C.
C프로그래밍 도구 컴퓨터공학과 강성인.
Presentation transcript:

05. gcc, make, gdb

GCC 05. gcc, make, gdb

gcc의 사용(1/5) gcc란? GNU Compiler Collection(C/C++/Objective-C, etc..) http://gcc.gnu.org/ C 컴파일러와 링커를 동작시키는 명령어 옵션에 따라 소스를 목적파일로 컴파일하거나, 목적파일을 링크시켜 실행파일 생성 옵션 -v : gcc의 버전정보 출력 -c : 컴파일 소스파일(.c)과 같은 이름의 목적파일(.o)이 생성됨 아래의 경우 main.o 파일이 생성됨 gcc –c main.c 05. gcc, make, gdb

gcc의 사용(2/5) #include <stdio.h> #include "my_header.h" 옵션 - cont. -o : 실행파일을 생성 소스파일(들)을 가지고 test 라는 실행파일을 생성 nlp% gcc –o test main.c 목적파일(들)을 가지고 test 라는 실행파일을 생성 nlp% gcc –o test main.o -I : #include 문장에서 지정한 헤더 파일이 있는 디렉토리를 지정 #include <stdio.h> #include "my_header.h" 시스템 표준 헤더 디렉토리인 /usr/include를 기준으로 파일을 찾아서 포함시킴 지금 컴파일러가 실행되고 있는 현재 디렉토리를 기준으로 파일을 찾아서 포함시킴 05. gcc, make, gdb

gcc의 사용(3/5) 옵션 - cont. -I (cont.) -L : 라이브러리의 위치를 지정 -g : 디버깅 정보 출력 nlp% gcc –I./Include –o test main.c -L : 라이브러리의 위치를 지정 -L 옵션 다음에 해당 라이브러리가 포함된 디렉토리를 지정 -L 옵션과 디렉토리 사이를 띄우면 안됨 -L 옵션은 여러번 쓸 수 있으며 주어진 순서대로 라이브러리를 검색 아래의 경우 현재 디렉토리에서 라이브러리를 찾는 예제 nlp% gcc –o test main.c read.c –L. -g : 디버깅 정보 출력 nlp% gcc –g –o test main.c 05. gcc, make, gdb

gcc의 사용(4/5) 정적 라이브러리 (static linked library) 정적 라이브러리 만들기 정적 라이브러리는 파일 생성 시 라이브러리 내용을 포함 공유 라이브러리와 같이 라이브러리 연동과정이 따로 필요 없으나 파일 크기가 커짐 다른 프로그램들과 공유하지 않아 라이브러리를 활용하는 프로그램들 모두 라이브러리 내용을 메모리에 맵핑 시켜 메모리 활용성에는 그리 좋지 않음 한번 생성한 파일에 대해서는 라이브러리를 따로 관리하지 않아서 편함 정적 라이브러리 만들기 1. 목적 파일을 생성 예) $ gcc –c src1.c src2.c 2. 오브젝트 파일을 아카이브로 묶기 ar rscv [라이브러리이름] [오브젝트 파일들] : 새로운 정적 라이브러리 파일 생성 ar ru [라이브러리이름] [오브젝트 파일들] : 기존 정적 라이브러리에 새로운 오브젝트 파일들을 추가 ar ds [라이브러리이름] [오브젝트 파일들] : 정적 라이브러리 파일에서 오브젝트 제거 ar x [라이브러리이름] : 정적 라이브러리에서 오브젝트 파일 추출 ar t [라이브러리이름] : 정적 라이브러리에 포함된 오브젝트 파일 리스트 출력 예) $ ar rscv libmy.a src1.o src2.o 03. LINUX 중·고급명령어

gcc의 사용(5/5) 공유 라이브러리(Dynamic Linked Library) 공유 라이브러리 만들기 정확하게는 동적 연동 라이브러리라 함 라이브러리를 하나의 메모리 공간에 맵핑한 후, 여러 프로그램에서 공유하여 활용하여 공유 라이브러리라고 함 메모리 용량 절약차원의 장점이 있으며 라이브러리 업데이트 등의 유연성을 가지고 있음 라이브러리 의존성에 따른 관리가 필요 공유 라이브러리 만들기 1. gcc –fPIC –c 소스파일들 2. gcc –share –fPIC –o lib라이브러리파일명.so 목적파일들 위의 과정을 거치면 공유 라이브러리(lib라이브러리파일명.so) 생성 -fPIC와 –fpic의 차이 -fPIC : 크고 느리지만 플랫폼에 무관한 확실한 코드를 생성 -fpic : 작고 빠르지만 경우에 따라서 플랫폼에 제약이 생기는 코드를 생성 -shared : 공유 라이브러리를 생성하는 gcc 옵션 ※ 같은 파일명을 가진 정적 라이브러리와 공유 라이브러리가 있을 경우 공유라이브러리가 우선순위를 가짐 ※ 컴파일 시 –static 옵션을 이용해서 정적 라이브러리에 우선순위를 줄 수 있음 03. LINUX 중·고급명령어

gcc 실습: 소스파일 컴파일하기 다음의 명령어를 차례로 실행 vi 편집기로 다음의 파일을 작성 소스 컴파일 $ mkdir ~/cfiles : c 관련 프로그램을 보관할 디렉터리 생성 $ mkdir ~/cfiles/pro01 : 첫 번째 프로그램을 보관할 디렉터리 생성 $ cd ~/cfile/pro01 : 첫 번째 프로그램이 있는 디렉터리로 이동 vi 편집기로 다음의 파일을 작성 $ vi main.c 소스 컴파일 // main.c // 2010.04.09. #include <stdio.h> main() { printf(“My 1st gcc programming.\n”); } $ gcc –c main.c $ ls main.c main.o 05. gcc, make, gdb

gcc 실습: 실행 파일 만들기(1/2) 목적 파일을 이용하여 실행파일 만들기 “-o” 옵션을 이용하여 실행파일명 지정하여 만들기(목적 파일 이용) $ gcc main.o $ ls a.out main.c main.o $ ./a.out My 1st gcc programming. $ gcc –o pro01 main.o $ ls a.out main.c main.o pro01 $ ./pro01 My 1st gcc programming. 05. gcc, make, gdb

gcc 실습: 실행 파일 만들기(2/2) 먼저 소스파일(main.c)을 제외한 나머지 파일 삭제 소스파일을 이용하여 바로 실행파일 만들기 소스파일을 이용하여 실행파일명을 지정하여 실행파일 만들기 $ rm a.out main.o pro01 $ ls main.c $ gcc main.c $ ls a.out main.c $ ./a.out My 1st gcc programming. $ gcc –o test main.c $ ls a.out main.c test $ ./test My 1st gcc programming. 05. gcc, make, gdb

gcc 실습: 정적 라이브러리 파일 만들기(1/4) 다음의 명령어를 차례로 실행 $ mkdir ~/cfiles/common : common 디렉터리 생성 $ mkdir ~/cfiles/common/src : 소스파일을 보관할 디렉터리 생성 $ mkdir ~/cfiles/common/include : 헤더 파일을 보관할 디렉터리 생성 $ mkdir ~/cfiles/common/lib : 라이브러리 파일을 보관할 디렉터리 생성 $ mkdir ~/cfiles/pro02 : 두 번째 프로그램을 보관할 디렉터리를 생성 $ cd ~/cfiles/common/include : 헤더파일을 보관할 디렉터리로 이동 vi 편집기로 다음의 헤더파일을 작성 $ vi lib.h // lib.h // 2010.04.09. #define PI 3.141592 extern double GetCircleArea(double radius); extern int GetSum(int arr[], int size); extern double GetAverage(int arr[], int size); 05. gcc, make, gdb

gcc 실습: 정적 라이브러리 파일 만들기(2/4) 다음의 디렉터리로 이동 $ cd ~/cfiles/common/src vi 편집기를 이용하여 다음의 소스파일 만들기 $ vi lib.c // lib.c // 2010.04.09. #include <lib.h> double GetCircleArea(double radius) { return radius*radius*PI; } int GetSum(int arr[], int size) int i, sum = 0; for(i = 0; i < size; i++) sum += arr[i]; return sum; double GetAverage(int arr[], int size) return (double)GetSum(arr, size)/(double)size; 05. gcc, make, gdb

gcc 실습: 정적 라이브러리 파일 만들기(3/4) 목적 파일 만들기 정적 라이브러리 파일 만들기 $ gcc –I../include –c lib.c $ ls lib.c lib.o $ ar rscv libstatic.a lib.o a – lib.o $ ls libstatic.a lib.c lib.o $ ar t libstatic.a lib.o $ mv libstatic.a ../lib 03. LINUX 중·고급명령어

gcc 실습: 정적 라이브러리 파일 만들기(4/4) 다음의 디렉터리로 이동 $ cd ~/cfiles/pro02 main함수 작성 $ vi main.c 실행파일 생성 및 파일 실행 // main.c // 2010.04.09. #include <stdio.h> #include <lib.h> main() { int radius; int arr[] = {4, 5, 3, 2, 1, 6}; printf(“Input a radius: ”); scanf(“%d”, &radius); printf(“Area of Circle: %f\n\n”, GetCircleArea(radius)); printf(“Average of array values: %f\n”, GetAverage(arr, 6)); } $ gcc –I../common/include –L../common/lib –o test1 main.c –lstatic $ ls main.c test1 $ ./test1 라이브러리 파일 명시 libmy.a에서 lib와 .a를 제외한 파일명 입력 ※ 주의: 가장 뒤에 와야 함 03. LINUX 중·고급명령어

gcc 실습: 공유 라이브러리 파일 만들기 다음 디렉터리로 이동 목적파일을 삭제 $ cd ~/cfiles/common/src 목적파일을 삭제 $ rm *.o 다음의 과정으로 목적파일 및 공유 라이브러리 파일 생성 실행파일 생성 및 실행 $ gcc –fPIC –I../include –c lib.c $ gcc –shared –fPIC –o libdynamic.so lib.o libdynamic.so lib.c lib.o $ file libdynamic.so libdynamic.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped $ mv libdynamic.so ../lib $ cd ~/cfiles/pro02 $ gcc –o test2 main.c –I../common/include –L../common/lib –ldynamic $ ls main.c test1 test2 $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/자신의그룹/자신의ID/cfiles/common/lib $ ./test2 03. LINUX 중·고급명령어

GDB 05. gcc, make, gdb

gdb 사용하기 gdb 설치 확인 gdb 실행 debug1.c $ ls /usr/bin/gdb /usr/bin/gdb $ $ mkdir ~/cfiles/pro03 $ cd ~/cfiles/pro03 $ vi debug1.c #include <stdio.h> int sum(int i); int main() { printf(“%d\n”, sum(10)); return 0; } int sum(int i) return i + sum(i-1); 05. gcc, make, gdb

gdb 사용하기 debug1.c 컴파일 및 실행 파일 생성 gdb를 종료하기 위한 명령어 : quit 소스파일과 디버깅할 실행 파일이 서로 다른 디렉토리에 있을 경우 # gdb –d source debug1 05. gcc, make, gdb

gdb 명령어 소스파일 내용 출력하기 (list) 05. gcc, make, gdb

gdb 명령어 프로그램 실행시키기 (run) debug2.c 05. gcc, make, gdb

gdb 명령어 명령라인 인수 주기 05. gcc, make, gdb

gdb 명령어 변수 다루기 디버깅의 run 실행 후 확인 whatis : 변수의 데이터형 확인 print : 변수의 값 확인 set variable : 변수의 값 변경 05. gcc, make, gdb

breakpoint 이용하기 break 명령어 현재의 프로그램에서 의심이 나거나 살펴보고 싶은 부분을 지정하기 위해 사용되는 명령어 정지할 위치를 지정하고 run으로 프로그램을 실행하면 gdb가 break에서 지정한 라인까지 실행하고 멈춤 debug3.c 05. gcc, make, gdb

breakpoint 이용하기 debug3.c (cont.) 05. gcc, make, gdb

breakpoint 이용하기 정지점 설정하기 break 문장번호 break 함수이름 break 문장번호 또는 함수이름 if 조건 [예] (gdb) break 11 if i==0  11번 문장에서 i의 값이 0이면 정지점으로 설정 05. gcc, make, gdb

breakpoint 이용하기 정지점 설정하기 (cont.) 05. gcc, make, gdb

breakpoint 이용하기 정지점 확인과 제거하기 info break : 설정된 정지점 확인 delete : 설정된 모든 정지점 제거 delete 정지점 번호 : 해당 정지점만 제거 05. gcc, make, gdb

단계별로 실행하기 debug4.c 명령어 step : 함수로 들어가서 한 문장씩 추적 next : 함수 호출 문장을 한 문장으로 인식하여 호출된 함수 안으로 들어가지 않음 05. gcc, make, gdb

단계별로 실행하기 step 05. gcc, make, gdb

단계별로 실행하기 next 05. gcc, make, gdb

단계별로 실행하기 여러 단계 실행 step n next n n은 자연수 05. gcc, make, gdb

MAKE 05. gcc, make, gdb

make(1/3) make란? “Makefile”이라는 특수한 형식에 저장되어 있는 일련의 의존 규칙(dependency rule)들에 근거하여 파일을 최신 버전으로 개정하는 유틸리티 man을 통해 찾아본 make make의 목적 프로그램 그룹 중에서 새롭게 컴파일되어야 하는지를 자동적으로 판단하고 필요한 커맨드(gcc, cc 등)를 이용하여 필요한 부분만을 재컴파일 시키기 위함 * gcc, cc : UNIX(cc)나 LINUX(gcc)에서 주로 쓰이는 C 컴파일러 05. gcc, make, gdb

c1.c, c2.c, c3.c, c4.c 중에 컴파일하지 않아도 지장이 없는 것은? make(2/3) make와 기술 파일의 관계 기술 파일(Makefile) a.c 파일을 디버깅 옵션으로 컴파일해라. b.c는 모듈을 컴파일해라. d.cc는 c++ 컴파일러로 컴파일해라. /temp/c 디렉터리에 들어가서 확장자가 c인 모든 파일을 컴파일해라. c1.c, c2.c, c3.c, c4.c 파일을 각각 컴파일해서 실행파일 mybin을 만들어라. 만든 mybin을 /user/local/bin에 복사해라. 모든 object 파일과 실행 파일을 지워라. /user/local/bin의 mybin을 지워라. /usr/bin/make 의미해석 c1.c, c2.c, c3.c, c4.c 중에 컴파일하지 않아도 지장이 없는 것은? 05. gcc, make, gdb

make(3/3) Makefile 구문 작성 기본 규칙 Target: dependency1 dependency2 … 명령어들(command1, command2, …)이 수행되어 나온 결과 파일(목적 파일[object file]이나 실행 파일)을 지정 의존 항목(dependency) 목표 파일을 빌드하기 위해 필요한 파일 목록들 명령(commandList) 의존 관계(depenency1 dependency2 …)부분에 정의된 파일의 내용이 바뀌었거나, 목표 부분에 해당하는 파일이 없을 때 이곳에 정의된 것들이 차례대로 실행. 일반적으로 쉘에서 쓸 수 있는 모든 명령어들을 사용할 수가 있음 * 목표 부분에는 결과 파일만 올 수 있는 것이 아니고, 보통 make clean에서와 같이 간단한 레이블(label) 기능 제공 * 명령 부분은 반드시 TAB으로 시작. 빈칸 등의 다른 문자를 사용하면 make 실행 중에 에러 발생 Target: dependency1 dependency2 … command1 command2 … 05. gcc, make, gdb

make의 기본 동작(1/4) 소스 파일들의 내용 diary.h : memo.c : calendar.c : main.c : #include <stdio.h> int memo(); int calendar(); #include “diary.h” int memo(){ printf(“function meme.\n”); return 0; } #include “diary.h” int calendar(){ printf(“function calendar.\n”); return 0; } #include “diary.h” int main(){ memo(); calendar(); return 0; } ※ 각 파일들은 cfiles 디렉터리 밑에 pro04 디렉터리를 생성하여 저장 05. gcc, make, gdb

make의 기본 동작(2/4) 소스 파일 구조도 diary.h memo.c memo.o calendar.o main.o calendar.c main.c diary 05. gcc, make, gdb

make의 기본 동작(3/4) Makefile의 내용 실행 all : diary diary : memo.o calendar.o main.o gcc –o diary memo.o calendar.o main.o memo.o : memo.c gcc –W –Wall –c memo.c calendar.o : calendar.c gcc –W –Wall –c calendar.c main.o : main.c gcc –W –Wall –c main.c ※ -W : 합법적이지만 모호한 코딩에 대한 부가 정보 제공 ※ -Wall : 모든 모호한 문법에 대한 경고 메시지 출력 소스의 엄격성을 제공하기 위해 사용 05. gcc, make, gdb

make의 기본 동작(4/4) 설명 1. make 명령을 내리면 make는 먼저 현재 디렉터리 내에서 기술 파일을 찾음, 현재의 경우는 Makefile이 됨 2. Makefile 내에서 처음 오는 타겟을 찾음. 현재의 경우는 all 3. all 타겟을 만들기 위해 diary를 보고 diary가 현재 디렉터리에 없음을 확인 4. diary를 생성하기 위해 다음 항목을 찾고 diary를 만들기 위한 memo.o가 아직 만들어 지지 않았음을 확인 5. memo.o를 생성하기 위한 룰을 찾고 종속항목 memo.c가 현재 디렉터리 내에 있는 것을 확인하면 컴파일을 수행하여 memo.o를 생성 ※ memo.o가 미리 만들어져 있을 경우 memo.o와 memo.c의 수정 시간을 확인 후 memo.c의 수정시간이 더 최근이라면 memo.o를 다시 만들고 그렇지 않다면 컴파일을 수행하지 않음 6. calendar.o와 main.o에 대해서도 5번 과정을 시도 7. memo.o, calendar.o 및 main.o가 모두 만들어지면 diary를 생성 8. all에 대해서는 특별한 명령어가 없으므로 all 타겟이 정상적으로 생성되었다고 간주하고 make 종료 05. gcc, make, gdb

매크로의 사용(1/6) C나 쉘 프로그래밍에서와 마찬가지로 사용자 정의 변수에 특정한 문자열을 정의하고 표현하는 것을 의미 매크로는 make 파일 내에 정의된 문자열로 치환되어 사용 가능 매크로를 사용하는 것은 보다 일관되고 이식성 높고 융통성 있는 make 파일을 만들기 위해 필요 $(매크로 명) 또는 ${매크로 명}을 이용하여 매크로를 참조 단, 중괄호는 쉘 환경 변수 치환에도 사용되므로 소괄호의 사용을 권장 편 정의되지 않은 매크로를 참조할 때는 null 문자로 치환 주석문은 #을 이용 여러 행을 사용할 때는 ‘\’를 사용 05. gcc, make, gdb

매크로의 사용(2/6) 실습 ~/cfiles 디렉터리 밑에 ex_make 디렉터리를 만들고 Makefile01 작성 실행 ※ make의 –f 옵션은 특정 파일로 make를 실행시킬 경우 사용 ※ 아무런 옵션 없이 make 명령을 할 경우는 현재 디렉터리에서 Makefile을 찾아서 실행 NAME = string MULTI = Our linux group is\ info01. all : @echo ${NAME} # string @echo $(NAME) # string @echo $(NAME).c # string.c @echo macro_$(NAME) # macro_string @echo ${MULTI} @echo my 05. gcc, make, gdb

매크로의 사용(3/6) 여러 가지 대입 기법 매크로의 사용시 주의사항 =  재귀적 대입 :=  단순 확장 대입 =  재귀적 대입 :=  단순 확장 대입 +=  기존의 매크로에 공백을 붙이고 문자열을 덧붙임 ?=  현재 정의하는 매크로가 정의되어 있지 않았을 때 정의 매크로의 사용시 주의사항 인용부호(“”, ‘’ 등)도 문자열의 일부로 인식 매크로의 이름에는 ‘:’, ‘=’, ‘#’이 들어가서는 안되고 탭으로 시작해서도 안됨 매크로는 반드시 치환될 위치보다 먼저 정의해야 함 ‘\’나 ‘<’, ‘>’와 같은 쉘 메타 문자의 사용을 자제해야 함 05. gcc, make, gdb

매크로의 사용(4/6) 실습 및 결과 ~/cfiles/ex_make 디렉터리에 Makefile02를 작성 A1 = $(B1) BB B1 = $(C1) CC C1 = D A2 := $(B2) BB B2 := $(C2) CC C2 := D A3 := A B3 := $(A3) B C3 := $(B3) C NAME1 := string1 NAME1 += string2 NAME2 = he NAME2 ?= she NAME3 ?= you all : @echo $(A1) @echo $(A2) @echo $(C3) @echo $(NAME1) @echo $(NAME2) @echo $(NAME3) 05. gcc, make, gdb

매크로의 사용(5/6) 실습 ~/cfiles/pro04의 Makefile을 다음과 같이 수정하고 make 실행 rm 명령어를 사용, 목적파일(*.o)와 실행파일(diary)를 삭제하고 make 다시 실행 CC = gcc CFLAGS = -W -Wall TARGET = diary OBJECT = memo.o calendar.o main.o all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) $(CFLAGS) –o $(TARGET) $(OBJECT) memo.o : memo.c $(CC) $(CFLAGS) –c memo.c calendar.o : calendar.c $(CC) $(CFLAGS) –c calendar.c main.o : main.c $(CC) $(CFLAGS) –c main.c 05. gcc, make, gdb

매크로의 사용(6/6) 실행 결과 실행 파일 및 목적 파일을 갱신할 필요가 없음 05. gcc, make, gdb

내부적으로 사용되는 매크로의 사용(1/4) 내부적으로 미리 정의되어 있는 매크로의 확인 -p 옵션 사용 RM 매크로의 경우 $ make –p | more RM 매크로의 경우 미리 rm –f 로 정의되어 있음 즉, 정의하지 않고 사용 가능 $(RM) * = rm –f * 05. gcc, make, gdb

내부적으로 사용되는 매크로의 사용(2/4) 내부적으로 정의된 매크로 리스트 05. gcc, make, gdb 매크로 설명 기본값 AR 아카이브 관리 프로그램 ar CWEAVE C Web을 TeX로 변환 cweave AS 어셈블러 as TANGLE Web을 파스칼로 변환 tangle CC C 컴파일러 cc CTANGLE C Web을 C로 변환 ctangle CXX C++ 컴파일러 g++ RM 파일을 지우는 명령어 rm –f CO RCS checkout 프로그램 co ARFLAGS ar 플래그 rv CPP C 전처리기 cc –E ASFLAGS 어셈블러 플래그 FC 포트란 컴파일러 f77 CFLAGS C 컴파일러 플래그 GET SCCS 관련 프로그램 get CXXFLAGS C++ 컴파일러 플래그 LD 링크 ld COFLAGS RCS co 플래그 LEX 스캐너 코드 생성기 lex CPPFLAGS C 전처리기 플래그 PC 파스칼 컴파일러 pc FFLAGS 포트란 컴파일러 플래그 YACC 파서 코드 생성기 yacc GFLAGS SCCS get 플래그 MAKEINFO Texinfo 파일을 Info 파일로 변환 makeinfo LDFLAGS 링크 플래그 TEX TeX 문서로부터 TeX DVI 생성 tex LFLAGS Lex 플래그 TEXI2DVI Texinfo 파일을 dvi 파일로 변환 texi2dvi PFLAGS 파스칼 컴파일러 플래그 WEAVE YFLAGS Yacc 플래그 05. gcc, make, gdb

내부적으로 사용되는 매크로의 사용(3/4) 자동 매크로 리스트 make 내부적으로 정의되어 있지만 make –p 명령어로 확인할 수 없는 매크로 make 파일을 보다 적은 양으로 표현할 수 있어 make에서 자주 사용 $% : 타겟을 생성하는데 라이브러리가 사용될 때 라이브러리 내에 특정한 함수 하나를 지정할 경우 사용하는 매크로 $<, $*는 확장자 규칙에서 다룸 target : dep1.c dep2.c gcc –o target dep1.c dep2.c gcc –o $@ $^ 매크로 설명 $? 현재의 타겟보다 최근에 변경된 종속 항목 리스트 (확장자 규칙에서 사용 불가) $^ 현재 타겟의 종속 항목 리스트 (확장자 규칙에서 사용 불가) $@ 현재 타겟 이름 $< 현재 타겟보다 최근에 변경된 종속 항목 리스트 (확장자 규칙에서만 사용 가능) $* 현재 타겟보다 최근에 변경된 현재 종속 항목의 이름(확장자 제외, 확장자 규칙에서만 사용 가능) $% 현재의 타겟이 라이브러리 모듈일 때 .o 파일에 대응되는 이름 ex) /temp/target : /usr/local/c/test.c ${@F}: 현재 타겟의 파일 부분(target) ${<F}: 현재 필요 항목의 파일 부분(test.c) ${@D}: 현재 타겟의 디렉터리 부분(/temp) ${<D}: 현재 필요 항목의 디렉터리 부분(/usr/local/c) 05. gcc, make, gdb

내부적으로 사용되는 매크로의 사용(4/4) 내부 매크로를 이용한 Makefile 수정 ~/cfiles/pro04의 Makefile을 다음과 같이 수정 후 make 실행 실행 전 목적파일과 실행파일을 삭제 : $ rm –f *.o diary CC = gcc CFLAGS = -W -Wall TARGET = diary OBJECT = memo.o calendar.o main.o all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) $(CFLAGS) –o $@ $^ memo.o : memo.c $(CC) $(CFLAGS) –c $^ calendar.o : calendar.c main.o : main.c 05. gcc, make, gdb

확장자 규칙의 사용(1/6) make –p 명령으로 출력되는 내용의 일부 05. gcc, make, gdb

확장자 규칙의 사용(2/6) 실습: 확장자 규칙을 이용한 컴파일 ~/cfiles/pro04의 Makefile을 다음과 같이 수정 후 실행 실행 전 목적파일과 실행파일을 삭제: $ rm –f *.o diary 실행결과 TARGET = diary OBJECT = memo.o calendar.o main.o all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ 매우 짧은 make 파일이지만 컴파일 과정에 필요한 모든 명령이 내려짐 05. gcc, make, gdb

확장자 규칙의 사용(3/6) 설명 1. make 파일에서 diary를 생성하기 위해 make는 종속 항목을 살펴보고 종속 항목을 각각 타겟으로 설정 2. diary는 memo.o에 의존하지 않고 memo.o는 만들어져 있지 않으며 memo.o를 생성하기 위한 툴도 기술 파일에는 정의되어 있지 않음 3. make는 확장자가 .o인 내부 확장자 규칙을 이용하여 다음과 같은 기준으로 현재 디렉터리에서 memo.o를 생성할 파일을 찾음 확장자를 제외하고 memo.o와 같은 이름이 있어야 함(memo.c) 중요 확장자를 가지고 있어야 함(.c .cc .cpp .s .S 등) 내부 확장자 규칙에 따라 memo.o를 만드는 데 사용할 수 있어야 함(50page에서 %.o: %.c에 대응되는 확장자 규칙이 존재 내부 정의 확장자 규칙의 명령어($(COMPILE.c) $(OUTPU_OPTION) $<)를 이용하여 memo.o를 생성  cc –c –o memo.o memo.c 05. gcc, make, gdb

확장자 규칙의 사용(4/6) 실습: 확장자 규칙의 재정의 실습 전 목적파일과 실행파일을 삭제: $ rm –f *.o diary ~/cfiles/pro04의 Makefile을 다음과 같이 수정 후 실행 .SUFFIXES 특수 타겟(후에 설명) 종속 항목: 확장자 규칙을 검사하는 데 사용되는 중요 확장자 리스트 확장자 규칙을 사용하고 싶은 확장자는 .SUFFIXES 타겟의 종속 항목으로 설정 바로 전 예제에서 .SUFFIXES을 사용하지 않아도 확장자 규칙이 적용되는 이유는 make 내부에서 중요 확장자에 대해 .SUFFIXES 타겟의 종혹항목으로 이미 등록이 되었기 때문 %의 의미는 확장자를 제외한 파일명 $^는 확장자 규칙에서 사용이 불가능하며, $<는 확장자 규칙에서만 사용이 가능 TARGET = diary OBJECT = memo.o calendar.o main.o .SUFFIXES : .o .c %.o : %.c # .o와 대응되는 .c를 발견하면 아래 명령 수행 $(CC) –DDEBUG –c –o $@ $< # -DDEBUG : 디버깅 메시지를 활성화 all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ 05. gcc, make, gdb

확장자 규칙의 사용(5/6) 실습: 와일드 카드 매칭 기법과 대입 참조 기법을 사용한 make 파일 실습 전 목적파일과 실행파일을 삭제: $ rm –f *.o diary ~/cfiles/pro04의 Makefile을 다음과 같이 수정 후 실행 소스 파일 및 목적 파일이 많을 때나 개발 과정 동안 파일들이 계속해서 늘어날 경우 유용 $(wildcard *.c) 와일드 카드 매칭 기법 현재 디렉터리에서 *.c와 파일명이 일치하는 파일을 찾아 공백을 구분 문자로 SRCS 매크로에 정의 $(SRCS:.c=.o) 대입 참조 기법 확장자 .c가 .o로 바뀌게 됨 TARGET = diary SRCS = $(wildcard *.c) OBJECT = $(SRCS:.c=.o) all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ 05. gcc, make, gdb

확장자 규칙의 사용(6/6) patsubst 함수를 이용한 make 파일 실습 전 목적파일과 실행파일을 삭제: $ rm –f *.o diary ~/cfiles/pro04의 Makefile을 다음과 같이 수정 후 실행 patsubst 함수 세 번째 인자로 오는 $(wildcard *.c)의 결과를 공백으로 구분된 문자열들 각각에 대해 첫 번째 인자인 %.c와 매칭되는 것을 %.o로 치환 %는 확장자를 제외한 파일명을 의미 TARGET = diary OBJECT = $(patsubst %.c, %.o, $(wildcard *.c)) all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ 05. gcc, make, gdb

더미 타겟의 사용 실습 실행 결과 ~/cfiles/pro04에 있는 Makefile을 다음과 같이 수정 TARGET = diary OBJECT = $(patsubst %.c, %.o, $(wildcard *.c)) all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ clean : rm –rf *.o diary 05. gcc, make, gdb

명령어 사용 규칙(1/4) 명령어 사용에는 몇 가지 간단한 규칙이 있음 이러한 규칙을 잘 알고 주의해서 사용을 해야함 위와 같은 룰이 있을 때 make echo를 실행하면 make는 내부적으로 새로운 쉘을 띄우고 다음과 같은 명령을 내림 다음과 같은 명령어는 주의 원래의 의도는 ./backup 디렉터리의 모든 파일을 삭제하는 것임 이유는 각 명령어가 서로 다른 쉘에서 수행이 되기 때문. 따라서 다음과 같이 작성 만약 ./backup 디렉터리가 없다면?  “cd ./backup”은 실패하고 “rm –rf *”을 수행 echo : @echo “echo test!” /bin/sh –c echo “echo test!” del : cd ./backup rm –rf * del : cd ./backup; rm –rf * del : cd ./backup && rm –rf * 05. gcc, make, gdb

명령어 사용 규칙(2/4) 명령어 에코 기능 .SILENT echo 명령어 앞에 ‘@’을 붙이는 이유: 명령어 에코 기능을 끄기 위해 명령어 에코 기능: 명령어를 수행할 때 수행되는 명령어를 보이는 기능 ‘@’을 붙이지 않으면 echo 명령도 출력되고 명령의 결과도 출력 ‘@’을 붙이지 않았을 때의 수행 결과 ‘@’을 붙였을 경우의 수행 결과 .SILENT 모든 명령에 대하여 에코 기능을 끄기 위해 사용되는 특수 내장 타겟 특수 내장 타겟은 추후 설명 .SILENT 타겟에 등록된 종속 항목에 수행되는 명령어들은 에코 기능을 끔 따라서, 명령어 수행이 화면에 출력되지 않음 05. gcc, make, gdb

명령어 사용 규칙(3/4) 명령어의 정상적인 종료와 비정상적인 종료 프로세스가 정상적인 종료를 했을 경우 0을 리턴, 비정상적인 종료를 했다면 0 이외의 값을 리턴(보통 1) echo $?로 프로세스의 리턴값을 확인할 수 있음 make의 경우 명령어가 비정상적으로 종료를 했을 경우 수행을 종료 비정상적인 종료를 하더라도 make의 수행을 계속하고 싶을 경우 명령어 앞에 ‘-’를 붙인다. make 파일 전체에서 명령어 오류를 무시하고 싶은 경우 다음을 추가 .IGNORE : 특수 내장 타겟, 종속 항목에 등록된 파일들의 수행시 발생하는 오류 무시 cat : -cat *.c .IGNORE : 05. gcc, make, gdb

명령어 사용 규칙(4/4) 쉘 변수의 사용 make 파일 내에서 쉘 변수를 참조할 때는 “$${변수명}” 또는 “$$변수명”의 형태로 사용 쉘 변수를 사용할 때는 make 파일 내부에 쉘스크립트를 사용하는 경우도 주의 만약, $를 하나만 쓰게 되면 매크로로 인식을 하게 됨 실습 TARGET = diary OBJECT = $(patsubst %.c, %.o, $(wildcard *.c) all : $(TARGET) $(TARGET) : $(OBJECT) $(CC) -o $@ $^ cp –f diary $${HOME} # 사용자의 홈디렉터리로 diary를 복사 05. gcc, make, gdb

재귀적 make의 사용(1/4) 프로젝트의 규모가 커질 경우 소스를 여러 디렉터리에 나누는 것이 관리가 용이 VPATH를 사용하는 방법 재귀적인 make 사용법 ※ 경로를 일일이 지정하는 것보다는 VPATH나 재귀적 make 사용법이 더 효율적이고 유연한 방법이나 VPATH는 파일명에 종속되는 경향이 있어 보통은 재귀적으로 make 사용 실습을 위한 디렉터리 및 파일 구조 ~/cfiles pro05 calendar include main memo Makefile diary.h main.c calendar.c memo.c ※ 헤더 파일 및 소스파일의 내용은 ~/cfiles/pro04의 헤더파일 및 소스파일과 내용 동일 ※ 볼드체의 Makefile은 최상위 Makefile 05. gcc, make, gdb

재귀적 make의 사용(2/4) 최상위 Makefile(~/cfiles/pro05) cd memo && make 대신 make –C memo를 사용해도 됨 TARGET = diary OBJECT = memo.o calendar.o main.o all : MEMO CALENDAR MAIN $(TARGET) MEMO : cd memo && make CALENDAR : cd calendar && make MAIN : cd main && make $(TARGET) : $(OBJECT) $(CC) -o $@ $^ clean : cd memo && make clean cd calendar && make clean cd main && make clean -rm –rf *.o diary 05. gcc, make, gdb

재귀적 make의 사용(3/4) 하위 디렉터리의 Makefile(모두 동일하게 작성) make 실행 OBJECT = $(patsubst %.c, %.o, $(wildcard *.c)) CFLAGS = -I../include all : $(OBJECT) cp –f $^ ../ clean : rm –rf *.o 05. gcc, make, gdb

재귀적 make의 사용(4/4) 일반적으로 최상위 Makefile은 다음과 같이 구현 DIRS = memo calendar main TARGET = diary OBJECT = memo.o calendar.o main.o all : objs $(CC) –o $(TARGET) $(OBJECT) objs : @for dir in $(DIRS); do \ make –C $$dir || exit $?; \ done clean : make –C $$dir clean; \ -rm –rf *.o $(TARGET) 05. gcc, make, gdb

VPATH를 사용한 make의 사용 최상위 Makefile을 다음과 같이 수정 실행 VPATH = memo calendar main TARGET = diary OBJECTS = memo.o calendar.o main.o CFLAGS = -I./include $(TARGET) : $(OBJECTS) $(CC) –o $@ $^ clean : -rm –rf *.o diary 05. gcc, make, gdb

서브 Makefile에 대한 매크로 전달 최상위 Makefile에서 지정한 매크로를 서브 디렉터리로 전달하는 방법 매크로 앞에 export 키워드를 추가 CC = gcc 최상위 디렉터리만 gcc로 컴파일이 되며 하위 디렉터리들은 cc로 컴파일이 됨 export CC = gcc 하위 디렉터리도 gcc로 컴파일이 됨 실습 강의노트 64 page의 Makefile에 export CC = gcc 구문을 추가해 본다. 05. gcc, make, gdb

조건부 수행 ifeq ~ else ~ endif 문 ifneq ~ else ~ endif 문 ifdef ~ else ~ endif 문 매크로가 정의되어 있으면 ifdef를 수행, 아니면 else를 수행 ifndef ~ else ~ endif 문 매크로가 정의되어 있지 않으면 ifndef를 수행, 아니면 else를 수행 all : ifeq ($(CC), gcc) @echo “C 컴파일러는 gcc입니다.” else @echo “C 컴파일러는 $(CC)입니다.” endif 05. gcc, make, gdb

함수의 사용(1/8) make 함수의 사용 형식 쉘 명령 함수 $(함수명 함수인자들) 함수인자가 여러 개라면 콤마(,)로 구분 $(shell 쉘 명령어) 자주 사용되는 함수 shell 함수는 쉘 명령을 수행하고 결과를 리턴 SRCS = $(shell ls *.c) echo : @echo $(SRCS) 05. gcc, make, gdb

함수의 사용(2/8) 문자열 처리 함수(1) : 문자열 치환 함수들 $(subst 찾을문자열, 변경할문자열, 목표문자열) $(patsubst 패턴, 변경할문자열, 목표문자열) $(매크로명: 패턴=치환할문자열) STR = $(subst like, LIKE, I like you.) echo : @echo $(STR) STR = $(patsubst %.c, %.o, memo.c main.c) echo : @echo $(STR) MACRO = memo.c main.c STR = $(MACRO:%.c=%.o) echo : @echo $(STR) 05. gcc, make, gdb

함수의 사용(3/8) 문자열 처리 함수(2) $(sort 문자열) : 문자열을 정렬 $(strip 문자열) : 공백 문자의 제거 MACRO = bbb aaa ccc aaa ddd STR = $(sort $(MACRO)) echo : @echo $(STR) STR = aaaa bbbb echo : @echo $(strip $(STR)) 05. gcc, make, gdb

함수의 사용(4/8) 문자열 처리 함수(3) : 문자 필터링 함수들 $(filter 패턴, 문자열) $(filter-out 패턴, 문자열) 패턴과 일치하지 않는 문자열을 필터링함 FILE = memo.c head.h main.c asm.S diary.h SRCS = $(filter %.c %.S, $(FILES)) HEADS = $(filter %.h, $(FILES)) echo : @echo “source files : $(SRCS)” @echo “head files : $(HEADS)” 05. gcc, make, gdb

함수의 사용(5/8) 문자열 처리 함수(4) : 특정 문자열을 찾는 함수 $(findstring 찾을문자열, 대상문자열) $(words 문자열) : 문자열에서 사용된 단어의 개수 리턴 $(word [n], 문자열) : 문자열에서 n번째 단어 리턴 $(wordlist 시작번호, 끝번호, 문자열) : 문자열의 시작 번호 ~ 끝 번호까지의 단어들을 리턴 $(firstword 문자열) : 문자열에서 첫 번째 단어 리턴 $(join 문자열, 문자열) : 두 문자열을 합쳐 하나의 문자열로 만듦 STR = aaa bbb ccc echo : @echo bbb: $(findstring bbb, $(STR)) @echo kkk: $(findstring kkk, $(STR)) 05. gcc, make, gdb

함수의 사용(6/8) 파일 이름 관련 함수 $(dir 문자열) : 문자열에서 디렉터리 부분만 추출 $(nodir 문자열) : 문자열에서 디렉터리가 아닌 부분만 추출 $(suffix 문자열) : 문자열에서 확장자만 추출 $(basename 문자열) : 문자열에서 파일명만 추출(경로 포함) $(addsuffix 접미사, 문자열) : 문자열의 각 단어 뒤에 접미사를 붙임 $(addprefix 접두어, 문자열) : 문자열 각각에 접두어를 붙임 05. gcc, make, gdb

함수의 사용(7/8) 기타 유용한 함수(1) $(wildcard 패턴) $(foreach 변수명, 대입문자열, 확장문자열) 현재 디렉터리에서 패턴과 일치하는 파일 리스트를 뽑는다. $(foreach 변수명, 대입문자열, 확장문자열) 변수명에 대입문자열을 단어별로 대입하여 넣고 그 변수를 확장문자열에서 사용 SRCS = $(foreach str, a b c, $(str).c) echo : @echo $(SRCS) SRCS = $(foreach str, a b c, TEXT) echo : @echo $(SRCS) SRCS = $(foreach dir, . memo main calendar, $(wildcard $(dir)/*.c) echo : @echo $(SRCS) 05. gcc, make, gdb

함수의 사용(8/8) 기타 유용한 함수(2) $(origin 매크로명) 매크로가 어떻게 정의된 매크로인지에 관한 문자열 리턴 DEFINE = str echo : @echo $(origin UNDEFINE) @echo $(origin DEFINE) @echo $(origin PATH) @echo $(origin CMDDEF) 리턴된 문자열 의 미 undfined 정의되지 않음 file make 파일 내에서 정의된 매크로 environment 환경변수(HOME, PATH, PWD 등) command line make 명령 시 정의된 매크로 default make 내부에 정의된 매크로 environment override 환경 변수 automatic 자동 매크로($@, $? 등) override override 매크로 <origin 함수에서 리턴하는 문자열의 의미> 05. gcc, make, gdb

함수 사용에 있어 주의 사항 함수를 지원하는 make에서 사용해야 됨 함수의 인자로 콤마(,)와 공백( )을 주의해서 사용 GNU make는 함수를 지원하기 때문에 바로 사용 가능 함수를 지원하지 않는 make도 많이 존재 함수를 make 파일에 사용하면 그 make 파일은 함수를 지원하는 make에만 종속  이식성 저하 함수의 인자로 콤마(,)와 공백( )을 주의해서 사용 콤마나 공백을 사용하고 싶다면 매크로를 정의해서 사용 comma = , space = $(null) $(null) # null 매크로는 정의되지 않은 매크로이며, 따라서 null 문자로 치환됨 comma =, space = $(null) $(null) TEXT1 = id, pass, name STR1 = $(subst $(comma), _, $(TEXT)) STR2 = $(subst $(space), _, $(TEXT)) echo : @echo $(STR1) @echo $(STR2) 05. gcc, make, gdb

특수 타겟 make 파일 전체에 영향을 미칠 수 있는 make의 기능을 정의할 때 사용 .DEFAULT 특수 타겟 종류 설 명 .DEFAULT make가 요청된 타겟을 빌드할 룰을 make 파일 또는 확장자 규칙에서 찾지 못하면 . DEFAULT 타겟에 기술된 명령어를 수행 .IGNORE 명령어 수행 시 반환되는 오류 코드를 무시. make 명령 시 i 옵션을 준 것과 동일. 또는 make 파일 내의 모든 명령어 앞에 ‘-’ 기호를 붙인 것과 동일 .PRECIOUS .PRECIOUS 타겟에 기술된 파일들은 빌드 중단 신호 또는 명령 행에서 오류가 반환되더라도 지우지 않는다. .SILENT 명령은 실행하지만 실행되는 명령을 화면에 출력하지 않는다. –s 옵션과 동일 또는 make 파일 내의 모든 명령어 앞에 ‘@’ 기호를 붙인 것과 동일 .SUFFIXES .SUFFIXES 타겟에 정의된 확장자들은 중요 확장자들로써 확장자 규칙과 연관될 수 있음 .EXPORT_ALL_VARIABLES 재귀적 make 사용법에 있어서 export 키워드를 단독으로 make 파일에서 사용한 것과 마찬가지로 make 파일 내의 모든 매크로들을 하위 기술 파일에 전달 #.DEFAULT : # @echo “.DEFAULT target test!” echo : @echo “Hello, world.!” 05. gcc, make, gdb

과제 프로그램 요구 사항 제출 방법 평가 기준 제출 기한: 01 강좌는 4월 19일까지, 02/03 강좌는 4월 21일까지 메뉴 구성 1. 키 입력: 암호화 및 복호화를 위한 키를 입력 받음 2. 평문 입력: 암호화 되지 않은 원문을 입력 받음  암호문 출력 3. 암호문 입력: 암호화된 암호문을 입력 받음  평문 출력 프로그램 구조 enc.h: 암호/복호와 관련된 함수 프로토 타입 선언 enc.c: 암호/복화와 관련된 함수 선언 Makefile을 이용하여 컴파일 할 것 제출 방법 소스는 실습 서버에 올리고 위의 프로그램 구조를 따를 것 소스에 대한 설명 및 실행 결과 화면을 추가하여 워드프로세서로 작성하고 인쇄하여 제출 비고 및 고찰 평가 기준 레포트 작성의 성실성 makefile의 다양한 적용 추가 기능 여부(소문자 이외의 문자 암/복호화, 파일 입/출력 기능 등) 위의 프로그램 구조를 따르지 않으면 감점(단, 추가 기능이 있는 파일은 추가 가능) 제출 기한: 01 강좌는 4월 19일까지, 02/03 강좌는 4월 21일까지 ~/report encrypt include src lib enc.h libencd.a enc.c main.c 05. gcc, make, gdb