Include statement for static library dependency in a static library - c

In my application I use a static library with header file foo.h
In my build script I use a gcc -I flag -I./lib.
The foo library is in a directory ./lib/foo. In my main application I include foo.h as
#include "foo/foo.h"
Now I'm refactoring part of my application as a library, bar, that I expect to statically link to another application. This library bar depends on foo. With my current project layout, I could include foo in bar as
#include "foo/foo.h"
However, that would force users of bar to place foo in a directory called foo.
Is the standard thing to do in this case the following?
Add an -I flag to the build script that allows including foo in bar with just
#include "foo.h"

The reason for using folder structures with include files is to prevent collisions with header files of the same name. For instance, lets say I am using a library for encryption, and they have a header file called "status.h". At the same time I want to use a messaging library, and they have also have a header file named "status.h". They cannot coexist in the same directory and if you make the directory an include path it may not know which one you want to include. If you keep them seperate you can include both:
#include "encryption/status.h"
#include "messaging/status.h"
So the answer to your question depends on how likely you think the name of the include files will conflict with other include files of other libraries. If it will never conflict then what you are suggesting is fine. If it will conflict them make them use the directory.
Happy coding!

Related

Include Files in Segger Embedded Studio

I am just starting out with Segger Embedded Studio. Right now trying to call a function of a included header file. The file seems to be included since it shows up in the dependencies. For now I simply included the header and C-File in the project directory.
The included Header- and C-Files are simply:
//##### Header-File ######
#ifndef TEST_H_
#define TEST_H_
void printText(void);
#endif //TEST_H_
and:
//###### C-File #########
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
void printText(void)
{
printf("Hello");
}
But when I try to call the printText Function in my main I get the error:
"Undefined Symbol: printText".
Why is the function not recognized?
"Undefined symbol" is a linker error. You are not linking the object code containing the definition of printText().
It is not an issue with the header file; including a header file does not cause the associated code to be linked - that is just the declaration so the compiler knows what the interface looks like. It is the linker than combines the separately compiled object code to form a program. You have not told the linker to use the object code containing printText(), and you have not told your IDE project to compile it to generate that object code.
The project tree clearly shows that only main.c is included in your project; you need to add the C file containing printText() too.
The concept of separate compilation and linking is what you need to grasp here.
Thank you Clifford for your answer. You are right I had some miss-conceptions about which files will be linked while building the project. In the special case of segger embedded studio there are, as I know by now, two ways to reference extern files.
Adding the files to the sources files folder is straight forward, but must be done separately for each project you want to use the respective files.
For frequently used files it is beneficial to create a dedicated library solution. Such a library can then be imported to any solution by choosing "add existing project". This will add all files of the library to your current solution (and show them in the project-tree). Now click the tab project -> dependencies. Your library should show up here. By acitivating the check box the linker will compile the referenced project upon builing your solution, allowing for the usage of your library functions.
Adding and linking library-project to a current solution

Should paths of #include in the C file and the -I directive given to GCC match?

