library definition

You are in Dependency Hell (tm) :wink:

What about a features.h that gest included both by the .ino file and by all library header files ?

Alternatively you could use the -D compiler flag, although passing custom flag to avr-gcc when used with the arduino IDE is something I've never done so far...

mromani:
You are in Dependency Hell (tm) :wink:

What about a features.h that gest included both by the .ino file and by all library header files ?

That's what I have been doing so far, and the whole purpose of this thread. I wanted to get rid of it.
The reason why is that to enable/disable features, the user has to actually edit a file features.h that has to be located on "Documents\Arduino\libraries\features", correct?
I would think any other place would make it invisible to all other libraries.
If so, let's suppose you enabled one feature today and uploaded. Then, you changed you mind and decided to go and use 3 other features and uploaded.
The INO code is the same for both and the only thing that was changed was 2 more defines on the features.h file.
A month from now, how would you know which features were compiled on the first code?
I wanted to place the defines inside INO to carry the history of features and make both INO codes different from one another.
Would you be able to explain a little better what the -D flag does and how to get it incorporated on the IDE, if you could?

In your situation I would switch to command line building. Reuse a build script or write your own. This will solve this kind of issue.

Can you please lead me to the right direction on how to do that?

The -D switch is on the command line what #define FOO is in the source code.

If you have an #ifdef DEBUG, and you compile with -D DEBUG, the #ifdef statement will evaluate to true.

Yeah, I realized that after I posted. I use those to burn bootloaders.
But, how would I get to do that within the IDE?

newhobby:

mromani:
You are in Dependency Hell (tm) :wink:

What about a features.h that gest included both by the .ino file and by all library header files ?

That's what I have been doing so far, and the whole purpose of this thread. I wanted to get rid of it.
The reason why is that to enable/disable features, the user has to actually edit a file features.h that has to be located on "Documents\Arduino\libraries\features", correct?
I would think any other place would make it invisible to all other libraries.
If so, let's suppose you enabled one feature today and uploaded. Then, you changed you mind and decided to go and use 3 other features and uploaded.
The INO code is the same for both and the only thing that was changed was 2 more defines on the features.h file.
A month from now, how would you know which features were compiled on the first code?
I wanted to place the defines inside INO to carry the history of features and make both INO codes different from one another.
Would you be able to explain a little better what the -D flag does and how to get it incorporated on the IDE, if you could?

Sorry, I didn't re-read you original question before posting my last comment.

What you have is a bounch of libraries and a sketch that can produce different programs based on which features the user enabled. If you want the compiled code to report its particular set of feature to the user once the build configuration is gone, you should find a way to compile in some sort of value that uniquely identifies each feature. (Cfr. e.g. squid or samba, whose binaries can print the list of the features the user selected at compile-time via the configure script.)
Off of top of my head, you could have a "features" unsigned int whose bits represent a particular feature. 1 = feature is present 0 = not compiled in.
You'd have a dump_features() function that would simply Serial.println(features, HEX) or, if you don't mind wasting some space, could print out the feature name for each '1' bit.

Oh, and there's always version control... not the easiest workflow if you're not used to it, but still a solution if you're willing to spend some time learning the basics of, say, subversion.

mromani:
Sorry, I didn't re-read you original question before posting my last comment.

What you have is a bounch of libraries and a sketch that can produce different programs based on which features the user enabled. If you want the compiled code to report its particular set of feature to the user once the build configuration is gone, you should find a way to compile in some sort of value that uniquely identifies each feature. (Cfr. e.g. squid or samba, whose binaries can print the list of the features the user selected at compile-time via the configure script.)
Off of top of my head, you could have a "features" unsigned int whose bits represent a particular feature. 1 = feature is present 0 = not compiled in.
You'd have a dump_features() function that would simply Serial.println(features, HEX) or, if you don't mind wasting some space, could print out the feature name for each '1' bit.

I agree that this solution would work for the code currently loaded on the board, but it would still not be enough.
What if I need to know which features I had enabled a month ago after uploading several codes.
Also, if one user wants to share the code with another user, simply giving out the INO file would not be sufficient.
And this is the biggest problem of them all.
If you simply post the INO file, the ending result is totally different from one user to another because what one user has inside the features.h file is different than the other one might have.
To be really honest, the INO file has nothing more than a couple of lines in it.
something like this:

<include TestClass1.h>
<include TestClass2.h>
<include TestClass3.h>
<include TestClass4.h>
<include TestClass5.h>
<include ParentTestClass.h>
<include features.h>

void setup()
{
  ParentTest.init();
}

void loop()
{
  ParentTest.DisplayScreen();
}

All the features are chosen from within the features.h
The best scenario would be to include the defines inside the INO file, which doesn't seem to be possible or in a file inside the same folder as the ino file, which would not really solve the problem 100%, but it would at least create history of codes if you saved the INO files with different names.

