C++ Include Relative Paths Broken - c++

I am currently working on a large-scale financial application.
There are multiple modules that are compiled separately and then combined in a higher-level makefile.
Due to poor design, a lot of the header files include lots of local includes.
My problem is, when I include /src/equity/pdeModels/EqUtil.H inside my current source file /src/rwBatch/calcVol.C, all the includes at the start of EqUtil.H start to break, giving an error: ../../equity/pdeModels/EqUtil.H:15:30: fatal error: ulbase/SpotPrice.H: No such file or directory compilation terminated.
rwBatch and the equity folder are separately compiled and linked together later. Is this a problem with the makefile? Or how should I go about resolving this?
Indepth example:
/src/Module1/file1.C
/src/Module2/folderA/file2.H
/src/Module2/folderB/file3.H
When I write #include "../folderA/file2.H" in file1.C there are errors because of file2.H. At the start of file2.H there are several includes, for example #include "/folderB/file3.H" which, when compiled in file1.C leads to fatal error: /folderB/file3.H: No such file or directory compilation terminated.
Is this a problem with the makefile? Or how should I go about resolving this?

Specifying a path in an #include statement is almost always a bad idea. It takes information needed by the builder but not by the code, and locks it into the code.
As long as there are no name collisions (e.g. folderA/file3.h and folderB/file3.h) you can simply remove those paths. Change these:
// file1.c:
#include "../folderA/file2.H"
// file2.H:
#include "/folderB/file3.H"
to these:
// file1.c:
#include "file2.H"
// file2.H:
#include "file3.H"
And in your makefile (or other build system):
gcc -I/src/Module2/folderA -I/src/Module2/folderB -c /src/Module1/file1.C -o /wherever/file1.o
If there are name collisions, and you have a module that depends on two headers with the same name, you have some options. The simplest -- and probably best -- is to rename one or both of the headers. If you really must, you can put paths into the #include statements, but the paths should reflect the directory structure you use, not the other way around.

Related

Header files not found even though they are in the right directory?

I'm fairly new to programming using linux so forgive me for any dumb errors I might make in my question but basically I am trying to compile using the terminal (C++) and my code in a .txt file however I keep getting a fatal error that my header file can't be found? When I try to type
g++ -o test main.cpp header.h
I get the error stating "header.h: no such file or directory" in the terminal. I've ensured that both the cpp and header files are in the same directory but no luck there. I've also used
#include <"header.h">
in my main.cpp and header file to try different fixes. I've researched and looked at different answers but no fixes either. Any suggestions?
#include <"header.h">
Use either
#include <header.h>
will lookup the standard include directories for these header files first
or
#include "header.h"
will lookup all include directory pathes specified with the preprocessor options
but don't mix these up.
Also you don't need to specify the header in the compiler command line
g++ -o test main.cpp header.h
# ^^^^^^^^ omit this
That's what the #include statement in your code is for.

Cant compile rocksdb, dependencies not found

I am trying to compile a program that uses rocksdb.
According to the example in the official webpage, the only header i should add to my code is db.h.
Now, the file i am compiling is in folder A.
db.h however is in A/rocksdb-master/include/rocksdb/.
So, i add this line to my file:
#include "rocksdb-master/include/rocksdb"
It finds the file, but the problem is that inside db.h, i have this line:
#include "rocksdb/metadata.h"
And when i compile i get this error:
fatal error: rocksdb/metadata.h: No such file or directory
#include "rocksdb/metadata.h"
I mean, it's obvious. db.h is in the same folder as metadata.h, so it's fine that the compiler cant find any rocksdb folder. But i doubt that people who wrote this library don't know that.
Is there any other way to add the path's to compile it?
Why is it that the path from db.h are not relative to where it is located?
You should normally use just the following header in your project:
#include "rocksdb/db.h"
When compiling your own project, you should then add the RocksDB include path to the list of include directories. For example, if the RocksDB source code is in directory ../rocksdb-master, the include path will be ../rocksdb-master/include.
How to add the include path to the compiler flags is indeed compiler-specific. With g++ or clang, it's done by passing -I../rocksdb-master/include to the compiler when compiling your own program. Note that you many need to link against the RocksDB library as well.
And finally, you may need to include some more RocksDB headers if you use some of its advanced concepts, e.g. transactions.

