Creating several precompiled header files using GNU make - c++

I use gcc (running as g++) and GNU make.
I use gcc to precompile a header file precompiled.h, creating precompiled.h.gch; the following line in a Makefile does it:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $#
All was well until i had to run g++ with different command-line parameters.
In this case, even though precompiled.h.gch exists, it cannot be used, and the compilation will be much slower.
In the gcc documentation i have read that to handle this situation,
i have to make a directory called precompiled.h.gch and put
the precompiled header files there,
one file for each set of g++ command-line parameters.
So now i wonder how i should change my Makefile to tell g++ to create
the gch-files this way.
Maybe i can run g++ just to test whether it can use any existing file
in the precompiled.h.gch directory,
and if not, generate a new precompiled header with a unique file name.
Does gcc have support for doing such a test?
Maybe i can implement what i want in another way?

It seems weird to answer my own question; anyway, here goes.
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file:
// precompiled.h
#include <iostream>
#include <vector>
...
#error Precompiled header file not found
This works because if gcc finds a precompiled header, it will not read the .h file, and will not encounter the error.
To "compile" such a file, i remove the error first, placing the result in a temporary file:
grep -v '#error' precompiled.h > precompiled.h.h
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name (mktemp). It was omitted for clarity.

There is a simpler way than introducing an #error in precompiled.h: never create this file at all. Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags).
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". Again, I I don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data.
Then in all other source files, the statement #include "precompiled_stuff" is not a genuine include, but simply loads precompiled data. It's up to you to prepare the precompiled data.
For g++, you need a build rule to create "precompiled_stuff.gch" from a source file whose name doesn't matter to the compiler (but would be "to_be_precompiled.cpp" here).
In Visual C++, the string "precompiled_stuff" equals the value of the /Yu flag and the precompiled data loaded comes from a .pch file with an unrelated name, that you also created from an unrelated source file (again "to_be_precompiled.cpp" here).
Only when building with a compiler without precompiled header support, a build rule needs to generate an actual file called "precompiled_stuff", preferably in the build directory away from the real source files. "precompiled_stuff" is either a copy of "to_be_precompiled.cpp", a hard or symbolic link, or a small file containing #include "to_be_precompiled.cpp".
In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers.

Related

How to make #if preprocessor be conditional upon a values in another different file?

For example if a "settings" file exists and has the following:
system,ubuntu
Can a preprocessor #if be used to customise the code based of the values in the settings file? For example:
#if lookup_system == "ubuntu" // loopup_system is pseudocode
Another use can could be to look up whether or not the code is running on production servers.
You cannot do that.
However, you might generate some header file from external data. The autoconf utility does that (actually generates some configure script generating such a header).
More generally, you should set up your build automation system (e.g. edit your Makefile for GNU make, or your build.ninja for ninja) to generate that header file suitably (perhaps with a tiny script, your own C++ -another- program, or whatever). You can also have a clever build system passing specific -D flags to your compiler.
Remember that C++ files (both header files e.g. .hh and implementation files e.g. .cc ...) can be generated by something else. This is common practice.
Read more about your preprocessor, e.g. about cpp. It is a compile only thing. With GCC you can get the preprocessed form foo.ii of your foo.cc file with a command such as g++ -C -E foo.cc > foo.ii.

C++: Import/Include system

