C++ cross-folder include failing - c++

I've got a project which has two source folders (main and lib). It produces a shared library and an executable. It is currently built as so:
copy all files from both folders into a new temp folder
run lib_makefile
run main_makefile
copy binaries out
delete temp folder
This struck me as being a weird way to do things, so I tried building each in-place by adding -I../main to lib_makefile (and vice-versa). Unfortunately, this doesn't seem to work.
Illustrative example:
foo.cpp (in lib) includes bar.h (in main), which includes baz.h (back in lib).
When I try to compile the shared lib, it correctly locates bar.h in main/, but then bails out with "no such file or directory" claiming it cannot find baz.h, even though baz.h is in the same directory as lib_makefile!
All includes are in the format #include "xxx.h" (i.e no relative paths in the include statements).
Is there a way to get this to work? I feel like I must be missing something obvious..
(nb: I can't modify the #includes because other people still build this the copy-everything-across way)

You should add something like -I../lib (or whatever your library path is) to the makefile for the library as well.
The reason for this is that the pre-processor looks for include-files relative to the directory the current file is in, not from where the original file is in.

Related

What is the best way to avoid missincluding same files?

Given the file tree:
DLL1
└───source
├───File1.h
└───SameHeader.h
DLL2
└───source
├───File2.h
└───SameHeader.h
File1 includes SameHeader.h, which is fine.
File2 includes File1 which won't compile, because the #include "SameHeader.h" now points to the DLL2/source/SameHeader.h. Is there a way to ensure File1 uses the file which in the same dll?
Sure - you can put the file SameHeader.h in a separate folder (not the same as the source files) and then specify that folder in your list of include paths to search (in the project options, or in the compiler command switches).
You will, of course, need to delete the file SameHeader.h from each of the source project directories, or that will be used in preference to the one in the separate folder.
So, using your "file tree" diagram, I would suggest this:
DLL1
└───source
├───File1.h
DLL2
└───source
├───File2.h
Include
└───SameHeader.h
You could then add ../Include to your compiler's include file search path. How to do this depends on your compiler and/or environment, but it will be something along the lines of a /I"..\_Include" switch in MSVC or (probably) -I"../_Include" with clang. This is what I do in multi-project solutions, for all header files that will be used by more than one project.
However, if you actually need two (different) SameHeader.h files, then you should perhaps specify the full path name (or, at least, a qualified path) in the #include "SameHeader.h" line in File1 - something like: #include "../../DLL1/source/SameHeader.h" (depending on the exact layout of your files & folders).

Compiling Eigen C++ QT

Eigen is located in the file
C:\Users\jherb_000\Downloads\eigen-eigen-07105f7124f9
I thought to include eigen you just use
`#include "C:\Users\jherb_000\Downloads\eigen-eigen-07105f7124f9\Eigen/Dense" `
But it is not compiling. I know it can work because I have done it before, and the eigen website does not explain how to do this unless you are using specific programs like g++.
Since you imply via the tags that you're using qt-creator, your problem boils down to "How do I add an include directory in qt-creator?" There are answers for that here, here and others. One thing to note is that the path you should add is C:\Users\jherb_000\Downloads\eigen-eigen-07105f7124f9.
What happens is when you include a specific file in a specific directory, if that file doesn't #include any other files (ok, other files that aren't in the include paths) all works well. But if it does, (and Eigen files include other file in the Eigen project) then the compiler does not know where to search for them. That's why you have to explicitly tell the compiler which directories to look for files that are included.
Very easy. Let's say you have a dependencies directory, and inside you have the eigen directory. In your .pro file, you could add your dependencies path to your INCLUDEPATH:
INCLUDEPATH += ../dependencies/ # or wherever that path is (relative to your .pro file)
Then, to include the Dense module, you do:
#include <eigen/Dense>
where eigen refers to your folder eigen in your dependencies folder. Many variations possible in function of your setup, but you got the idea.
Ok then what you need to do is:
Copy the C:\Users\jherb_000\Downloads\eigen-eigen-07105f7124f9\Eigen directory and all it's contents to wherever you're keeping all your third-party library files on your machine. (You probably wouldn't want to keep these files in your Downloads folder). For example let's say this directory is copied to C:\jacks_code\Eigen. Then,
Add this new directory to Qt-creator's list of directories to search (see Aki's answer for links):
In each of your source files, to include the Eigen templates, use the preprocessor directive:
#include <Dense>
The compiler will use the directories you told it, to dereference the file to C:\jacks_code\Eigen\Dense (the complete filename). It's a bit confusing here because the files in the root Eigen folder don't have .h or .c or .cpp or .hpp extensions.
Hope that helps. You can also read the INSTALL file in the base of the unzipped package.

Successfully Included File, now dealing with semantics issues

