编写Makefile

现在我们将创建一个程序,该程序能够读取次位码文件并打印其中定义的函数名称,以及它们的基本块数,从而显示LLVM库的易用性

什么是Makefile?

  • C语言中,我们使用visual studio开发软件时候,写程序开始时候都会创建一个project项目文件,然后在文件里面编译 .h 和.c 的文件。
  • 在Linux中,有一个叫make的东西,就相当于C语言的集成开发环境,我们只需要在make里面创建文件,写代码,make会帮我们管理这些文件。
  • 不过我们创建的项目不叫project,而是称为Makefile,打开一个make源程序包,发现很多Makefile的文件,说明里面有很多的项目。
  • 在源程序包里面,也有名为makefile的文件(m是小写),两个命名同时存在,这是合理的,在开发一个项目的时候,工程师一般都会命名为Makefile然后打包交给用户,用户觉得某个Makefile需要改动,用户改动后或者新建后的项目定义为makefile,并且在运行时候,先执行makefile,再执行Makefile文件。

Makefile文件

链接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 是参数和选项。

长命令行有以下缺点:

  • 难以阅读和理解
  • 容易出错
  • 不易于维护

为了解决这些问题,可以使用构建系统来帮助管理长命令行。构建系统可以自动生成命令行,并根据需要进行调整。

以下是一些常见的构建系统:

  • CMake
  • Makefile
  • Autotools
  • Bazel

使用构建系统可以带来以下好处:

  • 提高命令行的可读性和可理解性
  • 减少错误的可能性
  • 提高代码的可维护性

因此,如果需要使用长命令行,建议使用构建系统来帮助管理。

回到您最初的问题:“链接LLVM库需要使用长命令行,如果没有构建系统的帮助,想写出这些命令行是不切实际的。”

这句话的意思是,链接 LLVM 库通常需要使用大量的参数和选项。这些参数和选项用于指定要链接的库、编译器选项等信息。如果没有构建系统的帮助,手动编写这些命令行非常繁琐,而且容易出错。

使用构建系统可以自动生成链接 LLVM 库所需的命令行。这可以大大提高效率,并减少错误的可能性。

以下是一些使用构建系统链接 LLVM 库的示例:

  • CMake
cmake_minimum_required(VERSION 3.10)

project(Hello)

set(CMAKE_CXX_STANDARD 11)

add_executable(hello hello.c)

target_link_libraries(hello PRIVATE LLVM)
  • Makefile
all:
    gcc -o hello hello.c -lLLVM

clean:
    rm -f hello

在这个示例中,-lLLVM 选项用于链接 LLVM 库。

制表符

在 Makefile 中,制表符(Tab)是一种特殊的缩进符,用于指定定义规则的命令。它与空格不同,不能被空格替换。

具体来说,制表符在 Makefile 中有以下作用:

  • 区分命令和目标:Makefile 中的每一行都由目标和命令组成。目标是 Makefile 要生成的文件或要执行的命令,而命令是用于生成目标的具体操作。制表符用于将目标和命令区分开来。目标的后面必须跟一个冒号(:),然后是命令。命令必须以制表符开头。
  • 指定命令的缩进:Makefile 中的命令可以有多行,但只有第一行需要以制表符开头。后续行的缩进可以是制表符或空格,但必须一致。
  • 控制命令的执行顺序:Makefile 中的命令是按照顺序执行的。如果命令有多行,则第一行的制表符决定了该命令的执行顺序。制表符的数量越多,命令的执行顺序越靠后。

以下是一个简单的 Makefile 示例:

all:
    echo "Hello, world!"

clean:
    rm -f hello.txt

在这个示例中,all 是目标,echo "Hello, world!" 是命令。命令以制表符开头,因此它将在 all 目标之后执行。

clean 是另一个目标,rm -f hello.txt 是命令。命令以制表符开头,因此它将在 clean 目标之后执行。

需要注意的是,Makefile 中的制表符和空格是严格区分的。如果使用空格代替制表符,则 Makefile 可能无法正确执行。

