Where to put my header file

If I create a header file called "f1.h" with useful stuff I want to use in lots of sketches
and I intend to use it by coding "#include <f1.h>" in each sketch that uses it, where do I put the header file so the compiler will find it?
Thanks --Ray

Put it here:

<Sketchbook location>
|_ libraries
   |_ f1
      |_ f1.h

(where <Sketchbook location> is the path shown in the Arduino IDE at File > Preferences > Sketchbook location)

Notes:


The f1 folder can be named anything you like.

The Arduino build system does use the match between the header file name (f1.h in this case) and the folder name (f1 in this example) to determine while library is used when multiple libraries contain a file matching the #include directive, so it is best practices for the folder name to match the header file name. But in most cases there is only one library that matches, or if there are multiple the Arduino picks the right one, so it's not something to worry about too much if some other folder name seems more appropriate to you.


There is an alternative "recursive layout" for libraries:

<Sketchbook location>
|_ libraries
   |_ f1
      |_ library.properties
      |_ src
         |_ f1.h

You can learn about it here:
https://arduino.github.io/arduino-cli/latest/library-specification

Thank you for this answer to my question.
Just so I'm clear; when you wrote "determine while library", did you mean
"which" instead of "while"?
When I first read your reply, I couldn't quite grasp it.

Your answer is very well constructed (it's one of the better ones).
I also used the link you provided and spent some time wandering around in that world -- it's very involved. I had no idea how finely parameterized the Arduino build system is.

The reason I asked the question was this: I originally thought any header file I wanted to create would be placed in the "libraries" directory of the sketch directory (i.e. at the root level of the directory -- NOT in some subdirectory). I was quite surprised when the header file I put there was NOT found! I did some experimenting since your reply and now I'm under the impression that I can have a single directory subordinate to "libraries" (perhaps called 'util') and in that directory I can place all the header files I wish to create for my work and any sketch I develop will simply contain an include directive specifying the header file name (as in "cmds.h") and as long as I place the header file ("cmds.h") in the 'util' directory (in my example), the compiler will find it! Whew -- that was a lot.

In addition, it didn't seem to matter whether I enclosed the header file name in QUOTES or angle-brackets! That ran counter to my experience.

Again, thanks for a well written response.
Ray

Correct. It should have been "determine which library".

I apologize for the confusion.

I need to get into the habit of doing a careful proof read of my posts before submitting them. I get overwhelmed because so many people are asking for help here, and this makes me cut corners, but quality is more important than quantity.

That is correct. Each of the folders under libraries is considered a "library" by the Arduino build system. The library can contain as many header files as you like.

You should be aware that all the .cpp or .c files you put in a library are compiled when that library is used in your sketch program. So having a single monolithic library folder for unrelated utilities might not be as suitable if you start moving code out of header files and into source files.

The quotes syntax will cause the build system to first look for the file in the local path. If the file is not found there, it will then search the include paths and library folders for the file.

The angle brackets syntax will only search the include paths and library folders for the file. The local path is not used.

So this means that in most cases you can use quotes in place of angle brackets. The only time it always mandatory to use a specific syntax is when the file is in the local path and that local path is not in a global search location. In this case, only the quotes syntax will work.

However, I do recommend using the most appropriate syntax. Even when either will work, the syntax can communicate the intent of the code to the reader, making it more self documenting. It especially drives me crazy when I see developers mixing the two syntaxes at random in the same code base.

There are also cases where inappropriate syntax works in one context, but not in another. The most common example is this thing you will see in a lot of Arduino libraries:

Foo.cpp:

#include <Foo.h>

If you have a library like this:

<Sketchbook location>
|_ libraries
   |_ Foo
      |_ Foo.cpp
      |_ Foo.h

even though angle brackets were not the most appropriate syntax for a local file, it still works fine because <Sketchbook location>/libraries/Foo is in the include search path.

However, libraries can also be bundled under the src subfolder of an Arduino sketch, which is useful to create a self contained program with all library dependencies:

MySketch.ino:

#include "src/Foo/Foo.h

[...]

will work with this sketch structure:

MySketch
|_ MySketch.ino
|_ src
   |_ Foo
      |_ Foo.cpp
      |_ Foo.h

But now you get bitten by the sloppiness of the developer of the Foo library because their use of angle brackets does not work in this context where the library is not in the include search path.

Thanks again for this clearly explained 'intro' to the compiler's include processing.
At this point, my development needs are so basic, I'll be able to just stick with a single directory in the sketch directory where I can place the header files I'll be creating.
Thanks again;
Ray

You are welcome. Enjoy!