建立 LLVM 專案¶
概觀¶
LLVM 建構系統旨在簡化使用 LLVM 標頭檔、函式庫和工具的第三方專案的建構過程。為了使用這些功能,專案中的 Makefile
必須執行以下操作:
設定
make
變數。Makefile
需要設定幾個變數才能使用 LLVM 建構系統:PROJECT_NAME
- 專案的名稱。LLVM_SRC_ROOT
- LLVM 原始碼樹狀結構的根目錄。LLVM_OBJ_ROOT
- LLVM 物件樹狀結構的根目錄。PROJ_SRC_ROOT
- 專案原始碼樹狀結構的根目錄。PROJ_OBJ_ROOT
- 專案物件樹狀結構的根目錄。PROJ_INSTALL_ROOT
- 根安裝目錄。LEVEL
- 從目前目錄到專案根目錄($PROJ_OBJ_ROOT)
的相對路徑。
從
$(LLVM_OBJ_ROOT)
包含Makefile.config
。從
$(LLVM_SRC_ROOT)
包含Makefile.rules
。
您可以透過兩種方式設定所有這些變數:
您可以編寫自己的
Makefiles
來硬編碼這些值。您可以使用預先建立的 LLVM 範例專案。此範例專案包含
Makefiles
、一個可用於設定 LLVM 位置的設定指令碼,以及從單一原始碼目錄支援多個物件目錄的功能。
如果您想設計自己的建構系統,研究其他專案和 LLVM 的 Makefiles
應該可以提供足夠的資訊,讓您了解如何編寫自己的 Makefiles
。
原始碼樹狀結構¶
為了使用 LLVM 建構系統,您需要組織您的原始碼,以便利用建構系統的功能。主要是,您希望您的原始碼樹狀結構與 LLVM 原始碼樹狀結構類似。
在頂層目錄下,您應該有以下目錄:
lib
這個子目錄應該包含所有程式庫的原始碼。您建立的每個程式庫,都會在 lib 中有一個目錄,其中包含該程式庫的原始碼。
程式庫可以是目標文件、封裝檔或動態程式庫。lib 目錄只是一個放置程式庫的方便位置,因為它將它們全部放在一個目錄中,以便稍後可以從中連結它們。
include
這個子目錄應該包含專案中所有通用的標頭檔。所謂通用,我們指的是它們被專案中多個程式庫或可執行檔使用。
將標頭檔放在 include 中,LLVM 建置系統就會自動找到它們。例如,如果您有一個檔案 include/jazz/note.h,那麼您的原始碼檔案就可以簡單地使用 #include “jazz/note.h” 來包含它。
tools
這個子目錄應該包含所有可執行檔的原始碼。您建立的每個程式,都會在 tools 中有一個目錄,其中包含該程式的原始碼。
test
這個子目錄應該包含用於驗證程式碼是否正常運作的測試。自動化測試特別有用。
目前,LLVM 建置系統為測試提供基本支援。LLVM 系統提供以下功能
LLVM 在
llvm/test
中包含回歸測試。這些測試由 Lit 測試工具執行。這個測試程序使用實際測試案例中的RUN
行來決定如何執行測試。如需更多詳細資訊,請參閱 LLVM 測試基礎架構指南。LLVM 包含一個名為
llvm-test
的可選套件,它提供已知可使用 Clang 前端編譯的基準測試和程式。您可以使用這些程式來測試程式碼、收集統計資訊,並將其與目前的 LLVM 效能統計資訊進行比較。目前,無法將測試直接掛鉤到
llvm/test
測試工具中。您只需要找到一種方法,自行使用該目錄中提供的原始碼即可。
通常,您會希望先建立 lib 目錄,然後再建立 tools 目錄。
編寫 LLVM 風格的 Makefile¶
LLVM 建置系統提供了一種方便的方法來建立程式庫和可執行檔。大多數專案的 Makefile 只需要定義幾個變數。以下是可以設定的變數列表,以及它們的功能
必要變數¶
LEVEL
此變數是從這個
Makefile
到專案原始碼頂層目錄的相對路徑。例如,如果您的原始碼位於/tmp/src
中,那麼/tmp/src/jump/high
中的Makefile
會將LEVEL
設定為"../.."
。
用於建置子目錄的變數¶
DIRS
這是一個以空格分隔的子目錄列表,應該依序建置這些子目錄。
PARALLEL_DIRS
這是一個可以平行建置的目錄列表。這些目錄將在 DIRS 中的目錄建置完成後建置。
OPTIONAL_DIRS
這是一個目錄清單,如果它們存在,就可以被建置,但如果它們不存在,也不會造成錯誤。它們會按照列出的順序依序建置。
用於建置程式庫的變數¶
LIBRARYNAME
這個變數包含將被建置的程式庫的基本名稱。例如,要建置一個名為
libsample.a
的程式庫,LIBRARYNAME
應該設定為sample
。
BUILD_ARCHIVE
預設情況下,程式庫是一個直接連結到程式中的
.o
檔案。要建置一個封存檔(也稱為靜態程式庫),請設定BUILD_ARCHIVE
變數。
SHARED_LIBRARY
如果在您的 Makefile 中定義了
SHARED_LIBRARY
,則會建置一個共用(或動態)程式庫。
用於建置程式的變數¶
TOOLNAME
這個變數包含將被建置的程式名稱。例如,要建置一個名為
sample
的可執行檔,TOOLNAME
應該設定為sample
。
USEDLIBS
這個變數包含一個以空格分隔的程式庫清單,這些程式庫應該被連結到程式中。這些程式庫必須是來自您的 lib 目錄的程式庫。指定程式庫時,不應包含其
lib
前綴。例如,要連結libsample.a
,您應該將USEDLIBS
設定為sample.a
。請注意,這僅適用於靜態連結的程式庫。
LLVMLIBS
這個變數包含一個以空格分隔的程式庫清單,這些程式庫應該被連結到程式中。這些程式庫必須是 LLVM 程式庫。指定程式庫時,不應包含其
lib
前綴。例如,要與執行 IR 轉換的驅動程式連結,您可以將LLVMLIBS
設定為這個最小的程式庫集LLVMSupport.a LLVMCore.a LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a LLVMScalarOpts.a LLVMTarget.a
。請注意,這僅適用於靜態連結的程式庫。LLVM 被拆分為大量的靜態程式庫,您需要的程式庫清單可能比上面的清單長得多。要查看完整的程式庫清單,請使用:
llvm-config --libs all
。使用如下所述的LINK_COMPONENTS
,可以避免設定LLVMLIBS
。
LINK_COMPONENTS
這個變數包含一個以空格分隔的組件清單,LLVM
Makefiles
會將這些組件傳遞給llvm-config
工具,以便為程式產生連結行。例如,要與所有 LLVM 程式庫連結,請使用LINK_COMPONENTS = all
。
LIBS
要鏈接動態函式庫,請將
-l<函式庫 基本 名稱>
加入LIBS
變數中。LLVM 建置系統會在與靜態函式庫相同的位置尋找動態函式庫。例如,要鏈接
libsample.so
,您可以在Makefile
中加入以下行:LIBS += -lsample
請注意,LIBS
必須在 Makefile 中包含 Makefile.common
之後出現。
其他變數¶
CFLAGS
和 CPPFLAGS
這些變數可用於分別為 C 和 C++ 編譯器新增選項。它們通常用於新增選項,告訴編譯器搜尋標頭檔的其他目錄位置。
強烈建議您將選項附加到
CFLAGS
和CPPFLAGS
中,而不是覆蓋它們。LLVMMakefile
中可能已經有一些您不想覆蓋的有用選項。
物件碼放置位置¶
已建置函式庫和可執行檔的最終位置取決於您是進行 除錯
、發佈
還是 效能分析
建置。
函式庫
所有函式庫(靜態和動態)都將儲存在
PROJ_OBJ_ROOT/<類型>/lib
中,其中 *類型* 分別是除錯
、發佈
或效能分析
,分別表示除錯、優化或效能分析建置。
可執行檔
所有可執行檔都將儲存在
PROJ_OBJ_ROOT/<類型>/bin
中,其中 *類型* 分別是除錯
、發佈
或效能分析
,分別表示除錯、優化或效能分析建置。
進一步協助¶
如果您有任何問題或需要任何關於建立 LLVM 專案的幫助,LLVM 團隊非常樂意為您服務。您隨時可以在 Discourse 論壇 上發布您的問題。