5. 빌드된 배포판 만들기
***********************

참고:

  이 문서는
  https://setuptools.readthedocs.io/en/latest/setuptools.html 의
  "setuptools" 설명서가 현재 여기에 포함된 모든 관련 정보를 독립적으로
  다루기 전까지만 보존됩니다.

"빌드된 배포판"은 (여러분의 배경에 따라) 아마도 "바이너리 패키지
(binary package)"나 "설치 프로그램(installer)"이라고 생각하던 것입니다
. 파이썬 소스 코드 및/또는 바이트 코드만 포함 할 수 있기 때문에, 반드
시 바이너리 일 필요는 없습니다; 우리는 이것을 패키지라고 부르지 않습니
다, 이 단어는 이미 파이썬에서 사용되었기 때문입니다. (그리고 "설치 프
로그램"은 주류 데스크톱 시스템의 세계에 고유한 용어입니다.)

빌드된 배포판은 모듈 배포판 설치자의 삶을 가능한 한 쉽게 만드는 방법입
니다: RPM 기반 리눅스 시스템 사용자에게는, 바이너리 RPM입니다; 윈도우
사용자에게는, 실행 가능한 설치 프로그램입니다; 데비안 기반 리눅스 사용
자에게는 데비안 패키지입니다; 등등. 분명히, 누구도 하늘 아래 모든 플랫
폼에 대해 빌드된 배포판을 만들 수 없으므로, Distutils는 모듈 개발자가
자신의 전문 분야---코드 작성과 소스 배포판 만드는 것---에 집중하도록
하는 한편, 중간적인 존재인 *패키저(packagers)*가 소스 배포판을 패키저
만큼 많은 수의 플랫폼에 대해 빌드된 배포판으로 전환하도록 설계되었습니
다.

물론, 모듈 개발자는 스스로 패키저일 수 있습니다; 또는 패키저는 원래 개
발자가 접근할 수 없는 플랫폼에 액세스 할 수 있는 어딘가 "외부의" 지원
자일 수 있습니다; 또는 새로운 소스 배포판을 주기적으로 가져와서 소프트
웨어가 액세스 할 수 있는 많은 플랫폼에 대해 빌드된 배포판으로 전환하는
소프트웨어일 수 있습니다. 그들이 누구인지와 관계없이, 패키저는 설정 스
크립트와 **bdist** 명령군을 사용하여 빌드된 배포판을 생성합니다.

간단한 예로, Distutils 소스 트리에서 다음 명령을 실행하면:

   python setup.py bdist

Distutils는 내 모듈 배포판(이 경우 Distutils 자체)을 빌드하고, "가짜"
설치(역시 "build" 디렉터리에)를 수행하고, 내 플랫폼에 대한 빌드된 배포
판의 기본 유형을 만듭니다. 빌드된 배포판의 기본 형식은 유닉스에서는 "
아둔한(dumb)" tar 파일이고, 윈도우에서는 간단한 실행 가능한 설치 프로
그램입니다. (tar 파일은 작동하려면 특정 위치에서 풀어야 해서 "아둔하다
고" 간주합니다.)

따라서 유닉스 시스템에서 위의 명령은 "Distutils-1.0.*plat*.tar.gz"를
만듭니다; 이 tar 파일을 올바른 위치에서 풀면 소스 배포를 다운로드한 후
"python setup.py install"을 실행한 것처럼 Distutils가 설치됩니다. ("올
바른 위치"는 **bdist_dumb** 명령에 지정된 옵션에 따라 파일 시스템의 루
트나 파이썬의 "*prefix*" 디렉터리입니다; 기본값은 "*prefix*"에 상대적
으로 아둔한 배포판을 만드는 것입니다.)

분명히, 순수한 파이썬 배포판의 경우, 이것은 단지 "python setup.py
install"을 실행하는 것보다 간단하지는 않습니다---그러나 컴파일해야 할
확장을 포함하는 순수하지 않은 배포판의 경우, 누군가 여러분의 확장을 사
용할 수 있거나 그렇지 못한 차이를 줄 수 있습니다. 또한 배포판에 확장이
포함되어 있지 않더라도 RPM 패키지나 윈도우용 실행 가능한 설치 프로그램
과 같은 "똑똑한" 빌드된 배포판을 만드는 것은 사용자에게 훨씬 편리합니
다.

**bdist** 명령에는 **sdist** 명령과 유사한 "--formats" 옵션이 있습니다
. 이 옵션을 사용하여 생성할 빌드된 배포판의 유형을 선택할 수 있습니다:
예를 들어,

   python setup.py bdist --format=zip

은 유닉스 시스템에서 실행될 때, "Distutils-1.0.*plat*.zip"을 만듭니다
---역시, 이 아카이브는 루트 디렉터리에서 압축 해제되어 Distutils를 설
치합니다.

빌드된 배포에 사용 가능한 형식은 다음과 같습니다:

+---------------+--------------------------------+-----------+
| 형식          | 설명                           | 노트      |
|===============|================================|===========|
| "gztar"       | gzip 된 tar 파일 (".tar.gz")   | (1)       |
+---------------+--------------------------------+-----------+
| "bztar"       | bzip 된 tar 파일 (".tar.bz2")  |           |
+---------------+--------------------------------+-----------+
| "xztar"       | xzip 된 tar 파일 (".tar.xz")   |           |
+---------------+--------------------------------+-----------+
| "ztar"        | compress 된 tar 파일           | (3)       |
|               | (".tar.Z")                     |           |
+---------------+--------------------------------+-----------+
| "tar"         | tar 파일 (".tar")              |           |
+---------------+--------------------------------+-----------+
| "zip"         | zip 파일 (".zip")              | (2),(4)   |
+---------------+--------------------------------+-----------+
| "rpm"         | RPM                            | (5)       |
+---------------+--------------------------------+-----------+
| "pkgtool"     | 솔라리스 **pkgtool**           |           |
+---------------+--------------------------------+-----------+
| "sdux"        | HP-UX **swinstall**            |           |
+---------------+--------------------------------+-----------+
| "wininst"     | 윈도우 용 스스로 풀리는 ZIP 파 | (4)       |
|               | 일                             |           |
+---------------+--------------------------------+-----------+
| "msi"         | 마이크로소프트 설치 프로그램.  |           |
+---------------+--------------------------------+-----------+

버전 3.5에서 변경: "xztar" 형식에 대한 지원이 추가되었습니다.

노트:

1. 유닉스의 기본값

2. 윈도우의 기본값

3. 외부 **compress** 유틸리티가 필요합니다.

4. 외부 **zip** 유틸리티나 "zipfile" 모듈(파이썬 1.6 이후 표준 파이썬
   라이브러리의 일부입니다)이 필요합니다.

5. 외부 **rpm** 유틸리티 버전 3.0.4 이상이 필요합니다 (사용 중인 버전
   을 확인하려면 "rpm --version"을 사용하십시오)

**bdist** 명령을 "--formats" 옵션과 함께 사용할 필요는 없습니다; 원하
는 형식을 직접 구현하는 명령을 사용할 수도 있습니다. 이러한 **bdist**
"하위 명령" 중 일부는 실제로 여러 유사한 형식을 생성합니다; 예를 들어
**bdist_dumb** 명령은 모든 "아둔한(dumb)" 아카이브 형식("tar",
"gztar", "bztar", "xztar", "ztar" 및 "zip")을 생성하고, **bdist_rpm**
은 바이너리와 소스 RPM을 모두 생성합니다. **bdist** 하위 명령과 각각이
생성하는 형식은 다음과 같습니다:

+----------------------------+---------------------------------------+
| 명령                       | 형식                                  |
|============================|=======================================|
| **bdist_dumb**             | tar, gztar, bztar, xztar, ztar, zip   |
+----------------------------+---------------------------------------+
| **bdist_rpm**              | rpm, srpm                             |
+----------------------------+---------------------------------------+
| **bdist_wininst**          | wininst                               |
+----------------------------+---------------------------------------+
| **bdist_msi**              | msi                                   |
+----------------------------+---------------------------------------+

참고:

  bdist_wininst는 파이썬 3.8부터 폐지되었습니다.

다음 섹션에서는 개별 **bdist_*** 명령에 대해 자세히 설명합니다.


5.1. RPM 패키지 만들기
======================

RPM 형식은 Red Hat, SuSE 및 Mandrake를 비롯한 많은 인기 있는 리눅스 배
포판에서 사용됩니다. 이 중 하나(또는 다른 RPM 기반 리눅스 배포판)가 일
반적인 환경이라면, 같은 배포판의 다른 사용자를 위한 RPM 패키지를 만드
는 것은 간단합니다. 여러분의 모듈 배포판의 복잡성과 리눅스 배포판의 차
이점에 따라, 다른 RPM 기반 배포판에서 작동하는 RPM을 만들 수도 있습니
다.

모듈 배포판의 RPM을 만드는 일반적인 방법은 **bdist_rpm** 명령을 실행하
는 것입니다:

   python setup.py bdist_rpm

또는 "--format" 옵션이 있는 **bdist** 명령을 실행하는 것입니다:

   python setup.py bdist --formats=rpm

전자를 사용하면 RPM 특정 옵션을 지정할 수 있습니다; 후자는 한 번의 실
행으로 여러 형식을 쉽게 지정할 수 있습니다. 두 가지를 모두 수행해야 하
면, 여러 **bdist_*** 명령과 해당 옵션을 명시적으로 지정할 수 있습니다:

   python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" \
                   bdist_wininst --target-version="2.0"

Distutils 사용이 설정 스크립트에 의해 구동되는 것처럼, RPM 패키지를 만
드는 것은 ".spec" 파일에 의해 구동됩니다. 더욱더 쉽게 작업할 수 있도록
, **bdist_rpm** 명령은 일반적으로 설정 스크립트, 명령 줄 및 Distutils
구성 파일에 제공한 정보를 기반으로 ".spec" 파일을 만듭니다. ".spec" 파
일의 다양한 옵션과 섹션은 다음과 같이 설정 스크립트의 옵션에서 파생됩
니다:

+--------------------------------------------+------------------------------------------------+
| RPM ".spec" 파일 옵션이나 섹션             | Distutils 설정 스크립트 옵션                   |
|============================================|================================================|
| Name                                       | "name"                                         |
+--------------------------------------------+------------------------------------------------+
| Summary (프리앰블에 있는)                  | "description"                                  |
+--------------------------------------------+------------------------------------------------+
| Version                                    | "version"                                      |
+--------------------------------------------+------------------------------------------------+
| Vendor                                     | "author"와 "author_email", 또는 --- &          |
|                                            | "maintainer"와 "maintainer_email"              |
+--------------------------------------------+------------------------------------------------+
| Copyright                                  | "license"                                      |
+--------------------------------------------+------------------------------------------------+
| Url                                        | "url"                                          |
+--------------------------------------------+------------------------------------------------+
| %description (섹션)                        | "long_description"                             |
+--------------------------------------------+------------------------------------------------+

또한, ".spec" 파일에는 설정 스크립트에 해당 옵션이 없는 많은 옵션이 있
습니다. 이들 대부분은 다음과 같이 **bdist_rpm** 명령에 대한 옵션을 통
해 처리됩니다:

+---------------------------------+-------------------------------+---------------------------+
| RPM ".spec" 파일 옵션이나 섹션  | **bdist_rpm** 옵션            | 기본값                    |
|=================================|===============================|===========================|
| Release                         | "release"                     | "1"                       |
+---------------------------------+-------------------------------+---------------------------+
| Group                           | "group"                       | "Development/Libraries"   |
+---------------------------------+-------------------------------+---------------------------+
| Vendor                          | "vendor"                      | (위를 참조하십시오)       |
+---------------------------------+-------------------------------+---------------------------+
| Packager                        | "packager"                    | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Provides                        | "provides"                    | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Requires                        | "requires"                    | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Conflicts                       | "conflicts"                   | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Obsoletes                       | "obsoletes"                   | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Distribution                    | "distribution_name"           | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| BuildRequires                   | "build_requires"              | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+
| Icon                            | "icon"                        | (없음)                    |
+---------------------------------+-------------------------------+---------------------------+

분명히, 명령 줄에서 이러한 옵션 중 단지 몇 가지라도 제공하는 것은 번거
롭고 오류가 발생하기 쉬우므로, 일반적으로 설정 구성 파일 "setup.cfg"에
넣는 것이 가장 좋습니다---섹션 설치 구성 파일 작성하기를 참조하십시오.
많은 파이썬 모듈 배포판을 배포하거나 패키징한다면, 개인 Distutils 구성
파일 ("~/.pydistutils.cfg")에 모든 파이썬 모듈 배포에 적용되는 옵션을
넣을 수 있습니다. 이 파일을 일시적으로 비활성화하려면, "--no-user-cfg"
옵션을 "setup.py"로 전달하십시오.

바이너리 RPM 패키지를 빌드하는 데는 3가지 단계가 있으며, 이 단계는 모
두 Distutils에 의해 자동으로 처리됩니다:

1. 패키지를 설명하는 ".spec" 파일을 만듭니다 (Distutils 설정 스크립트
   에 해당합니다; 실제로, 설정 스크립트의 많은 정보가 ".spec" 파일에
   나타납니다)

2. 소스 RPM을 만듭니다

3. "바이너리" RPM을 만듭니다 (모듈 배포판에 파이썬 확장이 포함되어 있
   는지에 따라, 바이너리 코드를 포함하거나 포함하지 않을 수 있습니다)

일반적으로, RPM은 마지막 두 단계를 함께 묶습니다; Distutils를 사용할
때, 일반적으로 세 단계가 모두 함께 묶입니다.

원한다면, 이 세 단계를 분리 할 수 있습니다. "--spec-only" 옵션을 사용
하면 **bdist_rpm**이 단지 ".spec" 파일을 만든 후에 종료합니다; 이 경우
, ".spec" 파일은 "배포 디렉터리(distribution directory)"에 기록됩니다
---일반적으로 "dist/"이지만, "--dist-dir" 옵션으로 사용자 정의할 수 있
습니다. (보통은 ".spec" 파일은 **bdist_rpm**이 만든 임시 디렉터리의 "
빌드 트리"에 깊이 위치합니다.)


5.2. 윈도우 설치 프로그램 만들기
================================

경고:

  bdist_wininst는 파이썬 3.8부터 폐지되었습니다.

실행 가능한 설치 프로그램은 윈도우에서 바이너리 배포를 위한 자연스러운
형식입니다. 멋진 그래픽 사용자 인터페이스를 표시하고, 설정 스크립트의
메타 데이터에서 가져온 모듈 배포에 대한 일부 정보를 표시하며, 사용자가
몇 가지 옵션을 선택하고, 설치를 시작하거나 취소할 수 있도록 합니다.

메타 데이터는 설정 스크립트에서 가져오므로, 일반적으로 윈도우 설치 프
로그램을 만드는 것은 다음과 같이 쉽습니다:

   python setup.py bdist_wininst

또는 "--formats" 옵션이 있는 **bdist** 명령을 실행합니다:

   python setup.py bdist --formats=wininst

순수한 모듈 배포판(순수한 파이썬 모듈과 패키지만 포함하는)이면, 결과
설치 프로그램은 버전 독립적이며 "foo-1.0.win32.exe"와 같은 이름을 갖습
니다. "wininst" 바이너리 배포판을 만드는 것은 윈도우 시스템에서만 지원
됨에 유의하십시오.

순수하지 않은 배포판이면, 확장은 윈도우 플랫폼에서만 만들 수 있으며,
파이썬 버전에 종속됩니다. 설치 프로그램 파일 이름이 이를 반영하며 이제
"foo-1.0.win32-py2.0.exe" 형식입니다. 지원하려는 모든 파이썬 버전마다
별도의 설치 프로그램을 만들어야 합니다.

설치 프로그램은 설치 후에 대상 시스템에 일반과 최적화 모드로 순수 모듈
을 *바이트 코드*로 컴파일하려고 시도합니다. 어떤 이유로 이런 일이 발생
하지 않게 하려면, "--no-target-compile" 및/또는 "--no-target-optimize"
옵션을 사용하여 **bdist_wininst** 명령을 실행할 수 있습니다.

기본적으로 설치 프로그램은 실행될 때 멋진 "Python Powered" 로고를 표시
하지만, "--bitmap" 옵션으로 윈도우 ".bmp" 파일이어야 하는 여러분 자신
의 152x261 비트맵을 제공할 수도 있습니다.

설치 프로그램은 실행될 때 데스크톱 배경 창에 큰 제목을 표시하며, 배포
판 이름과 버전 번호로 구성됩니다. "--title" 옵션을 사용하여 다른 텍스
트로 변경할 수 있습니다.

설치 프로그램 파일은 "배포 디렉터리(distribution directory)" --- 일반
적으로 "dist/"에 기록되지만, "--dist-dir" 옵션으로 사용자 정의할 수 있
습니다.


5.3. 윈도우에서 크로스 컴파일하기
=================================

파이썬 2.6부터, distutils는 윈도우 플랫폼 간에 크로스 컴파일할 수 있습
니다. 실제로, 이는 올바른 도구가 설치된 경우, 32비트 버전의 윈도우를
사용하여 64비트 확장을 만들거나 그 반대로 할 수 있음을 의미합니다.

대체 플랫폼을 빌드하려면, build 명령에 "--plat-name" 옵션을 지정하십시
오. 유효한 값은 현재 'win32'와 'win-amd64'입니다. 예를 들어, 32비트 버
전의 윈도우에서, 다음을 실행해서:

   python setup.py build --plat-name=win-amd64

64비트 버전의 확장을 빌드할 수 있습니다. 윈도우 설치 프로그램도 이 옵
션도 지원하므로, 다음 명령은:

   python setup.py build --plat-name=win-amd64 bdist_wininst

32비트 버전의 윈도우에서 64비트 설치 실행 파일을 만듭니다.

크로스 컴파일하려면, 파이썬 소스 코드를 다운로드하고 대상 플랫폼에 맞
게 파이썬 자체를 크로스 컴파일해야 합니다 - (다른 플랫폼의 .lib 등의
파일이 포함되어 있지 않으므로) 바이너리 파이썬 설치로는 불가능합니다.
실제로, 이것은 확장을 크로스 컴파일하기 전에, 32비트 운영 체제 사용자
가 Visual Studio 2008을 사용하여 파이썬 소스 트리에서
"PCbuild/PCbuild.sln" 솔루션을 열고 'pythoncore' 프로젝트의 "x64" 구성
을 빌드해야 함을 의미합니다.

기본적으로 Visual Studio 2008은 64비트 컴파일러나 도구를 설치하지 않음
에 유의하십시오. Visual Studio 설치 프로세스를 다시 실행하고 이러한 도
구를 선택해야 할 수 있습니다 (Control Panel->[Add/Remove] Programs 사
용은 기존 설치를 확인하거나 수정하는 편리한 방법입니다.)


5.3.1. 설치 후 스크립트
-----------------------

파이썬 2.3부터, "--install-script" 옵션으로 설치 후 스크립트를 지정할
수 있습니다. 스크립트의 기본 이름(basename)을 지정하고, 스크립트 파일
명도 setups 함수의 scripts 인자에 나열해야 합니다.

이 스크립트는 설치 시에 모든 파일이 복사된 후 대상 시스템에서
"argv[1]"이 "-install"로 설정되어 실행되고, 다시 제거 시에 파일이 제거
되기 전에 "argv[1]"이 "-remove"로 설정되어 실행됩니다.

설치 스크립트는 윈도우 설치 프로그램에 내장되어 실행되며, 모든 출력
("sys.stdout", "sys.stderr")은 버퍼로 리디렉션되고 스크립트가 완료된
후 GUI에 표시됩니다.

이 문맥에서 특히 유용한 일부 함수는 설치 스크립트에서 추가 내장 함수로
사용 가능합니다.

directory_created(path)
file_created(path)

   설치 시 설치 후 스크립트가 디렉터리나 파일을 만들 때 이 함수를 호출
   해야 합니다. 설치 제거 프로그램에 *path*를 등록해서, 배포판이 설치
   제거될 때 제거됩니다. 안전을 위해, 디렉터리는 비어있을 때만 제거됩
   니다.

get_special_folder_path(csidl_string)

   이 함수는 윈도우에서 시작 메뉴나 데스크톱과 같은 특수 폴더 위치를
   검색하는 데 사용할 수 있습니다. 폴더의 전체 경로를 반환합니다.
   *csidl_string*은 다음 문자열 중 하나여야 합니다:

      "CSIDL_APPDATA"

      "CSIDL_COMMON_STARTMENU"
      "CSIDL_STARTMENU"

      "CSIDL_COMMON_DESKTOPDIRECTORY"
      "CSIDL_DESKTOPDIRECTORY"

      "CSIDL_COMMON_STARTUP"
      "CSIDL_STARTUP"

      "CSIDL_COMMON_PROGRAMS"
      "CSIDL_PROGRAMS"

      "CSIDL_FONTS"

   폴더를 검색할 수 없으면, "OSError"가 발생합니다.

   사용 가능한 폴더는 정확한 윈도우 버전과 아마도 구성에 따라 다릅니다
   . 자세한 내용은 마이크로소프트의 "SHGetSpecialFolderPath()" 함수 설
   명서를 참조하십시오.

create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])

   이 함수는 바로 가기를 만듭니다. *target*은 바로 가기로 시작될 프로
   그램의 경로입니다. *description*은 바로 가기에 대한 설명입니다.
   *filename*은 사용자에게 표시되는 바로 가기의 제목입니다.
   *arguments*는 명령 줄 인자를 지정합니다, 있다면. *workdir*은 프로그
   램의 작업 디렉터리입니다. *iconpath*는 바로 가기 아이콘이 들어 있는
   파일이고, *iconindex*는 파일 *iconpath*에서 아이콘의 인덱스입니다.
   역시, 자세한 내용은 "IShellLink" 인터페이스에 대한 마이크로소프트
   설명서를 참조하십시오.


5.4. Vista 사용자 액세스 제어 (UAC)
===================================

파이썬 2.6부터, bdist_wininst는 "--user-access-control" 옵션을 지원합
니다. 기본값은 'none'(UAC 처리가 없음을 의미합니다)이며, 다른 유효한
값은 'auto'(파이썬이 모든 사용자에게 설치된 경우 UAC 권한 상승을 프롬
프트 함을 의미합니다)와 'force'(항상 권한 상승을 프롬프트 함을 의미합
니다)입니다.

참고:

  bdist_wininst는 파이썬 3.8부터 폐지되었습니다.
