CPython 專案簡介
這個章節會介紹 CPython 專案的結構,以及如譯編譯專案,我們會試著從原始碼來編譯出自己魔改過的 Python,來感受一下當 Python Core Dev 是什麼感覺(開玩笑的)!
專案結構
首先,要開始讀原始碼,得先把專案從 GitHub 上拉一份下來:
$ git clone [email protected]:python/cpython.git
在這個系列單元我所使用的版本是目前最新的 3.12.5
版本,所以如果版本不同,可能原始碼的內容會有些許不同。扣掉一些比較不重要的檔案,剛從 GitHub 拉下來的 CPython 專案的目錄大概是這樣:
CPython
├── Doc
├── Grammar
├── Include
├── Lib
├── Mac
├── Misc
├── Modules
├── Objects
├── PC
├── PCbuild
├── Parser
├── Programs
├── Python
└── Tools
先簡單介紹一下每個目錄裡放的檔案:
Doc
:這很好猜,就如同它的名字一樣,就是放文件的地方,是用 reStructuredText(.rst
) 格式編寫的,如果晚上睡不著可以拿出來啃,助眠效果滿點!Grammar
:定義 Python 語法規則解析用的文件。Include
:專案裡 C 語言用到的 Header 檔案,後續如果想要幫 CPython 寫 extension 的話,應該都會用到這裡的檔案。Lib
:標準函式庫,這目錄裡的東西是用 Python 寫的,如果略懂 Python 的話,這個目錄裡的東西應該讀起來會比較親切。Modules
:同Lib
目錄,不過這裡的內容是用 C 語言寫的。Mac
:這是給 Mac 作業系統用的東西。Misc
:雜七雜八的檔案,依我自己個人的習慣,我開這種目錄就是用來放那種不知道怎麼分類的東西。Objects
:所有 Python 內建物件的原始碼在這裡,例如str
或是list
都在這裡。PCbuild
:這是給 Windows 作業系統用的東西,特別是 Visual Studio,裡面有可以直接點兩下就能開啟的專案檔。PC
:同上,但是是給比較早期的 Windows 版本用的。大多數已經過時,但有些文件仍然是為了相容性而保留下來。Parser
:把.py
檔轉換成 Python 看的懂的 Token 的程式碼在這裡,難度有一點高。Programs
:存放與 CPython 執行檔相關的原始碼。Python
:CPython 直譯器(Interpreter)的原始碼在這裡,難度比較高,但對直譯器有興趣的可以看看。Tools
:一些開發和維護 Python 的輔助工具。
以這整個系列單元來說,比較常看到的應該是 Include
、Lib
、Modules
、Objects
和 Python
這幾個目錄,這些都是 CPython 直譯器的核心原始碼,如果想要了解 Python 的運作原理,可能就得多一些時間泡在這些目錄裡。
編譯專案
專案下載之後,先 cd
切換到目錄裡並執行 ./configure
指令:
$ ./configure
如果在 ./configure
後面加上 --prefix
參數,像這樣:
$ ./configure --prefix=/tmp/my-python
有特別加上 --prefix
的話,之後如果執行 make install
指令的時候,就會把 Python 以及相關的程式安裝到 /tmp/my-python
目錄裡。以目前來說我並沒打算執行 make install
進行安裝,所以可以先不加 --prefix
參數,等到後續有機會執行其它外部程式例如 pip
的時候再加即可。
剛才這個 ./configure
指令會在畫面上不斷的跳出一堆我看不懂的資訊,這是在檢查系統環境,看看有沒有缺什麼套件或函式庫,沒問題的話會產生一個 Makefile
檔案,這個檔案會告訴 make
指令待會應該要怎麼編譯整個專案。
接著執行 make
指令,這個指令會根據剛才產生的 Makefile
檔案來編譯整個專案:
$ make
這個過程可能會花一點點時間,如果整個編譯沒出錯的話,應該會 在根目錄有個 python.exe
執行檔,即使在 macOS 上也是叫這個名字。我知道在 macOS 看到 .exe
可能有點不太習慣,不過這是刻意的設計,原因是因為在 CPython 專案裡原本就有個 Python/
目錄,所以刻意選擇 python.exe
而不是 python
避免跟這個目錄發生衝突。
如果想要「安裝」剛才我們自己編譯出來的 Python 版本,可以執行:
$ make install
如果剛才在 ./configure
指令後面有加上 --prefix
參數,那這個指令會把 Python 安裝到指定的目錄裡。不過就算不安裝也沒關係,執行剛才編譯出來的 python.exe
也可以直接執行。接下來,執行剛才編譯出來的 python.exe
,就會看到我們熟悉的 REPL 環境了:
$ ./python.exe
Python 3.12.6+ (heads/3.12:b2a7d718e3b, Sep 15 2024, 23:31:57) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'3.12.6+ (heads/3.12:b2a7d718e3b, Sep 15 2024, 23:31:57) [Clang 15.0.0 (clang-1500.3.9.4)]'
在版號後面的 +
表示這個 Python 版本並不是一個正式發行的版本,可能是「開發版本」或我們自己拿原始碼來編譯的「自訂版本」。