如何组织Arduino项目的结构以简化源代码控制?


74

我一直在寻找这个问题的好答案。

通常,除最简单的项目外,任何Arduino项目都将包括:

  • 主要源代码文件 MyProject.ino
  • 专用于项目的库(MyProjectLibrary1.hMyProjectLibrary1.cpp...)
  • 第三方库(通常是免费的开放源代码,已手动添加到Arduino库目录中)
  • 原理图,PCB图
  • 文献资料
  • ...

所有这些使得很难将一个项目的全部代码和文档保留在源代码管理下(例如,在Subversion,Git或GitHub上)。

管理项目的源代码管理意味着管理项目使用的所有文件的版本,包括第三方库。

现在,对于单个项目,我需要定义一个目录结构:

  • 包括上述所有项目文件
  • 我完全可以使用源代码管理工具(包括第三方依赖)
  • 我可以在硬盘上的任何地方签出并从那里构建项目(它必须是由Arduino IDE施加的一个位置)
  • 我可以将其压缩到一个独立的档案中,然后将其发送给朋友,以便他尽可能轻松地构建(无需额外的手动下载)

我发现Arduino项目特别棘手的是外部库依赖项的管理。Java项目开发人员为此拥有Maven存储库,这对管理所有外部部门很有帮助。但是我们没有用于Arduino库的等效系统。

我想知道其他Arduino项目制造商如何在自己的项目中处理这些方面。

还要注意,我愿意改变开发流程,包括我的IDE(目前,我大多数时候都将Eclipse与Arduino插件一起使用Eclipse,然后确保我的项目也可以直接与Arduino IDE一起使用)。


我也一直在为此苦苦挣扎。我有两个项目需要不同版本的外部库,目前它们不在版本控制范围内。
Cyber​​gibbons

1
请注意进一步的研究,它们是程序包管理器。JavaScript的Node.js的了/ NPM和凉亭,PHP有PEAR和作曲家等
凯泽

Answers:


29

我组织arduino项目的方式非常简单,我的所有项目都是git存储库,因此至少存在以下内容:

我偏爱使用我最喜欢的编辑器和一个Makefile,该文件专门针对大多数用例而设计(并且甚至改进了我即将分享的那个用例)。

对于库,我更喜欢将它们保留为它们自己的存储库,并使用git子模块将它们包括到项目中。由于社区编写的许多库都作为git存储库共享,所以这是一个很好的通用解决方案。然后,在Makefile中,我只需要添加要包含在LOCALLIBS变量中的库路径。

尽管对于某些项目,将这些库封装到为该项目设计的硬件抽象层库中是有意义的,但是我更喜欢使用如下路径:

  • project
    • project.ino
    • Makefile
    • project_hal_lib
      • library1
      • library2
      • library3

尽管使用arduino 1.5.x 提供了一种指定库的方法,这将提供一种创建和构建arduino项目的方法,就像在python中使用pipy和virtualenv一样,即定义所需的库集,它们下载。


我正在研究类似的答案。你打败我了!
asheeshr 2014年

+1谢谢!这种方式看起来很有趣。我必须在本周尝试一下(不过,我需要先检查如何设置Makefile的内容)。
jfpoilpret 2014年

@AsheeshR如果您的答案相似,那意味着它仍然存在一些差异,对吗?我很想知道这些!
jfpoilpret 2014年

实际上,下一个版本的Makefile的主要更改将是flash使用程序员或upload使用引导加载程序的能力。以及处理引导程序与固件的合并。我还写了一个makefile文件中的保险丝设置器。
2014年

@zmo赏金值得,尽管您的Makefile解决方案无法在我的情况下运行(使用Windows,但我未指定该点)。但是我坚信,使用现有的现有makefile解决方案之一是可行的方法。一旦找到适合我的作品,我将在此处发布答案。
jfpoilpret 2014年

23

最简单的方法是将库的头文件和代码文件复制到源目录中,并包括它们。

