How to include headers from another directory (but not knowing which) - gcc

I am trying to compile module. I can do so by calling make, which calls
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
But I want to see preprocessed output, So I am trying to compile manually with cc -E file.c. The problem is, It cannot see header <linux/init.h>:
fatal error: linux/init.h: No such file or directory
#include <linux/init.h>
I have notice, when make is called, it first enter this dir /usr/src/linux-headers-5.0.0-38-generic, There is probably the header, but I do not know where. I have tried gcc -E -I'/usr/src/linux-headers-5.0.0-38-generic file.c, but still the same error. So how is possible to include kernel headers (which <linux/init.h> is) in user mode - that is how to include headers from another dir?
PS: as #uzsolt in comments suggested, I add include to the end of path: gcc -I /usr/src/linux-headers-5.0.0-38-generic/include. But then another header is missing - <asm/linkage.h>, and again - I have no clue in what dir this header is.

You should use find command: find /usr/src/linux-headers-5.0.0-38-generic -name MISSED_FILE.
I don't know your linux distribution but I think you should add these parameters to gcc:
-I/usr/src/linux-headers-5.0.0-38-generic/include -I/usr/src/linux-aws-headers-5.3.0-1003/arch/x86/include/

Related

gcc not respecting my include directory order

I'm attempting to build some code using a temporary version of an include file in my local ../include/records directory. The orignal lives in /home/apps/include/records. I have my gcc command set to search ../include before /home/apps/include, but it's still picking up the original module from /home/apps/include and reporting errors. If I rename the original in /home/apps/include, then gcc picks up my local edited copy and it compiles clean. So, what's up with the include order...? This 'local include first' logic has always worked for me in the past, but this may be the first time I've used it since migrating from AIX to Linux.
Is there something beyond the order of the -I command-line options that could be overriding the requested include order?
The source module include statment is:
#include "records/novarec.h"
and the gcc command line looks like this:
$make
gcc -DLINUX64 -c -g -I. -I../include -I/home/apps/include -I/home/apps/include/em -I/home/apps/include/odbc -Wno-implicit-function-declaration -Wno-implicit-int -Wno-format-security -Wno-format-truncation -Wno-discarded-qualifiers novaget.c
The compiler complains about an undefined value that's in my local copy of novarec.h, but not in the production /home/apps/include/records/novarec.h:
novaget.c: In function ‘calcComscoreDemoV1’:
novaget.c:2651:15: error: ‘CSCD_W21_49’ undeclared (first use in this function); did you mean ‘CSCD_W25_49’?
fval = *(dm+CSCD_W21_49);
^~~~~~~~~~~
It seems like the answer is this:
My module called in 2 include files. The first one also includes the second one - and the first one lives in /home/apps/include. That seems to make gcc search there for the second include file - even though /home/apps/include is not the first include directory in my path.
When I reverse the 2 include statements in my .c file, the correct path is followed for novarec.h. i.e. when I code:
#include "spottvdemos.h" (this modules has a #include "records/novarec.h")
#include "records/novarec.h"
novarec.h gets picked up from /home/apps/include, but when I code:
#include "records/novarec.h"
#include "spottvdemos.h"
novarec gets picked up from ../include, which is what I wanted.

C++ makefile with relative include path to parent

I've got a working project that I need to take parts from it without changing it's code and just write new main() for it.
My directory structure:
[main_dir]/[main.cpp]
[main_dir]/[dir1]/[child1]/file1.h
[main_dir]/[dir2]/[child2]/file2.h
in main.cpp I have: include "dir1/child1/file1.h"
In file1.h I have: include "dir2/child2/file2.h"
I'm compiling:
g++ main main.cpp
I'm getting "dir2/child2/file2.h" no such file or directory.
I can't change file1 to do: include "../../dir2/child2/file2.h"
Somehow in the original project something in the makefile to search for all include path relative to the [main_dir] so the include from file1.h can be found.
What should I add to the makefile in order to do it as well?
When using double-quotes to include a header file, as in
#include "dir2/child2/file2.h"
then the compiler will use the directory of the current file to search for the header file.
If you have it in your file1.h then the compiler will look for the header file [main_dir]/dir1/child1/dir2/child2/file2.h. Which isn't correct.
You can solve it by telling the compiler to add [main_dir] to the list of standard include search paths. This is done with the -I (upper-case i) option:
g++ -I [main_dir] main.cpp
Then when the compiler fails to find dir2/child2/file2.h in its first search, it will continue with the list of standard include search paths, and it should be found.
You need to manage CPPFLAGS in your Makefile.
CPPFLAGS="-I[main_dir]"
And compile application with receipt like this:
g++ $(CPPFLAGS) main.cpp -o main
Also it's recommended to read make style guides to write a good one Makefile. You can meet there tips for include folders declaration.

Configure clang-check for c++ standard libraries

