I am developing C++ headers only library, lets call it PROJ. When a library header is including another, it uses:
#include <proj/foo.h>
And compiler (gcc and clang) have -I path-to-proj-parent. Users of the library should also have parent of PROJ in their include search path.
My rationally for using this scheme is that after installing this library into proj subdirectory of default-seachable parent (/usr/include/proj or /usr/local/include/proj), library user do not need to specify -I option.
Is there cons to this scheme? Is using <foo.h> without proj/ prefix is more conventional and recommended way?
Question is not about if installing in subdir or not (there will be proj subdir), but rather how to refer to include-files.
If you look at boost, you will note that they use a similar scheme:
#include <boost/shared_ptr.hpp>
It has the advantage of preventing clashes with another similarly named file from another dependency.
However, in the case of boost, they take it one step further. If you include <x/y/z.hpp>, then you are likely to be dealing with an entity named ::x::y::z (be it function or class). That is, the way the directories in the project are laid out mimic the namespace organization. It's quite neat really to orient oneself.
Normally, most projects are stashed in subdirectories (and subnamespaces), but the most used ones are pulled into the boost namespace for convenience, and thus they have headers living directly in the boost folder. There are also some convenience headers (whose job is just to gather a smattering of other headers to pull them in all at once).
You may finally note, if you open a header file, than the include guards they use follow the exact same hierarchy:
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
once again because it helps avoiding clashes since it's named after the very file it's in and there can be only one at that place in the whole Boost project (on case sensitive filesystems).
It is ok to have proj in the path if you create the proj directory when you install. In fact its a good way to prevent name collisions with other include files.
The name should not be something generic like "proj' though. It should be specific to the project.
Related
Whenever I start developing a new shared library in C++ I come across the same question:
Should I use includes relative to the position of the current file or includes relative to the (potential) include paths (-I) to refer to other header files within my project, i.e. the same library?
I checked with some of the library headers installed on my system.
boost appears to use includes relative to the include path and <>brackets to include other boost headers, i.e. #include <boost/move/move.hpp>
poppler on the other hand appears to use some weird relative paths with "", sometimes relative to the current location and sometimes relative to its base (I didn't even know that this works), .e.g. in fofi/FoFiEncodings.hthere is an #include "goo/gtypes.h" where fofi and goo are directories on the same level
many others simply include files with "" and their location relative paths, mainly files in the same directory
Does it depend on the directory structure (i.e. its complexity) of the shared library itself, i.e. location relative paths work well with simple layouts but have drawbacks with more cross references like in boost? Are there any technical reasons or pitfalls why one might work but the other doesn't (portability, compiler dependent behavior, ...)?
Boost uses brackets instead of quotes. This means that it isn't an absolute path, but that the search starts relative to the list of linclude directories that was provided to the compiler. So it's a variant of the relative path.
A really absolute path is a bad idea because if another developper installs the source code at another location, he/she'll not be able to compile unless he/she changes all the header references in the sources.
Edit:
If you develop a library that is general enough and designed to be shared across several (possibly unrelated) projects, the bracket option should be the preferred one. This lets you the freedom to install the library wherever you want, and also to switch libraries (different versions for different projects) very easily.
If you develop a more specific library in the context of a larger solution, mainly to isolate reusable code, the quoted relative path is an option. If later you want to reuse that library in another context, you would have to install its sources in the new solutions directory so that the relative paths still work. So the use case is a little different (narrow sharing and occasional reuse in the context of very specific projects).
In your source file, do whatever you want/prefer.
For public headers, relative path is the preferred way, as user might place your headers in a specific place and use not exactly the same include directive.
I mean, suppose that your hierarchy is:
lib/headers/sub1/h1.h
lib/headers/sub2/h2.h
lib/headers/lib.h
lib/src/..
with directive to set include path to lib,
user should do #include <headers/lib.h>, but then your lib.h should look like:
#include "headers/sub1/h1.h"
#include "headers/sub2/h2.h"
and sub1/h1.h to
#include "headers/sub2/h2.h"
With directive to set include path to lib/headers,
user should do #include <lib.h>, but then your lib.h should look like:
#include "sub1/h1.h"
#include "sub2/h2.h"
and sub1/h1.h to
#include "sub2/h2.h"
So depending of directive set by user, your code won't compile for user.
With relative path, for both above directives, your files would be identical
lib.h:
#include "sub1/h1.h"
#include "sub2/h2.h"
and sub1/h1.h to
#include "../sub2/h2.h"
I use a code with different libraries, which use names like defines.h. This does not only cause conflicts for identical filenames, but also creates confusion. From which library is the defines.h include?
Including as #include <library/defines.h> would be a clean solution, but then the include path would need to be the parent directory of the library, which is rather unclean again.
Is there some way to alias the include path, so that -I/path/to/library makes the headers available under library/headername.h?
Is there some way to alias the include path, so that -I/path/to/library makes the headers available under library/headername.h?
There seems to be no need to in this case. You can simply use -I/path/to which makes /path/to/library/headername.h available under library/headername.h.
That said, while there is no such compilation option (that I know of), you can create such "aliases" to file paths in most file systems. These aliases are called symbolic links. In this case, you could make a link /path/to/library/mylibrary that points to . which would make /path/to/library/headername.h available under mylibrary/headername.h assuming you've used -I/path/to/library.
At least on unixy systems, when you compile and install a library, headers are installed for example to
/usr/lib/libraryname/*.h
Or maybe something like
/opt/libraryname-1.2/include/libraryname/*.h
And then if necesssry (not installing to compiler's default include search path), right dir is added with compiler option, for gcc for example option
-I/opt/libraryname-1.2/include
Then just always do this in source code, trusting build system to have included the right search paths:
#include <libraryname/includefile.h>
While orienting myself to one of the open source C++ project I found a line of code in the root CMakeLists.txt file:
include_directories(${PROJECT_SOURCE_DIR}/../include)
And then in one of the source files there is this line:
#include "someFolder/someFile.h"
someFolder is found in include folder.
I have seen a different approach in another project,
in which the CMakeLists.txt has something like this:
include_directories(${PROJECT_SOURCE_DIR}/../include/someFolder)
then in the source file:
#include "someFile.h"
The first approach typically "namespaces" the include path by the name of the project the header belongs to. Are there common benefits to this when integrating multiple projects together? If so, what are those common benefits?
I prefer subdirectories for include files.
The main reason for this is to avoid file name conflicts. If dependency A has a file called someFile.h, and dependency B also has a file called someFile.h, you got a problem, because the compiler doesn't know which one to include.
So for the same reason you should use namespaces, you should also use subdirectories for include files when possible.
Well, this is very opinion based, in my opinion...
I prefer the former approach, especially for larger libraries. It exhibits the logical structure of the library as intended for by the authors.
In the following files:
app/main.cpp
app/config.hpp
app/show.hpp
app/file.hpp
lib/append.hpp
lib/clear.hpp
lib/reopen.hpp
lib/crypt.hpp
I have a problem. Imagine a few of my files use lib/crypt.hpp. For example in app/file.hpp I should write:
#include "../lib/crypt.hpp"
If I take this file to lib folder it does not work anymore. So I need a something like:
#include "LIB/crypt.hpp"
So, this LIB/ has meaning of (empty) in lib directory while it has meaning of "../lib/" in app directory.
Then I will have no worry about moving file.hpp from app to lib. I just need to fix the callers of it. But not what it calls.
Similar to concept of web programming frameworks. Is it possible in C/C++?
According to what you wrote you're searching for a way to move your sources around without worrying for hard-coded paths to your headers.
You didn't specify the compiler you're using so I'm not focusing on a specific one, anyway most C++ compilers have an option to specify one or more header search paths (on gcc you would just use something like -Ilib_parent_dir).
Once you've included your lib's parent path to the search list, you can move your sources around (as long as you don't move lib's headers) and have them include the right headers with something like #include <lib/crypt.hpp> (and keep include paths priority in mind)
This should be a cleaner and simpler way to achieve what you asked rather than using a macro.
What is the purpose or meaning behind the aux_ subdirectory in the boost libraries?
For example:
boost/parameter/aux_/
boost/mpl/aux_/
boost/local_function/aux_/
What #DevSolar wrote:
Lots of Boost functionality is implemented in templates, which -- as
we know -- need their definition to be included in the header file.
You cannot hide it in a linker library. But because portions of that
template code are auxiliary to the actual API functionality, they are
put into a subdirectory so they do not confuse the user.
It looks like several similar directory naming schemes are used in boost:
detail
impl
aux_
From what I can see all 3 of these subdirectories serve the same purpose. The naming just depends on the specific boost library. If there is a more specific purpose to the different naming convention, please edit or submit another answer...I'm only guessing here!
Thanks for the hints. I eventually did find a page on www.boost.org that mentions (just in passing!) the directory structure, and why there are different conventions. Here is what it says:
The organization of Boost library headers isn't entirely uniform, but most libraries follow a few patterns:
Some older libraries and most very small libraries place all public headers directly into boost/.
Most libraries' public headers live in a subdirectory of boost/, named after the library. For example, you'll find the Python library's def.hpp header in
boost\python\def.hpp.
Some libraries have an “aggregate header” in boost/ that #includes all of the library's other headers. For example, Boost.Python's aggregate header is
boost\python.hpp.
Most libraries place private headers in a subdirectory called detail/, or aux_/. Don't expect to find anything you can use in these directories.
Source: http://www.boost.org/doc/libs/1_56_0/more/getting_started/unix-variants.html