패치 파일 만드는 법과 적용하는 법

  1. 패치 파일의 쓰임
  2.  패치(patch) 파일은 두 파일들간의 차이들을 출력해 주는 프로그램인 diff에 의해
    생성된 파일을 의미한다. 주로 쓰이는 때는 어떤 프로그램에서 기능향상이나
    문제점을 해결하기 위해 소스파일들을 고치고 나서 고친 부분에 대한 정보만을
    기록해 놓고 싶을때 쓰인다. 고친 소스파일 전체보다도 고친 부분에 대한 정보만을
    갖고 있으면 저장해야 되는 양이 적고, 어떤 부분을 고쳤는지 파악하기도 쉽다는 
    장점이 있다. (특히 비공식적인 패치 적용시 프로그램이 버젼업이 되어 소스가
    변경되었을때 유용하다.) 패치파일의 확장자는 사용자 임의이긴 하지만 알아보기 
    쉽도록 주로 .diff 또는 .patch를 사용한다.
     그럼 먼저 패치 파일을 만들기 위해 diff 프로그램의 사용법을 익혀보자.
    

  3. diff 사용법
  4.  다음은 두 파일의 차이를 기록(또는 출력)해 두기 위해 diff를 사용하는 간단한
    예이다.
     다음과 같은 hello 라는 문구를 출력하는 hello.c 라는 파일을 만들었다고 하자.
    
    #include 
    
    int main(void)
    {
    	printf("hello\n");
    	return 0;
    }
    
    위에서 'hello' 라는 문구 대신 '안녕하세요'로 바꾸고 싶다고 하자. 먼저 다음과 
    같이 위의 hello.c 파일을 hello.c.orig 라는 파일로 백업해 둔다.
    
    % cp hello.c hello.c.orig
    
    그리고 hello.c파일을 다음과 같이 고친다.
    
    #include 
    
    int main(void)
    {
    	printf("안녕하세요\n");
    	return 0;
    }
    
    이 두 파일의 차이점을 패치 파일로 기록해 두기 위해 다음과 같이 diff 명령을 
    이용한다. diff 명령의 일반적인 형식은 다음과 같다.
    
     diff [options] from-file to-file
    
    이 예에서는 다음과 같이 실행해 본다.
    
    % diff -uNr hello.c.orig hello.c > hello-hangul.patch
    
    앞의 -uNr 은 diff 프로그램의 옵션인데 자세한 것은 man 명령을 이용하기로 하자.
    (사용자에 따라 다르지만 주로 이 옵션을 붙여서 사용한다.) 뒤에 오는 인수로서
    앞에 있는 hello.c.orig 는 고치기 전의 원래 파일이름, 뒤의 hello.c 는 고친 후의
    파일이름을 써 준다. 그리고 diff 는 그 출력이 standard output이기 때문에 이것을
    hello-hangul.patch 라는 패치파일에 저장하기 위해 파이프를 이용하였다. 굳이 
    패치 파일의 이름을 hello.patch 라고 하지 않고 hello-hangul.patch 라고 한 것은 
    여러가지 패치 파일을 만드는 경우에 대비해 그것들을 구분하기 위해서이다.
     생성된 hello-hangul.patch 라는 파일은 단순한 텍스트 파일이다. 그 내용을 보기
    위해 다음과 같은 명령을 실행해 보자.
    
    % cat hello-hangul.patch
    --- hello.c.orig	Sun Jan 16 16:54:32 2000
    +++ hello.c	Sun Jan 16 16:53:04 2000
    @@ -2,6 +2,6 @@
     
     int main(void)
     {
    -	printf("hello\n");
    +	printf("안녕하세요\n");
    	return 0;
     }
    
    
     고친 파일의 이름, 고친 부분의 아래 위 세줄의 내용과 고친 부분이 -, + 로
    표시되어 있는 것을 알 수 있다.
     고칠 파일이 여러개 있는 경우에 파일각자를 백업하는 것은 귀찮은 일일 것이다.
    이때에는 다음의 예와 같이 디렉토리를 이용한다.
     프로그램이 xchat-1.2.0 인 경우의 예를 들어 보자. 먼저 원래 프로그램 소스의
    디렉토리에서 컴파일한 적이 있다면 make clean, make distclean 등의 명령을
    이용하여 원래의 프로그램 소스만 남도록 한다. 변경하지 않은 원래 프로그램
    소스의 최상위 디렉토리가 xchat-1.2.0 라고 하면 다음과 같이 xchat-1.2.0-orig
    디렉토리에 그 내용을 백업을 해 둔다.
    
    % cp -a xchat-1.2.0 xchat-1.2.0-orig
    
    ls 라고 치면 xchat-1.2.0 이란 디렉토리와 xchat-1.2.0-orig 이란 디렉토리가
    동시에 보일 것이다. 
     그 다음 xchat-1.2.0 이란 디렉토리 내에 있는 여러 파일들을 원하던 대로 수정한다
    . 수정이 다 끝났으면 diff 프로그램을 이용하여 패치 파일을 만든다.
    
    % diff -uNr xchat-1.2.0-orig xchat-1.2.0 > xchat-1.2.0-serverlist.patch
    
    전처럼 패치 파일을 살펴보고 자신이 의도한 바대로 되어 있는 확인하면 된다.
     지금까지 패치를 만드는 법을 알아보았다. 이제는 패치를 적용하는 법을 알아보자.
    
    

  5. 패치 적용법
  6.  다음은 패치 파일과 변형되지 않은 원래 프로그램 소스 파일을 가지고 있을 때
    패치를 적용하는 방법이다.
     일단 패치를 적용하기 위해서는 patch 라는 명령어를 이용하는데, 그 일반적인 
    형식은 다음과 같다.
    
     patch [options] [originalfile [patchfile]]
    
     일단 패치 파일을 살펴본다. 패치의 맨 윗줄을 보면 다음과 같이 파일에 관한 정보가
    있는 부분이 있다. 
    --- xchat-1.2.0/src/serverlist.h.orig   Wed Aug 25 14:48:57 1999
    +++ xchat-1.2.0/src/serverlist.h        Sun Oct 31 18:06:13 1999
    
     변경되지 않은 프로그램의 소스 디렉토리로 이동한다음 다음과 같이 patch 라는
    명령을 이용하여 패치를 한다.
    
    % cd xchat-1.2.0/
    % patch -p1 < ../xchat-1.2.0-serverlist.patch
    
     위에서 옵션 '-p1' 은 현재 디렉토리에서 볼때 패치파일의 정보
    xchat-1.2.0/src/serverlist.h 에서 첫번째 슬래쉬 앞쪽으로 뺀 src/serverlist.h
    파일에 패치를 적용하기 위한 의도이다. 만약 그 상위디렉토리에서 패치를 적용하기
    원한다면 그냥 다음과 같이 하면 될 것이다.
    
    % patch -p0 < xchat-1.2.0-serverlist.patch
    
     만약 프로그램이 버젼업 되었는데 패치 파일은 그 전 버젼의 소스에서 만들어졌을때
    패치를 적용하면 어떻게 될까? 운이 좋아서 바뀐 부분의 근처부분이 별로 바뀐 점이
    없다면 그대로 적용될 것이고 아니라면 reject 한다는 에러메시지를 만나게 될
    것이다. 따라서 기능개선이나 버그를 개선하는 패치를 만든 경우 저자에게 전달해서
    다음버젼에는 적용되도록 하는 것이 좋다. 또한 패치파일이 여러개일 경우에는
    패치를 적용하는 순서에 주의하여 패치를 해야 한다. (어떤 패치를 먼저 적용하느냐
    하는 것은 상황에 따라 다르다.) 
    

  7. 참고: 권장하는 패치 파일 이름
  8.  어떤 한 프로그램에 대한 패치가 여러개인 경우 그 파일 이름만을 보고 무엇을 하는
    패치인지 파악할 수 있다면 좋을 것이다. 따라서 패치의 이름은
    xchat-1.2.0-serverlist.patch와 같이 프로그램-버젼-역할.patch 정도로 할 것을
    권장한다. (단지 권장일 뿐이다. 사실 그 이름이 홍길동이든, 손오공이든 상관이
    없다.)
    
     참고로 한글 패치 홈페이지에 있는 패치들은 역할과 그에 맞는 이름으로 다음과 같은
    단어들을 사용하였다.
    
     font guess관련 패치 => fontguess
     fontset 관련 패치 => fontset
     nls hangul 관련 패치 => nls-hangul
     한글 사용 관련 default setting 변경 => default
    
     * 위에 속하지 않는 다른 것들.
     8bit-clean, 또는 멀티바이트 개념이 없는 패치 => 8bit
     locale관련 함수를 사용하지 않지만 내부적으로 글자 구분을 하는 패치 => euc
     locale관련 함수를 사용하여 다른 언어에도 통하는 패치 => i18n
    
     * 나머지 불분명한 것 => hangul
    


<주 페이지로> <한단계 위로>
Copyright 2000.8 by HyunChul Kim

최근 수정일: 11/30/00