1. 程式人生 > >llvm 學習筆記 2 : 新增 Pass 與除錯

llvm 學習筆記 2 : 新增 Pass 與除錯

在BackendUtil.cpp 的 void EmitAssemblyHelper::EmitAssembly 函式中, if (PerFunctionPasses)  條件後 new 了自帶的 Hello pass. 重新 make 時發生以下錯誤

make[4]: Entering directory '/home/nightwish/code/GIT/llvm/release/tools/clang/tools/driver'
llvm[4]: Linking Release+Asserts executable clang (without symbols)
/home/nightwish/code/GIT/llvm/release/Release+Asserts/lib/libclangCodeGen.a(BackendUtil.o): In function `clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Module*, clang::BackendAction, llvm::raw_ostream*)':
BackendUtil.cpp:(.text+0x1318): undefined reference to `Hello::Hello()'
collect2: error: ld returned 1 exit status

請教高博之後學長告訴我這是linking時錯誤,編譯是通過了的.問題發生在靜態連結時沒有這個hello符號.動態連結會生成 .so , 而靜態連結生成的是 .a ( a 是什麼的縮寫?)

錯誤發生在

llvm/release/tools/clang/tools/driver
切換到 llvm/tools/clang/tools/driver, 檢視 Makefile, 發現有跟連結相關的這行
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
                   instrumentation ipo irreader linker selectiondag option

以 selectiondag  為線索, 在 llvm 根目錄下查詢 
grep "selectiondag" -RI .

發現一些結果,主要是在 LibraryDependencies.inc 中,如下:

./release/tools/llvm-config/LibraryDependencies.inc:  { "aarch64codegen", "libLLVMAArch64CodeGen.a", 1, { "aarch64asmprinter", "aarch64desc", "aarch64info", "asmprinter", "codegen", "core", "mc", "selectiondag", "support", "target" } },
所以檢視該檔案,發現是自動生成的檔案,有一個 AvailableComponents 的陣列, 描述的是 Makefile 中 components 和 生成的 .a 檔案的對應關係.

所以,做如下修改

LINK_COMPONENTS := $(TARGETS_TO_BUILD) hello asmparser bitreader bitwriter codegen \
                   instrumentation ipo irreader linker selectiondag option
同時在 AvailableComponents 中加入新的一項, 並修改陣列大小。在我後來又新增一個與Hello平行的目錄的Pass,發現這個陣列component的名稱,也就是'hello'這項,必須是全小寫,否則有誤。高博推測makefile會把所有名稱轉成小寫。
  { "gtest_main", "libgtest_main.a", 0, { "gtest" } },
  { "hello", "LLVMHello.a", 1, {}},                          //added
  { "hexagon", 0, 1, { "hexagoninfo", "hexagondesc", "hexagonasmprinter", "hexagoncodegen" } },

重新make則成功. 在  Release+Asserts/lib 目錄下生成了新的 LLVMHello.a , 同時防止 LibraryDependencies.inc 被重新生成抹去, 備份好.

體會:

高博講,做科研是要靠猜著學,比如發現連結錯誤,就去找與連結相關的makefile, 不斷的推理找到答案.程式碼就是最好的文件,看到link_...就自然明白這是連結相關的.學東西不要指望有個教程從頭到尾學,要猜中學.收益匪淺,感謝高博.