解读帖子:结构化编译器前端 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

猜你喜欢

转载自blog.csdn.net/sinat_27382047/article/details/104879902