I have 2 Dirs and 3 header files stored in them, as follows:
Dir A : contains Header files A and C
Dir B : contains Header file B
Dirs A and B are sub-directories of a dir named Apps (which is a subdir of some other dirs).
Basically, the problem occurred in a similar situation, from which I have isolated the problem. Hence, the C++ source files shown below are trivial:
Header file A.h:
#ifndef A_H
#define A_H
class A
{
};
#endif /// A_H
Header file C.h:
#ifndef C_H
#define C_H
#include "B.h"
class C
{
};
Tester for A.h, viz. TestA.cpp:
/** TestA.cpp */
#include "A.h"
/// ...
int main()
{
}
Tester for C.h, viz. TestC.cpp:
/** TestC.cpp */
#include "C.h"
/// ...
int main()
{
}
Dir B contains 1 C++ header file B.h and its tester TestB.cpp, both trivial:
Header file B.h:
#ifndef B_H
#define B_H
#include "A.h"
class B
{
};
#endif /// B_H
Tester for B.h, viz. TestB.cpp:
/** TestB.cpp */
#include "B.h"
/// ...
int main()
{
}
The 3 testers TestA.cpp, TestB.cpp and TestC.cpp have 3 makefiles: MakeA, MakeB and MakeC respectively. MakeA and MakeC are in dir A and MakeB is in dir B, as expected.
I am not showing MakeA and MakeB, since they work correctly.
The error occurs in MakeC:
CPP = g++
OFLAG = -o
CFLAG = -std=c++11 -c
PROG1 = TestC
HC = C
HB = B
HA = A
HBDIR = ../B/
HADIR = ./
IHBDIR = -I$(HBDIR)
IHADIR = -I$(HADIR)
all : $(PROG1).o $(PROG1).exe run1
$(PROG1).o : $(PROG1).cpp $(HADIR)$(HC).h $(HBDIR)$(HB).h $(HADIR)$(HA).h
$(CPP) $(CFLAG) $(IHADIR) $(IHBDIR) $<
$(PROG1).exe : $(PROG1).o
$(CPP) $(OFLAG) $# $^
run1:
$(PROG1)
This make file is unable to locate header file A (which is #included by header file B) and gives the following error:
In file ...
../B/B.h fatal error: A.h : no such file or directory
#include "A.h"
compilation terminated
Evidently, make is searching for A.h in B.h's dir (since B.h #includes A.h). However, I have defined the symbol HADIR (as ./), which should have caused make to search in the default dir, which is Dir A.
Please note:
1) The header file references are simple and linear : A.h is #included by B.h which is #included by C.h.
2) I don't wish to hard-code dir paths in the source files. They must be stored only in the makefiles, since that's one of the purposes of makefiles.
3) There are 2 solutions to the problem that I know of:
a) Relocate C.h, its tester and makefile to a dir C. However, I don't want to do this, since A.h and C.h are semantically related.
b) In MakeC, define HADIR as ../A, rather than ./ But I don't understand why I should do that.
The BAT file that invokes the make utility with MakeC as input makefile, is as follows:
cd /f/Files/C/SW/Applications/Samples/C++Samples/Introductory/
Classes/Apps/A/
make -f MakeC
Thanks.
See this link for information on which paths include searches. Assuming you used the form include "file" (with quotes, not #include <file>, which is slightly different):
By default, the preprocessor looks for header files included by the
quote form of the directive #include "file" first relative to the
directory of the current file, and then in a preconfigured list of
standard system directories. For example, if /usr/include/sys/stat.h
contains #include "types.h", GCC looks for types.h first in
/usr/include/sys, then in its usual search path.
...
There are a number of command-line options you can use to add
additional directories to the search path. The most commonly-used
option is -Idir, which causes dir to be searched after the current
directory (for the quote form of the directive) and ahead of the
standard system directories. You can specify multiple -I options on
the command line, in which case the directories are searched in
left-to-right order.
notice that
directory of the current file
refers to the directory that gcc was invoked from, as opposed to the directory of the source file (not the best wording). So, if you invoke gcc from the directory of your .c file, you would want to add a -IA -IB flag to your compiler options, and then do not include paths in your #include directives (assuming gcc is being called from the directory of the .c file).
If you do want to include paths, they must be relative to the directory from which gcc was invoked, or one of the other include paths specified by a -I option.
---- EDIT -----
OK, I just read your updates, and it seems that TestC.c is in directory A, which I didn't get from your original post This means you're compiling from directory A. In this case I cannot reproduce your problem (at least not on my linux system):
[157]~/tmp/tmp9/A> find .. -type f -exec echo "------ " {} " ------" \; -exec more {} \;
------ ../A/A.h ------
#pragma message "A.h"
// blank
------ ../A/C.h ------
#pragma message "C.h"
#include "B.h"
------ ../A/testC.c ------
#pragma "message file.c"
#include "C.h"
int main() {}
------ ../B/B.h ------
#pragma message B.H
#include "A.h"
[157]~/tmp/tmp9/A> gcc -I. -I../B testC.c
In file included from testC.c:2:
C.h:1: note: #pragma message: C.h
In file included from C.h:2,
from testC.c:2:
../B/B.h:1: warning: expected a string after ‘#pragma message’
In file included from ../B/B.h:2,
from C.h:2,
from testC.c:2:
./A.h:1: note: #pragma message: A.h
[157]~/tmp/tmp9/A>
Your make command should echo the command used to build your test program -- attach that output to the question.
Per https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_2.html#SEC6:
Section 2.1: Include Syntax
[#include with quotation marks] is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the same directories used for <file>
Since we're discussing an include-with-quotes from another header, we must figure out what is considered the "current file". Our options are:
the source file that included the original header
the original header itself (that now includes the subject header)
Section 2.2: Include Operation
The `#include' directive works by directing the C preprocessor to scan the specified file as input before continuing with the rest of the current file
To me, this wording implies that #include acts as an interruption to the processing of "current file", during which the included file becomes "current". (Consider how this would have been written if the #include were interpreted as expanding into or as a part of the #including file.) Also, if the quotation-mark version of #include were interpreted in the context of the #including file, it would break all the time and be mostly useless.
So the #include "A.h" within B.h looks for A.h relative to the location of B.h. But $HADIR is not equal to $HBDIR so this lookup fails.
Note however that -I adds to the list of places that should be searched by #include-with-angle-brackets...which should also be searched after "directory of the current file" for #include-with-quotation-marks...so your compiler is doing something weird with it's search.
I also confirm that gcc 4.8.5 does not repro your issue. Here's my test setup relative to the directory Prog
[Prog]$ find ..
../Prog
../Prog/A.h
../Prog/MakeC
../Prog/TestA.cpp
../Prog/TestC.cpp
../Prog/C.h
../B
../B/B.h
../B/TestB.cpp
Then building yields:
[Prog]$ make -f MakeC
g++ -std=c++11 -c -I./ -I../B/ TestC.cpp
g++ -o TestC.exe TestC.o
TestC
What compiler are you using? (I'd bet a fair sum it's either old (circa gcc 2.9.6) or is customized by a vendor to target an embedded plaform) I've seen interesting include path checks with some of these.
Here's a small contrived demo to show the proper behavior of #include-with-quotes:
inc/a.h
#pragma once
#include "b.h"
inc/b.h
#pragma once
extern int garbage;
test.c
#include "inc/a.h"
Then
$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
# 1 "inc/a.h" 1
# 1 "inc/b.h" 1
extern int garbage;
# 4 "inc/a.h" 2
# 1 "test.c" 2
Note the main .c file includes "inc/a.h" directly, and there is no search path given on the compiler commandline, yet it still finds "b.h".
OK, I've finally solved the problem as follows:
1) Make the BAT file set the default dir to 1 dir above the A and B dirs, ie, to the Apps dir, and invoke the make utility from there:
cd /f/Files/C/SW/Applications/Samples/C++Samples/Introductory/Classes/Apps/
make -f A/MakeC
2) Modify the makefile to access each header explicitly from the dir in which it is stored, create the obj and exe file in a specified dir and invoke the exe file in the specified dir:
CPP = g++
OFLAG = -o
CFLAG = -std=c++11 -c
# BAT file invoking MakeC sets default to ... Classes/Apps/
HADIR = ./A/
HBDIR = ./B/
# HADIR contains HA and HC
# HBDIR contains HB
HA = A
HC = C
HB = B
PROG1 = TestC
IHADIR = -I$(HADIR)
IHBDIR = -I$(HBDIR)
all : $(PROG1).o $(PROG1).exe run1
$(PROG1).o : $(HADIR)$(PROG1).cpp $(HADIR)$(HC).h $(HBDIR)$(HB).h $(HADIR)$(HA).h
# Create obj file in HADIR explicitly
$(CPP) $(OFLAG) $(HADIR)$# $(CFLAG) $(IHADIR) $(IHBDIR) $<
$(PROG1).exe : $(HADIR)$(PROG1).o
# Create exe file in HADIR explicitly
$(CPP) $(OFLAG) $(HADIR)$# $^
clean:
# Specify dir explicitly
rm $(HADIR)*.exe $(HADIR)*.o
run1:
# Specify dir explicitly
$(HADIR)$(PROG1)
As I've stated, I'm using g++ 4.8.1.
What worked for me, was to have the invoking BAT file set the default dir to one level above the dirs that contain the source files and in the makefile, specify the dirs explicitly.
---- EDIT ----
I'd like to suggest a possible reason for why this works.
First, notice that originally, the HADIR variable was set to ./ (the default dir).
As #lockcmpxchg8b said, the "default dir" could be interpreted as (a) wrt the original file or (b) the #included header file. These are the only 2 possibilities. Since the compiler can't find the #included header, it means it has selected the wrong possibility. This is obviously a version-specific gcc problem, since others can't repro the problem on later gcc versions.
Then, the solution is to avoid using ./ as a value for a dir symbol such as HADIR. Instead set the default dir outside make to another dir. In this case, it was done to the dir one level above A and B (viz. Apps). Then, the makefile's dir symbols can be made all wrt to that dir and would obviously not be ./
With values other than ./ (interpreted as the default dir by the compiler), the compiler interprets the value for the dir symbol as desired.
I think in your "B.h", you should do: #include "(Adir)/A.h"
It seems like "A.h" is in a adjacent directory of the "B.h" directory. so when "B.h" tries to look for it in its current directory, it can't find it.
I'm guessing #include "../A/A.h"
The path to my .cpp and .h files: /home/quasiturbine/ServerProject/Network/NetworkIncludes/
There you can find TCP_Connexion.h and TCP_Connexion.cpp
In the .cpp file, I got #include "NetworkIncludes\TCP_Connexion.h" and default constructor/destructor. That's it.
G++ command:
g++ -o program -I/home/quasiturbine/ServerProject/Network/ /home/quasiturbine/ServerProject/Network/NetworkIncludes/TCP_Connexion.cpp
fatal error:
/home/quasiturbine/ServerProject/Network/NetworkIncludes/TCP_Connexion.cpp:1:43: fatal error: NetworkIncludes\TCP_Connexion.h: No such file or folder
#include "NetworkIncludes\TCP_Connexion.h"
What is wrong and how can I fix it?
The problem is, that you are using backslashes \ when you should be using forward slashes /. Backslashes in include paths are undefined behavior before C++11 and implementation defined afterwards (reference).
So change your include to
#include "NetworkIncludes/TCP_Connexion.h"
and you should be good to go.
Environment
Ubuntu 16.04
G++ 5.3.1
I have a header file with the following intended to include a different .h file depending on platform:
#ifdef _WIN32
#include "curses.h"
#else
#include <ncurses.h>
#endif
This works fine in windows but in Ubuntu I get errors about the curses.h file:
In file included from /usr/include/unctrl.h:54:0,
from /usr/include/curses.h:1694,
from headers/command_window.h:8,
from command_window.cpp:1:
headers/curses.h:900:19: error: macro "clear" passed 1 arguments, but takes just 0
int clear(void);
This when compiling with:
g++ -g -lncurses -std=c++11 -Iheaders -c -o command_window.o command_window.cpp
Why is headers/curses.h, which is the windows specific file for PDCurses being involved here at all?
/usr/include/unctrl.h contains this line:
#include <curses.h>
And since you've told the compiler to look in your headers/ folder for header files with the -Iheaders flag , the compiler picks up curses.h in that folder.
So you need to drop the -Iheaders flag (and e.g. use #include "headers/header_name.h") or you need to rename your headers/curses.h to not collide with /usr/include/curses.h
In your version of g++, the -I option is not the correct way to add application-specific header files (those that shouldn't be found by #include in system headers) to the search path (this change surprised me as well).
Instead, you should use -iquote headers.
See this answer: How to tell g++ compiler where to search for include files? and this official documentation
I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx
I'm trying to compile a third-party library, but g++ is complaining about the following line:
typedef boost::shared_ptr<MessageConsumer> MessageConsumerPtr;
The strange thing is, there is no #include directive in the file - and it is clearly supposed to be this way; there are about 60 files with the same (or very similar) issues. Clearly if there was an #include directive referencing the relevant boost header this would compile cleanly.
My question is: how can I get g++ to somehow automagically find the relevant symbol (in all instances of this issue, it is a namespace that can't be found - usually std:: or boost::) by either automatically processing the relevant header (or some other mechanism).
Thanks.
Edit
My current g++ call looks like:
g++ -fPIC -O3 -DUSING_PCH -D_REENTRANT -I/usr/include/boost -I./ -c MessageInterpreter.cpp -o MessageInterpreter.o
You can use the -include command line option:
g++ -include boost/shared_ptr.hpp ...
From the man page:
-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.
Create your own wrapper .h file that includes the boost .h and then the broken .h .
Or (very fragile) ensure that you precede every use of the broken .h with boost .h .
Perhaps the third-party library is designed in such a way that you should always include a certain "main" header file in order to get the dependencies right.
Otherwise, you can add #include <boost/shared_ptr.hpp> before including the third-party header file that is giving the error message.