以下是一些使用制表符的注意事项:

  • 制表符的宽度:不同的编辑器可能会对制表符的宽度进行不同的设置。为了确保 Makefile 在不同的编辑器中都能正确执行,建议将制表符的宽度设置为 8 个空格。
  • 混合使用制表符和空格:在 Makefile 中,最好不要混合使用制表符和空格。如果需要使用空格进行缩进,则建议在所有行都使用空格,而不是只在某些行使用空格。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/385982.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

专业140+总分420+浙江大学842信号系统与数字电路考研经验电子信息与通信,真题,大纲,参考书。

今年考研已经结束,初试专业课842信号系统与数字电路140,总分420,很幸运实现了自己的目标,被浙大录取,这在高考是想都不敢想的学校,在考研时实现了,所以大家也要有信心,通过自己努力实…

Kubernetes(K8S)集群部署实战

目录 一、准备工作1.1、创建3台虚拟机1.1.1、下载虚拟机管理工具1.1.2、安装虚拟机管理工具1.1.3、下载虚Centos镜像1.1.4、创建台个虚拟机1.1.5、设置虚拟机网络环境 1.2、虚拟机基础配置(3台虚拟机进行相同处理)1.2.1、配置host1.2.2、关闭防火墙1.2.3…

【北邮鲁鹏老师计算机视觉课程笔记】08 texture 纹理表示

【北邮鲁鹏老师计算机视觉课程笔记】08 texture 纹理表示 1 纹理 规则和不规则的 2 纹理的用处 从纹理中恢复形状 3 分割与合成 4 分析纹理进行分类 通过识别纹理分析物理性质 如何区分纹理 5 寻找有效的纹理分类方法 发现模式、描述区域内模式 A对应图2 B对应图…

LeetCode、136. 只出现一次的数字【简单,位运算】

文章目录 前言LeetCode、136. 只出现一次的数字【简单,位运算】题目链接与分类思路异或一遍运算 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术…

Python实现EMV指标计算:股票技术分析的利器系列(2)

Python实现EMV指标计算:股票技术分析的利器系列(2) 介绍算法解释: 核心代码:rolling函数介绍 完整代码:一定要看 介绍 先看看官方介绍: EMV(简易波动指标) 用法 1.EMV 由下往上穿越…

【MySQL】:分组查询、排序查询、分页查询、以及执行顺序

🎥 屿小夏 : 个人主页 🔥个人专栏 : MySQL从入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. 分组查询1.1 语法1.2 where与having区别1.3 注意事项:1.4 案例: 二. 排序查询…

C# CAD2016 判断多边形的方向正时针或逆时针旋转

方法一&#xff1a;基于相邻顶点相对位置判断顺时针排列 // 计算当前子序列是否为顺时针排列 for (int i 1; i < outerPoints.Count; i) {int index (startVertexIndex i) % outerPoints.Count;int prevIndex (startVertexIndex i - 1) % outerPoints.Count;Point2d c…

day39 Bootstrap——容器简括

前言 前言Bootstrap5 容器容器内边距容器的边框和颜色响应式容器 前言 Bootstrap&#xff0c;来自 Twitter&#xff0c;是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的&#xff0c;它简洁灵活&#xff0c;使得 Web 开发更加快捷。 Bootstrap5 容器 B…

SPP改进(多窗口池化)

论文创新点汇总&#xff1a;人工智能论文通用创新点(持续更新中...)-CSDN博客 原来的模型 15年提出 本质&#xff1a; 多个不同大小的池化窗口进行池化 池化窗口越大得到的特征越少 之后再将不同池化窗口得到的特征拼接起来 现在的改进 实现代码 class SPPCSPC(nn.Modul…

Oracle数据库自动维护任务(Automated Maintenance Tasks)

