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**            |           |
+---------------+--------------------------------+-----------+
| "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_msi**              | msi                                   |
+----------------------------+---------------------------------------+

참고:

  bdist_msi는 파이썬 3.9부터 폐지되었습니다.

다음 섹션에서는 개별 **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>"

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. 윈도우에서 크로스 컴파일하기
=================================

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

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

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

to build a 64bit version of your extension.

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

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

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


5.2.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" 인터페이스에 대한 마이크로소프트
   설명서를 참조하십시오.
