Placing header files in a subdirectory of /usr/include with automake? - header-files

If I write a library, and have header files for development included, and have a src/Makefile.am like this:
AM_CFLAGS = -std=c99 -Wall -Werror -Os
lib_LTLIBRARIES = libmylibrary.la
libmylibrary_la_SOURCES = a.c b.c
include_HEADERS = a.h b.h
Everything works nicely. However, a.h and b.h are installed directly under /usr/include (or /usr/local/include). What should I do to get them installed, in a subdirectory specific to my library, e.g. /usr/include/mylibrary?

As well as pkginclude_HEADERS, which you mention, you can also install header files into an arbitrary subdirectory of /usr/include with any name you like, like this:
otherincludedir = $(includedir)/arbitrary_name
otherinclude_HEADERS = a.h b.h
The advantage of using pkginclude_HEADERS = publicHeader.h is that in a large system, each package stay in its own subdirectory of $prefix/include and avoids the chance of overwriting headers from different package with the same name. Furthermore, this naming convention helps users easily locate the header for a particular package.

Looks like I asked Stack Overflow too quickly ;)
With a little more searching, I found that if I use pkginclude_HEADERS instead of include_HEADERS, the headers go in /usr/include/[package name].
http://realmike.org/blog/2010/07/18/gnu-automake-by-example/

Related

Is there a way to tell the g++ compiler, not to look for include header in a certain -I path?

