我记得在学校写过makefile,但是那时我没有看到任何特殊的优势(我们只在Unix终端中使用它们时才使用它们,在该终端中,IDE带有方便的“ build”按钮。 t礼物)。除此之外,我在这里还看到了其他问题,这些问题讨论了构建脚本不仅可以创建程序还可以做更多的事情-它们可以运行单元测试以及安全的资源,而不管主机是什么。
我不能忘记构建脚本对于作为开发人员来说很重要的感觉,但是我想要一个有意义的解释;为什么我应该使用/编写构建脚本?
构建脚本和Build Server的职责讨论了它在更广泛的范围内所扮演的角色。我正在寻找构建脚本相对于IDE的“ build / run”命令或类似的简单方法所提供的特定优势。
#1 楼
自动化。开发时,只有在最简单的项目中,默认的“ build”按钮才可以完成您需要做的所有事情;您可能需要使用API创建WS,生成文档,与外部资源链接,将更改部署到服务器等。某些IDE允许您通过添加额外的步骤或构建器来自定义构建过程,但这仅意味着您已经通过IDE商品生成构建脚本。
但是开发系统不仅是编写代码。涉及多个步骤。可以自动执行独立于IDE的脚本,这意味着:提交对版本控制的更改时,服务器可以自动启动新的构建。它将确保您不会忘记提交构建所需的任何内容。
类似,构建完成后,可以自动运行测试以查看您是否破坏了某些内容。
现在组织的其他成员(QA,sysadmins)拥有一个内置的产品,该产品仅从控制版本即可完全再现。
b)是所有产品通用的。
即使我是一个人的团队,我也为此目的而使用脚本。开发修补程序后,我将致力于SVN,将SVN导出回另一个目录中,并使用构建脚本生成解决方案,然后将其提交到Preproduction系统,再到Production。如果几个星期后(我的本地代码库已经更改)有人抱怨一个错误,我将确切知道我必须检出哪个SVN版本才能正确调试系统。
评论
这是恕我直言的最佳答案。每个人的想法都是正确的,但这确实说明了为什么要构建脚本。由于它们支持自动化,随着项目的扩展,自动化将为您节省大量时间。
– Alexus
2015年6月29日17:00
@Alexus不只是时间,而且还有愚蠢的错误。 ;)“重复导致无聊。乏味导致可怕的错误。可怕的错误导致'我希望我仍然很无聊。' “(您也可以及时衡量愚蠢的错误,但重要的是要意识到这可以节省一些原因的时间。)
– jpmc26
2015年6月29日在20:27
即使对于单人项目,运行本地Jenkins服务器以自动执行“在单独目录中构建”也可能会有所帮助。我正在Windows下进行某些工作,我还需要确认是否可以交叉编译,因此让Jenkins生成并运行测试,然后生成交叉编译版本使我在需要时更加自信(当然,也是有效的!)。发布错误修复。
– Ken Y-N
15年6月29日在23:13
我不同意可复制构建的说法。当今的构建系统中有许多不受控制的变量,因此很难获得可复制的构建。您的论点听起来像是开箱即用,那是完全不对的。
–乔纳斯·格罗格(JonasGröger)
15年7月1日在11:08
@JonasGrögerAutomation去除了最大的变量之一:人。
–CurtisHx
15年7月1日在11:33
#2 楼
像代码一样,构建脚本由计算机执行。计算机非常擅长遵循一组说明。实际上,(在自我修改代码之外),计算机将在给定相同输入的情况下以完全相同的方式执行相同的指令序列。这样提供的一致性水平很好,只有一台计算机可以匹配。相比之下,在执行以下步骤时,我们充水的肉袋简直是卑鄙的。那个讨厌的分析大脑倾向于质疑它遇到的一切。 “哦...我不需要那个”,或“我真的要使用这个标志吗?恩...我只是忽略它。”此外,我们有一种自满的趋势。完成几次操作后,我们开始相信我们已经了解了说明,而不必阅读说明表。
摘自《实用程序员》:
另外,我们要确保项目的一致性和可重复性。手动程序可以使一致性保持变化;不能保证可重复性,尤其是在过程的各个方面可以由不同的人解释的情况下。
此外,我们在执行指令时总是比较迟钝(与计算机相比)。在一个拥有数百个文件和配置的大型项目中,手动执行构建过程中的所有步骤将花费数年。
我将为您提供一个真实的示例。我正在开发一些嵌入式软件,其中大多数代码是在几个不同的硬件平台上共享的。每个平台具有不同的硬件,但是大多数软件是相同的。但是,每种硬件只有很少的一部分。理想情况下,将公共部分放置在库中并链接到每个版本中。但是,这些常见的片段无法编译到共享库中。必须使用每种不同的配置进行编译。
首先,我手动编译了每个配置。只需几秒钟即可在配置之间进行切换,并不是什么大麻烦。在项目快要结束时,在代码的共享部分发现了一个严重的缺陷,其中设备实际上将接管通信总线。这真是糟糕!特别糟糕。我在代码中找到该错误,对其进行了修复,然后重新编译了每个版本。除了一个。在构建过程中,我分心了,忘了一个。释放了二进制文件,构建了机器,一天后,我接到一个电话,说机器停止响应。我检查了一下,发现设备锁定了总线。 “但是我已经修复了该错误!”。
我可能已经修复了它,但是它从未找到过解决该问题的方法。为什么?因为我没有一个可以一键构建每个版本的自动构建过程。
评论
您可以在构建脚本运行时喝咖啡!
– Peter Mortensen
15年7月1日在19:48
#3 楼
如果您只想做<compiler> **/*.<extension>
,构建脚本就没什么用(尽管有人会说,如果您在项目中看到Makefile
,就知道可以使用make
进行构建)。问题是-非平凡的项目通常需要更多的东西-至少,您通常需要添加库并(随着项目的成熟)配置构建参数。IDE通常位于至少是可配置的-但是现在构建过程依赖于IDE特定的选项。如果您使用的是Eclipse,则Alice更喜欢NetBeans,而Bob则想使用IntelliJ IDEA,因此您无法共享配置,并且当您之一将更改推送到源代码管理时,他们需要手动编辑IDE创建的配置其他开发人员的文件,或通知其他开发人员以便他们自己完成(这意味着在某些IDE的IDE配置错误的地方会有提交...)。
您还需要弄清楚如何在团队使用的每个IDE中进行更改,并且如果其中一个不支持该特定设置...
现在,这个问题取决于文化-开发人员可能会发现不选择IDE是可以接受的。但是,具有IDE经验的开发人员在使用它时通常会更快乐,更高效,并且文本编辑器用户往往会虔诚地热衷于他们最喜欢的工具,因此这是您想要给开发人员自由的地方之一-并且构建系统使您可以做到这一点。有些人可能具有构建系统首选项,但是它不像IDE /编辑器首选项那么狂...
即使您让所有开发人员都使用同一IDE,也很幸运-可以说服构建服务器使用它...
现在,这是针对简单的构建过程自定义,IDE倾向于为其提供漂亮的GUI。如果您需要更复杂的内容(例如在编译之前进行预处理/自动生成源文件),通常必须在IDE配置的某些基本文本区域中编写预构建脚本。您仍然必须对哪个构建系统进行编码,但是可以在编写代码的实际编辑器中进行编码,更重要的是:构建系统的框架本身通常为组织这些脚本提供一些支持。
最后-构建系统不仅对构建项目有好处,还可以对它们进行编程以执行团队中每个人可能需要执行的其他任务。例如,在Ruby on Rails中,存在用于运行数据库迁移,清理临时文件等的构建系统任务。将这些任务放入构建系统可确保团队中的每个人都能一致地执行它们。
评论
这不仅仅是不同的IDE的问题。一些开发人员讨厌并讨厌所有类型的IDE。
–David Hammen
2015年6月29日17:38
@DavidHammen我是这些开发人员之一(尽管我对Vim进行了如此艰难的配置,以至于有可能将其转换为IDE ...),在编写该段落时,我自动编写了“编辑器”,并且不得不修复它到IDE,因为我认为IDE上的装置是我回答的重要部分。提问者显然来自IDE领域,这个问题是关于无IDE开发的问题,这是在没有合适的IDE时您必须做的事情。这个答案的重点是说明即使对于纯粹由IDE用户组成的团队,构建系统也有好处。
–伊丹·阿里(Idan Arye)
15年6月29日在22:01
我也是那些开发人员之一。我不希望我的手指离开键盘。这样做打断了我的思考过程。
–David Hammen
15年6月29日在22:25
我不同意。我更喜欢IDE。它们使我不必在乎名称,轻松查找,重构,漂亮的UI。我的意思是,如果IDE可以为我做某些事情,否则我会用sed ack等做些事情,那么我就使用它。
–xyz
15年6月29日在22:40
关键是,使用构建脚本,团队中的每个开发人员都可以使用他们喜欢的任何东西,而使用IDE的构建功能,您将迫使每个人不仅使用IDE,而且要使用为项目配置的非常特定的IDE(除非您为多个IDE配置了它,并祝您好运同步...)
–伊丹·阿里(Idan Arye)
15年6月29日在23:16
#4 楼
许多IDE只是将用于构建内容的命令打包在一起,然后生成脚本并调用它!例如,在Visual Studio中,您可以在C语言中看到C ++编译的命令行参数。命令行”框。如果仔细查看生成的输出,您将看到包含用于运行编译的生成脚本的临时文件。
现在,所有的都是MSBuild,但是仍然由MSBuild直接运行。 IDE。
所以使用命令行的原因是,您直接进入源代码并跳过中间人,可能已更新或需要大量依赖项的中间人,而您只是不这样做不需要或不需要充当连续集成(CI)服务器的无头服务器。
此外,您的脚本所执行的工作比通常针对开发人员的常规步骤还要多。例如,在构建后,您可能希望将二进制文件打包并复制到一个特殊位置,或者希望创建二进制文件或在其上运行文档工具。 CI服务器执行了许多不同的任务,这些任务在开发人员机器上是没有意义的,因此,尽管您可以创建一个IDE项目来执行所有这些步骤,但是您必须维护其中的两个-开发人员项目和构建项目。一些构建任务(例如静态分析)可能会花很长时间,这对于开发人员项目是不希望的。
总之,这很容易-创建脚本来完成您想要的所有事情并且可以在命令行或构建服务器配置上快速轻松地将其启动。
#5 楼
make
比
更容易记住和键入
gcc -o myapp -I/include/this/dir -I/include/here/as/well -I/dont/forget/this/one src/myapp.c src/myapp.h src/things/*.c src/things/*.h
项目可以具有非常复杂的编译命令。构建脚本还具有仅重新编译已更改内容的功能。如果您想进行整洁的构建,则正确设置后,比试图记住每个地方都可能会产生中间文件的地方更容易,更可靠。
make clean
。
当然,如果您使用IDE,也可以轻松单击build或clean按钮。但是,将光标自动移动到屏幕上的特定位置要比自动简单的文本命令自动化要困难得多,尤其是当窗口移动时该位置可能会移动时。
#6 楼
另一种方法是指定一个长的命令行命令。
另一个原因是makefile允许增量编译,这大大加快了编译时间。 br />
Makefile也可以使构建过程跨平台。 CMake基于平台生成不同的构建脚本。
编辑:
使用IDE,您将被束缚于一种特定的工作方式。许多人使用vim或emacs,尽管它们没有许多类似IDE的功能。他们之所以这样做,是因为他们想要这些编辑器提供的功能。对于不使用IDE的人来说,构建脚本是必需的。
即使对于那些不使用IDE的人,您可能也想真正了解正在发生的事情,因此,构建脚本为您提供了实现的底层细节
IDE本身也经常在内部构建脚本。运行按钮只是运行make命令的另一种方式。
#7 楼
上面的答案涵盖了很多基础,但是我想添加的一个真实示例(由于没有因果关系,因此无法添加为注释)来自Android编程。我是一名专业的Android / iOS / Windows Phone开发人员,并且经常使用Google服务API(主要是Google Maps)。
在Android中,这些服务要求我添加密钥库,或者一种开发人员ID文件,可将开发者控制台告知Google我是谁。如果我的应用是使用其他密钥库进行编译的,则该应用的Google Maps部分将无法工作。
与其在开发者控制台中添加和管理许多密钥库,实际上只能使用其中的一个无论如何要更新应用程序,我将这个密钥库包含在我们的安全存储库中,并使用Gradle告诉Android Studio在构建“调试”或“发布”时确切使用哪个密钥库。现在,我只需要在我的Google开发人员控制台中添加两个密钥库,一个用于“调试”,一个用于“发行”,我的所有团队成员都可以克隆该存储库并直接进行开发,而无需进入开发人员控制台并添加其特定密钥库的SHA哈希,或者更糟的是,让我对其进行管理。这具有为每个团队成员提供签名密钥库副本的额外好处,这意味着如果我不在办公室并且计划了更新,则团队成员只需要遵循很短的说明列表即可推送更新。
这样的构建自动化可保持构建一致性,并通过减少新开发人员,新机器或需要重新映像时的设置时间来减少技术负担。一台机器。
#8 楼
构建脚本的优点:更改看起来像代码(例如,在git diff命令中),而不是对话框中不同的选中选项
创建比简单构建更多的输出
在我以前的一些项目中,我使用了构建脚本来:
生成项目文档(基于Doxygen)
构建
运行单元测试
生成单元测试覆盖率报告
将二进制文件打包到发行档案中
生成内部发行说明(基于“ git log”消息)
自动化测试
评论
此处的答案已经涵盖了所有内容,但是我想提到一个事实,当您单击IDE中的“运行”按钮时,它(几乎总是)执行您的IDE生成的构建脚本。编写自己的构建脚本只是让您对过程有更多的控制。编写和共享您自己的构建脚本还意味着,即使其他人使用不同的IDE,任何人都可以使用与您的过程相同的过程来构建它。这有助于保持一致性。
blog.codinghorror.com/the-f5-key-is-not-a-build-process
对于开发人员来说,构建脚本通常很重要,尽管并非总是如此。即使在构建脚本是实际需求的环境中,许多“开发人员”也丝毫不关心它们。但是,脚本对于“构建者”而不是开发者而言很重要。在我工作的最后一个地方,大多数开发人员几乎没有建立脚本的零连接。
并非每个人都使用带有“构建”按钮的IDE