46
votes

I know that you are supposed to place any external libraries under the "libraries" folder of the arduino install directory, but I have a project that uses several libraries that I have created for the project and mainly to keep all that code self contained and out of the main pde file. However, I have tried to place the libraries in the same directory as the main PDE file so that I can more easily keep everything synced up in subversion (I work on this on multiple computers) and I don't want to have to keep going back and syncing up the libraries separately. Also, just for the sake of being able to easily zip of the sketch folder and know that it contains everything it needs.

I've tried adding the header files to the sketch as a new tab, but that doesn't seem to work at all... don't even care if they should up in the arduino IDE.

I've also tried adding the libraries to the sketch directory in subdirectories (what I would greatly prefer) and then linking to them as:

#include "mylib/mylib.h"

and

#include <mylib/mylib.h>

But both of these result in file not found errors.

Is this possible? And, if so, how do I include them in the main file for building? Preferably in their own subdirectories.

10
Partial solution here using macros: arduino.stackexchange.com/a/9575/6697jjz

10 Answers

18
votes

I had the same issue. Solved it for Arduino IDE > 1.8. Seems a specialty in newer IDEs (?) according to the reference (see bottom link).

You have to add a "src" Subdirectory before creating a library folder. So essentially your project should look like this:

/SketchDir (with *.ino file)  
/SketchDir/src  
/SketchDir/src/yourLib (with .h and .cpp file)  

and finally in your sketch you reference:

#include "src/yourLib/yourLib.h"  

otherwise in my case - if I am missing the "src" folder - I get the error message that it cannot find the yourLib.cpp file.

Note: I am using a windows system in case it differs and actually VS Code as wrapper for Arduino IDE. But both IDE compile it with this structure.

References: https://forum.arduino.cc/index.php?topic=445230.0

9
votes

For the sketches I have, the "*.h" and "*.cpp" library files actually reside in the same folder as the sketch, and I call them like "someheader.h". I also noticed that if I go into sketch menu and add file... that the file doesn't appear until I close and reopen the sketch.

8
votes

I agree with you; this is an intolerable way to develop software: it requires every file that you need to be in the same directory as the main program!

To get around this, I use make to put together a single .h file from my .h and .cpp sources - you can see this used in this Makefile:

PREPROCESS=gcc -E -C -x c -iquote ./src
# -E : Stop after preprocessing.
# -C : Don't discard comments.
# -x c : Treat the file as C code.
# -iquote ./src : Use ./src for the non-system include path.

TARGETS=sketches/morse/morse.h

all: $(TARGETS)

clean:
    rm $(TARGETS)

%.h: %.h.in
    $(PREPROCESS) $< -o $@

Arduino is very picky about file endings - if you put a .cpp or .cc file in its directory it automatically uses it in the source, and you can't include anything that's not a .cpp, .cc or .h - so this is about the only way to do it.

I use a similar trick also to put together JavaScript files here.

This requires that you run make after editing your files, but since I'm using an external editor (Emacs) anyway, this is zero hassle for me.

4
votes

Unfortunately the Arduino IDE is awful and shows no signs of improving. There is no real build system so it only lets you build programs that reside in a single directory.

The only real solution is to write a makefile, then you can use a real IDE. I'm hopeful that one day someone will write an Arduino plugin for QtCreator.

Here's an example makefile:

http://volker.top.geek.nz/arduino/Makefile-Arduino-v1.8

3
votes

I just had this same problem (I also like to keep the code self-contained), so I'll just jot down some notes; say I have a MyPdeSketch.pde using MyLibClass.cpp; then I have it organized like this

/path/to/skdir/MyPdeSketch/MyPdeSketch.pde
/path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.cpp
/path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.h

(In principle, /path/to/skdir/ here is equivalent to ~/sketchbook/)

 

What worked for me is something like:

mkdir /path/to/arduino-0022/libraries/MyLibClass
ln -s /path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.* /path/to/arduino-0022/libraries/MyLibClass/

After restart of the IDE, MyLibClass should show under ''Sketch/Import Library''.

Note that the only way I can see so far for a library class file to refer to other library files is to include them relatively (from 'current location'), assuming they are all in the same main arduino-0022/libraries folder (possibly related Stack Overflow question: Is it possible to include a library from another library using the Arduino IDE?).

Otherwise, it should also be possible to symlink the MyLibClass directory directly into arduino-0022/libraries (instead of manually making a directory, and then symlinking the files). For the same reason, symlinking to the alternate location ~/sketchbook/libraries could also be problematic.

Finally, a possibly better organization could be:

/path/to/skdir/MyLibClass/MyLibClass.cpp
/path/to/skdir/MyLibClass/MyLibClass.h
/path/to/skdir/MyLibClass/MyPdeSketch/MyPdeSketch.pde