source and header files

I'm facing difficulty in understanding source and header files stuff.
Suppose
1)I have a source file(functions.cpp) which contains function named 'int add(int x,int y)' in the location /Users/xyz/Desktop/functions.cpp.
2)The header file(functions.h) which contain the declaration of the functions in source file(functions.cpp) is placed in /Users/xyz/Documents/function.h
3)Other source file(main.cpp) which contain 'main()' function need to call the 'add()' function defined in 'functions.cpp'.The source file 'main.cpp' is located in /Users/xyz/Downloads/main.cpp
I'm placing these files in different locations so that i can understand these concepts better.
So,how do i link function.cpp to main.cpp using functions.h.
#include " "
What is the path that i should use in the above include?
Also,it is my understanding that .h files provides the declaration of functions which are defined some where else and having a declaration is necessary for the compiler to call the functions which are defined in some other files or functions which are not defined yet. Is that right? Please correct me in case I'm wrong.
#include "functions.h"
Your code should not know about how you choose to arrange your source tree. To hard-code paths is to earn the hatred of whoever has to maintain this code (and that includes you six months from now).
Your build system -- whatever it is -- can deal with the paths. That could be as simple as:
g++ -I/Users/xyz/Documents -c functions.cpp
Your statement of how declarations/definitions work is basically correct.
Your first question has no answer. C++ does not define how header files are found, it's up to the compiler and they all do it a bit differently. If you want an answer you'll have to look up the details in the documentation of your compiler. I would recommend you put everything the same directory and stop worrying about it.
In the second part of your question, your understanding seems pretty good to me.
You should include in your main the exact path to your header file:
#include "/Users/xyz/Documents/function.h"
Hope this help.
Regards.
You include functions.h in functions.cpp and main.cpp using #include then you compile both main.cpp and functions.cpp. The linker then links the two resulting object files. Your inclusion of functions.h in main.cpp will allow you to call the functions from functions.h within your main.cpp file
As for paths of files, provided that you specify to your compiler the required paths in which to find your code you should be fine.
You can either use a full path
#include "/Users/xyz/Documents/function.h"
or a relative path (which is usually more preferable)
#include "../Documents/function.h"
Don't forget to specify full or relative paths to your .obj files when you are linking the final executable as well ;)

How can the order of include statements matter in the linking step?

I cannot explain the behaviour I am seeing when linking my code. Maybe someone has an idea what's going on...
I have a multiple file C++ project which uses GNU automake tools as its build system (all on Linux).
After adding a source and header file (lets call them util.cc and util.h) to the project and having an already existing source file (calc.cc) calling a function from the newly added files I get a linking error depending on where the include statement appears. I repeat: The error occurs in the linking step, compilation runs fine!!
Example:
I get an error when putting the new include statement at the end of the preexisting statements, like:
calc.cc:
#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"
#include "util.h" // new header
This version compiles fine. But linking produces an error (symbol not found)!!
Now, when changing this to
#include "util.h" // new header
#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"
then compilation and linking runs fine!
Since the linker only reads the .o files, this must mean that different content is produced depending on where the include statement appears. How can this be?
Compiler is g++ (GCC) 4.4.6
Chances are that util.h has a #define that changes the behaviour of one of the other files.
Your best chance of working out exactly what is going on would involve examining those header files for the name of the missing symbol and getting the pre-processor output from compiling calc.cc both 'working' and 'non working' way, and comparing the two files.
Simple, header files can (re)define macros which can change the interpretation of later macros.
For instance, in your example above, if file1.h does
#define lseek lseek64
and util.h has an inline function which calls lseek, then depending on the include order the generated object code will have a symbol reference to lseek or lseek64.
Which is why projects tend to have rules that config.h (generated by autoconf) is included first.
You're absolutley right: different object code is produced in the two cases. As #hmjd also points out, most likely there's a macro in util.h which one of the other (.h or .c) files use, and any undeclared, called identifier is assumed to be a function by the compiler -- this is most likely the error here.

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".