在某些时候,我和一位同事从网上抓起了一个“示例”makefile,用于构建xmega芯片的嵌入式代码。我们发现这种体验非常令人沮丧。我们俩都不是专家,也不是新手。我们偶尔进行调整/调整。我们花了几个小时阅读制作手册和投掷飞镖试图做更严重的改变。
通常在我们建造的时候,我们总是从干净的一切开始。因为自动依赖生成似乎不能可靠地工作,我们刚刚了解到它更安全。由于它是一个嵌入式项目,在小型处理器上,编译实际上很快。这是在眨眼间完成的,这引出了我真正的问题:
如果我没有使用make进行任何类型的依赖关系管理并利用增量构建,那么使用它而不是简单的shell脚本是否真的有意义?
我更自信地编写C代码,python和好的'bash脚本'。今天最近的挫败感,是试图将一些与FreeRTOS相关的源文件移到子目录中。 make对我们来说唯一真正的好处是,它是在OSX上安装的库存,而vi和QtCreator和XCode有一些能力与我们的makefile集成(但我可以创建一个非常小的makefile,在这里桥接)。
答案 0 :(得分:17)
Make是一个用于构建软件的古老专家系统。它仍然被广泛使用,所以是值得学习的。你可能很幸运能够在瞬间建立一个项目,但是,根据我的经验,这是例外而不是规则。
鉴于依赖关系跟踪和动作推理是Make的目的,将其用作批处理系统是零增益,并且它还会干扰您学习如何使用该工具(Make)。
从您的帖子中发现,您发现与使用Make with子目录有冲突。虽然它可能无法解决您的直接问题,但本文:Recursive Make Considered Harmful可能有助于解释情况,并让您深入了解Make本身的操作。
Make不会自动生成依赖项。您将在网上找到许多有关如何自动生成GNU Make依赖项的资源。我不确定OSX是否使用GNU Make或BSD Make(或者即使BSD变体仍然存在)。如果是后者(BSD),我相信你可以找到如何自动生成BSD变体的依赖关系的方法。
我在这篇文章中推断的更为存在的问题是:当它不能为我的项目提供直接的好处时,学习这个旧工具是否有价值?
我会回答:你的小项目是学习这个工具的绝佳机会。如果你面临一个增量编译真正节省时间的项目,痛苦阈值肯定会高得多。
还有许多其他构建系统要么替换Make,例如:Jam,SCons,Rake,要么充当元制作文件生成器:CMake,有些集成开发环境。绝大多数的替换表明很多人认为Make不合适(或者在某些情况下可能只是令人不愉快)。
然而,在可预见的未来,对Make的一点了解可能会让你处于有利地位。它也可能是理解构建系统如何工作的第一步(或最明显的步骤),以及与规则生成和依赖关系跟踪相关的问题。
祝你好运。
答案 1 :(得分:2)
几乎所有不是单个编译单元的非平凡C程序都会在其自身内部具有依赖关系,并且几乎所有程序都依赖于系统库。
除非您打算每次都编写一个执行干净构建的脚本,否则需要使用某种依赖关系管理工具来保持工作流程的正常运行。
make
是规范的选择,并且非常适合工作,只要您找到一种自动生成依赖关系规则的方法。
QT构建系统不与Makefile集成,它从更高级别的项目描述创建它们。 QTCreator
是围绕此过程提供GUI的众多工具之一。当您从QTCreator
内进行编译时,它实际上是调用的结果Makefile
。您还可以使用qmake
生成XCode和Visual Studio工作区文件。
QT构建系统实际上是嵌入式项目的一个相当不错的选择,即使不使用QT也是如此,因为设置它来处理交叉编译相对容易。
答案 2 :(得分:2)
这是我刚才提出的一个问题。我个人使用python脚本编译我的AVR代码(link)。我不是制作专家,但我确实有一些经验。我仍然感到沮丧,因为uC需要毫无价值,除非你无论如何已经是专家。
并不是说我会鼓励任何人这样做,但没有什么可以阻止你在Python中实现相同的依赖性检查(Perl,Ruby,Bash ......),甚至可能更强大。我相信这只是一个语言选择问题或者你觉得舒服的问题。 make只是一种编程语言,初学者可能看起来很模糊。
答案 3 :(得分:2)
我个人不会直接使用make,几乎与系统的大小无关(意味着我可以在极少数情况下在非常小的系统上使用它)。我会使用一个为你生成makefile的工具。当然,你会松开现有操作系统部分的安装,但会摆脱很多麻烦。
我个人建议你看看cmake和autotools。我个人更喜欢cmake,并发现它很棒,而autotools消除了一些头痛,但增加了一些新的。我发现其中任何一个都比makefile更好。
Cmake还有一个优势,它更加跨平台,可以创建makefile,visual studio文件,code :: block文件等等。它还支持完整的源外构建,这意味着您可以创建一个_build文件夹,并从那里构建。然后,这会将所有生成的文件放入_build文件夹,而不是污染源树。
编辑:回答你的问题:我会学习基本的make文件,了解它的作用。但后来我会转过来。所以我会学习制作,但不能使用它。
答案 4 :(得分:1)
除非你使用的是IDE,否则make实际上是这类事物的事实上的工具,除非你想在这条路上更进一步并使用automake或类似的东西。我认为这对你的案子来说太过分了。
自动依赖生成有点棘手,但您通常可以在Web上找到有效的配方。我不确定你遇到了什么具体问题,但也许值得一个单独的问题。
可能是bash脚本足以满足您的需求;如果这是真的,那就去吧。鉴于您对Python更熟悉,您可能还想查看SCons之类的内容。
我已经做了很多Makefile工作,但我正在转向Rake。我发现Ruby的强大功能可以更好地满足我的需求。
答案 5 :(得分:0)
如果你每次都进行完整的构建,那么每次使用make来运行完全相同的命令序列都不会给你带来任何好处。然而,make是一个非常强大的系统,你错误地避开了它。 Make比你希望用自定义的“python构建脚本”拼凑出更多的东西。
即使此项目足够小,无法从头开始快速构建,您很快就会解决更大问题。使用简单的用例比使用复杂的用例更容易学习。您说“自动依赖生成似乎无法可靠地工作”:如果您正确定义了依赖关系,则make 非常可靠。因此,您的设置必定存在错误(详见下文)。
即使您总是从头开始构建,Make也很有用:您可以使用Makefile作为所有构建相关命令的容器,而不是手工制作一些小构建脚本,所有这些命令都由符号变量:例如,如果你有一个像ALLSOURCE
这样的变量,你可以将它与伪目标一起使用,这些伪目标可以产生一个zipfile,一个ctags索引等等。(make clean
也可以这样工作)。如果您为所有内容编写单独的批处理脚本,那么随着项目的发展,您将忙于更新它们 - 并且它们将无缘无故地混乱您的目录。
但是,你说,你无法让依赖项可靠地工作。我怀疑从其他人的示例脚本开始是一个错误:它可能做了太多你不需要,并且不完全理解。从干净的Makefile开始,为您生成的二进制文件添加目标,并编写自己的依赖项。把事情简单化;如果你的项目很容易构建,你甚至考虑做自己的脚本,那么为它编写一个makefile应该很容易。如果您遇到困难,请在此处提出具体问题。