为什么构建工具使用的脚本语言不同于基础编程语言?


23

当我意识到大多数语言的主要构建工具/系统使用的语言与基础编程语言本身所使用的语言不同时,我最近一直在为Nodejs项目使用一些构建工具。

例如,make不使用C或C ++编写脚本,而ant(也不是Maven)不使用Java作为脚本语言。

诸如Ruby之类的较新语言的确将相同的语言用于诸如rake之类的构建工具,这对我来说很有意义。但是,为什么情况并非总是如此?拥有使用与基础语言不同的语言的构建工具的优势是什么?


14
通用语言可能不足以适合该工具的专家使用吗?例如,我不想用C编写make文件!有时DSL更好。
安德烈斯F.

13
从另一个角度来看:为什么不使用make编写应用程序软件?
whatsisname 2015年

4
本文的主要内容是作者认为使Lisp变得更好的原因,但其中包含有关Ant为什么使用XML而不是Java的一些相关信息。
8bittree

6
如果您想用C编写一个可以自动构建C程序的程序,您难道不会只是make再次写完(无论如何用C实现)?
布兰登2015年

6
@ joshin4colours做在C.写,使所使用的语言,然而,是调用需要的外壳说明性语言。

Answers:


36

选择使用哪种编程语言来完成任务,必须取决于该目标的特定功能,而不是与该项目相关的其他任务。

构建工具可以完成非常具体的工作,无论您在主项目中使用哪种语言,构建工具本身就是一种软件。

试图捆绑主项目及其构建工具可能是一个非常糟糕的决定。构建工具需要的主要是简单规则的快速处理,以及文件和IO的快速管理。

如果像ruby这样的语言确实使用它们自己来实现其构建工具,则与该语言的功能有关的更多的是,而不是与使所有内容都用同一语言编写的假定需求有关。


18

编写使用C或Java之类的语言作为脚本语言的构建工具并非没有可能。但是,构建工具得益于使用更多的声明性脚本语言。想象一下用C编写makefile(或build.xml或其他内容)的痛苦和样板。

构建工具得益于DSL的使用,而DSL并不是一个特别好的选择。对于构建工具而言,C 太笼统,并且过于关注容易出错和底层的细节。例如,您不想关心构建工具中的显式内存管理!因此,即使使用类似C的语法,您也可能会在脚本编写工具中使用垃圾回收,这时为什么不简单地使用专用DSL?

可以使用Ruby是有道理的,因为它是比C或Java更高级,更具声明性的语言。另请参阅:Gradle,sbt。


13
Imagine the pain and boilerplate of writing a makefile (or build.xml, or whatever) in C.想象一下尝试在声明性XML脚本中表达非平凡的条件逻辑(您知道,标准命令性内容)的痛苦和混乱。哦,等等,您不必想象;您可能不得不处理它,而且可能是一团糟,不是吗?对于声明性脚本语言来说,构建是最糟糕的选择之一,因为严重的问题很快就会变成声明性限制,而问题又不够简单,不需要构建工具。
梅森惠勒

7
@MasonWheeler是的,有些情况下现有的构建工具使我受苦。没有人会一直使用低级别的C-像命令式语言帮助。我认为像Ruby这样的东西可能是理想的:声明式和命令式根据需要足够。C会让我做这个任务的噩梦。对我来说,构建系统是(大多数)声明性DSL的一个好用例:您关心的做什么,而不是(大多数时候)如何做。
安德烈斯F.

2
很公平。坦白说,我一直认为C是“如果X是您在问一个错误问题的答案”技术之一。每次我不得不深入研究XML“脚本”时,这都是一场噩梦。我同意具有DSL功能的高级命令式语言是理想的。
梅森惠勒

@AndresF .:诸如make文件之类的东西需要多种方法的结合。声明性地指定了期望的输出状态,但是强制性地指定了实现该状态所需的操作。
超级猫

1
@MasonWheeler我认为这是设计配置语言的人们比XML本身面临的更多问题。此类语言的作者经常犯的错误是,假设仅由于XML中的某些内容,该内容便会自动被人类读取。(我知道我犯此错误的次数比我所接受的要多。这很诱人。)一种设计良好且精简的配置语言在XML上的工作方式与其他形式一样好。
biziclop 2015年

12

让我们给您一个真实的例子。

大约15年前,我致力于将用C语言编写的大型系统从Unix移植到Windows,这大约需要300万行代码。为了给您一些扩展的概念,在我们的某些Unix系统(RS6000)上编译花费了24小时以上,而Windows可以在大约4小时内完成编译。

(我们还用自己的解释语言编写了200万行代码,但是由于从未为文件处理而设计,因此决定不将其语言用于构建系统。此外,我们还需要一个构建系统来编译实现我们语言的C代码)

