18

I'm trying to write an Arduino library (effectively a C++ class) which itself references another library I have installed in my Mac's ~/Documents/Arduino/libraries directory.

At the top of the .cpp of the library I'm writing, I've tried

#include <ReferencedLibrary.h>

and

#include "ReferencedLibrary.h"

... neither of which work. I can successfully #include <ReferencedLibrary.h> from sketches in my ~/Documents/Arduino directory. Am I missing something or is this a limitation of the Arduino IDE/makefile? Is there a workaround?

casperOne
  • 73,706
  • 19
  • 184
  • 253
Robert Atkins
  • 23,528
  • 15
  • 68
  • 97

5 Answers5

12

I have been able to include a library in another Arduino library by using a relative path. For example, to include the AbstractSwitch library into the DigitalSwitch library, assuming that both of these libraries live in their own separate folders within Arduino's standard library folder, you can use the following include statement:

#include "../AbstractSwitch/AbstractSwitch.h"

In other words, your include statement should read:

#include "../LibraryFolder/LibraryHeaderFile.h"
julioterra
  • 121
  • 1
  • 3
  • 1
    I get `undefined reference` errors during the linker phase. It looks like the header is included but the source files are not compiled or linked in. – Justin808 May 28 '14 at 05:48
  • 1
    Same here .. Arduino 1.0.5 .. such a simple feature - no solution. – flyandi Nov 25 '14 at 17:45
  • @Justin808 you can also #include .cpp files in the same way, which worked for me. – Robin Hartland Aug 26 '15 at 15:56
  • For Arduino IDE 1.7 the trick above is not working. Use: `#include "../../libraries/LibraryName/LibraryName.h"` instead. – P.W. Dec 06 '15 at 23:10
11

The documentation here https://github.com/arduino/Arduino/wiki/Build-Process states:

The include path includes the sketch's directory, the target directory (/hardware/core//) and the avr include directory (/hardware/tools/avr/avr/include/), as well as any library directories (in /hardware/libraries/) which contain a header file which is included by the main sketch file.

This means that if you #include "ReferencedLibrary.h" from your main sketch file, this causes that file's libraries directory to get added to the include path for other libraries to include. A bit of a hack but it does work on my Mac.

djvg
  • 11,722
  • 5
  • 72
  • 103
nicolaskruchten
  • 26,384
  • 8
  • 83
  • 101
  • 1
    It might seem like a hack, but it goes in line with the whole processing paradigm. Basically a sketch is something that you use to fuse all the working pieces together so providing all the glue logic in the sketch is very appropriate. – SRM Jan 05 '12 at 03:54
  • 16
    This is "evil". The idea of a library is to abstract functionality and provide a concise API for use. `#include "lib.h"` should be all it takes to get the library (assuming it's in the load path). Requiring the client of the library to know about the inner workings of the library is just plain wrong. – Nathan Lilienthal Jul 04 '13 at 03:38
  • There is discussion that says the user must include all referenced libraries in the main sketch. However, even doing this seems to produce multiple definition errors for macros or arrays that are defined in the depended library header and excluding the header in the dependent source file results in not being able to find those same symbols. The only way to satisfy library dependencies is to include all headers and sources in the same directory (or else run through all include statements and change the path to relative, a huge pain when wrapping a 3rd party lib and hardly portable). – Joey Carson Jul 06 '14 at 14:11
  • 3
    This is the correct answer. It is not a hack, it avoids new users from having to know where the libraries are located and avoids the complexity or requiring a project file and other more advanced options. It is one reason why Arduino is so simple and easy to use. The Visual Studio and Atmel Studio plugins work the same way. Keeps everything compatible. – Visual Micro Jun 28 '15 at 13:49
7

This issue was solved in the Arduino 1.6.6 release. The release notes of 1.6.6 mention that library to library dependencies have been fixed.

Library to library dependencies: when your sketch imports a library, and that library uses another, the IDE will find out without you having to add a useless #include to your sketch

Updating your version to 1.6.6 or newer will resolve your problem.

agakshat
  • 176
  • 3
  • 7
4

Using the Arduino environement, as I understand it, you cannot access your own library from another of your own libraries. There is no way to add paths, so there is simply no way for the compiler to find the code. That makes it hard to write libraries that use code in another of your libraries. My web research indicates this has been a problem for years but to my knowledge has not been solved. I suspect there are difficulties in the implementation details or perhaps a desire to keep the system simple at the expense of capability.

Of course, you can always cut and paste code into each new library, but that's exceedingly sub-optimal. You can also write one huge library with all of your code in one pair of .h and .cpp files. That's also not very satisfactory, but I've done it on occasion.

There is a work around, however, for using standard Arduino libraries in your own library that you're placing in your sketchbook/libraries directory. Since sketches include paths to the standard library locations, and link the standard library code, you can include the header file for the standard library of interest in your sketch. Below that, also in your sketch, include your own library header file. The standard library will then become available to your library as well as to your sketch.

Pete Carter
  • 2,691
  • 3
  • 23
  • 34
Tim Egbert
  • 41
  • 1
1

Not recommended method: It is possible to add basically any external library code to Arduino IDE build by knifing boards.txt file. Headers in c/cpp flags and libraries in ld flags. This may be useful for library dev using external tools (cmake/QT creator for me today).

I modified /home/pekka/arduino-1.8.5/hardware/teensy/avr/boards.txt by adding "/coderoot" to gcc include path and E_OS_arduino define, modified lines below:

teensy36.build.flags.cpp=-fno-exceptions -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -I/coderoot -DE_OS_arduino

teensy36.build.flags.c=-I/coderoot -DE_OS_arduino