C++ makefiles - Header files dependencies with external libraries - c++

I want to add dependency target to my Makefile, I knew it could be done through makedepend or g++ -MM option, and I am open for using any of them but I prefer -MM option as it allowed me to exclude standard libraries (I do not know if makedepend can do it or not).
The problem is that I use some external libraries headers in my application and I want these headers to be excluded from the dependencies generated so how can I exclude certain directories from these generated dependencies.
[Edit-start] I already tried using grep -v but the problem is that if the excluded line is the last wrapped line in a certain target, the next target would be joined to that target due to the escape '\' character at the end of the line before it leading to a corrupted dependency rule. In addition to that the time it takes to go through the library headers parsing them [Edit-end].
Another problem is that How can I edit the suffixes of the generated object-files targets, I am using a Makefile that compiles the source files provided through a variable by using through a target like that:
%.o: %.cpp
g++ $< -o$*.o ...

The first problem (external libraries) could be solved by first using grep -v and then passing the output to sed 'N;s/\\\n\(.*\.o\)/\n\1/;P;D' which removes unneeded escape characters '\' to solve the problem of joined targets due to the exclusion introduced by grep -v. But the time overhead of going through the external libraries headers parsing them still as it is.
And the second problem (generated targets suffixes edit) could be solved by sed also using sed 's/.o:/$(MY_SUFFIX):/' where $(MY_SUFFIX) is the suffix to replace .o in the generated target rules.

#pragma GCC system_header is a gcc pragma to identify system header.
You may use proxy header with this pragma which include library header
//Proxy_header.h
#ifndef PROXY_HEADER_H
#define PROXY_HEADER_H
#pragma GCC system_header
#include "external_library.h"
#endif
but post-processing dependencies seems cleaner.
-MF file seems to be the gcc option you want to edit the suffix of dependency files.

Related

How to make C/C++ compiler to look for headers in a user specified path

