library definition

Hi,

If I have something like this on my custom library:

void TestClass::TestFunction()
{
// Doing Something
#ifdef TESTING
// Do something else
#endif
// Continue doing something
}

Which are the places I could define TESTING, besides TestClass.h or TestClass.cpp?
Could I use a separate .h file on the same folder as INO file?
Could I define somehow inside the INO file?

Thank you,
RI

  • The .h and .cpp files can reside in your "libraries" folder, if they are to be used in more than one sketch, or in the same folder as the .ino file, if they are project-specific.

  • The #define TESTING can be placed in the .ino file, before the #include "TestClass.h" statement. If you use the #ifdef TESTING statement consistently across you .h and .cpp files, you can compile a "testing" version or a "production" version of you sketch in no-time by simply commenting out the #define TESTING line atop you .ino file.

Doesn't work.
Here is what I have.
Well, it's pde cause I'm still using 0022
TestClass.pde:

#define TESTING
#include "TestClass.h"

TestClass  t;

void setup()
{
  Serial.begin(57600);
  Serial.println("Start");
  t.TestFunction();
  Serial.println("End");
}

void loop()
{
}

TestClass.h

#ifndef __TESTCLASS_H__
#define __TESTCLASS_H__

#include <TestClass.h>

class TestClass
{
public:
	TestClass();
	void TestFunction();
};

#endif  // __TESTCLASS_H__

TestClass.cpp

#include "TestClass.h"

TestClass::TestClass()
{
}

void TestClass::TestFunction()
{
#ifdef TESTING
	Serial.println("Test");
#endif
}

When I comment or uncomment the define on the PDE file, I get no change on the compiled code.
I tried adding new file on the same folder as the PDE called TestH.h:

#define TESTING

It still does not do anything.

Any other ideas?

It still does not do anything.

The code does something. Maybe not what you expect/want. But, it does something. What does it do? What do you expect?

One issue with the way that the IDE processes files is that #define can't be the first bit of code in a file. Try adding a dummy variable declaration before the #define in the sketch.

In this example, all I wanted to do was to print "Test" if TESTING was defined on either the PDE or in a header file in the same folder as the PDE file:

#ifdef TESTING
	Serial.println("Test");
#endif

I tried what you recommended and my code turned out to be:

byte r;
#define TESTING
#include "TestClass.h"

TestClass  t;

void setup()
{
  Serial.begin(57600);
  Serial.println("Start");
  t.TestFunction();
  Serial.println("End");
}

void loop()
{
}

But it still does not run what's indide the ifdef :frowning:

the #define check is in a .cpp file.
It gets compiled before the pde/ino. Move the function into the header or use the #define in the .h file only.

.h

#ifndef __TESTCLASS_H__
#define __TESTCLASS_H__

#include <TestClass.h>

#ifdef TESTING
  #define DEBUG_PRINT( text ) ( Serial.println(text ) )
#else
  #define DEBUG_PRINT( text ) ( (void) 0 )
#endif

class TestClass
{
public:
	TestClass();
	void TestFunction();
};

#endif  // __TESTCLASS_H__

.cpp

#include "TestClass.h"

TestClass::TestClass()
{
}

void TestClass::TestFunction()
{
  DEBUG_PRINT( "Test" );
}

I tried your code, but it didn't print "Test".

Perhaps the function gest "optimized away" ? Just a thought, haven't had the time to test it still...

Oh, and now that I look closer... you have #include <TestClass.h> in... TestClass.h! ?-|

Ok, so the problem is this: the .cpp file doesn't #include the sketch, therefore at the time it gets compiled, TESTING is never defined.

The place where to put #define TESTING is therefore TestClass.h, which is included by TestClass.cpp, which in turn will notice if the symbol is defined or not.

Alternatively, you could define TestFunction directly in the .h file, like this:

#ifndef _TESTCLASS_H
#define _TESTCLASS_H

#include <Arduino.h>

class TestClass {
public:
    TestClass();
    void TestFunction() {
        #ifdef TESTING
        Serial.println("Test");
        #endif
    };
};


#endif

This way, putting the #define TESTING statements right before the #include "TestClass.h" line works as expected.

I think it worked!!!!
You are a genius!!!
Definitely owe you a beer :slight_smile:
I'll make some more tests later, gotta go to a meeting atm.
Thank you so much!!!

RI

Glad to hear that. Thanks for the beer. La berrò alla tua salute :wink:

Ok, I've done some tests, but I'm still getting somewhat of a problem.
So, I need to add another level of difficulty.
I have a very complex set of libraries.
The solution provided works if the function is called from withint the INO file itself, but does not work if another library is calling it.
What do I need to do so the define becomes globally visible by all libraries?
Let explain a little of what I'm trying to achieve and maybe you could point me to a better solution.
I have a very large code that I'd like to fit on a UNO board.
If I add all features of the code, it won't fit.
So, I have right now a header file located on Arduino\libraries folder that I can edit and #define which features should be included on the compiled code.
Everything is working really good, except that it makes it really hard to know which features you had uploaded a month ago after you have changed this header file and picked different features.
So, I'm trying to make it so I can pick features within the INO itself and making as simple as possible for the user and at the same time, saving the file would also keep track of which features that code was using.

Here is what my test stuff looks like:
INO file:

#define TESTING
#include <TestClass.h>
#include <ParentTestClass.h>

void setup()
{
  Serial.begin(57600);
  //p.DoSomething();
  p.t.TestFunction();
}


void loop()
{
}

In the code above, it works if I call p.t.TestFunction(), but not if I use p.DoSomething().
Even though the DoSomething() function calls the same t.TestFunction()
Here are the supporting libraries:
TestClass.h

#ifndef _TESTCLASS_H
#define _TESTCLASS_H

#include <Arduino.h>

class TestClass {
	public:
    TestClass();
    byte TestFunction() {
		#ifdef TESTING
    		Serial.println("Test");
		#endif
    };
};


#endif

TestClass.cpp

#include "TestClass.h"

TestClass::TestClass()
{
}

ParentTestClass.h

#ifndef _PARENTTESTCLASS_H
#define _PARENTTESTCLASS_H

#include <Arduino.h>
#include "TestClass.h"

class ParentTestClass {
	public:
	TestClass t;
	ParentTestClass();
	void DoSomething();
};

extern ParentTestClass p;
#endif

ParentTestClass.cpp

#include "ParentTestClass.h"

ParentTestClass::ParentTestClass()
{
}

void ParentTestClass::DoSomething()
{
	t.TestFunction();
}
ParentTestClass p = ParentTestClass() ;

What about looking into const global variables? They'll get optimized away no problem, and you'll be able to see them from every file in your project.

I think need defs.
I have stuff like this:

#if defined FEATURE1
	#include <Feature1.h>
#endif  // defined FEATURE1

And this:

#ifdef FEATURE1
const prog_char feature1menu_5_label[] PROGMEM = "Feature 1";
#endif  // FEATURE1

And this:

#ifdef FEATURE1
		case Feature1Menu_Option1:
		{
			SetupFeature1();
			break;
		}
#endif  // FEATURE1

So, by just not using one single #define, I can strip a lot of code that won't be used and reduce the code size.
Is there a way to do that with Const too? Could Const be declared inside the INO file and be seem by all libraries?

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?