Is it possible to specify extra header files to include from the command line (using GCC 4 / C++)?
Or is there any other way files can be included except with #include?
Background: I'm trying to compile a large code base on my own PC. The code is usually compiled in a cluster, with a complicated build system (SoftRelTools anybody?), which is intertwined with the operating system, such that it is virtually impossible to install it somewhere else (literally hundreds of makefiles and shell scripts, and hard coded paths to network drives). However, the actual code is fairly straightforward, and compiles fine, BUT it is missing a lot of includes (mostly a la "include <vector>" and "include <math.h>"). I'm guessing the build system takes care of this usually, but I have to go through the code and add the includes manually, which I'd rather avoid.
I found the -include option. Does this what you want?
-include file
Process file as if "#include "file"" appeared as the first line of
the primary source file. However, the
first directory searched for file is
the preprocessor's working directory
instead of the directory containing
the main source file. If not found
there, it is searched for in the
remainder of the "#include "...""
search chain as normal.
If multiple -include options are given, the files are included in the
order they appear on the command line.
From the gcc manual:
-include file
Process file as if "#include "file"" appeared as the first line of the primary source file. However, the first directory searched for file is the preprocessor's working directory instead of the directory containing the main source file. If not found there, it is searched for in the remainder of the "#include "..."" search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.
According to gcc documentation, the command line switch "-include file" would do the job.
Related
Is it possible to specify extra header files to include from the command line (using GCC 4 / C++)?
Or is there any other way files can be included except with #include?
Background: I'm trying to compile a large code base on my own PC. The code is usually compiled in a cluster, with a complicated build system (SoftRelTools anybody?), which is intertwined with the operating system, such that it is virtually impossible to install it somewhere else (literally hundreds of makefiles and shell scripts, and hard coded paths to network drives). However, the actual code is fairly straightforward, and compiles fine, BUT it is missing a lot of includes (mostly a la "include <vector>" and "include <math.h>"). I'm guessing the build system takes care of this usually, but I have to go through the code and add the includes manually, which I'd rather avoid.
I found the -include option. Does this what you want?
-include file
Process file as if "#include "file"" appeared as the first line of
the primary source file. However, the
first directory searched for file is
the preprocessor's working directory
instead of the directory containing
the main source file. If not found
there, it is searched for in the
remainder of the "#include "...""
search chain as normal.
If multiple -include options are given, the files are included in the
order they appear on the command line.
From the gcc manual:
-include file
Process file as if "#include "file"" appeared as the first line of the primary source file. However, the first directory searched for file is the preprocessor's working directory instead of the directory containing the main source file. If not found there, it is searched for in the remainder of the "#include "..."" search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.
According to gcc documentation, the command line switch "-include file" would do the job.
I've been asked to make a small mod to some software that was written back in the mid naughties on IAR Embedded Workbench v3.3
I have had the original source files copied from an old machine to one I have been given for the task.
For the moment I am simply trying to get the software compiling. It took me a while to realise, or at least I thought I'd realised, that the reason it couldn't open various header files was that, incredibly, all the include paths were absolute, not relative.
So, I changed all the paths to be $PROJ_DIR$ relative, but then started to get different files that couldn't be opened. Then realised that the machine they gave me just happened to have a very similar directory structure to the original machine used and, amazingly, had quite a few of the same files in the directory structure of this machine I'm using as was on the machine used to compile the code originally.
I then thought, OK, I'll just check I have got my relative paths correct by choosing one of the header files it was complaining about not finding and putting, in the Preprocessor tab, an absolute path to the directory on this machine I'm using that contained the header file it wanted. However, that still wouldn't find the header file!
Finally, I put an absolute path in the c file to point to the desired header file.
#include "C:\absolute__Path\stdtyp.h"
And it compiled.
To confirm:
Putting C:\absolute__Path
in the Project | Options | C/C++ compiler | Preprocessor tab will not work if I just have:
#include "stdtyp.h"
in the c file.
I have used IAR in the past - not that much - but I have used it and I was sure that's where you set your include directories. So, am I wrong, or can there be something else that is overriding that path in the Preprocessor tab as described above?
Edit: I'm not wrong, after having slept on it, I decided to create a new project with random directories, subdirectories and header files. Sure enough, if I set and remove $PROJ_DIR$ referenced paths in the preprocessor tab, the new project compiles, then doesn't. So, there must be something, presumably in the ewp file that is borking it.
It turns out you can override the paths on an individual file by file basis. So, the rogue files had the paths overridden and had absolute paths.
Right click on the file in EW and select Options.
That then for most file shows a load of greyed out boxes. What I'd failed to do was thoroughly check all files. The few I'd randomly checked were greyed out, but some files had their properties overridden here with different (and absolute) paths put there.
At least now the project can be easily copied between machines having used relative paths.
I would like to have g++/gcc tell me the paths to everything non-system it is #include-ing in C++ build. Turns out, that is a tough search as Google mus-interprets it about ten different ways.
I want these filenames and paths so I can add them to the search path for Exuberant CTAGS. We have a huge project and if I use ctags on the whole thing it takes about half an hour to generate the tags file and nearly as long for the editor to do a look-up.
We use CMakeLisats to do the compiling. If there is a directive I can paste into the CMakeLists.txt, that would be extra wonderfulness.
I don't really need the default paths and filenames, Johnathan Wakely gave a good tool for that here. I think that pretty much covers the fact that this is a cross compile job. I don't need the cross-system files either.
Try gcc or g++ with the -H option (to the preprocessor part of it). From the doc:
-H
Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the ‘#include’ stack it is. Precompiled header files are also printed, even if they are found to be invalid; an invalid precompiled header file is printed with ‘...x’ and a valid one with ‘...!’ .
It tells you all the headers which are included. You may filter out (with grep -v or awk) those that you don't want.
You could also consider developing your GCC plugin to register these headers somewhere (e.g. in your sqlite database), perhaps inspired by this draft report, or the CHARIOT or DECODER European projects. You could also consider using, or extending, the Clang static analyzer.
In contrast to the -M options suggested in Oliver Matthews' answer, it does not tell you more (but gives all the included files).
You need to invoke g++ with the -M option.
From the manual:
Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source file.
The preprocessor outputs one make rule containing the object file name
for that source file, a colon, and the names of all the included
files, including those coming from -include or -imacros command line
options.
It's worth reading the manual to consider the other -M sub options (-MM and -MF in particular may be of use).
I have a very large code, a lot of which is legacy code.
I want to know which of all these files are taking part in the compilation.
The code is written in GNU compilers and mostly in C/C++, but some in other programs too.
Any advice will be highly appreciated.
Thanks,
Moshe.
I am compiling under linux with a mix of scripts/makefiles. I want to somehow 'wrap' this build with a tool which will give an output of all the source files used in the build, preferably with absolute path names.
What do you say?
If you want to show included headers then whether that's supported and how to do it depends on the compiler.
E.g.,
C:\test> (g++ --help --verbose 2>&1) | find "header"
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers
--sysroot=<directory> Use <directory> as the root directory for headers
-H Print the name of header files as they are used
-MG Treat missing header files as generated files
-MM Like -M but ignore system header files
-MMD Like -MD but ignore system header files
-MP Generate phony targets for all headers
-Wsystem-headers Do not suppress warnings from system headers
-print-objc-runtime-info Generate C header of platform-specific features
-ftree-ch Enable loop header copying on trees
C:\test> (cl /? 2>&1) | find "include"
/FI<file> name forced include file /U<name> remove predefined macro
/u remove all predefined macros /I<dir> add to include search path
/nologo suppress copyright message /showIncludes show include file names
C:\test> _
In the above you can see the relevant options for respectively g++ and Visual C++.
Cheers & hth.,
– Alf
For a given compilation unit, e.g. foo.cpp, add the flags -E -g3 to the call of g++.
This gives you the preprocessed code. There you can look which things are included.
Two options come to mind.
Parse the compilation log
Run a build, save the log, and then search in the log.
Find the files that are opened during the compilation time.
A way to do that might be to use a system tracing tool like strace or library tracing tool like ltrace and then look out for file open calls.
See also How can I detect file accesses in Linux?
How do you build the application? I.e. what do you type at the terminal to build it?
Depending on your answer to (1), find the relevant program used for the build (i.e. make, scons, etc.)
Now find the input file(s) to that build program, like Makefile, SConstruct, etc.
Look into this build file and other build files used by it to figure out which source files go into the build
Here is a technique that finds all include files using make.
It is non intrusive so you don't need to make any changes to files, or even to actually compile. Make will do all the work for you.
make -d
will run make and emit lots and lots of lines describing the inner processing of the make process. The most important is the consideration of dependencies.
Parsing the output it is easy to find the dependencies, and all other files.
Here is a Linux command line that gets a sorted list of directories that contain include files:
make -d | awk '/Prerequisite/ { if(match($2,".(.*)(/)(.*\\.h)",m)) { c[m[1]]++ ; } } END {for(d in c) print "\"" d "\",";} ' | sort
In this case the directories are quoted and a comma is added at the end, so the ouput is ready to be included in Visual Studio Code (vscode) configuration file c_cpp_properties.json
Simple variations can produce the grand list of include dependencies, like so:
make -d | awk '/Prerequisite/ { if(match($2,".(.*\\.h)",m)) { c[m[1]]++ ; } } END {for(d in c) print d ;} ' | sort
This should also work with targets (e.g. make All)
Does anyone know what the "-FC" option does in g++?
I have it in my SConstruct script that builds the command line g++ command, I have searched google
You know, if all fails, read the manual :-).
Fdir
Add the framework directory dir to the head of the list of directories to be searched for header files. These directories are interleaved with those specified by -I options and are scanned in a left-to-right order.
[...]
Source: http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Darwin-Options.html#Darwin-Options
So -FC will apparently add the framework directory "C" to the header file search path.