Oracle数据库自动维护任务(Automated Maintenance Tasks) Oracle数据库有以下预定义的自动维护任务: Automatic Optimizer Statistics Collection - 收集数据库中没有统计信息或只有过时统计信息的所有模式对象的优化器统计信息。SQL查询优化器使用该任务收集的统计信息来提高…

SpringCloud-Feign:负载均衡(基于服务端)

7.Feign&#xff1a;负载均衡(基于服务端) 7.1 Feign简介 Feign是一个开源的声明式HTTP客户端&#xff0c;它可以简化HTTP API的调用过程。Feign的设计目标是使得使用者可以像调用本地方法一样调用远程服务&#xff0c;使得编写和维护HTTP客户端变得更加简单。类似controller…

小游戏和GUI编程(7) | SimpleNN 界面源码解析

小游戏和GUI编程(7) | SimpleNN 界面源码解析 0. 简介 SimpleNN 是 AdamYuan 在高中一年级时用 1 天时间写出来的简易 CNN, 使用 SFML 做 UI, 用于交互式输入手写数字&#xff0c;这个数字被训练好的 CNN 网络执行推理得到识别结果, 它的运行效果如下&#xff1a; 这一篇我们…

每日一题(最大连续1的个数,完全数计算)

485. 最大连续 1 的个数 - 力扣&#xff08;LeetCode&#xff09; #include <stdio.h> int findMaxConsecutiveOnes(int* nums, int numsSize) { if (numsSize 0) return 0; // 如果数组为空&#xff0c;返回0 int maxCount 0; // 最大连续1的个数 int currentCo…

状态监测防火墙详细工作流程

状态监测防火墙是一种用于监测和分析网络通信状态的安全设备。其工作流程通常包括以下几个步骤&#xff1a; 1. 采集数据&#xff1a;防火墙会采集来自网络流量的数据&#xff0c;包括 IP 地址、端口号、协议类型等信息&#xff0c;并将其存储在数据库中。 2. 分析数据&#xf…

vue前端系统启动报错Module not found: Error: Can‘t resolve ‘sass-loader‘

1、确认项目中是否已安装 node-sass 包。sass-loader 是依赖于 node-sass 包的&#xff0c;如果没有安装 node-sass 包&#xff0c;也会导致无法找到 sass-loader 包。 npm ls node-sass安装 node-sass 包&#xff1a; npm install --save-dev node-sass2、确认项目中是否已安…

【每日一题】牛客网——链表的回文结构

✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&#xff0c;相互学习…

mysql表设计

表设计流程&#xff1a; &#xff08;1&#xff09;分库&#xff1a;根据模块分 &#xff08;2&#xff09;分表&#xff1a;根据流程分表 &#xff08;3&#xff09;冗余字段和视图设计 21个表设计准则 &#xff08;1&#xff09;命名规范 account_no,account_number 表名用t…

ChatGPT高效提问—prompt实践

ChatGPT高效提问—prompt实践 ​ 探索prompt在实际生活中的各种应用&#xff0c;旨在帮助理解和掌握如何将之前学到的prompt基础和技巧应用到具体实践中&#xff0c;从而在各个领域实现人工智能的价值。 ​ 通过生动的案例&#xff0c;发现并挖掘ChatGPT和prompt的无穷潜力。…

华为机考入门python3--(12)牛客12-字符串反转

分类&#xff1a;字符串 知识点&#xff1a; 字符串是否为空 if not my_str 字符串逆序 my_str[::-1] 题目来自【牛客】 def reverse_string(s): # 判断字符串是否为空或只包含空格 if not s.strip(): return "" # 使用Python的切片语法反转字符串 re…

(AtCoder Beginner Contest 334) --- F - Christmas Present 2 -- 题解

F - Christmas Present 2 F - Christmas Present 2 题目大意&#xff1a; 思路解析&#xff1a; 因为他是顺序前往每个孩子的家&#xff0c;前往时必须要带一个礼物&#xff0c;并且最多只能带k个礼物&#xff0c;所以它每次前往最多k个孩子之后就要回到初始点重新出发。…
最新文章