myproject/
    myproject.ino
    somelib.h
    somelib.cpp

在您的代码中,您可以执行 include "somelib.h"

不利的一面是,这些库必须位于同一文件夹中,而不是子文件夹中,因此会使您的目录显得混乱。


关于我整个项目的目录结构,包括原理图和文档,我的通常看起来像这样:

myproject/
  schematics/ - eagle files or whatever you may have
  docs/       - include relevant datasheets here
  test/       - any test cases or other code to test parts of the system.
  myproject/  - since Arduino code must be in a directory of the same name
    myproject.ino
    ...

另一个缺点是,我将不得不在许多项目中复制相同的库。另外,对我来说不清楚是您只在其中放置您的库还是在第三方库中?
jfpoilpret 2014年

第一点:这并不是真正的负面影响,这只是将库和项目源代码保持在版本控制中所需要的副作用。如果另一个项目需要该库的更新版本怎么办?如果您修改了该怎么办?第二点:两者都会起作用。
sachleen

1
我不。Arduino IDE在很多方面都受到限制。您可能希望寻找一个更好的工作环境,以便对此有更好的支持。人们制作了自定义的制作文件,使您也可以从其他来源导入库。
sachleen

1
从软件许可的角度来看,这不是组织项目的好方法。如果您的项目中包含第三方库,这些库可能具有不同的许可证,那么一旦开始共享项目文件,您可能会违反它们。不同的开源许可证通常彼此不兼容。
asheeshr 2014年

3
@AsheeshR将所有文件保存在一个目录中,因此arduino IDE不会抱怨这根本不是组织项目的好方法。这只是一种方式。欢迎提出更好的解决方案。我不知道还有什么可以让您使用Arduino软件。
sachleen 2014年

19

当组织多个嵌套存储库时,Git子模块非常强大。使用git子模块,可以轻松处理来自不同来源的多个库,甚至处理您自己项目中可能存储在不同来源的部分。

目录结构

组织项目的一种方法是:

  • projectA-父目录

    • projectA-包含Arduino代码的源代码目录

      1. projectA.ino
      2. 头文件
      3. 实现.cpp
    • docs-您的主要文档目录

    • 原理图 -这些可以分别保存在单独的Git仓库或同一仓库的一部分中

    • libs-将包含您的第三方库。

      1. libA-这些可以作为第三方存储库进行维护
      2. libC-...
    • 执照

    • 自述文件

    • Makefile-处理目录之间的依赖关系所必需

工作流程

就主存储库而言,您将遵循正常的更改,添加和提交周期。子存储库使事情变得有趣。

您可以选择将存储库添加到主存储库的父目录中。这意味着目录结构的任何部分(例如文档,示意图等)都可以作为独立的存储库维护,并可以从中不断进行更新。

您可以使用git submodule add <repo.git>命令执行此操作。要使其保持最新状态,可以使用git submodule update <path>

当要在存储库中维护多个第三方库时,每个库本身都可以进行版本控制,或者可以根据需要保持每个库的最新状态,而git子模块又可以节省您的时间!

要将第三方仓库添加到库中,请使用命令git submodule add <lib1.git> libs/lib1。然后,要在发布周期中将库维护在固定点,请签出库并进行提交。要使库保持最新状态,请使用命令git submodule update <path>

现在,您可以在主存储库中维护多个存储库,以及在其独立发行阶段维护多个第三方库。

与单目录方法

尽管单目录方法是最简单的方法,但是要对目录的各个部分进行版本控制会带来很多麻烦。因此,简单的方法无法适应项目中状态不同的不同存储库。

这种方法允许维护多个存储库,但是需要Makefile来处理编译和链接过程。

根据项目的复杂程度,可以选择最佳方法。


1
+1,但作为一个旁注:Git子模块非常不稳定,可能会出现松动的情况。这没有什么区别,如果你使用一个单独的目录或倍数(如vendornode_modules等)。Git引用它们并对其进行跟踪。
kaiser 2014年