... which, after symlinking to libraries, would force MyPdeSketch to show under the examples for the MyLibClass library in Arduino IDE (however, it may not be applicable if you want to self-contain multiple class folders under a single directory).

EDIT: or just use a Makefile - which would work directly with avr-gcc, bypassing the Arduino IDE (in which case, the sketchbook file organization can be somewhat loosened)..

1
votes

Think I know what do u need exactly.

you have a project folder say MYPROJ_FOLDER and you want to include a Libraries folder that contains more children folders for your custom libraries.

you need to do the following: 1- create folders as follows:

-MyProjFolder
-MyProjFolder/MyProjFolder        

and then create a file with the folder name in .ino extension -MyProjFolder/MyProjFolder/MyProjFolder.ino

2- create libraries folder: -MyProjFolder/libraries <<<<< name is not an option should be called like that.

3- then create your own libraries -MyProjFolder/libraries/lib1 -MyProjFolder/libraries/lib1/lib1.cpp -MyProjFolder/libraries/lib1/examples <<<< this is a folder -MyProjFolder/libraries/lib1/examples/example1

repeat step 3 as much as you want

also check http://arduino.cc/en/Guide/Libraries

1
votes

What has worked for me is to create a dir, for example "src" under the sketch dir, and under that a dir for each personal library.

Example:

I have a project called ObstacleRobot, under that a folder for my sketch, named obstaclerobot (automatically created by the IDE) and there my sketch "obstacleRobot.ino"

Up to now we have:

 /ObstacleRobot
    /obstaclerobot
       obstacleRobot.ino

Then I wanted to include a personal library that was fully related with this project and made no sense in including it in the IDE libraries, well in fact I want to do this for each part of the robot but I'm still working on it.

What in the end worked for me was:

 /ObstacleRobot
    /obstaclerobot
       obstacleRobot.ino
       /src
          /Sonar
             Sonar.h
             Sonar.cpp

Then what you have to do in the main sketch is to write the include as follows:

#include "src/Sonar/Sonar.h"

And thats all.

0
votes

I did it a little differently. Here is my setup.

Visually this is the directory layout

~/Arduino/Testy_app/  <- sketch dir
                   /Testy_app.ino <- has a #include "foo.h"
                   /foo           <- a git repo
                   /foo/foo.h
                   /foo/foo.cpp

Here is how I build:

~/Arduino/Testy_App/$ arduino-cli compile --library "/home/davis/Arduino/Testy_app/foo/" --fqbn arduino:samd:mkrwan1310  Testy_app

If you wish to be more elaborate and specify libs and src dirs, this also works

~/Arduino/Testy_app/  <- sketch dir
                   /Testy_app.ino <- has a #include "foo.h"
                   /lib           <- a git repo
                   /lib/foo/src/foo.h
                   /lib/foo/src/foo.cpp

and the build method is:

~/Arduino/Testy_App/$ arduino-cli compile --library "/home/davis/Arduino/Testy_app/lib/foo/src" --fqbn arduino:samd:mkrwan1310  Testy_app

One more bit of tweaking needs to be done to include files from the lib dirs to main dir. If you need to do that, this is the work around:

~/Arduino/Testy_app/  <- sketch dir
                   /Testy_app.ino <- has a #include 
"foo.h"
                   /inc/Testy_app.h
                   /foo           <- a git repo
                   /foo/foo.h
                   /foo/foo.cpp   < has a "include testy_app.h"

Then do the compile like this

~/Arduino/Testy_App/$ arduino-cli compile \
--library "/home/davis/Arduino/Testy_app/inc" \ 
--library "/home/davis/Arduino/Testy_app/foo/src" \ 
--fqbn arduino:samd:mkrwan1310  Testy_app
-1
votes

Following the lines of Hefny, make your project an example for your library.

For example (Unix env), let's say the libraries are in ~arduino/libraries

Your create your project ~arduino/libraries/MyProject, your libraries go there (for example ~/arduino/libraries/MyProject/module1.h ~/arduino/libraries/MyProject/module1.cpp ~/arduino/libraries/MyProject/module2.h ~/arduino/libraries/MyProject/module2.cpp

Now: mkdir -p ~arduino/libraries/MyProject/examples/myproj

edit ~arduino/libraries/MyProject/examples/myproj/myproj.ino (note that this is not examples/myproj.ino but examples/myproj/myproj.ino)

Restart the IDE, you should find your project in the menu File/Example/MyProject.

Also note that you do the include with #include

-3
votes

Why dont we just write a script with a single copy command, copying our libs from wherever our library is located into the arduino IDE library folder?

This way we keep the file structure we want and use the IDE library requirements without fuss.

Something like this works for me:

cp -r mylibs/* ~/Documents/programs/arduino-1.5.8/libraries/.

Note that the paths are relative to my own file structure.

Hope this helps someone. This includes my future self that I bet will be reading this in a near future... as usual!

J