I'm writing a programming language, that convert the source files to C++ and compile they.
I want to add an way to work with a large number of files, compiling they to .o files, making it possible to use makefiles. A Better explanation (thank #Beta):
You have a tool that reads a source file (foo.FN) and writes C++ source and header files (foo.cpp and foo.h). Then a compiler (gcc) reads those source and header files (foo.cpp and foo.h) and writes an object file (foo.o). And maybe there are interdependencies (bar.cpp needs foo.h).
The problem is: my interpreter delete the .cpp and .h after the GCC compile they. Because this, it can't use #include, cause when it will compile, the referenced files don't exist anymore. How I can solve this?
There are two parts to the answer.
First, don't write explicit header files. You know what they should contain, just perform the #include operation yourself.
Secondly, don't write out the .cpp file either. Use gcc -x c++ - to read the code from standard input, and have your tool emit C++ to standard out, so you can run tool foo.FN | gcc -c -o foo.o -x c++ - to produce foo.o.

How a compiler knows from a header file, that a source file exists somewhere?

I just started to learn C/C++, but I'm a bit confused. I often see the #include preprocessor directive, with a header file argument:
#include <stdio.h>
#include <iostream.h>
#include "windows.h"
#include <math.h>
But sometimes the .h is missing:
#include <iostream>
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h?
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
When you install the compiler, the standard header and library files are also installed into well-known locations. For example, on a Linux or Unix system, the standard headers are typically installed under /usr/include or /usr/local/include and the standard libraries are typically installed under /usr/lib or /usr/local/lib.
When you #include the header file, the compiler will look for it in different places depending on whether you use the angle brackets (#include <stdio.h>) or quotes (#include "myfile.h"). For example, if you include a header file in angle brackets, gcc will search for that header in the following directories:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
If you include a header file with quotes, gcc will first search the current working directory, then additional directories as specified by command-line options, and finally the standard include paths above.
Most compilers allow you to specify additional include paths as arguments to compile command, such as
gcc -o executable-name -I /additional/include/path source-files
But sometimes the .h is missing:
#include <iostream>
This is the C++ convention1; C++ standard headers do not have the .h extension, I guess to make it look more object-oriented than it really is (that is, you can pretend you're importing the class directly, rather than including the text of the file that describes the class).
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h?
The implementations of the math functions are typically kept in a separate library (code that's already been compiled and archived into a single binary file); depending on the compiler, the math library may or may not be automatically linked into the executable. For example, gcc does not automatically link in any math library functions, even if you include the math.h header file. You have to explicitly include the math library as part of the build command:
gcc -o executable-name command-line-options source-files -lm
With gcc, the convention is that -lname links in a library named libname.a2. The standard math library file is named libm.a, so -lm tells gcc to link in the machine code that's contained within libm.a.
Like the standard headers, the compiler will search for the standard libraries in well-known locations. You can specify additional search paths for libraries that aren't part of the standard installation, like so:
gcc -o executable-name command-line-options source-files -L /additional/library/path -ladditional-library
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
You can put the files pretty much anywhere you want; you'll specify where they are as part of the build command. So, say you're creating a new library named mylib. You create a new directory under your home directory:
mkdir ~/mylib
cd ~/mylib
Then you create and edit your source files and headers:
cd ~/mylib
vi mylib.h
vi mylib.c
To build mylib as a static library, do the following:
cd ~/mylib
gcc -c mylib.c
ar libmylib.a mylib.o
So when you're done, the directory ~/mylib contains the following:
libmylib.a
mylib.c
mylib.h
mylib.o
To use the functions collected in mylib in a program, you'd specify the header and library include paths as part of the compile command:
gcc -o executable-name command-line-options source-files -I ~/mylib -L ~/mylib -lmylib
So, if you include "mylib.h" in another program, this will tell the compiler to search for that header in ~/mylib, and it will tell the linker that the libmylib.a library will be found under ~/mylib.
In a real-world situation you'd handle all of the builds with makefiles instead of building everything by hand. You'd also probably set it up so that as part of the build process, all the headers that anyone else would need to use your library would be copied to a separate include subdirectory, and the library would be written to a separate lib subdirectory, so you could distribute your library without exposing your source code. In that case, the build command above would look more like:
gcc -o executable-name command-line-options source-files -I ~/mylib/include -L ~/mylib/lib -lmylib
1. This hasn't always been the case; the earliest implementations of C++ used iostream.h, vector.h, etc. I'm not sure exactly when that convention changed, but it's been a while.
2. Actually, I'm not sure anymore if this is a gcc convention or a *nix convention; the two have been joined at the hip for so long it's hard to remember sometimes.
Actually, the compiler doesn't know anything about other source files, it only knows about the current translation unit. It's the job of the linker to take all translation units and link them together with the libraries to create the executable program, and it's the linker that will resolve all definitions and that notice missing function definitions.
Traditionally, working with C or C++ is a four step process:
Edit files
Compile source files into object files
Link object files and libraries to generate the executable program
Run the program.
The preprocessor is usually built into the compiler, so preprocessing and compiling is only a single step.
As for the "missing" .h, none of the C++-only standard library header files have that extension.
Standard Template Library headers, such as < algorithm > include source code for the template functions, which get instantiated at compile time, based on the template type(s) involved in source code calls to template functions.
A library is a collection of object files in a single library file. The linker normally only includes the object files needed to satisfy the references to functions or data to build the program, not the entire library file. The exception to this is a dynamic link library, since all of that library will be loaded (if not already loaded) at program load time.
The compiler has default locations for headers using < > and using " ". The headers using " ", can include relative or absolute paths. The relative path may vary depending on the tool set.
Re
” How a compiler knows from a header file, that a source file exists somewhere?
Generally, how a compiler locates header files, or if they are files, depends on the compiler.
But usually one or more of the following mechanisms are used:
The compiler knows its own program location, and can look for include directories for standard headers, relative to that location. g++ does this.
The compiler can be configured with paths to include directories in one or more environment variables. E.g. g++ uses CPATH (among others), and Visual C++ uses INCLUDE (and possibly more).
The compiler can accept include directory paths as command line options. Typically this is -I or with Visual C++, alternatively /I.
The compiler can be configured via a configuration file in a well known location. For example, g++ uses a specs file.
The compiler can accept one or more configuration files as command line options. E.g. Visual C++ accepts so called "response files", and g++ accepts specs files, although with slightly different semantics than the general configuration specs file.
Possibly there are more mechanisms in use, but the above are the most common ones.
Re
” But when and how does the compiler include the math functions, if I include math.h?
It doesn't.
The whole of the standard library is linked in regardless of what headers you include. Depending on the quality of the implementation the unused parts of the standard library are then discarded.
When you use a 3rd party library you will generally have to explicitly link with that library, in addition to including one or more of its headers. The Visual C++ compiler supports #pragma directives that can be placed in headers and serve to automatically direct the linker. But this is not standardized, and e.g. g++ does not support that automagic mechanism.
Re
” If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
Essentially you have free reins, you can do it any way you want. Which is problematic because users of a C++ library have to deal with different conventions and tools for each library, to the extent of using a different OS to "configure" things. However, nowadays it's popular to employ CMake for libraries with separate compilation, which helps to reduce the DIY problems.
A nice alternative is to create a header only library, with all the code in headers. Large parts of Boost are header only. The advantage is that it's very easy to use, no configuration or toolset adaption or whatever, but with currently popular 1950's build technology it can cause longer build times.

How to use .h.gch files

I recently found out about precompiled headers in C++, specifically for gcc compilers.
I did find something about the .h.gch files on the net, but haven't yet been able to use them.
I need to know:
How to create a .h.gch file?
My code isn't creating one?
Once created, how to use it?
do you include it like any other user-defined file?
ex: #include "SomeCode.h.gch"
Or is there some other way of using it?
please help
Using GCH (Gnu preCompiled Headers) is easy, at least in theory.
How to create a GCH
Just use gcc <compiler-options> myfile.h. That will create myfile.h.gch. You can use the -o <name> to specify the name of the output file.
If your header file is C++, you will have to name it myfile.hpp or myfile.hh, or GCC will try to compile it as C and probably fail. Alternatively you can use the -x c++-header compiler option.
How to use a GCH
Put your myfile.h.gch in the same directory than myfile.h. Then it will be used automatically instead of myfile.h, at least as long as the compiler options are the same.
If you do not want to (or can) to put your *.gch in the same directory of your *.h, you can move them to a directory, say ./gch, and add the option -Igch to your compiler command.
How to know your GCH is being used
Use gcc -H <compiler-options> myfile.c. That will list the included files. If your myfile.h.gch does not appear, or has an x, then something is wrong. If it appears with a !, congratulations! You are using it.

how to include certain header files by default so that i don't have to type them in every programs

how to include certain header files by default so that i don't have to type them in every programs:
In dev c++ and code::blocks
Make a global header file that in turn includes whatever files you need in every project, and then you only have to include that single file.
However I would recommend against it, unless all your different project are very similar. Different projects have different needs and also need different header files.
You could issue a compiler directive in your project file or make script to do "per project" includes, but in general I would avoid that.
Source code should be as clear as possible to any reader just by its content. Whenever I have source code that dramatically changes its semantics, eg. by headers that are unknown to me, this can be quite confusing.
On top of that, if you "inject" those headers for certain compilation units that don't need them, that will negatively impact compile time.
As a substitution, what about introducing a common.h/hpp header that includes those certain header files? You can then include your common header in all files that need them and change this common set of headers for all depending files at once. It also opens the door to use precompiled header files, which may be worth a look for you.
From GCC documentation (AFAIK GCC is default compiler used by the development environment you are citing)
-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.
-imacros file
Exactly like -include, except that any output produced by scanning file is thrown away. Macros it defines remain defined. This allows you
to acquire all the macros from a header without also processing its
declarations.
All files specified by -imacros are processed before all files specified by -include.
But it is usually a bad idea to use these.
Dev c++ works with MingW compiler, which is gcc compiler for Windows. Gcc supports precompiled headers, so you can try that. Precompiled headers are header files that you want compiled and added to every object file in a project. Try searching for that in Google for some information.
Code::blocks supports them too, when used with gcc, even better, so there it may even be easier.
If your editor of choice supports macros, make one that adds your preferred set of include files. Once made, all you have to do is invoke your macro to save yourself the repetitive typing and you're golden.
Hope this helps.