“如果使用单个目录或多个目录(如供应商,node_modules等),则没有区别。” 我不明白这部分。你能详细说明吗?
asheeshr 2014年

16

这是我最终决定为我的项目遵循的方式。

Arduino的CMake

我做出的第一个重要决定是选择适用于我的环境(Windows)但不限于此的构建工具(我希望我的项目易于被其他人重用)。

我已经测试了各种开源Arduino make工具:

  • Guyzmo Makefile(由@zmo答案建议):这只是为Arduino构建手工制作的标准Makefile;这是一个Unix Makefile,但是 Windows很好 Unix make 端口 ; 遗憾的是,该Makefile仅适用于Unix,当然它可以适用于Windows,但是我想要一个“开箱即用”的工具。
  • Arduino-Makefile(由@adnues答案建议):这是一个基于Unix Makefile的更高级的项目,旨在使所有Arduino项目均可轻松重用;它可以在Mac,Linux和Windows上运行,但在我的第一个实验中证明Windows支持是错误的(许多依赖Unix shell)。
  • Graduino(没有任何答案建议):该构建工具基于 groovy世界中著名的 gradle构建工具;该工具看起来做得不错,但是需要一些(很少)常规/知识知识,并且只有很少的文档;由于安装groovy和gradle只是为了它而造成的负担,我决定不使用它(我想避免对想在其环境中构建我的项目的人提出太多先决条件)。
  • Arduino-CMake(没有任何答案建议):这似乎是最好的,它历史悠久,有许多支持者和维护者,有很好的文档记录,带有简单的示例,并且在网络,例如在这里那里。它基于 CMake(一种“跨平台制作”)。

我还找到了ArduinoDevel,这是另一个我尚未尝试过的Arduino构建工具,它可以生成Unix Makefileant build.xml文件。那个看起来很有趣,但是在功能上有些局限。

最后,我决定使用Arduino-CMake

  • 设置很容易:只需将CMake安装在您的机器上,然后将Arduino-CMake复制到可以从项目目录轻松访问(通过相对路径)的某个目录中即可。
  • 这些示例对我来说是开箱即用的(仅遵循CMakeLists.txt配置文件中的注释以适应我的环境所需的属性,例如Arduino类型,串行端口)
  • 您可以根据需要组织项目
  • 它可以为各种构建工具生成配置文件(尽管我仅测试了Unix Makefile),包括Eclipse项目。
  • 在生成的品牌中,创建了几个目标来支持:

    • 图书馆建设
    • 程序建立
    • 程序上传到板
    • 串行监视器启动
    • 还有一些我还没有测试过

项目结构

由于Arduono-CMake不会为您的项目添加任何目录结构,因此您可以选择最适合您的目录结构。

这是我个人完成的工作(仍然需要进一步完善,但现在我对此感到满意):

在此处输入图片说明

我决定将所有项目放在一个公共arduino-stuff目录下(我将其作为一个整体提交给github,我知道我可以使用git子模块在github上进行更好的组织,但还没有时间进行检查)。

arduino-stuff 具有以下内容:

  • build:这是cmake和make将生成其所有内容的目录(makefile,缓存,目标文件...);这一点并没有致力于github
  • cmake:这只是Arduino-CMake cmake目录的一个副本(未修改)。这个放在github上,这样对于想要构建我的项目的人来说更容易
  • CMakeLists.txt:这是“全局” CMake配置,它声明了我的环境(板,串行端口)的所有默认值以及构建目标子目录的列表
  • TaskManager:这是我的第一个基于Arduino-CMake的项目,这是一个带有示例的库;这个idrectory还包含一个CMakeLists.txt陈述该项目目标的

改善点

但是,当前的解决方案并不完美。我看到的改进中(对于Arduino-CMake项目,如果他们认为合适,则包括这些改进):

  • 将库目录从当前项目复制到Arduino库目录的功能
  • 将库上传到github的功能
  • 从github下载库的功能

