How to organize my Arduino projects' structure for easy source control?
My way of organizing an arduino project is quite simple, all my project are git repositories so that there is at least the following:
- project/
- project.ino
- Makefile
I have a preference using my favorite editor and a Makefile which I have crafted to work against most use cases (and I even improved on that one that I'm going to share soon).
For the libraries, I prefer to keep them as their own repositories and use git submodule to include them to the project. As many libraries written by the community are shared as git repositories, that's a good generic solution. Then, within the Makefile, I just have to add the libraries path I want to include in the LOCALLIBS variable.
Though, for some projects, it makes sense to encapsulate the libraries into a hardware abstraction layer library crafted for the project, then I prefer to use a path such as:
project
project.ino
Makefile
project_hal_lib
library1
library2
library3
- …
Though, with arduino 1.5.x a new way to specify libraries is offered, that will offer a way to create and build arduino projects the same way we already do with pipy and virtualenv in python, i.e. you define the set of libraries you need and they get downloaded.
The simplest way to do this is to copy the header and code files of the library into your source directory and include them.
myproject/
myproject.ino
somelib.h
somelib.cpp
In your code, you can do include "somelib.h"
The down side to this is that the libraries must be in the same folder, not sub folders, so it makes your directory look messy.
Regarding the directory structure of my entire project, including schematics and documentation, mine usually looks like this:
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
...
Git submodules are extremely powerful when it comes to organizing multiple nested repositories. Handling multiple libraries from different sources, and even handling parts of your own project which may be stored at different sources becomes easy with git submodules.
Directory Structure
A way to organize your projects would be:
projectA - Parent Directory
projectA - Source code directory containing Arduino code
- projectA.ino
- header.h
- implementation.cpp
docs - Your main documentation directory
schematics - these may be maintained separately on a separate Git repo or part of the same repo
libs - This will contain your third party libraries.
- libA - These may be maintained as third party repositories
- libC - ...
license
README
Makefile - Necessary to handle dependencies across directories
Workflow
You would follow your normal cycle of make changes, add and commit as far as the main repository is concerned. Things get interesting with the sub-repositories.
You have the option of adding a repository into the parent directory of your main repository. This means that any part of you directory structure, i.e. docs, schematics, etc. can be maintained as a separate repository and continuously updated from.
You can do this using the git submodule add <repo.git>
command. To keep it up to date, you can use git submodule update <path>
.
When it comes to maintaining multiple third party libraries within your repository such that each can be version controlled in itself or each can be kept up to date if need be, git submodule again saves your day!
To add a third party repo to libs, use the command git submodule add <lib1.git> libs/lib1
. Then, to maintain the library at a fixed point in the release cycle, checkout the library and make a commit. To keep the library up to date, use the command git submodule update <path>
.
Now, you can maintain multiple repositories within a main repository as well as multiple third party libraries in their independent stages of release.
Versus Single Directory Approach
While the single directory approach is the simplest, it is not possible to version control parts of a directory without a lot of pain. Hence, the simple approach fails to accomodate different repositories with varying states in the project.
This approach allows maintaining multiple repositories but brings in the need for a Makefile to handle the compilation and linking process.
Depending on the complexity of your project, the optimal approach can be selected.