3. 編寫設(shè)置腳本的配置文件?

備注

這篇文檔是歷史遺留文檔,在 https://setuptools.readthedocs.io/en/latest/setuptools.html 上的 setuptools 文檔獨(dú)立涵蓋此處包含的所有相關(guān)信息之后,將不再單獨(dú)作為正式文檔保留。

通常,在 事前 就寫出構(gòu)建發(fā)布包所需的一切是不可能的:你可能需要從用戶或者用戶的系統(tǒng)獲取一些信息,才能繼續(xù)下去。 只要這些信息相當(dāng)簡(jiǎn)單 —— 例如一個(gè)用于搜索 C 頭文件或庫(kù)的目錄列表 —— 那么提供配置文件 setup.cfg 供用戶配置就是一個(gè)低成本且方便的解決方式。 配置文件還允許你為任何命令選項(xiàng)提供默認(rèn)值,而安裝器可以通過(guò)命令行或編輯配置文件來(lái)覆蓋這些默認(rèn)值。

安裝配置文件是在安裝腳本和安裝腳本命令行之間一個(gè)適當(dāng)?shù)恼壑苑绞?--- 安裝腳本在理想情況下應(yīng)當(dāng)不受安裝者的控制 1 --- 而安裝腳本命令行則在你的控制范圍之外且完全取決于安裝者的選擇。 實(shí)際上,setup.cfg (以及目標(biāo)系統(tǒng)上的其他任何 Distutils 配置文件) 是在配置腳本之后、命令行之前被處理。 這導(dǎo)致了幾個(gè)有用的后果:

  • 安裝者可以通過(guò)編輯 setup.cfg 來(lái)覆蓋你放在 setup.py 中的配置

  • 你可以為無(wú)法在 setup.py 中方便設(shè)置的選項(xiàng)提供非標(biāo)準(zhǔn)的默認(rèn)值

  • 安裝者可以使用 setup.py 的命令行選項(xiàng)來(lái)覆蓋 setup.cfg 中的一切

配置文件的基本語(yǔ)法很簡(jiǎn)單:

[command]
option=value
...

其中 command 是一個(gè) Distutils 命令 (例如 build_py, install),而 option 是該命令所支持的某個(gè)選項(xiàng)。 可以為每個(gè)命令提供任意數(shù)量的選項(xiàng),并且可以在文件中包括任意數(shù)量的命令組。 空白行會(huì)被忽略,以一個(gè) '#' 開始的注釋行也是如此。 長(zhǎng)選項(xiàng)值可以簡(jiǎn)單地通過(guò)縮進(jìn)后續(xù)行的方式被拆分為多行。

你可以用通用的 --help 選項(xiàng)找出特定命令所支持的選項(xiàng)列表,例如

$ python setup.py --help build_ext
[...]
Options for 'build_ext' command:
  --build-lib (-b)     directory for compiled extension modules
  --build-temp (-t)    directory for temporary files (build by-products)
  --inplace (-i)       ignore build-lib and put compiled extensions into the
                       source directory alongside your pure Python modules
  --include-dirs (-I)  list of directories to search for header files
  --define (-D)        C preprocessor macros to define
  --undef (-U)         C preprocessor macros to undefine
  --swig-opts          list of SWIG command line options
[...]

請(qǐng)注意在命令行中拼寫為 --foo-bar 的選項(xiàng)在配置文件中會(huì)拼寫為 foo_bar。

例如,假設(shè)你希望你的擴(kuò)展在“原地”構(gòu)建 --- 就是說(shuō)你有一個(gè)擴(kuò)展 pkg.ext,你希望編譯出的擴(kuò)展文件 (例如在 Unix 上為 ext.so) 放在與你的純 Python 模塊 pkg.mod1pkg.mod2 相同的源目錄中。 你總是可以在命令行中使用 --inplace 選項(xiàng)來(lái)確保這一點(diǎn):

python setup.py build_ext --inplace

但是這要求你總是顯式地指定 build_ext 命令,并且記得提供 --inplace。 一個(gè)更容易的方式是通過(guò)將其編碼在此發(fā)布包的配置文件 setup.cfg 中,“設(shè)置并忘記”該選項(xiàng)。

[build_ext]
inplace=1

這將影響此模塊發(fā)布包的所有構(gòu)建,不論你是否顯式指定 build_ext。 如果你在你的源發(fā)布包中包括了 setup.cfg,它還將影響最終用戶的構(gòu)建 --- 對(duì)此選項(xiàng)來(lái)說(shuō)這可能不是個(gè)好主意,因?yàn)榭偸窃貥?gòu)建擴(kuò)展會(huì)破壞模塊發(fā)布包的安裝。 不過(guò)在某些特殊情況下,模塊是在其安裝目錄中被構(gòu)建的,因此這可能會(huì)是個(gè)有用的功能。 (但是,發(fā)布預(yù)期在其安裝目錄中被構(gòu)建的擴(kuò)展幾乎總是一個(gè)壞主意。)

另一個(gè)例子:特定的命令會(huì)接受許多在多次運(yùn)行中都不發(fā)生變化的選項(xiàng);例如,bdist_rpm 需要知道為創(chuàng)建 RPM 發(fā)布包生成 "spec" 文件所要求的所有信息。 這些信息有的來(lái)自安裝腳本,有的由 Distutils 自動(dòng)生成(例如已安裝文件列表)。 但有的則必須作為 bdist_rpm 的選項(xiàng)提供,每次運(yùn)行時(shí)都在命令行中完成將會(huì)非常繁瑣。 因此,這里提供 Distutils 本身的 setup.cfg 中的一段代碼:

[bdist_rpm]
release = 1
packager = Greg Ward <gward@python.net>
doc_files = CHANGES.txt
            README.txt
            USAGE.txt
            doc/
            examples/

請(qǐng)注意 doc_files 選項(xiàng)只是一個(gè)空格分隔以提高可讀性的多行字符串。

參見

"安裝 Python 模塊" 中的 Syntax of config files

有關(guān)配置文件的更多信息可在系統(tǒng)管理員手冊(cè)中查看。

備注

1

在 Distutils 完全支持自動(dòng)配置之前,這一理想可能是無(wú)法實(shí)現(xiàn)的。