Earlier I asked for help in including an external library called Eigen in xcode 4. I finally managed to get it to include the header file I wanted to use, Array, by going to build phases, link binary with libraries, and then adding the sub-folder within the Eigen archive where Array.h was located, Core. I also added the filepath to Core's parent directory, src, in header search paths.
When I finally managed to add the line of code #include <Core/Array.h> without it getting highlighted as an error, I ran the application (which worked previously) and XCode said that the build failed, with the error messages citing semantic issues. I checked the error message and they include, "Uknown identifier 'Array'" in a file named Array.h.
All of the header files are in src and according to the Eigen website, they are all that's needed to use Eigen with c++. I've attempted to reformat the binary links so they go to src instead of Core, and adjusting the buildpath to lead to the parent directory of src, ensuring that all header files can now be accessed, but I'm still getting semantics issues. Does anyone have a solution to this?
You generally want to include the Core file, not the individual .h files, i.e.
#include <Eigen/Core>
There are exceptions, but again, you won't be including the .h files, those are used internally. Additionally, it appears that your include path points to the ./Eigen/src/ directory. You want to move it up two directories so that when you write #include <Eigen/Core> it finds the Core file correctly. The files that you'll most likely include are the extension-less ones in the Eigen directory.

Visual Studio unable to find header file during compile despite include directory have been specified

After adding the include directory of the library which I am using. Visual Studio 2010 is able to find the header files I #included into my source code (IntelliSense does not show any errors). However when building the solution, it tells me that it wasn't able to find the header file. The same property used in my previous project does not post this issue.
The only solution I have now is to use the direct address for all the header files from that library, but I find it very irritating to do so, as the header files of the library cross reference each other and it does not make sense to edit all of them.
Does anyone have any idea what causing this problem?
It might because you have source + headers in 2 directories that refer to each other's header files. I.e. the files are
1/a.c
1/a.h
2/b.c
2/b.h
and the contents of a.c and b.c have the same includes
#include "a.h"
#include "b.h"
Your project can find a.h when compiling a.c, and it can find b.h when compiling b.c (since the same directory is assumed in the search path when you use double-quotes in #include "xxx"). But a.c can't find b.h and b.c can't find a.h by default. Your project might be in directory 1 and you may have set up the include directory to look at 2. That works fine until 2/b.c needs to include "a.h". You need to set up the include directory path to include 1 as well as 2, even though 1 is your original project directory and it seems silly to do that.
This is a reason why IntelliSense can open the files (since it is omniscient), but the compiler can't (since it just looks at one file at a time).
IntelliSense uses a slightly different algorithm when searching for include files compared to the compiler & linker. In particular, it can also (sometimes) find header files even though the include directories are not properly specified.
I'll assume you specified the include directories correctly.
An idea: There's a bug in Visual Studio 2010 that if you specify a rooted path (ex. \myproject\includes), then when building the solution, VS uses the drive where it is installed (usually C:) rather than the drive where the solution is located. If this is the case, you'll have to either specify the drive (ex. D:\myproject\includes) or use a relative path (ex. ..\..\myproject\includes).
It seem like the actual problem is cause by me not adding the include directory in the project which was referring to the project which was implementing the library.
This explain why I could build the referred project by itself and only having the problem when I compiled the solution as a whole.
I find this rather dumb to require us to re-declare the include directories in referring project when we have already done so in the referred project

segfault because of missing header files

I had forgotten to put a 3rd party "header only" library header (.h) files into the correct path when building a shared object. It built fine - retrospectively surprising.
When run a segfault occurred exactly at the line when that 3rd party lib was used in my shared object.
The part I do not understand is when I copied those header files to the path specified with #include, I could not cause a segfault. I did not even re-build the object. The very strange thing is that when I mv the dir the header files are in, it still worked - no segfault. However, when I completely rm the dir, it crashed. Does it look for header files the current dir and subdirs? I've also got that header-only library in the standard(?) /usr/local/include
I've not worked with shared objects before. I usually create static objects and include them in the build. The flags I used to create the shared object in question are -shared -fPIC
I'd like to understand this behavior. It's interesting because of deployment. Do I need to include those header files when deploying on the production machine? Essentially I don't want to have that as a dependency as it is a "header-only" lib.
edit
Code:
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
void MyClass::myFunction()
{
rapidjson::StringBuffer string;
rapidjson::Writer<rapidjson::StringBuffer> jsonWriter(string);
}
Here is a link to the debug session:
http://pastebin.com/a0FaQwf1
You never need to supply header files to the user in order to run the program.
Your library probably just refines defaults,
that is the reason why it do not fail when missing at compile time
An explanation for the strange move/remove behavior could be that the shared object was still loaded into memory during the move and kept an open file handle to something in the include dir.
You know, under ext2/3/4 open files are connected to inodes and not to dir paths. Thus moving an open file won't harm. On the other hand IIRC also removing won't harm. The freeing of the inode will be delayed until all processes have closed the file. Maybe this just happened between your mv and rm.