I'm trying to compile a cpp file that uses include headers from 2 folder locations. Both the folders has lot of headers that are necessary for my file.
Now, one of the header file is present in both the folders, but the problem is they are of different version. Hence the functions in that common header have same name but different API signature.
Something like this:
Folder A:
foo.hpp
bar1.hpp
bar2.hpp
bar3.hpp
Folder B:
foo.hpp
bar4.hpp
bar5.hpp
bar6.hpp
API of function foobar from foo.hpp of folder A:
void foobar(arg1, arg2);
API of function foobar from foo.hpp of folder B:
void foobar(arg1, arg2, arg3);
#include "foo.hpp"
#include "bar1.hpp"
...
#include "bar4.hpp"
...
...
int main(){
...
foobar (arg1, arg2);
...
}
g++ main.cpp -o MyExe -I< path-to-folder-A > -I< path-to-folder-B >
This throws the errors like multiple redefinition of function, no matching function call etc., for various functions in the header.
So, my question is: Are there any flags to tell the compiler only to consider the definition found from folder A and ignore the one from folder B?
Note on code limitations: I cannot alter the folders or files of A and B in any manner. Neither can I give absolute paths to the headers instead of -I.
Assuming that you can give more elaborate relative paths:
If folder b is a subfolder of main.cpp's, you can just use
#include "<relative-path-to-folder-b>/foo.hpp"
If folder b isn't a subfolder and you can add another -I directive, then add another -I directive:
g++ main.cpp -o MyExe -I<path-to-folder-before-b> -I< path-to-folder-A > -I< path-to-folder-B >
and then add the include
#include "b/foo.hpp"
One (very brittle, hack-ish and possibly slow-to-compile) way of solving this relies on the manual include guards (#ifndef MY_HEADER etc.) that are presumably present in the headers in question:
Gather all the header files that you want to use (excluding all the ones you don't want/need).
Create a central include file that #includes all of these files (by as absolute of a path as you can, i.e. make sure this picks the correct foo.hpp gathered above, not one of the "original" ones).
Tell your compiler to force-include this central include file. Realistically, you should just make this a precompiled header (or include it in yours).
Due to force-including all these headers at the start of every translation unit, all the include guard defines are already set before you ever reach the point of the "wrong" headers being included. The compiler will still copy-paste them in there, but the include guards will prevent any code in them from being considered.

Why do projects use the -I include switch given the dangers?

Reading the fine print of the -I switch in GCC, I'm rather shocked to find that using it on the command line overrides system includes. From the preprocessor docs
"You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories."
They don't seem to be lying. On two different Ubuntu systems with GCC 7, if I create a file endian.h:
#error "This endian.h shouldn't be included"
...and then in the same directory create a main.cpp (or main.c, same difference):
#include <stdlib.h>
int main() {}
Then compiling with g++ main.cpp -I. -o main (or clang, same difference) gives me:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:194:0,
from /usr/include/stdlib.h:394,
from /usr/include/c++/7/cstdlib:75,
from /usr/include/c++/7/stdlib.h:36,
from main.cpp:1:
./endian.h:1:2: error: #error "This endian.h shouldn't be included"
So stdlib.h includes this types.h file, which on line 194 just says #include <endian.h>. My apparent misconception (and perhaps that of others) was that the angle brackets would have prevented this, but -I is stronger than I'd thought.
Though not strong enough, because you can't even fix it by sticking /usr/include in on the command line first, because:
"If a standard system include directory, or a directory specified with -isystem, is also specified with -I, the -I option is ignored. The directory is still searched but as a system directory at its normal position in the system include chain."
Indeed, the verbose output for g++ -v main.cpp -I/usr/include -I. -o main leaves /usr/include at the bottom of the list:
#include "..." search starts here:
#include <...> search starts here:
.
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/lib/gcc/x86_64-linux-gnu/7/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
Color me surprised. I guess to make this a question:
What legitimate reason is there for most projects to use -I considering this extremely serious issue? You can override arbitrary headers on systems based on incidental name collisions. Shouldn't pretty much everyone be using -iquote instead?
What legitimate reasons are there for -I over -iquote? -I is standardized (at least by POSIX) while -iquote isn't. (Practically, I'm using -I because tinycc (one of the compilers I want my project to compile with) doesn't support -iquote.)
How do projects manage with -I given the dangers? You'd have the includes wrapped in a directory and use -I to add the directory containing that directory.
filesystem: includes/mylib/endian.h
command line: -Iincludes
C/C++ file: #include "mylib/endian.h" //or <mylib/endian.h>
With that, as long as you don't clash on the mylib name, you don't clash (at least as far header names are concerned).
Looking back at the GCC manuals it looks like -iquote and other options were only added in GCC 4: https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Directory-Options.html#Directory%20Options
So the use of "-I" is probably some combination of: habit, lazyness, backwards compatibility, ignorance of the new options, compatibility with other compilers.
The solution is to "namespace" your header files by putting them in sub directories. For example put your endian header in "include/mylib/endian.h" then add "-Iinclude" to the command line and you can #include "mylib/endian.h" which shouldn't conflict with other libraries or system libraries.
I this your premise that it's -I that's dangerous is false. The language leaves the search for header files with either form of #include sufficiently implementation-defined that it's unsafe to use header files that conflict with the names of the standard header files at all. Simply refrain from doing this.
An obvious case is cross-compilation. GCC suffers a bit from a historical UNIX assumption that you're always compiling for your local system, or at least something that's very close. That's why the compiler's header files are in the system root. The clean interface is missing.
In comparison, Windows assumes no compiler, and Windows compilers do not assume you're targeting the local system. That's why you can have a set of compilers and a set of SDK's installed.
Now in cross-compilation, GCC behaves much more like a compiler for Windows. It no longer assumes that you intend to use the local system headers, but lets you specify exactly which headers you want. And obviously, the same then goes for the libraries you link in.
Now note that when you do this, the set of replacement headers is designed to go on top of the base system. You can leave out headers in the replacement set if their implementation would be identical. E.g. chances are that <complex.h> is the same. There's not that much variation in complex number implementations. However, you can't randomly replace internal implementation bits like <endian.h>.
TL,DR : this option if for people who know what they're doing. "Being unsafe" is not an argument for the target audience.

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.

c/c++ : header file not found

Some header files are present in /src/dir1/ (eg: a.h, b.h, c.h etc). My source file is present in /src/dir2/file.cpp. I used some header files that are present in /src/dir1/ but during compilation I got errors like header file not found.
Then I changed the include path like #include "../src/dir1/a.h", then error is gone in file.cpp but I get not found error in the headers files that are present in /src/dir1. Because I included the header file say a.h, that a.h included some other header files that are present in /src/dir1/ (say b.h and c.h present in a.h).
How to add the header file (a.h) in /src/dir2/file.cpp so that it should not ask to modify the include path in the header files that are present in /src/dir1/?
Note: I am using scons to build.
You can add directories to the include file search path using the -I command line parameter of gcc:
gcc -I/src/dir1 file.cpp
SCons FAQ:
How do I get SCons to find my #include files?
If your program has #include files in various directories, SCons must somehow be told in which directories it should look for the #include files. You do this by setting the CPPPATH variable to the list of directories that contain .h files that you want to search for:
env = Environment(CPPPATH='inc')
env.Program('foo', 'foo.c')
SCons will add to the compilation command line(s) the right -I options, or whatever similar options are appropriate for the C or C++ compiler you're using. This makes your SCons-based build configuration portable.
Note specifically that you should not set the include directories directly in the CCFLAGS variable, as you might initially expect:
env = Environment(CCFLAGS='-Iinc') # THIS IS INCORRECT!
env.Program('foo', 'foo.c')
This will make the program compile correctly, but SCons will not find the dependencies in the "inc" subdirectory and the program will not be rebuilt if any of those #include files change.
It's not found because it's not there. You have one extra level of indirection. A file in "/src/foo/" would include a file in "/src/bar/" with "include ../bar/the_file"
In other words, in your example, there is no "../src/" relative to dir1 or dir2. The relationship is "dir1/../dir2" or "dir1/../../src/dir2"
To see this for yourself, make dir1 your current directory (chdir /src/dir1) and compare the difference betwee "ls .." and "ls ../src". The second ls will not work but the first one will.
Make sense? hope that helps

in include if i use "test.h" is the same with "path/test.h"?

I am working in ubuntu under c++ language.
I have a question: i use #include"header.h". Is this the same with /path/header.h? I ask you this question because as I've seen is not the same thing. Need some explications.
I ask you this question because I've downloaded and install gsoap on my computer. I added all the necessary dependencies in a folder and I've tried to run the app without installing gsoap ...on a different computer. I had some errors..i forgot to add stdsoap2.h file...I will add it today..in my folder..
The answer is it depends:
If you have "path/" added to your include path then including only "header.h" will work because then compiler already knows the path to lookup for your header files, if not
then you have to include entire path "path/header.h" so the compiler knows where to look for the header file.
If header.h is in the directory path/, then #include "header.h" will work for those header and source files (which #include header.h which happen to be in the same directory as header.h (path/).
On the other hand, if you are #include-ing header.h in a file that is in a different directory than path/, then the above way would not work. To make it work, you can try 2 different approaches:
#include the complete path to header.h. Your #include will look something like:
#include "path/header.h"
Include the path/ directory to the makefile. This will get g++ to look for header.h in those directories as well. This can be done like so (in the makefile):
g++ <some parameters> -Ipath/ -c main.cpp -o main.o (assuming header.h is called from within main.cpp). If you choose this way, then the #include will also change, like so:
#include <header.h>. Note the use of the -I flag as a parameter to g++. That flag tells g++ to look into additional directories as well.
No, they are not the same, conceptually. The results, however, could be the same. It depends on how you tell your compiler to find headers (the -I flag in g++). If you would compile with -I /path/, then you'd find /path/header.h with #include "header.h". If you do not use that include path flag, then you'd have to write #include "/path/header.h".