Installing a C header on Linux/POSIX systems - c

I have a header foo.h with functions bar(), baz(), qux(). Where would I copy it/what would I have to do it so that I can include it in C programs like other systemwide headers, like stdio.h, unistd.h etc?

From the GCC documentation (I am assuming you are using GCC since you included the Linux tag):
2.3 Search Path
GCC looks in several different places for headers. On a normal Unix system, if you do not instruct it otherwise, it will look for headers requested with #include in:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
[...] In the above, target is the canonical name of the system GCC was configured to compile code for; often but not always the same as the canonical name of the system it runs on. version is the version of GCC in use.
So that mostly answers your question. But really, you probably shouldn't be putting non-system headers in places like /usr/include. Most of the time, it's best to keep the headers for your program in the include sub-directory for the project. Then tell GCC how to find those files like this:
You can add to this list with the -Idir command line option. All the directories named by -I are searched, in left-to-right order, before the default directories. The only exception is when dir is already searched by default. In this case, the option is ignored and the search order for system directories remains unchanged.
[...]
Also keep in mind the differences between #include "file.h" and #include <file.h>
GCC looks for headers requested with #include "file" first in the directory containing the current file, then in the directories as specified by -iquote options, then in the same places it would have looked for a header requested with angle brackets. For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.
[...]

Related

Is my understanding of C header files/gcc options related to these correct?