I'm using a library written by others which is kinda based on C for C++ usage -I think-. All inclusions used inside the headers or source files are in the form <> instead of "" even though they are not standard library files. My compiler doesn't recognize them and returns error "file not found"
An example of the problem is inside the following header:
#ifndef _ga_ga_h_
#define _ga_ga_h_
// Make sure that we get the configuration into each of the galib components
// that will be used.
#include <ga/gaconfig.h>
// These are the headers for all of the genetic algorithm classes.
#include <ga/GASimpleGA.h>
#include <ga/GASStateGA.h>
#include <ga/GAIncGA.h>
#include <ga/GADemeGA.h>
#include <ga/GADCrowdingGA.h>
// Here we include the headers for all of the various genome types.
#include <ga/GA1DBinStrGenome.h>
#include <ga/GA2DBinStrGenome.h>
#include <ga/GA3DBinStrGenome.h>
#include <ga/GABin2DecGenome.h>
I include that header inside my program using #include "ga.h" but it is very hard to change inside every header/source file in the library.
Is there a way to make the compiler use <> as if they were ""?
I tried adding the paths to "Addition include directories"from Project properties (I'm using Visual Studio), Many inclusions' errors disappeared but around 30 persisted. The strange thing is that they are in a file called "c1xx" but i don't have that file!!
thanks,
The definition is somewhat that <> is used for "system" header files, usually found in locations like /usr/include (on Unix-like systems) and "" is used for local header files. When you compile your code, you can indicate the location of additional directories containing header files e.g. using the -I option when using GCC. Check your compiler's documentation for the setting needed
So, e.g. on Linux and GCC, if your "ga" directory is in /usr/local/include/ga, you would use cc -I /usr/local/include.
This indeed looks like a problem of telling the compiler where to look for the included header files. As mentioned in the other answers, when you do a #include <header.h>, header.h must be in one of the include search paths - either the system includes, or the additional paths that you are telling the compiler to look for headers. In Linux/g++ (as mentioned in the other answers here), you do that by passing in the the additional search paths in the -I flag. The compilation command would look something like:
g++ -I/additional/header/search/path -o a.out your_file.cpp
Since you are using visual studio and the MSVC compiler, the equivalent would be the /I flag, and the compilation command would look something like:
CL /I\additional\header\path your_file.cpp
I am assuming you are using Visual Studio - you can also configure that from the project properties. Go to Configuration Properties > C/C++ > General and modify Additional Include Directories. Refer these for more info:
Setting C++ compiler and build properties
Additional include directories
First about the difference between <header> and <file>. The standards (both C and C++) only specifies that
#include <header>
includes an header named header and that
#include "file"
includes a source file named file, if none is found an header named file is included instead.
What are headers and how they differ from source files is left to the implementation. In practice they are files as well. So #include <header> is looking for a file in some places, #include "file" is looking for a file in some other places and if not found at the same places as for #include <file>.
AFAIK all compilers
are able to search for source files in the directory of the file containing the include directive
are able to be given a list of directories to search for headers before their default search path.
ISTR that Visual C++ is also searching for a source file in the directories of files indirectly including it. (I can't confirm currently if my memory is good; that behavior is AFAIK unachievable with other compilers so I never relied on it and -- by luck? -- it never resulted in a different behavior for my programs).
Obviously that behavior is more or less customizable. For instance with g++ is possible to:
disable the search of a source file in the directory of the file containing the include directive (with -I-, note that -I- is deprecated since gcc 4.0 -- 2005 -- when -iquote has been introduced and there is no non-deprecated way to achieve this)
to add a list of directories to search for source files and not for headers (with -iquote and it's an effect of -I- as well)
to give a list of directories to search for headers after the default list of directories (with -idirafter)
to give a list of directories to search for headers which are processed specially (with -isystem; less warnings are given for constructs in those files which help when using the "treat warnings as errors" flags, they aren't considered as dependencies with -MM and -MMD which usually is a nuisance)
Now for your problem. The library has been visibly designed to be used by adding the directory containing the directory ga to the include path. That should be enough as I'm unaware of any compiler modifying its search path for headers depending on how the file including the header has been included.
Note that c1xx is probably the name of the compiler executable, not the name of a file trying to include another (again, I'm not in position to ensure that's the case now, but compare with cc1plus which is the name of the compiler for GCC -- g++ is a driver handling several things and executing cc1plus to handle the compilation of C++ code)
If you do on the command line:
echo | gcc -v -E -x c++ -
You will get an output with the default include directories for C++. Those are the built in system's include search paths.
If you compile with g++ -I/some/dir -o foo foo.cpp, you are adding an additional include search path (/some/dir) to the compilation.
Headers in the above locations can be found by include directives like #include <header>. #include "header" directives can also find headers in those locations, but they are more relevant for the following case.
When you do #include "header", your compiler will first try to find "header" relative to the directory of foo.cpp if it includes it, despite foo.cpp directory being in search paths or not. If it doesn't find it there, it will try to look up in the include search paths. So this one is more relevant for headers that are more tied to a specific .cpp file and you don't want additional include search paths added to the compilation, or if you prefer to use include directives with relative paths.
So if you use #include <header>, header must be in some of the include search paths, system or /some/dir from -I flag. If header is relative to foo.cpp, but not in search paths, compilation will fail.
If you use #include "header" and header is not in any of the include search paths, it can still be found relative to foo.cpp location.

Specify source file that defines function previously declared in a header file

I have a bunch of C++ files that reference functions defined in a sub-directory inside src/. Is there a way to specify the cpp files inside the sub-directory via g++?
Here is the structure of the package:
# SeqLib
# |----src
# |-----|---Makevars
# |-----|---rcpp_hello_world.cpp
# |-----|---SeqLib(a submodule)
# |-----|------|---SeqLib
# |-----|------|---FermiAssembler.h
# |-----|------|---src
# |-----|------|---|----FermiAssembler.cpp
************************* EDIT **************
When running -I../src/SeqLib/, I get an error undefined symbol: _ZN6SeqLib14FermiAssemblerD1Ev. Using c++filt, the symbol references the destructor declared in FermiAssembler.h but, defined in FermiAssembler.cpp
You have to pass all the .cpp files to the compiler command. It's strongly discouraged to include .cpp files in other .cpp files.
The command line that is likely to work for you is:
g++ -ISeqLib -o my_executable rcpp_hello_world.cpp SeqLib/src/FermiAssembler.cpp
If you have a lot of files, it is advised to create a makefile script to avoid recompiling all the code every time.
if your FermiAssembler product contains Makefile.am/in files, it can build itself using a configure script which is probably here. The general idea is the:
cd SeqLib
./configure
make
If it's a library product, it builds as a .a or .so file. In that case, the command line becomes:
g++ -ISeqLib -o my_executable rcpp_hello_world.cpp SeqLib/bin/FermiAssembler.a
(I'm just gessing the path & name of the output library file)
To include .a files from there, just add their path. Not sure that SeqLib/bin/*.a would do it because lib dependencies don't follow alphabetical order. A very bruteforce thing that would work would be specifying all .a files twice (so inter-lib dependencies would work):
g++ -ISeqLib -o my_executable rcpp_hello_world.cpp SeqLib/bin/*.a SeqLib/bin/*.a
it would be better, though, to include only the required .a files, respecting the following order: first the ones depending on the following ones. The last library mustn't depend of any of the previous ones.

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.

linker script conditional includes

I am converting a scatter file to linker file. Now the problem is armlink can accept symbols e.g --predefine=-DSOME_VARIABLE at link time and in the scatter file other header files can be included with the #include "someHeader.h directive. There are files which are included in scatter file on the bases of defined symbols e.g
#ifdef INCLUDE_RANDOM_FILE
randomFile (*)
#endif
in linker script these options are not available. is there a work around for this problem.
There are two fairly simple options.
Use a compiler pre-processor and use the output.
Invert your logic.
Use the C pre-processor in GCC or any compiler.
$(CC) $(DEFINES) -E -P -o output.lds -x c-header input.lds
This option allows the full range of pre-processor defines and conditional inclusion.
The invert option is to have separate master 'lds' files for each case you need and then include the common portion.
flash.lds
start = 0xf000000;
size = 0x100000;
include "common.lds"
ram.lds
start = 0x0;
size = 0x10000;
include "common.lds"
The same can be production and debug variants. This is fairly easy if the permutations are low. Otherwise, I would use the pre-processing.
The bin-utils ld documentation also has a good example with a linkcmds.memory file. You would have to symlink or copy the linkcmds.memory file in your Makefile or build process.
It is often surprisingly easy to get rid of the conditions by using weak symbols and stub file and routines that make conditions unneeded.

Which directories does include statement search in C/C++?

test.c:
#include "file.h"
In the above statement, which directories will be searched ?
I suppose the directory where test.c locates will be searched, right?
But is that all?
BTW, what's the benefit to use a header file? Java doesn't require a header file...
#include <header_name>: Standard include file: look in standard paths (system include paths setup for the compiler) first
#include "header_name": Look in current path first, then in include path (project specific lookup paths)
The benefit of using a header file is to provide others with the interface of your library, without the implementation. Java does not require it because java bytecode or jar is able to describe itself (reflexion). C code cannot (yet) do it.
In Java you would only need the jar and have the correct use statement. In C you will (mostly) need a header and a lib file (or header and dll).
The other reason is the way c code is compiled. The compiler compiles translation units (a c/cpp file with all included headers) and the linker in a second step links the whole stuff. Declarations must not be compiled, and this saves time and avoid code to be useless generated for each compilation unit which the linker would have to cleanup.
This is just a general idea, I am not a compiler specialist but should help a bit.
It's controlled by your compiler. For example, gcc has a -I option to specify the include path.
C and C++ prototypes are required so the compiler (distinguished from the linker) can make sure functions are being called with the correct arguments. Java is different in that the compiler uses the binary .class files (which unlike C are in a standard bytecode format with all type information preserved) to check that calls are valid.
Using quotes after the #include instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of any files that include (#include) that file. The preprocessor then searches along the path specified by the /I compiler option, then along paths specified by the INCLUDE environment variable.
If you use the angle bracket form, it instructs the preprocessor to search for include files first along the path specified by the /I compiler option, then, when compiling from the command line, along the path specified by the INCLUDE environment variable.
The C++ Standard doesn't really say which directories should be searched. This is how the C++ Standard describes what happens when #include "somefile.h" is encountered:
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that
directive by the entire contents of
the source file identified by the
specified sequence between the "
delimiters. The named source file is
searched for in an
implementation-defined manner. If this
search is not supported, or if the
search fails, the directive is
reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence
(including > characters, if any) from
the original directive.
So exactly what directories are searched are at the mercy of your specific C++ implementation.
strace, or truss, etc., may be helpful. For example, create a file foo.c with the single line #include "foo.h". Then on CYGWIN, the command:
strace /usr/bin/gcc-4.exe foo.c | grep 'src_path.*foo.h,' | sed 's/.*src_path //;s/foo.h.*//'
produces:
foo.c:1:22: error: foo.h: No such file or directory
/home/Joe/src/utilities/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed/
/usr/include/
/usr/include/w32api/
I was actually surprised this list was so short: the last time I did this exercise, on SunOS 4 fifteen years ago, the search path had over a dozen directories.
The first directory, obviously, is where foo.c lives. See aslo http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html for the environment variables CPATH and C_INCLUDE_PATH. But these are not set on my machine. (And I am unclear whether CYGWIN uses them, anyway.)
Edit: The simplest solution is to use cpp -v (not gcc -v). It gives:
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i686'
/usr/lib/gcc/i686-pc-cygwin/4.3.4/cc1.exe -E -quiet -v -D__CYGWIN32__ -D__CYGWIN__
-Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../..
/include/w32api -idirafter
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api -
-mtune=generic -march=i686
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/include"
ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed
/usr/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../include/w32api
End of search list.