Define a global macro for an Arduino IDE project: how?

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Let's say I have a sketch that uses a bunch of libraries: A, B ,C.... All these libraries also refer to some common bottom-level utility library U. That library U provides an assert-like macro: `my_assert(condition)`. To control what this macro does the user has to define (or not to define) `NDEBUG` macro. (I.e. it works the same way the standard `assert` works.) All libraries A, B ,C... use that macro. My sketch also uses that macro.

 

So, let's say I finally decided to compile the "release" version of my sketch. Which means that I will have to do `#define NDEBUG` and re-compile everything (including all libraries) in presence of that `NDEBUG` definition. What is the proper way to do it within Arduino IDE's approach to build process?

 

AFAIK, there's no way to just globally ask Arduino IDE to supply `-DNDEBUG` to avr-gcc commands. (Unless I directly edit the config file, which is not the way to go).

 

Another common approach is to create something like `options.h` file and include it "everywhere". Global macro definitions like `#define NDEBUG` will go into that file. But where do I place that file? Common sense says that these settings are sketch-specific, meaning that each sketch should be able to define its own `options.h`. But, unless I'm missing something, implementation files in the libraries will not see my sketch-specific `options.h`...

 

So, what is the common practice for performing this kind of macro-based global configuration of Arduino IDE projects?

 

Dessine-moi un mouton

Last Edited: Sun. Apr 19, 2020 - 02:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arduino projects tend not to do that sort of thing :-(

 

just globally ask Arduino IDE to supply `-DNDEBUG` to avr-gcc commands. (Unless I directly edit the config file, which is not the way to go).

It's not THAT obvious that this isn't the "way to go."  You'd probably want to add a new "board" sub-menu for debug on/off.  Some boards already seem to have this (Adafruit Grand Central, for example.)  Or a new board "Uno-debug" that is only slightly different  from the Uno.  (rather similar to the "production" and "debug" targets in Atmel Studio.)

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can't you just do it in your sketch a the first line before including those libraries?

#define NDEBUG
#include <foo.h>

That's what I do for the libraries I write. There's probably a way in the IDE to pass the -D to gcc.

AFAIK, the IDE rebuilds the libraries every time so should be OK?

My GitHub (FAB_LED bitbang for ws2812, DigitalIO, SerialMenu...).
I make portable, code optimized Arduino libraries as a hobby and use AtTiny85 the most for my builds.
I am a burner and an OS and systems programmer by trade.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't like user-editable #defines in libraries because, if you decide to publish them, the Library Manager update process will happily overwrite any changes you've made each time a new version is released. There's an otherwise excellent graphics library that uses this method to define the control pins, and had me chasing what I thought was a hardware error because I forgot about this. As it is, I have to distribute an edited copy of the library .h with my code to ensure users have the correct definitions to hand and make the required updates.

 

How about a variable that's extern to the library code that must be set in the top-level sketch. Or a function/method that sets debug state with a bool argument, and defaults to your preferred state.

 

I'm not certain the IDE checks multiple levels of dependency, i.e. a depends on b which depends on c etc ...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I'm not quite understanding your ask. You want to set NDEBUG in your library but not allow users to do so?

An NDEBUG name implies it's only on to debug code (aka print traces or do more checks). I would not define that way stuff that's not meant to be configurable by the user unless it's not documented and non obvious (for example using __MY_LIB_INTERNAL_DEFINE__).

Anyways you can use at the beginning of your library:

#ifdef NDEBUG

#undef NDEBUG
#define NDEBUG the_internal_value

After all we use the ifndef / define paradygm for includes.

 

You're gonna have a hard time mixing defines / externs /methods are defines are processed in a precompilation stage that won't interact with your code. In fact defines interact with each other in weird ways sometimes and you need to take it into account when macros call each other.

My GitHub (FAB_LED bitbang for ws2812, DigitalIO, SerialMenu...).
I make portable, code optimized Arduino libraries as a hobby and use AtTiny85 the most for my builds.
I am a burner and an OS and systems programmer by trade.