Linking against C files in Libraries

I've just begun using arduino-0010 on a MacBook Pro with 0S 10.4.11.

I'm tring to add a library in /Applications/arduino-0010/hardware/libraries. To test, I created a directory "myfoo" there, and put simple myfoo.c and myfoo.h files in there. I added #include <myfoo.h> to the top of my sketch. But when I try to call the function I defined, I get an undefined reference error. If I change the name of myfoo.c to myfoo.cpp (and delete the .o file - shouldn't arduino be able to see that the sources have changed and recompile automatically?) it works. How do I include a .c file without changing its name to .cpp? The documentation on this web page: Redirecting says that libraries can include .c or .cpp files.

More generally, is there a way to explicitly add paths/files to link against?

thanks.

THis isn't an answer to your question, but why not just change the name to .cpp? C++ is a superset of C, so if it's C it's also C++.

If it's an actual library, it won't be a .o file - it'll be libsomething.a instead of something.o.

-j

I have assumed from the library documentation that a library must be declared as a class and therefore there must be at least one cpp file, although any .c files used by that class would also get compiled.

However the tutorial documentation doesn't say that explicitly so I may be wrong.

Anyway, you can copy your .c and .h files to the sketch directory and they will appear as tabs in the IDE and be compiled and linked as part of the sketch. Or you could create a C++ wrapper classs for your C functions.

Yes, I could obviously just rename my files as .cpp or wrap them in a .cpp file. It just seems a bit strange since the compiler knows to generate the object file from the .c yet fails when it tries to wrap it in. I was more curious to know what's going on under the hood that causes the problem, and am admittedly a bit too lazy to dig into the source if someone knows the answer offhand.

Copying .c files into the sketch directory wouldn't be very convenient for libraries that you'd want to reuse over and over.

As for .a files, I was using the word "library" in the arduino sense, not the C sense. Arduino seems to generate .o files from all of the "libraries" that came with arduino. The only .a file I see is core.a, which contains the objects generated from the hardware/cores/arduino directory and seems to include the essential bits of i/o functionality. I'm not sure why else you'd want to wrap up a bunch of object files into a library for a microcontroller since this would probably just hog program memory with unused instructions. I think Arduino is right in this respect to keep "libraries" as self-contained units rather than wrapping them up into big archives.

On this note, I just noticed something potentially wasteful if not seriously problematic in this regard: If I have 2 libraries with the same header file in them (i.e. if I wanted to use some custom typedefs in a bunch of my own libraries) and I include that header file and only one of the libraries in my sketch, the compiler seems to seek out all instances of the header file in subdirectories of hardware/libraries and compile in the contents of all of them!

This leads back to the second half of my original question: rather than have the compiler try to be too smart, I'd like to just put my common header files somewhere and add the include path and/or precompile some object files to wrap in when I build.

Having .c files (w/ or w/o .cpp files) in a library should work. The only tricky thing is that the main sketch file is compiled as C++, so you need to wrap the library's function declarations in an extern "C" block. For example (in foo.h):

#ifdef __cplusplus
extern "C" {
#endif

void foo(int pin);

#ifdef __cplusplus
}
#endif

This is, as far as I know, standard practice for C functions that you want to use from C++. In theory, you could also put the extern "C" statements around the #include in your sketch, but this won't work in Arduino because the pre-processor lifts #include's to the top of the sketch.

Also, note that you need to delete the .o file to get Arduino to recompile the corresponding .c or .cpp file.

As for the header file that you'd like to use from multiple libraries: I'm hoping to add support for library dependencies soon. That would allow you to create a separate library with the functionality that you'd like to share across your other libraries.

Also, I'm hoping to write an advanced library writing tutorial soon, this kind of thing will go in there.

Great, thanks for clearing that up! The tutorial would be very helpful.

Am I correct about the way that the compiler is searching the libraries directory for all instances of a header file? This might not be sustainable in the long run for a project where community users are contributing and installing their own/each other's libraries with possibly overlapping names and functionalities.

My 2 cents: As a long-time user/contributor to Pd, I can tell you that this is a big problem that is now harder to deal with in retrospect, with thousands of external libraries already written. And Arduino is much more susceptible to this problem as user-contributed libraries potentially step on each other's and Arduino's usage of microcontroller resources in addition to names (e.g. implementing interrupt vectors). Not to mention that libraries will also inevitably be tied to different microcontrollers as the Arduino platform expands and technologies change. I'm not sure if any other open projects have better strategies deal with this kind of thing, but it's worth a good amount of healthy debate now, while Arduino is still quite young.

If you have any ideas about how to handle this feel free to post them here or on the developers mailing list. There are a bunch of goals and it's hard to achieve them all. For example, the libraries used by a sketch should be defined by that sketch's code (so if you post example code on your website, you don't need a separate description of which libraries to link against). Also, the problem with having any sort of "expert" mode in which you provide explicit instructions to the compiler is that very quickly everything requires that expert mode (and there's no more simple mode).

Maybe we should require that each library provide a header file whose name is the same as the library, and then only include that header file in the sketch? And then people just need to pick distinctive names for their libraries?

This is definitely something worth discussing.

Having .c files (w/ or w/o .cpp files) in a library should work.

I am quite surprised that a library does not need to be a C++ class :o
I was convinced that a C++ class was required because there seemed no other reason why the tutorial would describe converting C functions into a C++ class. This was reinforced by noting that all the arduino libraries included in the distro are C++ classes.

I wonder if a non C++ library is a hidden capability because of concerns about potential name collision in C libraries. If so, then perhaps you could recommend and demonstrate the use of C++ namespaces around C libraries functions to reduce this problem.

But FWIW my own personal view would be to recommend that all libraries posted for general reuse should be wrapped in a class because this discourages implementations that rely on global data.

The reason for preferring C++ libraries to C ones is mostly an aesthetic / design issue. We like the syntax for user sketches to look more like:

Stepper stepper(9, 10);
//...
stepper.step(20);

and less like:

stepper_step(9, 10, 20);

It just seems to make things feel a bit simpler.