calling a function from a library not in \libraries

Hi all,

I'm trying to test a library that I am developing for another microcontroller with an Ardunio Due.

So basically, in my .ino file I have an include that is like #include "c:\some_long_path\header.h" (it is encolosed in a extern "C" { }).

If I use some structure declared with a typedef in the header.h, I have no problem.
But if I try to call a function declared in the .h and defined in his .c, I get a undefined reference for this function.

But if I try to put the .c and .h in the same folder of my .ino file ( or in the \libraries folder as well), it works.

If I put an inline function inside my .h, it works.

So, I understand that the compiler is not including my .c into his compilation process so the linker cannot find the reference to my function.

There is a way to use function from a .c not in the \library folder?

moving my file to the \libraries folder for sure is an option, but I have some dependencies inside my .h and it will be a little painful to adapt everything.

thank you

But if I try to call a function declared in the .h and defined in his .c, I get a undefined reference for this function.

how is this function defined ? as extern?

J-M-L:
how is this function defined ? as extern?

Yes, I tried marking it as extern, but no luck; I know, or better I think, that every function with his prototype defined in a .h is marked by the compiler as extern.
well, maybe I just need to call the compiler from command line adding some options or looking for a makefile.

So basically, in my .ino file I have an include that is like #include "c:\some_long_path\header.h" (it is encolosed in a extern "C" { }).

Why on earth is it in some_long_path and not where it should be for Arduino?

And why enclose it in extern "C"?

septillion:
Why on earth is it in some_long_path and not where it should be for Arduino?

What does that matter?

I’m a great believer in some_long_path

…R

Sorry, I’m not. If you want the simplicity of the Arduino IDE, stick to the simplicity of the Arduino iDE :slight_smile: So put the library or next to the sketch or in the libraries folder.

Robin2:
What does that matter?

I'm a great believer in some_long_path

...R

lol

well, I'm doing that because I want to test some function which are part of code of another project and it is located in this some_long_path.

I'm pretty sure I need to use a makefile, I've took a look at preferences.txt but is quite tricky to add sources file to be compiled.

Note: I'm really new to Arduino, so I barely know the rules beyond the compiling/linking process.

I confess that, apart from .ino files I have only put my code into .h files and I have had no trouble accessing them using full path names as you are doing. In some cases I did find it necessary to include function prototypes at the top of the .h file for the functions that it contains.

I'm sure this is utter heresy in the eyes of people who are C/C++ experts.

...R

Thing is, all source files are compiled separate and form the base of the code. And even source files you don't use but is in the compile path are compiled. All header files are just descriptions of what to expect in the source file and are just included to tell the code what will be available. And normally that's done in two places, the source file itself which contains the implementation of it. And the code that wants to access it to tell it how to interface the external source code.

So if you include some header file in some directory which is not included in the path to compile, the source file are not compiled because the compiler has no notion of them. But the header file is found and include but normally does not contain the implementation, just the interface to it :slight_smile:

Aka, put the library in a place that is included in the compilation by the Arduino IDE. So in the project folder or in theuser libraries folder in your Sketchbook (Default c:\Users[user]\Documents\Arduino\libraries)

septillion:
So if you include some header file in some directory which is not included in the path to compile, the source file are not compiled because the compiler has no notion of them. But the header file is found and include but normally does not contain the implementation, just the interface to it :slight_smile:

Maybe there should also be a #include for the .c files?

All of this is because the Arduino IDE copies your code to another location before it tries to compile it so all references are relative to the place where the Arduino IDE has copied the code.

Maybe if all the files are put into the same directory as the .ino file things will work?

...R

Robin2:
Maybe if all the files are put into the same directory as the .ino file things will work?

Agreed, the IDE wants to work the way the IDE wants to work. Not very flexible. I often put additional .cpp and .h files in the same folder as the .ino file. I believe in partitioning my projects and ruthlessly limiting variable and function scope as much as possible. The file-level scope control that multiple files provides helps a lot. But, I never have multiple .ino files in a folder. The IDE just smashes them all together before compiling anyway. No added in value in this, stupid feature.

Finally, even if your extra files are only ‘C’ code, put the code in .cpp files anyway. That way you don’t have to jump through any additional IDE hoops to get them to compile. ‘C’ is a subset of ‘C++’ anyway.

Robin2:
Maybe there should also be a #include for the .c files?

That might actually work, as long as you only put the #include in one spot in one .ino file, and not in a header.

The #include directive is just a text insertion. It basically says "Take the text of this file, and put it in this spot before sending this off to the compiler". There is nothing restricting #include to work only with .h files, it can be used with any text file.

All of this is because the Arduino IDE copies your code to another location before it tries to compile it so all references are relative to the place where the Arduino IDE has copied the code.

This isn't really an Arduino-specific issue. No matter what IDE or toolchain you use, it needs to know what files to send to the compiler. Whether that's tracked in a manually curated makefile or your IDE keeps track of them in a project file, you need those files listed somewhere. In most IDEs you can add references to external files in your project file so it can add them to the makefile it generates, but that still requires you to tell the IDE about those external source files. If you just #include random headers without adding a reference to their corresponding source files, your project won't build properly. I've used about 3 different C++ IDEs to make small desktop programs (Qt, Bloodshed Dev-C++, and Falcon C++), and they've all worked roughly the same way.

The Arduino IDE doesn't let you add references to external files, so you have to either put the source files in a place that the Arduino IDE looks for them (the libraries folder or the sketch folder), or #include the .c and .cpp files too.

I've done this before when I wanted to rewrite the whole structure of a small program I've written, but didn't want to get rid of the old one just yet and didn't want to create a separate project directory for it. The old main.cpp file becomes main_old.cpp, and I make a main_new.cpp that contains the new program. This in main.cpp I do this:

//#define __OLD

#ifdef __OLD
#include "main_old.cpp"
#else
#include "main_new.cpp"
#endif

That made it easy to change between the old and new behavior by just commenting or uncommenting the #define line and recompiling.

Maybe if all the files are put into the same directory as the .ino file things will work?

...R

That works too.

I don't think it's stupid, shouldn't related files/projects be together? And the Arduino IDE is not designed to be flexible, it's designed to be simple and not having to worry about make files is one of them. Just put the code in the project folder or in the libraries folder. I really don't see any need to place files in some random distant folder.

And I also disagree tabs in the IDE are useless. If you just start out you might not write the most compact code and it can give you some overview. Later you can learn about separate source files and headers and do it more efficient that way :slight_smile:

And you can include a .c(pp) but then you are kind of loosing the nice separate structure of the code. Everything becomes a single file for the compiler so no separation of globals for example. It's just a big copy and insert.

Jiggy-Ninja:
This isn't really an Arduino-specific issue. No matter what IDE or toolchain you use, it needs to know what files to send to the compiler. Whether that's tracked in a manually curated makefile or your IDE keeps track of them in a project file, you need those files listed somewhere. In most IDEs you can add references to external files in your project file so it can add them to the makefile it generates, but that still requires you to tell the IDE about those external source files

Thanks. I stand corrected.

I had been assuming that other systems would automatically look for the ,c file in the same place it was told to find the .h file. (Shows that I never use "proper" C/C++)

...R

If you put your library files in development in the project folder with the ino then open them in IDE tabs and #include the header files in the ino, as #include "mylib.h"

Your sketch will use those files.
Changes you make in the tabs will be saved to them.
You won't need no steenking path.

When you're done developing is the time to move them to a libraries folder.

I have done this many times already, it works.

@septillion, you missed (or ignored) my point. Multiple tabs are good if they are .h or .cpp files. It’s stupid /useless when they are multiple .ino files. The whole point is to increase modularity and limit scope. Having multiple .ino files all mashed together (in alphabetical order) before compilation does neither of those.

GoForSmoke:
If you put your library files in development in the project folder with the ino then open them in IDE tabs and #include the header files in the ino, as #include "mylib.h"

Your sketch will use those files.
Changes you make in the tabs will be saved to them.
You won't need no steenking path.

When you're done developing is the time to move them to a libraries folder.

I have done this many times already, it works.

Agreed. But, you don’t have to limit this technique to just library code development. As a project grows you should always try to increase modularity and limit scope. Even if the additional .cpp and .h files can’t be used in any other project (the whole point of a library) they will still make THIS project easier to maintain.

Just don't have more than one .ino file in the project folder!

Robin2:
Thanks. I stand corrected.

I had been assuming that other systems would automatically look for the ,c file in the same place it was told to find the .h file. (Shows that I never use “proper” C/C++)

…R

Nope.

That is because there is no inherent coupling between a header and source file. It is true that usually there will be a .h file with all the declarations, and a .cpp file with the implementation, but that is not enforced. I have seen cases where the header file has prototypes for many classes and functions, but their implementation is is strewn among multiple source files.

For an Arduino example, look at the source files for the IRRemote library. There are only two header files, but the functions declared in those headers are spread among a dozen and a half cpp files. Most of that is because each IR protocol is implemented in a separate cpp file.

All of those cpp files need to be compiled individually, so they need to be known by your toolchain. The Arduino IDE has its process that it uses to look through library folders and automatically include all the files for each library you’re using. Or IDEs might need a reference to each individual file, or maybe you can tell it the folder path and it pulls in all the source files automatically. It’s up to the IDE what ways it has to enumerate source files.

It can’t just assume that if you #include IRRemote.h from some arbitrary location, it only needs to grab IRRemote.cpp from the same folder. Any one of the 18 other cpp files might be needed, or maybe the cpp file is in a different folder.

gfvalvo:
@septillion, you missed (or ignored) my point. Multiple tabs are good if they are .h or .cpp files. It’s stupid /useless when they are multiple .ino files. The whole point is to increase modularity and limit scope. Having multiple .ino files all mashed together (in alphabetical order) before compilation does neither of those.

I disagree. Partitioning for readability or organization is beneficial on its own, even if it provides no technical advantage.

Jiggy-Ninja:
I disagree. Partitioning for readability or organization is beneficial on its own, even if it provides no technical advantage.

So, if both techniques provide readability and organization, why not use the one that also provides MAINTAINABILITY as an advantage? Especially important as the project grows.

I found it easier/cleaner to make C++ classes for my projects using local .h and .cpp files.

Early on with Arduino I did try to work on library files in the libraries folder using the IDE include tool and every change went to copies in the local folder. It was a pain copying contents to the libraries folder files before every compile. The words were "bag this" and I haven't looked back since.

When I replace this PC I'll be able to run Atmel Studio. If I do a big enough (read: Real) project I just might.