开发区域

先进与MATLAB软件开发

构建块

我的人!哦,我错过了你。已经这么长时间以来我们已经讲过一些开发工作流善良在这个博客。我发现很难坐下来写更多的想法和思考这些主题,但是这里的一线希望我缺少时间是一个很大的原因是,我们一直努力把MATLAB开发基础。

其中之一是新的构建工具MATLAB,包括在R2022b !我们是超级兴奋这个工具的新秀,但更兴奋的价值将会作为你开始使用它为您的MATLAB项目。

这个东西到底是什么呢?总之它是一个标准的接口你在MATLAB建立和合作项目。“构建?”,you say?

是的,“构建!”,我说。任何发展中严重的、可共享的、生产级MATLAB代码知道即使MATLAB是一种“easy-to-leverage”语言,通常不需要一个实际的“编译”步骤中,它仍然需要一个开发过程,包括测试等任务,质量检验关,撞一个版本号。也证明,MATLAB确实有很多方法构建一些东西。认为墨西哥人文件,p代码,代码生成,工具箱包、文档页面,或生产工件从MATLAB编译器和编译器SDK。这些都是构建步骤。

不过,问题是,没有标准的API为MATLAB项目组织这些构建步骤。通常情况下的结果看起来是这样的:

这看起来很熟悉吗?对我来说就大不一样了。所有这些脚本在一个项目或回购为做这些特定的任务。每一个看起来有点不同,因为一个是写在下周一周二和其他。如果我们幸运的话,我们还记得这些所有的工作时,我们需要与它们进行交互。然而,有时我们不幸运。有时,我们回到我们的代码,我们如何建立它的一点概念没有,以什么样的顺序,与脚本。

也知道是谁从来没有那么幸运?一个新的贡献。人想贡献代码,并没有学到位的系统开发项目。有些项目是严格的,确实有自己的custom-authored构建框架。这是伟大的,但需要更多的维护,甚至在这些情况下一个新开发项目需要学习这个定制系统,这是不同于其他系统建立MATLAB代码。

哦,不了。从R2022b我们现在有了一个标准接口和构建框架使项目业主容易产生它们的构建方式,任何人都可以消费,无论多么复杂的构建管道。我们现在可以从特定的脚本和定制构建系统到一个已知的、结构化的和标准的框架。

让我最喜欢的简单例子质-弹(看起来像我还在心脏机械工程师)。这是一个简单的例子“工具箱”,有三个组件,设计脚本springMassDamperDesign.m定义系统的刚度和阻尼常数,一个函数simulateSystem.m模拟系统的初始条件以外的平衡显示阶跃响应,和一个墨西哥人文件convec.c可变两个数组,这可能是一个有用的工具这样的动态系统。它也有几个测试,以确保一切都好和良好的代码更改。

希望这段代码的作者了解这些组件和为什么他们写成。然而,如果我是一个贡献者第一次到这个代码我不知道。我的工作流可能会看起来像这样:

  1. 得到的代码
  2. 使用工具箱
  3. 看到有一些我想改变工具箱,功能添加或调整设计
  4. 使改变
  5. 提交的改变赢! !

好像我自己设置了一个坚实的贡献,我很为自己感到骄傲。后我看到初始设计的代码看起来像这样:

函数设计= springMassDamperDesign(质量)如果输入参数个数m =质量;其他的m = 1500;%需要知道质量来确定临界阻尼结束设计。k = 5 e6;%弹簧常数设计。c = 5 e5;%阻尼系数

…当使用包含的功能:模拟

函数[x, t] = simulateSystem(设计)如果~ isstruct(设计)| | ~所有(isfield(设计,{“c”,“k”}))错误(“simulateSystem: InvalidDesign: ShouldBeStruct”,设计应该是一个结构的字段“c”和“k”);结束%设计变量c = design.c;k = design.k;%不变的变量z0 = (-0.1;0);%初始位置和速度m = 1500;%的质量odefun = @ (t, z) [0 1;- k / m - c / m] * z;(t, z) =数值([0,1],odefun z0);%的第一列的位置(从平衡位移)x = z (: 1);

…它会产生如下反应:

[t、y] = simulateSystem (springMassDamperDesign);情节(y, t)

非常不错的,但我认为仍有改进的空间。我认为我们可以很快回到平衡,我像一个平滑转变有点过激。因为我是一个优秀的机械工程师,这显然是一个更好的设计,我们只需要有一个少阻尼:

目录.changes / round1
函数设计= springMassDamperDesign(质量)如果输入参数个数m =质量;其他的m = 1500;%需要知道质量来确定临界阻尼结束设计。k = 5 e6;%弹簧常数设计。c = 1 e5;%阻尼系数
[t、y] = simulateSystem (springMassDamperDesign);情节(y, t)

…并提交。这是当我得到一个剂量的谦逊和经历一个痛苦的世界。工具箱维护者下降我提交,因为这种设计失败测试已经到位意在限制的过度反应。看到了吗?

runtests (“测试/ designTest.m”)
designTest运行。= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = designTest / testOvershoot验证失败。- - - - - - - - - - - - - - - - -测试诊断:- - - - - - - - - - - - - - - - -过度侵犯!最大超调是0.01 - - - - - - - - - - - - - - - - - - - - - - - -框架诊断:- - - - - - - - - - - - - - - - - - - - - - - - verifyLessThan失败了。- - >的值必须小于最大值。实际值:0.010846982843858最大值(独家):0.010000000000000 - - - - - - - - - - - - - - - - - -堆栈信息:- - - - - - - - - - - - - - - - - - /用户/ acampbel /图书馆/ CloudStorage OneDrive-MathWorks /回购/ msd_blog1 /测试/ designTest。米(testOvershoot) 23岁= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = . .完成designTest __________失败总结:名字不完整的原因失败(s) = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = designTest / testOvershoot X验证失败。ans = 1×3 TestResult数组属性:名称传递失败的不完整的时间细节总数:2通过,1失败,0不完整,测试时间0.052733秒。

回想起来这是容易预测,毕竟有测试。我应该提交之前运行它们。但是没有指出我的方向,我刚好错过了那班车。回购可能为一个简单的例子是显而易见的,但对于一个“真实”的工具箱这很难看到的。

好的显然有更多的工作要做在我的贡献是拒绝精练地劳累工具箱的作者。但我仍胜任这一任务。得知有一个过度需求我可以调整我的设计,以适应这些约束:

目录.changes / round2
函数设计= springMassDamperDesign(质量)如果输入参数个数m =质量;其他的m = 1500;%需要知道质量来确定临界阻尼结束设计。k = 5 e6;%弹簧常数设计。c = 1.1 e5;%阻尼系数
[t、y] = simulateSystem (springMassDamperDesign);情节(y, t)

看起来不错,它通过测试吗?

runtests (“测试/ designTest.m”)
运行designTest……完成designTest __________ ans = 1×3 TestResult数组属性:名称传递失败的不完整的时间细节总数:3过去了,失败了,0不完整,测试时间0.011899秒。

是的!最后,我必须完成。然而,当我提交这个代码我得到另一个拒绝,因为还有一个测试失败的墨西哥人文件实用程序,我甚至不知道:

runtests (“测试”)
运行对流传热= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =错误发生在对流传热/ MatchesConvBaseline和它不运行完成。错误ID: - - - - - - - - - - - - - - - - - - - - - - - -“MATLAB: UndefinedFunction”- - - - - - - - - - - - - - - -错误细节:- - - - - - - - - - - - - - - -未定义的函数“convec”“双”类型的输入参数。对流传热误差(第6行)断言(isequal (convec (x, y), conv (x, y)),…= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =。完成对流传热__________运行designTest……完成designTest __________失败总结:名字不完整的原因失败(s) = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =对流传热/ MatchesConvBaseline X X错误。ans = 1×4 TestResult数组属性:名称传递失败的不完整的时间细节总数:3过去了,失败了,1不完整,测试时间0.036491秒。

好了,这时,我看到有一些实用程序,我不改变,使用,甚至熟悉测试是失败的。此外,我意识到这是失败的,因为它不是编译。我不知道如何编译这个墨西哥人文件,此时我放弃,因为我没有打算投入这么多时间到的贡献。我没有时间去学习这个回购的所有细节(我只是想调整阻尼系数)。放弃我离开后一个坏味道在我口中。我可能做的努力促成这个代码库,实际上可能会三思而后行试图为其他代码库。不好的。没有尔巴布埃纳岛。希望自己的直觉。

进入buildtool

所有这一切痛苦可以通过使用这个新的构建工具。作为一个新的因素,我需要知道的是,我需要调用构建工具通过作者的意图开发工作流程。我需要学习这第一次,但是一旦我熟悉这个标准框架可以与之交互其他项目这也是使用构建工具。一旦我看到,项目文件的根buildfile.m我知道我在商业和作者我能做任何事,包括运行测试和墨西哥人编译文件,只需调用工具。让我们试一试:

buildtool
* *从墨西哥人建筑的Xcode的叮当声。墨西哥人成功完成。* * * *完成了墨西哥人开始设置* *完成设置* *开始测试运行的对流传热。完成对流传热__________运行designTest……完成designTest __________ 1×4 TestResult数组属性:名称传递失败的不完整的时间细节总数:4了,失败了,0不完整,测试时间0.16678秒。* *完成测试

这不是美丽吗?我不需要知道任何关于如何构建这个项目,我能快速滚动。我可以让我的小变化,需要发生的一切(如文件构建一个墨西哥人)然后我们可以确认它不会发生失败的测试。它使高质量的烘焙(er)。

它是如何做的呢?

我一直在关注的角度不熟悉的贡献者。作者/所有者如何使用这个设置成功?这是超级简单,利用MATLAB接口容易处理可编写脚本的基本框架。你首先创建buildfile.m,这是一个函数,创建您的构建计划。

函数计划= = buildplan构建文件计划(localfunctions);结束

通过所有的本地函数当您创建您的构建计划很容易定义简单的任务。这使您能够从任何函数创建任务,以这个词任务(或任务_task任务等等)。第一个评论功能(H1)给出了任务描述。对于这种情况我们想添加有3个任务。

设置任务

函数setupTask(上下文)%设置路径的构建目录(fullfile (context.Plan.RootFolder,“工具箱”));结束

这个任务可以确保正确的路径来构建。你可能会问这是否应该使用一个MATLAB项目,答案绝对是肯定的!这是一个更好的方法。现在我们正在建设,但将在另一篇博文projectify。

一个墨西哥人的任务

函数mexTask (~)%编译墨西哥人文件墨西哥人墨西哥人/ convec.c-outdir工具箱/;结束

这是一个非常简单的编译在这个例子中,但对许多项目这一步可以更多的参与。简单或复杂的,在这里,你可以让新来的琐碎。

一个测试任务

函数testTask (~)%运行单元测试结果= runtests (“测试”);disp(结果);assertSuccess(结果);结束

简单。现在,这些任务定义和自动包含在你的构建文件任何人都能看到哪些任务可以运行:

buildtool任务
墨西哥人-编译墨西哥人文件设置安装路径构建测试,运行单元测试

太好了,我们可以看到3任务,但这些任务可以预测,不能运行在任何顺序。测试不通过,除非适当的代码路径和墨西哥人文件建立。这些任务依赖关系可以在主函数中定义为你设置你的计划。我们需要添加这些依赖项,当我们,所以我们设置一个默认的任务buildtool甚至不需要传递任何参数。

函数计划= = buildplan构建文件计划(localfunctions);计划(“测试”)。依赖项= [“墨西哥人”,“设置”];计划。DefaultTasks =“测试”;结束

现在我们可以通过打电话只是默认调用它buildtool(如上我们做)或者我们可以调用我们想运行一个特定的任务,如墨西哥人,它只会运行这个任务所需:

buildtool墨西哥人
* *从墨西哥人建筑的Xcode的叮当声。墨西哥人成功完成。* *完成了墨西哥人

这是完整的构建文件,供您参考:

函数计划= = buildplan构建文件计划(localfunctions);计划(“测试”)。依赖项= [“墨西哥人”,“设置”];计划。DefaultTasks =“测试”;结束函数setupTask(上下文)%设置路径的构建目录(fullfile (context.Plan.RootFolder,“工具箱”));结束函数mexTask (~)%编译墨西哥人文件墨西哥人墨西哥人/ convec.c-outdir工具箱/;结束函数testTask (~)%运行单元测试结果= runtests (“测试”);disp(结果);assertSuccess(结果);结束

好了我或发送你开始你的MATLAB项目开发与新冒险构建工具。我们希望听到你的反馈。让我们把这一系列的!我要博客几次在这你可以看到这个项目增长能力和真正开始利用这个构建框架。同时,我们正在疯狂地对未来这个工具的功能。所以在多个领域这只是更多的开始。




发表与MATLAB®R2022b

|

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。