I don't have a ready-made solution because I've never done this on Arduino, however I'll throw my 2 cents in...

So you want to manage build configurations, and keep them around. You also want to be able to distribute them easily.

A naive but IMHO workable solution is to have a template project which contains the .ino file, all of the libraries and a features.h files with all of the available #defines. In this features.h you uncomment only those that make sense for a default or example configuration.
When you need to build a new project, let's call it A, with a particular feature set. You create a copy of the template folder, and rename it to A. Then you edit the feature.h commenting out the unwanted feature and uncommenting the desired ones. You then build and test the project. To share it, simply zip the folder to A.zip and attach it to an e-mail.
PRO: self-contained code and build configuration. Easy sharing.
CON: you're copying libraries around. If you spot a bug in a library, you have to manually patch every project. Tedious and error-prone.

A more elegant solution is to use version control. You put the libraries, the sketch and features.h under, say, subversion. You use trunk for the development of new features, new libraries, and for testing out various build configurations. At some point you create a "template" branch, and off that one or more "template" tags, with increasing version numbers.
When you need to implement a new feature set, you branch off the more recent "template" version. Then you edit features.h, build and test the program. When you're satisfied you commit the changes. You can also tag that branch "featureset_A", and package it as a release zip.
PRO: usual PROs of version control. No copying of code. Clear separation of base code and per-project modifications.
CON: complex setup and workflow. Needs a good understanding of version control and requires the learning at least one VC software.

I'm sure others will come up with simpler or more straightforward solutions...

The first option is exactly what we are doing, except the libraries don't need to be moved around. Just the features.h file that needs to be updated.
The second option will not work for someone that has not knowledge of computers nor programming.
My target user is the one that has no knowledge of programming and thus the simple INO code.
Editing a features.h file works, but it gets very confusing and hard to troubleshoot problems, because you never know what the user has inside the features.h file.

newhobby:
The first option is exactly what we are doing, except the libraries don't need to be moved around. Just the features.h file that needs to be updated.
The second option will not work for someone that has not knowledge of computers nor programming.
My target user is the one that has no knowledge of programming and thus the simple INO code.
Editing a features.h file works, but it gets very confusing and hard to troubleshoot problems, because you never know what the user has inside the features.h file.

How can you avoid copying libraries around(*) ? You have to have a features.h in each project folder, otherwise you'll end up overwriting the configuration every time you build a particular project.

Now that I think about it, I wonder if softlinks would work...

PS: (*)obviously each library header file would have to #include "features.h", i.e. the one specific for that particular project (build configuration, to be precise)

That's the problem I'm having right now.
We don't have a history track either. So, one could only know what the latest code had and not past changes on the features.h file.
Yes, each one of my libraries gets the include of the features.h file.
What is softlinks?

That's a linux feature.
In simple words, you can have a file in multiple folders, but instead of having multiple copies, you have just one file and the other "fake" copies just point to it.
The softlinks don't take up space (well, they do, but it's negligible).
If you try to open a softlink to a .h file, you see the .h file exactly as if it were the real file. If you modify and save it, the real file gets updated. The modifications are obviously "seen" automatically by all the other softlinks (this doesn't make sense of course, but you get the point).

To summarize:

the libraries live in the global /libraries folder;
each project folder contains symlinks to .h and .cpp files of every library (or a subset of them);
each project folder contains real (not a symlink) features.h and projectname.ino;

The .ino file uses #include "LibraryOne.h" instead of #include <LibraryOne.h>. This forces the compiler to look for the library header file in the current folder (i.e. the project folder).
Each library header file contains a #include "features.h" statement at the beginning (again, notice the use of double quotes instead of angle brackets).
This means that LibraryOne.h includes features.h found in the project folder, as expected.
If you find a bug in a library and update it, all project see the change automatically.

I hope all of this makes sense. Please don't laugh, but it's strictly untested :stuck_out_tongue:

PS: working on windows ? too bad... install ubuntu and get rid of that buggy beast :slight_smile: (just kidding!)

Thanks for the explanation, but that won't work either.
I can't expect all users to use linux.

newhobby:
Thanks for the explanation, but that won't work either.
I can't expect all users to use linux.

This code management problem could be an excellent excuse to force them to use it! :stuck_out_tongue:

Seriously... I don't see any solution other than copying code around or resorting to a custom build script.

It's worth the shot.
Thanks for trying though.
Here is the entire set of libraries: GitHub - curtbinder/ReefAngel: DEPRECATED - This repository is not used anymore. For updates to the Reef Angel Libraries, please look at https://github.com/reefangel/Libraries

Wow, impressing project! :astonished:

TBH, it's not entirely clear to me what it's for, even after having a look at the website. But I can see the problem is myself not knowing exactly what a "reefing hobbyst" does :stuck_out_tongue: