热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

寻求一种能够处理文件丢失的Makefile依赖规则

我们正在使用GNUMake来构建我们的系统,在makefile文件的末尾,我们通过一个名为Makedepends的包含来生成一系列的.d文件。然而,当文件被删除或移动时,依赖关系会中断,我们需要寻找一种方法来优雅地处理这种情况。

在我们的系统构建过程中,我们采用了GNU Make工具。在每个makefile文件的结尾,我们通过一个名为Makedepends的指令来生成多个.d文件,这些文件是通过gcc的-MM选项生成的。接着,我们使用include $(CXXFILES:.cc=.d)语句为每个.cc文件包含相应的.d文件。然而,当文件被删除或移动时,依赖关系检查步骤会出现问题,导致我们需要手动删除.d文件,即便是执行make clean也无法解决,因为依赖项检查失败导致整个过程无法正常进行。


是否存在一种方法,可以在生成或包含这些依赖.d文件时,优雅地处理文件的删除或重定位?


例如:假设我有一个serial.cc文件,makefile会生成一个serial.d文件,该文件声明了一个对buffer.h的依赖。之后,我对代码进行了修改,不再需要buffer.h,并且删除了这个文件。下一次运行make时,由于serial.d文件中仍然存在对buffer.h的依赖,这将导致构建过程失败。


解决方案



#1




网站make.mad-scientist.net/papers/advanced-auto-dependency-generation详细描述了这个问题,并提供了一些解决方案。虽然其中的第一个建议有些误导,但高级方案基本上是正确的,能够有效解决问题。




#2




有两种可能的解决方案:


第一种,你可以在Makefile中添加一条规则来运行依赖关系生成步骤:


.SUFFIXES: .d

%.d::
makedepend_command_here

如果上述方法不可行,根据GNU Make的文档中的“最后手段”部分,可以尝试以下方法:



例如,在测试makefile时,你可能不关心源文件是否包含实际数据,只关心它们是否存在。这时可以这样做:


%::
touch $@

这样可以自动创建所有作为先决条件的源文件。



这种方法是否可以为你创建空的.d文件呢?




#3




如果你使用makepp工具,并启用--rm-stale选项,它可以识别出无法构建的文件并将其删除。如果这是一个常见的需求,你可以将此选项添加到构建树根目录下的.makepprc文件中,以便每次构建时都使用它。


此外,makepp能够自行处理所有的依赖关系检测,因此你无需在makefile中添加复杂的依赖关系管理。它甚至优于传统的gcc -MM方法,能够在编译器需要之前及时生成必要的头文件。


makepp的功能远不止于此。除了具备GNU make的所有功能外,还提供了许多其他有用的特性,甚至支持通过Perl编程来扩展makefile。



推荐阅读
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • C语言实现推箱子游戏的完整代码
    本文详细介绍了如何使用C语言在Linux环境下实现一个简单的推箱子游戏,包括游戏的基本规则、地图设计及代码实现。适合C语言初学者学习。 ... [详细]
  • 本文详细解析了muduo库中的Socket封装及字节序转换功能。主要涉及`Endian.h`和`SocketsOps.h`两个头文件,以及`Socket.h`和`InetAddress.h`类的实现。 ... [详细]
  • 本文详细介绍了如何通过修改Lua源码或使用动态链接库(DLL)的方式实现Lua与C++之间的高级交互,包括如何编译Lua源码、添加自定义API以及在C++中加载和调用Lua脚本。 ... [详细]
  • 本文深入探讨了在安装PostgreSQL数据库系统时,执行Configure、Make及Make Install命令的具体含义与作用。 ... [详细]
  • Pro*C访问Oracle数据库的例子test.pc$cattest.pc#includeEXECSQLINCLUDESQLCA;EXECSQLBEGINDECLARESECTIO ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • ###问题删除目录时遇到错误提示:rm:cannotremoveusrlocaltmp’:Directorynotempty即使用rm-rf,还是会出现 ... [详细]
  • 本文介绍如何在Ubuntu环境下为OpenWrt系统构建并安装首个'Hello World'应用程序的IPK包。文章不仅涵盖了基本的环境搭建,还详细说明了代码编写、Makefile配置及最终的IPK包生成与安装过程。 ... [详细]
  • 探讨在C语言编程中,当头文件中声明了一个const变量,但在实现文件中却将其定义为非const变量时,编译器如何处理这一冲突。 ... [详细]
  • 本文介绍如何利用C语言在Linux操作系统中实现递归创建多级目录的功能,包括必要的头文件引入和函数实现。 ... [详细]
author-avatar
覃维欢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有