当前位置: 首页 > news >正文

当“Make”坏了,我们该如何“Make”

背景

你有没有遇到过这样一种尴尬的局面:你试图修理一把螺丝刀,结果唯一能用的工具,就是这把已经坏了的螺丝刀本身。最近,我在构建 Buildroot 时,就真切地体验了一把这种“自举”的窘境,而故事的主角,正是我们每天都会用到的、最基础的构建工具——make

这一切始于一个看似普通的构建错误。我的 Buildroot 构建过程卡壳了,经过一番排查,线索指向了 GNU Make 4.3 版本的一个已知 Bug。这好办,我心想,升级不就完了嘛!于是,我兴冲冲地换上了当时最新的 4.4.1 版本。

然而,事情并没有那么简单。新版本虽然解决了老问题,却带来了新的报错。作为一名“不信邪”的开发者,我决定深入虎穴,开始调试 make本身的源码。我东改改,西试试,试图找到问题的根源。可就在某个不经意的操作后,最戏剧性的一幕发生了:我的 make工具,它……​​坏了​​!

是的,你没听错。那个负责编译整个世界的工具,在我笨拙的调试下,彻底罢工了。任何尝试运行 make的命令都会以失败告终。更讽刺的是,我现在想要重新编译一个完好的 make,却发现这个编译过程本身,就需要一个能正常工作的 make来执行。

我仿佛陷入了一个死循环:要修好 make,需要先有 make。这感觉就像是被关在了一个没有钥匙的房间里,而制造钥匙的模具,还锁在房间的保险箱里。

​绝境逢生:官方文档里的“金钥匙”​

在经历了短暂的恐慌后,我冷静下来,决定不再瞎搞,而是去求助最权威的文档——GNU Make 源码目录下的 README和相关构建脚本。果然,智者从不打无准备之仗,官方早就预料到了这种“鸡生蛋,蛋生鸡”的极端情况。

解决方案优雅得令人拍案叫绝。在完全没有 make的环境下,我可以这样做:

  1. 运行配置脚本,但明确告诉它:​​“嘿,如果你需要调用 make,请去别处找一个叫 gmake的工具来用。”​​ (通常在一些系统上,GNU Make 被安装为 gmake以避免与系统自带的旧版 make冲突)。

    ./configure MAKE=gmake
  2. 然后,运行项目自带的一个 Shell 脚本 build.sh。这个脚本非常聪明,它内部包含了必要的构建逻辑,能够在不依赖 make的情况下,完成最初始的构建步骤,从而生成第一个可执行的 make二进制文件。./build.sh

./build.sh

就这样,靠着 gmake这个“外援”和 build.sh这个“预备方案”,一个新的、健康的 make终于被成功地“Make”了出来。那一刻,我感觉自己不是修复了一个软件,而是完成了一次计算机世界的“创世”仪式。

引申思考:世界上第一个 Make,是如何被“Make”出来的?​

问题解决了,但一个更有趣的哲学问题浮现在我的脑海里:我们今天用来编译一切的 make,最初到底是怎么被编译出来的?难道第一行 make代码是用另一把“螺丝刀”拧上去的吗?

答案是肯定的,而且这段历史非常有趣。

在 make诞生之前,它的创造者斯图尔特·费尔德曼(Stuart I. Feldman)博士在贝尔实验室工作。当时,编译一个大型项目需要输入一长串复杂的、容易出错的命令。费尔德曼受够了这种重复劳动,于是决定创造一个工具来自动化管理构建过程。

那么,最初的 make是用什么编译的呢?

​答案是用它更古老的“前辈”:手工编写的 Shell 脚本和 make的前身——一个名为 mk的、功能更简单的构建工具。​​ 或者,在某些情况下,开发者甚至可能直接使用了汇编器或更底层的编译命令。

根据费尔德曼本人在 1979 年发表的原始论文《Make — A Program for Maintaining Computer Programs》以及 GNU Make 官方文档中提及的历史,最早的 make其实是一个相对简单的程序。它的复杂性远低于今天的功能。因此,它的第一个版本很可能是通过​​直接调用系统编译器(如 cc)​​ 来手工构建的。

想象一下这个场景:费尔德曼博士小心翼翼地敲下命令:

cc -o make main.c ...

当屏幕上没有报错,并生成一个名为 make的可执行文件时,历史就此定格。从此,这个最初的 make就可以用来编译它自身后续更复杂的版本了——这就是著名的​​自举(Bootstrapping)​​。

这就好比,人类先粗糙地打磨出了一把石斧,然后用这把石斧去砍伐木材、打磨金属,最终制造出更精良的铁斧、钢斧,乃至现代化的机械。第一把石斧,或许只是用另一块更坚硬的石头砸出来的。

所以,下次当你轻松地键入 make命令时,不妨想想这个有趣的悖论和它背后蕴含的智慧:最强大的工具,往往始于一个最简单、甚至有些笨拙的起点。而这,或许就是编程最迷人的地方之一。

参考来源:​

  1. Feldman, S. I. (1979). Make — A Program for Maintaining Computer Programs. Bell Laboratories. 

  2. GNU Make 官方手册。

http://www.dtcms.com/a/523918.html

相关文章:

  • 【北京迅为】iTOP-4412精英版使用手册-第六十七章 USB鼠标驱动详解
  • 基于Three.js在Vue中实现3D模型交互与可视化
  • 网站功能分析门户网站建设招标公告
  • 【计算机网络】HTTP协议(二)——超文本传输协议
  • ip开源网站FPGA可以做点什么网站开发一般用哪个浏览器
  • Hive数据仓库:架构原理与实践指南
  • Azure OpenAI PTU 自动化运维完整指南
  • iOS 架构设计全解析 从MVC到MVVM与使用 开心上架 跨平台发布 免Mac
  • 深度学习-176-知识图谱技术之langchain与neo4j的嵌入向量Neo4jVector
  • Azure OpenAI PTU 容量自动调整方案:基于历史使用模式的智能伸缩
  • F033 vue+neo4j图书智能问答+知识图谱推荐系统 |知识图谱+neo4j+vue+flask+mysql实现代码
  • 深度学习-177-知识图谱技术之langchain与neo4j完整的RAG系统示例
  • seo网站平台wordpress自动生成网站地图
  • 《图解技术体系》Wonderful talk AI ~~人“涌现”
  • 浅谈ColchisFM地震正演分析在地震资料解释中的作用(六)
  • 动态规划or分治法——力扣53.最大子数组和
  • 【解决】蚁剑下载插件过慢、下载插件无法安装等问题
  • 在dify平台智能体工作流中迭代和循环如何选择?
  • UE5 蓝图-13:HUD蓝图的 beginPlay里创建了 mainUI 蓝图对象,蓝图函数库里的函数 getMainUI 以及 getPawn
  • 11.盛最多水的容器
  • 【C++】stack和queue:优先级队列的使用及底层原理
  • 兰州营销型网站建设优化游戏的软件
  • 廊坊做网站的公司专门做孕婴用品的网站
  • 3. char、字符串、字符串数组、二维字符数组、char[] 的区别与联系
  • 数据结构C语言
  • RTX5060Ti安装cuda加速的openCV
  • 金融网站建设重庆网站建设电脑版
  • 超越图像:机器学习之生成对抗网络(GAN)在时序数据增强与异常检测中的深度实践
  • C# 企业微信机器人消息推送
  • 原生日历表