I have found an unusual C makefile setup that relies upon a deprecated feature of GCC that appears to have no modern replacement.
This system needs to preprocess or 'cook' the local header files before including them. The makefiles take care of this and put the cooked versions in local './prepared/' directories. The header files are included as normal in the c using their normal names eg #include "name.h". The system simply needs './prepared/' to occur in the GCC header file search path before '.'.
Gcc used to offer the -I- option to remove the default '.' and allow the addition of header search path entries before it, but this option is deprecated.
From the gcc docs:
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.
Is there no way to control the C header search path properly in gcc any more? Or is there another sensible way forward? I don't want to use a deprecated feature that may disappear. Right now I am sadly filtering the gcc deprecated feature warning messages to hide them. I didn't create the build environment, and it would be unpopular to solve the problem in a way that breaks the 'cookery'.
As far as I can tell, GCC provides no other means than the one you've described to avoid having each source file's directory first in the include search path used when compiling that file.
The best solution is probably to fix the headers and build system to get rid of header cooking. Such a scheme is very unusual -- pretty much everybody else gets by without.
If you must continue to rely on header cooking, then you probably should move the original headers to a directory that is not in the include search path. For example, create an "include" subdirectory of the main source directory, and put them there.
Edited to add:
Another alternative is to switch from the quoted include style to the angle-bracketed include style, and rely on -I options to set up the needed internal include directories however you want.
Related
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.
I've been trying to work without an IDE. Now I'm setting up a project that I had done
on stm32cubeIDE. I got to the point where I'm adding headers and such to the main.c file. In the IDE I was able to tell the IDE where to look for headers, like the driver folder or w/e I called it. Without IDE, I had to go and change the path in the #include statement such that
#include "cooldriver.h"
became
#include "driver/cooldriver.h"
Then,I also have to change cooldriver.c's path to point to the right path.
Is there a way to simplify this so I don't have to go through and change all the #includes and just keep what I had.
I'm working in linux env and using arm-none-eabi-gcc.
The path i have is like,
main.c
Makefile
drivers
Inc
driver1.h
driver2.h
Src
driver1.c
driver2.c
TLTR: I want to tell compiler where to look for header files without an ide and without rewriting all the include statements.
Thanks.
TLTR: I want to tell compiler where to look for header files without an ide and without rewriting all the include statements.
Among their many available command-line options, compilers accept some that tell them about paths to search for headers and external libraries. On UNIX-heritage systems, the traditional one for paths that #include should consider is -I. Your compiler's documentation will provide more detail.
The traditional approach would be to set one or more variables in your makefile to contain the wanted command-line flags, and to expand those variables where appropriate in your make recipes. Sticking with convention, I would use variable CPPFLAGS for -I and other flags directed toward the C preprocessor.
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
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.
Are there any compiler options to deal with it? Without patching sources.
You can tell gcc to look in another include directory with -I:
gcc -I/home/bob/includes
This will add /home/bob/includes to the location that gcc searches. Your best bet is to create the tree that gcc is expecting there - for example, if /home/bob/includes was the directory where the headers really were, and the code asks for dir/header.h, then put the headers in /home/bob/includes/dir