现在我们将创建一个程序,该程序能够读取次位码文件并打印其中定义的函数名称,以及它们的基本块数,从而显示LLVM库的易用性
链接LLVM库需要使用长命令行,如果没有构建系统的帮助,想写出这些命令行是不切实际的
注意:Makefile依赖于制表符来指定定义规则的命令
即应该手动插入制表符(下面有解释)
这个Makefile文件基于(DragonEgg中使用的代码)
解释一:
第一部分定义将用作编译器标志的第一个Makefile变量
第一个变量决定llvm-config程序的位置
llvm-config工具是一个LLVM程序
它可以构建需要与LLVM库连接的外部项目的各种有用信息
Ag:
定义在C++编辑器中使用的标志集时
我们将要求Make启动llvm-config --cxxflags
shell命令行,该命令行将打印用于编译LLVM项目的C++标志集
这样就使得项目源码的编译与LLVM源码兼容。
最后一个变量定义要传递给编译器预处理的标志集
解释二:
第二个片段
定义了Makefile的规则
第一个是默认的,用它构建hello-word可执行文件
第二个是通用规则,将所有c++文件编译生成目标文件
将预处理标志和C++编辑器标志传递给它
用$(QUIET)变量来省略屏幕上出现的完整命令
如果想要一个详细的构建日志,运行GUN Make 时定义VERBOSE
最后一个链接规则所有目标文件(在这里只有一个)来构建与LLVM库链接的项目可执行文件
这部分由链接器完成的,但是一些C++标志也可能会生效。
因此我们将C++和链接器标志都传递给命令行
用“command”的结构来完成此操作,它指示shell“command”的输出替换这部分内容
在Ag中命令是 llvm-config --libs bitreader core support
“–libs 标志向llvm-config请求提供链接到所有LLVM库中的链接器标志列表
请求libLLVMBItReader、libLLVMCore、libLLVMSupport
由llvm-config返回的标志列表是一系列-l链接器参数
Ag:-lLLVMCore-lLLVMSupport
注意
传递给链接器的参数顺序很重要,并且要求你依赖于其他库的参数放在前面
Ag:
由于libLLVMCore使用libLLVMSupport提供的通用功能,因此正确顺序是-lLLVMCore-lLLVMSupport
顺序很重要,因为一个库就是一个目标文件的集合,将在项目与库链接时
链接器只选择到目前为止目标文件来解析见到的未定义的符号
因此,如果它正在处理命令行参数的最后一个库,并且该库恰好使用已经处理的库中的符号
则大多数链接器(包括GUN id)将不会返回去包括有可能确实的目标文件,从而导致构建失败
如何避免这个问题?
强制链接器迭代访问每个库,直到所有必要的目标文件都被解析,则必须在库列表的开始和结束出使用–start–group和–end-group标志,但有可能会减慢速度
在构建完整的依赖关系图时,为了避免因为要弄清楚链接器参数的顺序而头疼
可以简单的使用llvm-config --libs 让它为你这些工作
解释三
Makefile文件的最后一部分定义了一条清理规则以删除编译器生成的所有文件
使我们从头开始从新启动构建
在计算机科学中,长命令行是指包含大量参数和选项的命令行。这些参数和选项用于控制命令的行为。
长命令行通常有以下特点:
长命令行的示例:
# 这是一个长命令行示例
gcc -o hello hello.c -Wall -Wextra -pedantic -std=c11 -g -O2
在这个示例中,gcc
是命令,-o
、-Wall
、-Wextra
、-pedantic
、-std=c11
、-g
和 -O2
是参数和选项。
长命令行有以下缺点:
为了解决这些问题,可以使用构建系统来帮助管理长命令行。构建系统可以自动生成命令行,并根据需要进行调整。
以下是一些常见的构建系统:
使用构建系统可以带来以下好处:
因此,如果需要使用长命令行,建议使用构建系统来帮助管理。
回到您最初的问题:“链接LLVM库需要使用长命令行,如果没有构建系统的帮助,想写出这些命令行是不切实际的。”
这句话的意思是,链接 LLVM 库通常需要使用大量的参数和选项。这些参数和选项用于指定要链接的库、编译器选项等信息。如果没有构建系统的帮助,手动编写这些命令行非常繁琐,而且容易出错。
使用构建系统可以自动生成链接 LLVM 库所需的命令行。这可以大大提高效率,并减少错误的可能性。
以下是一些使用构建系统链接 LLVM 库的示例:
cmake_minimum_required(VERSION 3.10)
project(Hello)
set(CMAKE_CXX_STANDARD 11)
add_executable(hello hello.c)
target_link_libraries(hello PRIVATE LLVM)
all:
gcc -o hello hello.c -lLLVM
clean:
rm -f hello
在这个示例中,-lLLVM
选项用于链接 LLVM 库。
在 Makefile 中,制表符(Tab)是一种特殊的缩进符,用于指定定义规则的命令。它与空格不同,不能被空格替换。
具体来说,制表符在 Makefile 中有以下作用:
以下是一个简单的 Makefile 示例:
all:
echo "Hello, world!"
clean:
rm -f hello.txt
在这个示例中,all
是目标,echo "Hello, world!"
是命令。命令以制表符开头,因此它将在 all
目标之后执行。
clean
是另一个目标,rm -f hello.txt
是命令。命令以制表符开头,因此它将在 clean
目标之后执行。
需要注意的是,Makefile 中的制表符和空格是严格区分的。如果使用空格代替制表符,则 Makefile 可能无法正确执行。
以下是一些使用制表符的注意事项: