我想鐺編譯我C/C++
代碼LLVM
字節碼而不是二進制可執行文件。我怎樣才能做到這一點?如果我得到LLVM
字節碼,我該如何將它進一步編譯爲二進制可執行文件。如何使鐺編譯成LLVM IR
基本上我想編譯成二進制可執行文件之前添加一些我自己的代碼到LLVM
字節碼。
我想鐺編譯我C/C++
代碼LLVM
字節碼而不是二進制可執行文件。我怎樣才能做到這一點?如果我得到LLVM
字節碼,我該如何將它進一步編譯爲二進制可執行文件。如何使鐺編譯成LLVM IR
基本上我想編譯成二進制可執行文件之前添加一些我自己的代碼到LLVM
字節碼。
鑑於一些C/C++文件foo.c
:
> clang -S -emit-llvm foo.c
可生產foo.ll
其是LLVM IR文件。
-emit-llvm
該選項還可以通過手段被傳遞給編譯器前端直接的,也不驅動的-cc1
:
> clang -cc1 foo.c -emit-llvm
可生產foo.ll
與IR。 -cc1
增加了一些很酷的選項,如-ast-print
。查看-cc1 --help
瞭解更多詳情。
爲了進一步編譯LLVM IR組裝,使用llc
工具:
> llc foo.ll
主要生產foo.s
與組件(默認爲你運行它的計算機體系結構)。 llc
是LLVM工具之一 - here is its documentation。
你看過clang
documentation?您可能正在尋找-emit-llvm
。
使用
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
我建議保持擴展的含義不變。 IOW中,'.o'應該指向二進制目標文件,將'.s'指定爲彙編文件,以及其他指令(按照慣例'.ll')指向LLVM IR文件。否則很容易混淆。 Clang/LLVM現在沒有自己的二進制對象鏈接器(儘管其中一個正在工作中)。 LLVM鏈接器'llvm-ld'只是將幾個IR文件合併到一個文件夾中: – 2012-02-05 13:06:51
@EliBendersky:在涉及文件擴展名的地方你是正確的 - 如果使用'.bc',clang前端實際上做得正確;另外,請記住,'llvm-ld'可以作爲系統工具鏈的前端,也就是說,我以前使用'llvm-ld -native'的答案應該按預期工作.... – Christoph 2012-02-05 13:13:10
不起作用。 foo.bc是一個對象文件。 – rickfoosusa 2014-09-25 21:15:04
如果你有多個源文件,你可能真的想使用鏈接時優化輸出一個位碼文件的整個程序。給出的其他答案會導致您最終得到每個源文件的位碼文件。
相反,你想鏈接時優化
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
和最終鏈接步驟來編譯,添加參數輪候冊,-plugin-OPT =也-發出-LLVM
clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
這給你都已編譯的程序和與之對應(program.bc)的位碼。然後,您可以修改program.bc在任何你喜歡的方式,這樣做
clang program.bc -o program
在任何時候重新編譯修改的程序,雖然知道你需要包括任何必要的連接標誌(外部庫等)在這一步再次。
請注意,您需要使用金連接器這個工作。如果要強制鐺使用特定的連接,創建一個符號連接到連接在叫你的計算機上的「fakebin」的地方一個特殊的目錄名爲「LD」,並添加選項
-B/home/jeremy/fakebin
到任何連接步驟以上。
這非常有幫助,謝謝! – baibo 2015-01-29 23:18:08
如果你有多個文件,你不希望有鍵入每個文件,我建議你遵循這些簡單的步驟(我用clang-3.8
但你可以使用任何其他版本):
生成所有.ll
文件
clang-3.8 -S -emit-llvm *.c
它們鏈接到一個單一的一個
llvm-link-3.8 -S -v -o single.ll *.ll
(可選)優化你的代碼(也許有些別名分析)
opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
生成彙編(生成optimised.s
文件)
llc-3.8 optimised.ll
創建可執行文件(命名爲a.out
)
clang-3.8 optimised.s
您的解決方案非常獨特:您使用「-S」而不是將其作爲二進制輸出。有「-S」和沒有「-S」有沒有區別? – 2017-09-24 01:46:55
@PeterTeoh我使用'-S'選項(在步驟2中),我指定我想在LLVM IR中生成輸出。基本上,所有的* .ll文件放在一個單一的。我這樣做是爲了檢查優化是否真的改變了代碼,即'single.ll'和'optimised.ll'現在應該看起來不同(代碼方式),並且您還可以顯示報告以查看是否存在任何差異。 – 2017-10-16 07:39:16
什麼-S在這裏做? – meawoppl 2014-02-27 16:17:53
@meawoppl:-S像gcc中說的那樣發出文本彙編而不是彙編二進制 – 2014-02-28 16:53:26
Ahha。我很難在關於它的文檔中找到任何內容。可以肯定的是,鏗鏘聲中的許多標誌鏡像gcc標誌結構? – meawoppl 2014-02-28 17:35:25