建立 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.common
之後出現在 Makefile 中。
其他變數¶
CFLAGS
& CPPFLAGS
此變數可用於分別為 C 和 C++ 編譯器新增選項。它通常用於新增選項,告知編譯器要搜尋標頭檔的其他目錄位置。
強烈建議您附加到
CFLAGS
和CPPFLAGS
,而不是覆寫它們。LLVMMakefiles
可能已經包含您可能不想覆寫的有用選項。
物件程式碼的放置位置¶
建置的函式庫和可執行檔的最終位置將取決於您執行的是 Debug
、Release
或 Profile
建置。
函式庫
所有函式庫(靜態和動態)都將儲存在
PROJ_OBJ_ROOT/<type>/lib
中,其中 type 是Debug
、Release
或Profile
,分別用於偵錯、最佳化或分析建置。
可執行檔
所有可執行檔都將儲存在
PROJ_OBJ_ROOT/<type>/bin
中,其中 type 是Debug
、Release
或Profile
,分別用於偵錯、最佳化或分析建置。
進一步協助¶
如果您有任何問題或需要任何關於建立 LLVM 專案的協助,LLVM 團隊非常樂意提供協助。您可以隨時將您的問題發佈到 Discourse 論壇。