2
您是否尝试过PlatformIO?它可能不是已经存在了,当你问这个问题.. platformio.org
ohhorob

4
MyProject
|_MyProject
  |_MyProject.ino
  |_data
  |  |_documentation 
  |  |_PCB
  |  |_schematics
  |_src
     |_MyProjectLibrary1
     |_ThirdPartyLibrary

MyProject文件夹(存储库根目录)

我建议看似冗余的MyProject根文件夹的原因是您提到使用GitHub。当您下载(而非克隆)GitHub存储库的内容时,分支名称或标记名称将附加到存储库名称(例如,MyProject-master)。Arduino IDE要求草图文件夹名称必须与草图文件名称匹配。如果打开与草图名称不匹配的文件夹中的.ino文件,则Arduino IDE会提示您创建一个名称适当的草图文件夹,并将草图移至该文件夹。除了对用户而言不是很好的初始体验之外,更大的问题是Arduino IDE可能不会将所有其他关联文件复制到新创建的文件夹中,这可能导致程序无法编译。通过将草图放在子文件夹中,可以避免GitHub更改草图文件夹的名称。

如果GitHub文件名对您来说不是问题,则不需要冗余根文件夹。

资料夹

我建议data对非代码文件使用子文件夹,因为Arduino IDE对该名称的子文件夹有特殊的处理。当您执行File> Save As ...时,它们将被复制到新位置。没有其他名称的子文件夹。

src文件夹

src子文件夹具有允许的特殊属性递归编译。这意味着您可以将库保留在该文件夹中,并从草图中包括它们,如下所示:

#include "src/MyProjectLibrary1/MyProjectLibrary1.h"
#include "src/ThirdPartyLibrary/ThirdPartyLibrary.h"

Arduino的1.5库格式文件夹结构也支持,你只需要调整#include相应的语句。

请注意,只有Arduino IDE 1.6.10(arduino-builder 1.3.19)和更新的版本才支持递归草图编译。

不幸的是,某些库#include对本地文件include 使用了不正确的语法(例如#include <ThirdPartyLibrary.h>而不是#include "ThirdPartyLibrary.h")。当将库安装到Arduino libraries文件夹之一时,此方法仍然有效,但是当库与草图捆绑在一起时,则无效。因此,某些库可能需要进行少量编辑才能使用此方式。

我非常喜欢这样做,而不是将所有库文件都转储到Sketch文件夹的根目录中,因为这很麻烦,打开草图时每个库文件都会在Arduino IDE中显示为选项卡(当然,您要做的任何源文件想要从Arduino IDE进行编辑的对象应放置在草图根文件夹中)。

能够就地使用捆绑库也符合您的另一个目标:

发送给朋友让他尽可能轻松地构建

消除了手动安装库的要求,使该项目更易于使用。

这也将避免与先前安装的同名库文件的其他版本发生冲突的机会。



0

可能真的是游戏晚了,但这是一个很受欢迎的问题,可以使用与已经发布的方法稍有不同的方法来回答。

如果您需要直接保持与Arduino IDE的兼容性,则可以使用类似于我在此处概述的内容:

https://gitlab.com/mikealger/ExampleArduinoProjectStructure/tree/master/ExampleSketchBook

我将大部分内容基于Arduino的注释-项目结构和构建过程,以及多年来积累的一些技巧。

我真的不知道为什么直接在Arduino页面上很难找到它,似乎来自半专业背景的愚蠢知识使得构建过程太笨拙了。

祝你好运


gitlab链接似乎已损坏
Greenonline

奇怪的是没有直接链接吗?即gitlab.com/mikealger/ExampleArduinoProjectStructure
Mike Alger

实际上,两个链接都可以在Firefox中使用,但是在我过时的Chrome版本49.0.2623.112(64位)中都不能使用。我猜没什么好担心的。:-)
Greenonline
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.