解讀帖子:結構化編譯器前端 Clang 介紹(VS2017編譯clang)

因爲需要提取出頭文件或源文件的函數名列表和相應的函數參數類型,我想從已有的編譯器中尋找函數調用,於是我找到了——結構化編譯器前端 Clang 介紹

這個貼子折騰了我很久(還有幾個開源項目我也沒有搞定)……人家寫的沒問題,但是對於我這個要環境沒linux(虛擬機太慢了)還一點都不懂(GCC?哈?我就大學操作系統課程用過一次。)的小白來說實在是太難了。。

經過將近一個月的折騰,終於有點經驗,放出來做個記錄也幫助有需要的人

一、折騰clang

1.介紹一下clang、llvm

當初那個帖子說要將clang、llvm的源碼都下載下來並編譯,我說clang爲啥還要下個llvm??後來才明白clang是前端,llvm是後端,中間用AST(抽象語法樹)連接到一起。

再說一下本文的源碼存放路徑(重要【clang源碼放在llvm的tools下面】)
在這裏插入圖片描述

2.MinGW編譯clang(本節失敗,可跳)

鏈接原文中,編譯,一個gcc的make命令就好了……我???

$cd ../../ ( 返回 llvm_source) 
$mkdir build ( 建立編譯的工作目錄 ) 
$cd build 
$../llvm/configure – prefix=$HOME/llvm ( 配置 LLVM,將目標安裝目錄設定爲 $HOME/llvm) 
$make ( 以 DEBUG 模式來編譯 LLVM 和 Clang)

後來誤打誤撞找到了cmake,說是能生成makefile,但是不太會用沒成功。
最後又回到了MinGW(Minimalist GNUfor Windows),就是windows上的GCC

2.1先安裝MinGW環境

win10 MinGW make、./configue等命令使用

2.2配置環境變量C:\MinGW\msys\1.0\bin以及C:\MinGW\bin

1)MinGW,是Minimalist GNUfor Windows的縮寫。它是一個可自由使用和自由發佈的Windows特定頭文件和使用GNU工具集導入庫的集合,允許你在GNU/Linux和Windows平臺生成本地的Windows程序而不需要第三方C運行時(C Runtime)庫。MinGW 是一組包含文件和端口庫。
2)MSYS,Minimal GNU(POSIX)system on Windows,是一個小型的GNU環境,包括基本的bash,make等等。是Windows下最優秀的GNU環境。
3)Cygwin,在windows平臺上運行的類UNIX模擬環境,是cygnus solutions公司開發的自由軟件。
三者的關係:
Cygwin和 MSYS的角色是有重疊的,可以在Cygwin提供的環境下用MinGW的compiler&library來編出可單獨執行的Windows 執行檔,在MinGW的FAQ,就是把PATH設定正確,在Cygwin下使用MinGW的compiler & library即可 。

2.3用sh執行configure文件

由configure生成makefile
configure.*和Makefile.*之間的關係

在MingW下編譯llvm/clang
命令是

轉到lvm源碼的目錄
sh
configure --prefix=【要安裝的目錄,路徑要“/”否則不認】

在這裏插入圖片描述
然後我就崩了
在這裏插入圖片描述
於是我開始學習makefile怎麼寫……
後來在我的linux虛擬機上make也有問題,於是先放棄了。
可參考資料:
在MingW下編譯llvm/clang
如何在Windows上編譯Clang?
(三)LLVM概述——第一個LLVM項目

3.vs2017編譯clang(本節成功)

多虧了官方文檔!
https://clang.llvm.org/get_started.html
其實就兩步
1)藉助cmake生成項目文件
2)編譯項目文件

使用Visual Studio
以下詳細信息說明了如何使用Visual Studio在Windows上設置和構建Clang:

獲取所需的工具:
Git的。源代碼控制程序。從以下 網址獲取:https://git-scm.com/download
CMake的。這用於生成Visual Studio解決方案和項目文件。從以下 網址獲取:https://cmake.org/download/
Visual Studio 2017或更高版本
Python。它用於運行clang測試套件。從以下 網址獲取:https: //www.python.org/download/
GnuWin32工具 Clang和LLVM測試套件使用各種GNU核心實用程序,例如 grep,sed和find。gnuwin32軟件包是獲得這些工具的最古老且經過最充分測試的方法。但是,已知git爲Windows提供的MSys實用程序可以工作。Cygwin過去曾工作過,但未經過良好測試。如果您還沒有其他來源的核心實用程序,請從 http://getgnuwin32.sourceforge.net/獲得gnuwin32 。
查看LLVM和Clang:
git clone https://github.com/llvm/llvm-project.git
注意:一些Clang測試對行尾敏感。確保檢出文件不會將LF行尾轉換爲CR + LF。如果您在Windows上使用git,請確保您的core.autocrlf設置爲false。

1)運行CMake生成Visual Studio解決方案和項目文件:
cd ..\..(回到開始的地方)
mkdir build (用於構建而不污染源目錄)
cd build
如果您使用的是Visual Studio 2017,則:  cmake -DLLVM_ENABLE_PROJECTS=clang -G "Visual Studio 15 2017" -A x64 -Thost=x64 ..\llvm
-Thost = x64是必需的,因爲32位鏈接器將耗盡內存。
要生成x86二進制文件而不是x64,請傳遞-A Win32。
有關CMake其他配置選項的更多信息,請參見LLVM CMake指南(https://www.llvm.org/docs/CMake.html)。
如果成功,以上內容將在構建目錄中創建一個LLVM.sln文件 。

2)構建(編譯) clang:
在Visual Studio中打開LLVM.sln。
僅爲編譯器驅動程序和前端構建“ clang”項目,或者爲所有內容(包括工具)構建“ ALL_BUILD”項目。