I am currently taking a class on C and I am baffled by gcc options a lot of the time, because the videos/documentation on the options are sparse and those that eixst are hard to understand(for idiots/non-technical majors like myself). Please consider the following scenario:
Lets say I have a header file, myHeader.h and main.c which would like to include myHeader.h. Assume they are in the same directory.
In main.c, I could write #include "myHeader.h". However, according to my professor the "" is permitted because gcc will check in the current directory for anything in the "". However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work. I am wondering what gcc commands would work, and why they work in specific. I would love any references(that aren't super nerdy) to better understand this.
So far, I researched on stackoverflow and on google, and it said something about -Idir gcc command, where dir is the directory you would like to add to the header file search path, but I am confused as to why this works or how to actually implement it. Since the "path" to myHeader.h is CStuff/workspace/myHeader.h I attempted to do gcc -I/CStuff/workspace/myHeader.h but this didn't really work out. I really thought it would take that directory and add it to the header file search path, but it just gave me an error.
I am a very confused business major so please take it easy on me! I really would love a dumbed-down explanation or a reference to a source that is more "basic" and has more than 1-2 sentences of explanation(if possible).
However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work.
If you want to add search path directory for system headers, there is -isystem <path>. For ordinary headers — which your header very likely is — there is -I <path>. This supports relative and absolute path formats.
To see which search paths GCC is using, add -v to the options:
> gcc main.c -v ...
...
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
There are more special options, see Directory-Options in the GCC documentation, if it comes to search order, for instance.
To see the outcome of including, i.e. the C-preprosessed file, use -save-temps and have a look at the preprocessed file *.i for C, *.ii for C++, *.s for assembly.
To also see built-in and explicit #define's values in preprocessed code, also add -H -g3.
In main.c, I could write #include "myHeader.h". However, according to my professor the "" is permitted because gcc will check in the current directory for anything in the "". However, where I am lost is when it comes to how I could add myHeader.h to the gcc header file search path such that #include <myHeader.h> would work.
As a preliminary matter, you are already lost when you conceive the idea that you should want to use that form for the private headers associated with your program. The <header.h> form is conventionally and best reserved for use with system headers. That is, exactly those that do not accompany the code being compiled.
That does not moot the question, however. Sometimes one might want to amend the header search path to help the compiler find headers distributed with the source code and referenced via the "header.h" form, too.
I am wondering what gcc commands would work, and why they work in specific. I would love any references(that aren't super nerdy) to better understand this.
You will not earn friends or respect here by eschewing technical references, nor by casting aspersions on those who do read such references. Technical documents can be hard reading at first, but reading and understanding them is a skill that you will need to cultivate if you want to enjoy success as a programmer.
So far, I researched on stackoverflow and on google, and it said
something about -Idir gcc command, where dir is the directory you
would like to add to the header file search path,
Good start.
but I am confused as
to why this works or how to actually implement it. Since the "path" to
myHeader.h is CStuff/workspace/myHeader.h I attempted to do gcc
-I/CStuff/workspace/myHeader.h but [...] it just gave me an error.
It is important to pay attention to details. You yourself wrote:
where dir is the directory you would like to add to the header file search path
(emphasis added). If /CStuff/workspace/myHeader.h is the header you want gcc to find, then that path is not the path of a directory. The directory is /CStuff/workspace, so -I/CStuff/workspace is a viable option.
Alternatively, for gcc runs in which the working directory is also /CStuff/workspace, you can refer to it by the name . (that is, use -I.). It is a general feature of Unix and Windows paths, not specific to gcc, that the . represents the current working directory.

gcc 5.3.0 for unix reports included c file not found despite it existing

I created a very simple hello world program in C and I'm trying to call a function from an included file. The problem is the gcc program is strange in how it recognizes files.
Suppose the main file is named a.c and the file I want to include is b.c
So in my headers, I add:
#include <./b.c>
and when I run gcc 5.3.0, I receive this error:
./a.c:xx:yy: fatal error: ./b.c: No such file or directory
compilation terminated.
(where xx is the line number of the include line and yy is where the > is located on that line.)
I also tried another idea. I executed gcc while including the library path as follows:
gcc -I./ a.c
and I still get the same error.
In all tests, the file b.c exists in the same folder as a.c is and that I execute gcc from.
Now If I change the include line in the source to the following:
#include </path/to/b.c>
(thereby replacing the relative path with an absolute path) and run gcc, the file is then read for processing.
Is there a way I can change my code so I don't have to constantly specify absolute paths if I need to include multiple custom C files that are all in the same folder as the code that references them?
Like... is there such thing as....
#setlibpath /path/to/my/c/files
#include <./item.c>
#include <./item2.c>
....
#include <./itemn.c>
or do I have to do this....
#include </path/to/my/c/files/item1.c>
#include </path/to/my/c/files/item2.c>
....
#include </path/to/my/c/files/itemn.c>
Converting my comments into an answer.
Use double quotes around the name and the header (source file) will be found. Use angle brackets around system headers. And generally, avoid using ./ (and ../ even more so) in header names. For GCC, see also Include Operation and the following sections.
Also see the POSIX specification for the c99 compiler for the -I option:
Change the algorithm for searching for headers whose names are not absolute pathnames to look in the directory named by the directory pathname before looking in the usual places. Thus, headers whose names are enclosed in double-quotes ("") shall be searched for first in the directory of the file with the #include line, then in directories named in -I options, and last in the usual places. For headers whose names are enclosed in angle brackets (<>), the header shall be searched for only in directories named in -I options and then in the usual places. Directories named in -I options shall be searched in the order specified. If the -I option is used to specify a directory that is one of the usual places searched by default, the results are unspecified.
Note that ./b.c is not an absolute pathname — so the name is appended to a set of directories, and the current directory is not used unless the #include line uses double quotes.

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.

New .h file in /usr/include linux

I developed small c application in linux. For this application i placed .h file in
linux standard path (/usr/include). Again i am compiling the same program
Output:
FATA ERROR : xyz.h(my own header file) not found
Do i need to update any variable in gcc or way to solve this problem
Thank You
Place the header file in the same directory as your .c file and use -I. when compiling
gcc -I. main.c -o myprog
You shouldn't place your header files in /usr/include that is meant for the system headers.
Note: you don't actually need the -I. because the current directory is searched by default, nevertheless, it doesn't hurt to add it.
Files specified by include directives are meant to be located in one of the search paths of the complier which are specified with the -I option in many cases (at least for gcc, is it the same for other compilers?). The search paths are verified in the order of definition in the command line.
There are 2 kinds of include directives:
double quoted ones (#include "xyz.h")
angle bracket ones (#include <xyz.h>)
IIRC, the default and first search path for the former is the working directory. For the later, it's compiler dependant, but it's usually /usr/include/.
Depending of the include directive you used, you should pick the right location for your file. Or better, put your file in a good location (say the same place as the including file), and add a search path to your gcc command.
You should separate your header .h files, from system and repository built headers so you don't break anything.
I would recommend making a folder in your home directory called include and just adding it to your path, that way you never have to worry about it again and no need for the -I/flag

Compiling a C prog winth unix syle header files in windows

well i have a few Cpp source and header files, and the header files have include statements in the form,
#include<include/config.h>
#include<include/controls.h>
the thing is im using gcc on windows and it says no such file or directory as the windows style paths has '/' and not '\' ,
so i changed the path to include\config.h but again, the problem is config.h has many header files included in it with the similar unix path style, and its not feasible to change the paths in all the header files cos its a library and there are 100s of such headers, is there any way to compile this using GCC (minGW) ??
Thanks :)
this may sound like a silly problem, sorry if it is!!..
I don't think the direction of the / is the problem here. Windows should convert between the two for you when calling its API precisely for the purposes of (some) unix compatibility.
I think the problem is the include path. Try compiling your program with
gcc -o output.exe -I"c:\path\to\directory\above\include" file.c
So that in the directory you specify with the include flag, there is a subdirectory "include" containing your headers. This assumes all your paths in your other headers are relative to this.
config.h and controls.h are not standard header files. Try this instead:
#include "include/config.h"
#include "include/controls.h"
Even better would be to use the command line to specify the include directory and use
#include "config.h"
#include "controls.h"
Probably mingw uses the same option as all other c compilers: (compiler name) -I(directory name)...
As others have stated, / vs. \ is a non-issue. Even Microsoft compilers and utilities accept / everywhere. The use of \ is a historical mistake, perpetrated needlessly.
A good discussion of your issue can be seen here:
How to generate a OS independent path in c++
Don't change forward slash / to back-slash \ - you are making the compiler to interpret the next character as a special character \c. GCC has no problem dealing with UNIX-style paths on Windows. The problem is probably the lack of -I directive to the compiler - something like -I. to search for files in current and sub-directories.

Resources