在构建系统是用Shell脚本和make文件混合编写的时候,这些文件不能移植到Windows上-因此,我们决定编写自己的构建系统。

我们本可以使用C,但是我们决定使用python,原因很少。(我们同时也在python中重写了源代码控制系统,这与构建系统非常集成,因此开发人员可以共享用于检入模块的目标文件。)

  • 我们的大多数代码都可以使用一些简单的规则(从文件的命名约定驱动)(对于所有平台,Windows,VMS和Unix的6个版本来说,只有几千行python)可以构建。

  • 当RegEx在不同平台上的C系统之间不是很标准时,Python就内置了RegEx。

  • 一些模块需要自定义构建步骤,Python允许动态加载类文件。我们基于文件夹中具有魔术名称的python文件,允许使用自定义类来构建模块(lib)。 这就是使用python的杀手级原因。

  • 我们考虑过Java,但当时还没有在所有平台上发布。

(我们的源代码控制系统的UI使用了Web浏览器,因为该浏览器可在所有平台上移植。这距离我们建立互联网连接已有6个月了。我们必须通过X25下载浏览器!)


在几个重要的系统上工作过后,我有时会觉得自己掌握了开发规模。然后我读了这样的故事。嘘。
dmckee

@immibis这是15年前的时尚。更重要的是,这种做法实际上得到了领先的Unix供应商(尤其是SGI和DEC,但也包括IBM)的认可和鼓励。
Oakad 2015年

1
人们往往会忘记Unix曾经是“昂贵”的意思。Windows以更便宜的价格赢得了台式机/工作站之战。出于同样的原因,Linux后来赢得了服务器大战。
slebetman

1
如果我想让一台计算机运行我自己编写的软件,那么我希望它具有灵活性,并具有101种内核编译方式等选项。但是,如果我要出售要安装在客户计算机上的软件,我希望客户可以运行的操作系统不灵活,因此我知道如果它在我的计算机上也可以在他们的计算机上工作。将Linux视为软件供应商时,这是一个很大的因素-支持看起来太昂贵了。Linux赢得了托管服务器软件大战,服务器由软件供应商提供,例如大多数Web部署软件。
伊恩

3
@slebetman这是唯一的公平-Unix通过便宜(与LISPM和类似机器相比)赢得了上一场“战争”。使用C作为主要编程语言,这绝对是可怕的,可怕的设计并且不断崩溃(但启动起来比LISPM!:P快得多)(相当多的LISP和类似的语言),但是它便宜得多。实际上,许多人之所以采用它是因为它是免费的(在Linux之前很久就有许多免费的变体)。实际上,我遇到了许多老式的LISPer,他们在当时的时代更喜欢MS-DOS。是的,太可怕了。
a安2015年

3

这个问题的简短答案是,这就是构建工具。一种自动使用其他工具的工具,目的是从某些源文件构建最终产品。如果我们使用与产品本身相同的语言来编写构建脚本,那么我们将进入特定于语言的工具领域,而这些工具将不能以相同的方式被视为构建工具。

这就提出了一个问题-编译器为什么不提供像make这样的工具所习惯的构建自动化?对此的答案仅仅是因为make存在。Unix的哲学“做一件事情,做好一件事情”表明,提供此功能不是编译器的责任。就是说,我个人经历了很多麻烦事,因此有兴趣尝试提供自己的引用-不引用“本机”构建系统的编译器。

有关以此方式设计的编译器的示例,请参见Jon Blow的Jai(尚未发布),该语言旨在替代C ++。在此收集了有关编译器的讨论和演示的链接。该语言编译为在编译器中运行的字节码,而编译为二进制是标准库提供的功能,可从字节码访问。目的是允许在语言的本机语法内进行构建自动化和元编程。

*查看Microsoft的Visual Studio将为您展示相反哲学的示例。:)


2

首先,构建工具是一个工具,就像“ gcc”,“ ls”,“ awk”或“ git”一样。您向工具提供输入(文件名,参数等),它将相应地做一些事情。

所有这些工具都允许您以应该足够容易编写和理解的方式传递输入。对于特定的构建工具,输入是一个配方文件,该文件描述了您的项目从源文件到成品的过程。

如果您的食谱很简单,只需传递包含要使用的项目和编译器的文件夹,那么声明性的“语言”就足够了。一旦配方变得越来越复杂,逻辑越来越多,使用声明性语言来处理它就会变得很麻烦,并且会使用更多通用语言。

现在应该很明显,仅仅因为它们具有不同的目的和要求,用于编写构建配方的语言与用于编写产品代码的语言之间就没有联系了。甚至在编写构建工具所用的语言与应该编写构建配方的“语言”之间都没有任何联系。始终使用最佳工具来完成工作!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.