I am looking at FreeRTOS demo project for an AVR port. The Makefile has paths to the directories where the source files of RTOS are located through an "-I" directive. However, in the main.c module of the project #include does not provide any path like this:
#include "FreeRTOS.h"
So I am not able to understand is that is the "-I" directive required only for linker to find the object files? Does it also mean that once the files are compiled to object code, for GCC they are essentially lying in the same folder if it knows where to look?
I have this confusion because I have seen #include statements like these previously:
#include <avr/io.h>
If GCC already knows the location of io.h why include the "avr" part in front of it?
When we say
#include <foo/bar.h>
the compiler usually looks for a file called bar.h in a directory called foo in one of the places it is configured to look for headers. For example, the standard header search path usually contains `/usr/include', so a file 'bar.h' will be found, if it exists, in '/usr/include/foo'.
If you use the -I switch like this:
-I /usr/include/foo
you could alternatively write
#include <bar.h>
because you've subsumed the directory foo into the compiler's header search path.
However, if foo is some kind of library or module, it's probably more expressive to use a variant of #include that includes the subdirectory foo, rather than manipulating the header search path so that you don't have to.
For the record, the -I switch has no direct effect on linking behaviour.
Incidentally, the variant
#include "foo/bar.h"
conventionally indicated a file in a directory foo in the same directory as the source file. However, modern compilers seem to apply search header paths to these directives as well. I'm not sure whether this is standards-based behaviour, or just compiler writers trying to guess our intentions.

How to organize header files in a library

Say I am writing a small libary in C, with most of the source code in two folders src/A and src/B, and where the header file src/A/a.h needs to include src/B/b.h. When writing code for a non-library project, I usually write
#include "B/b.h"
in a.h and use the -Isrc flag to tell the compiler where to look for header files.
Now suppose that my library is installed locally at ~/mylib and that I want to use functions from a.h from a different project. Simply including that file using
#include "~/mylib/src/A/a.h"
would not work, because ~/mylib/src/B/b.h might not be part in the search path. My question is about the canonical way to solve this issue. It's probably quite basic, but I haven't done any advanced programming in C and have been unsuccessful in my attemps to find a solution online.
Possible solutions I thought of are the following:
Add ~/mylib to the search path, but that might lead to problems if the library and client projects have header files with the same name (say src/helpers.h). Is it possible to include one header file without cluttering the search space with files I won't need?
Use relative paths in the library header files, but that doesn't feel very robust.
Thank you.
The normal approach is to have a separate directory specifically for the headers which form the public interface of your library. Usually this directory would be called 'include'.
You would then place the public headers for your library under a library-specific directory in there, i.e. "mylib/include/mylib/b.h". This extra 'mylib' directory prevents clashes if you're using some other library that also has a "b.h". You can also, if you wish, keep other private headers, which do not form the public interface of your library, under the 'src' directory instead, to stop them being exposed to users of the library.
This means a user of the library can then use "-I mylib/include" to include this directory, and include the individual files with, for example, "#include "mylib/b.h".
Why aren't you using the standard implementation? Break out into header and source files into their own directories. Add #define headers to avoid multiple includes or namespace corruption.
Here is your directory structure:
~/mylib/headers/a.h
b.h
~/mylib/src/a.c
b.c
Now a.h will have at the very top of the file...
#ifndef __A_H__
#define __A_H__
// code
#include "~/mylib/headers/b.h"
// end of file
#endif
Now b.h will have at the very top of the file...
#ifndef __B_H__
#define __B_H__
// code
// end of file
#endif
Then just compile. gcc -I~/mylib/headers
If you have 2 helpers.h just change the #define __HELPERS_H__ in one of the files to something else like #define __HELPERS2_H__

Distribution and Linking of C Header Files and Libraries

I am brand new to C programming (but not programming) and am trying to understand how libraries and header files work together, particularly with respect to packaging and distribution.
After reading this excellent question and its answer, I understand that the header file(s) act as the API to a library, exposing capabilities to the outside world; and that the library itself is the implementation of those capabilities.
However one thing that I cannot seem to find a good explanation of is: how are header files packaged into or distributed with the libraries?
Are the libs and their headers packaged into an archive (zip, tarball, etc.)?
Are headers compiled into libs and distributed alongside them?
When I do a #include "mylib.h", how does the linker know where to find:
the header file itself, mylib.h
the library implementing the functions declared in mylib.h.
how does the linker know where to find: (1) the header file itself, mylib.h
With a notation like #include <mylib.h>, it searches the header file in the system defined include PATH.
With a notation like #include "mylib.h", it searches the header file in the system defined include PATH and in the current directory.
if the header file is present in some other hierarchy, you can provide the path to get the header file with -I option with gcc.
(2) the library implementing mylib.h?
You need to provide the path to the library using -L (in case of non-standard path to the library) and link the library using -l option.
As per the convention, if the (shared) library is named libmylib.so, you can use -lmylib to link to that directory.
For example , consider the pow() function.
It is prototyped in math.h, so in your source file, you need to add #include <math.h> to get the function declaration.
Then, at compile (rather, linking) time, you need to link it with the "math" library using -lm to get the function definition.

How to include custom .h files in /usr/include

I have some custom .h files placed under /usr/include, but in a directory (/usr/include/itsmag1c), and I'm trying to include them in my C file. I'm guessing that because I use
#include "filename.h";
for files in the same directory, and I would use angle brackets for including a file like math.h or stdio.h. Am I right in guessing that I would use the angle brackets for including my custom header files? If so, my program wont compile, I get the error that the included files cannot be found. Can someone please point to me how I would include these files, or would it be best to have them in the same directory as my program?
Two choices:
Use #include <itsmagic1c/filename.h>
Use #include <filename.h> as before but add a -I switch.
Boost etc use method 1. (which works well provided you have Boost installed in system locations as you would on a reasonably standard Linux box with reasonable package management).
Method 2. is fine too, but more work on the build system, Makefiles, etc.
Usually, you would put your own headers in the same directory or in a subdirectory. Same-dir includes work with "". For bracket includes, if you use gcc, you can pass additional include directories with
-Irelativedir
or
-I/usr/local/yourpath.

Resources