試試看(假設您已將llvm / debug / bin添加到路徑中)。(請參見上面的運行示例。)【就是你可以命令行clang了】
有關 在Windows上運行迴歸測試的信息,請參見在Clang上進行黑客攻擊-在Windows上使用Visual Studio進行測試。

我們在與llvm代碼目錄的平級目錄下新建build文件夾(也可以用CMake的GUI界面完成)
1)然後開啓cmd,並輸入

cmake -DLLVM_ENABLE_PROJECTS=clang -G "Visual Studio 15 2017" -A x64 -Thost=x64 ..\llvm

然後會輸出很多check……
2)編譯clang
等cmake完成後,在build文件夾應該有名爲llvm.sin的項目文件,然後用vs打開,編譯即可
等待很長時間……(我有一部分庫失敗、幾個跳過,不太清楚原因)
然後你可以在build目錄的bin下找到一些exe文件,lib目錄下的debug目錄下找到很多的lib文件(這個在二次開發裏用的到)

二、二次開發clang

1.把帖子上的源碼拷出來新建項目粘貼

#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include <cstdio> 
#include <iostream> 
using namespace clang; 
namespace { 
   class BoostConASTConsumer : public ASTConsumer, 
   public RecursiveASTVisitor<BoostConASTConsumer> 
   { 
       public: 
       /// HandleTranslationUnit - This method is called when the 
       /// ASTsfor entire translation unit have been parsed. 
       virtual void HandleTranslationUnit(ASTContext &Ctx); 
 
       bool VisitCXXRecordDecl(CXXRecordDecl *D) 
      { 
          std::cout << D->getNameAsString() << std::endl; 
          return true; 
      } 
   }; 
} 
 
ASTConsumer *BoostConAction::CreateASTConsumer //這句編譯器看不懂,我也沒看懂,求教!!
    (CompilerInstance &CI, llvm::StringRef InFile) 
{ 
   return new BoostConASTConsumer(); 
} 
 
void BoostConASTConsumer::HandleTranslationUnit(ASTContext &Ctx) 
{ 
   fprintf(stderr, "Welcome to BoostCon!\n"); 
   TraverseDecl(Ctx.getTranslationUnitDecl()); 
}

2.引用include目錄

2.1版本對應。

首先,clang版本後期出現了很大目錄結構的變化!原文說是3.0,我沒看到下了個9.0,結果連頭文件的名字都給你變嘍!找都沒地方找。

2.2引用。

VS是右鍵項目,屬性,VC++目錄,包含目錄。然後把llvm和clang的“include”文件夾的目錄放上去就好了。
Qtcreator就是在pro文件裏寫個“INCLUDEPATH+=”然後把目錄放上去(才發現qmake和cmake這麼相似)。

如果沒編譯clang源碼(就不會產出inc、lib等文件,加之無法引用)會出現如很多報錯:
在這裏插入圖片描述
後來看散落在各個文件夾的makefile中就是生成相應inc文件用的……【所以想要用源碼不得不編譯源碼】

.inc 文件顧名思義是include file的意思。 實際上,文件的後綴對於文件包含是無所謂 你可以包含一個asp文件,也可以包含txt文。 一般我們使用inc作爲後綴,是因爲這樣能體現該文件的作用。
.inc文件的作用有點類似於C/C++內的.H .HPP頭文件,使用inc文件可以使我們的程序,增加可讀性,更易於開發和維護。
——————C/C++項目中.h和.inc文件區別
C/C++的標準慣例是將class、function的聲明信息寫在.h文件中。.c文件寫class實現、function實現、變量定義等等。然而對於template來說,它既不是class也不是function,而是可以生成一組class或function的東西。編譯器(compiler)爲了給template生成代碼,他需要看到聲明(declaration )和定義(definition ),因此他們必須不被包含在.h裏面。
爲了使聲明、定義分隔開,定義瀉在自己文件內部,即.inc文件,然後在.h文件的末尾包含進來。當然除了.inc的形式,還可能有許多其他的寫法.inc, .imp, .impl, .tpp, etc.

2.3項目設置(重重險阻!)

引用clang、llvm的頭文件

右鍵項目,屬性,VC++目錄,包含目錄。然後把llvm和clang的“include”文件夾的目錄放上去就好了。

引用inc文件(以及一些.h文件)

右鍵項目,屬性,VC++目錄,包含目錄。然後把文件夾的目錄放上去就好了。
(目錄是生成的build\include

C4146錯誤 一元負運算符應用於無符號類型,結果仍爲無符號類型

error C4146: 一元負運算符應用於無符號類型,結果仍爲無符號類型
解決辦法——關閉SDL檢查
右鍵選中要配置的屬性的項目->配置屬性->C/C+±>SDL檢查,選擇否。

LNK2019錯誤

error LNK2019: 無法解析的外部符號
我們一是要把“解決方案平臺”上的x86或x64和我們編譯時選的位數匹配
二是要把編譯生成的一衆lib庫引用進來(在build\lib\Debug下)

C1010 在查找預編譯頭時遇到意外的文件結尾。是否忘記了向源中添加“#include “pch.h””?

http://tieba.baidu.com/p/5873241608
在這裏插入圖片描述

3.編譯二次開發代碼

引入llvm頭文件
然後用他們的類、函數來做你需要的東西吧。

項目已經配置好了,可以在GitHub上找幾個開源項目練練手
比如:https://github.com/stephenatwork/clang-extract

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章