I am trying to run Ale as my linter, which in turn uses clang-check to lint my code.
$ clang-check FeatureManager.h
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "FeatureManager.h"
No compilation database found in /home/babbleshack/ or any parent directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
/home/babbleshack/FeatureManager.h:6:10: fatal error: 'unordered_map' file not found
#include <unordered_map>
^~~~~~~~~~~~~~~
1 error generated.
Error while processing /home/babbleshack/FeatureManager.h.
Whereas compiling with clang++ returns only a warning.
$ clang++ -std=c++11 -Wall FeatureManager.cxx FeatureManager.h
clang-5.0: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
There are no flags to clang-check allowing me to set compilation flags.
Took a while to figure this out, but you can do
clang-check file.cxx -- -Wall -std=c++11 -x c++
or if you are using clang-tidy
clang-tidy file.cxx -- -Wall -std=c++11 -x c++
To get both working with ALE, I added the following to my vimrc
let g:ale_cpp_clangtidy_options = '-Wall -std=c++11 -x c++'
let g:ale_cpp_clangcheck_options = '-- -Wall -std=c++11 -x c++'
If you want ALE to work for C as well, you will have to do the same for g:ale_c_clangtidy_options and g:ale_c_clangcheck_options.
I was getting stumped by a similar error message for far too long:
/my/project/src/util.h:4:10: error: 'string' file not found [clang-diagnostic-error]
#include <string>
^
I saw other questions suggesting that I was missing some critical package, but everything already seemed to be installed (and my code built just fine, it was only clang-tidy that was getting upset).
Passing -v showed that my .h file was being handled differently:
$ clang-tidy ... src/*.{h,cc} -- ... -v
...
clang-tool ... -main-file-name util.cc ... -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9 ... -x c++ ... /tmp/copy/src/util_test.cc
...
clang-tool ... -main-file-name util.h ... -x c-header /my/project/src/util.h
...
As Kris notes the key distinction is the -x c-header flag, which is because clang assumes a .h file contains C, not C++, and this in turn means that the system C++ includes weren't being used to process util.h.
But the -main-file-name flag also stood out to me as odd; why would a header file ever be the main file? While digging around I also came across this short but insightful answer that header files shouldn't be directly compiled in the first place! Using src/*.cc instead of src/*.{h,cc} avoids the problem entirely by never asking Clang to try to process a .h on its own in the first place!
This does introduce one more wrinkle, though. Errors in these header files won't be reported by default, since they're not the files you asked clang-tidy to look at. This is where the "Use -header-filter=. to display errors from all non-system headers.*" message clang-tidy prints comes in. If I pass -header-filter=src/.* (to only include my src headers and not any other header files I'm including with -I) I see the expected errors in my header files. Phew!
I'm not sure whether to prefer -x c++ or -header-filter=.* generally. A downside of -header-filter is you have to tune the filter regex, rather than just passing in the files you want to check. But on the other hand processing header files in isolation is essentially wasteful work (that I expect would add up quickly in a larger project).

Include mpi to make file

I am trying to include MPI compiler to my makefile. The makefile is already prepared such that I only need to include the address of the MPI compiler in a a separate env file. However doing so does not work. I can get the cpp file to run manually by typing:
mpicxx Demo_00.cpp -o aprogram
./aprogram
I test where the mpi compiler is located using:
which mpicxx
/usr/bin/mpicxx
In the env file the corresponding line is:
MPICXX=/usr/bin/mpicxx
However, when I try to 'make' he cpp file I get the following error:
make Demo_00
g++ Demo_00.cpp -o Demo_00
Demo_00.cpp:2:17: fatal error: mpi.h: No such file or directory
compilation terminated.
make: *** [Demo_00] Error 1
The cpp file is in the same folder as the env file and the makefile.
I am not quite sure how to identify the error.
Thank you for your help,
Tartaglia
If you want to change the name of the C++ compiler, you have to change the variable CXX. That's the default variable make uses when it wants to compile C++ code.
This line in your log file:
g++ Demo_00.cpp -o Demo_00
says that you are using g++ compiler instead of mpixx.
Usually in makefiles compiler definition is at the beginnig of the file and looks like this:
CC=g++
just change it to mpixx
CC=mpixx
Thank you all for your responses, I took a closer look into the makefile I thought I was using and it turns out, as you have already suggested, I was not using it at all. The makefile was only able to execute one specific cpp file with one specific name. So whenever I typed in make *.cpp I was using the standard make as you already pointed out.
Thanks again for your help.

How to tell GCC to map include directory?

I need to compiler source code that contains includes like this:
#include <tr1/unordered_map>
However my compiler (based on GCC 4.6) does not have the tr1 directory. I need to somehow tell the compiler to map <tr1/unordered_map> to <unordered_map without modifying source code of file system?
when you build your code, provide include directory as an argument.
-I. - For current directory as an include directory
-I tr1 - tr1 as an include directory.
-I /yourpath/ - To put any directory as include directory
Gcc headers <unordered_map> and <tr1/unordered_map> are different. One requires C++11 support turned on, the other does not. Substituting one for the other may or may not work.
Probably the easiest solution to your problem is to use the tr1 implementation from Boost.
A bit hacky: Go to the include directory containing unordered_map and:
ln -s . tr1

Resources