Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a concept like include directory aliases?

In a cross-platform project I make use of many third party libraries. I finally decided to include their source into my repository, to not need to download them again on every platform. This is is allowed by the licences.

To include headers from those libraries, I need to specify their file paths. Some libraries have them in name/include/name/file.h but generally, every library comes with a different directory structure.

I would like to include the headers in my code always in the form #include "name/file.h" where name is the name of the library. But I neither want to modify the directory structure of the libraries nor copy all headers into include directory of my desired structure.

Is there a way to define something like include directory aliases? For example, Bullet Physics has its headers in bullet/src, Sqlite has its headers directly in sqlite and SFML has them in sfml/include/SFML. I would like to specify something like this:

#alias "dependencies/bullet/src" "bullet"
#alias "dependencies/sqlite" "sqlite"
#alias "dependencies/sfml/include/SFML" "sfml"

So that #include "sfml/System.hpp" becomes equivalend to
#include "dependencies/sfml/include/SFML/System.hpp".

The technique doesn't have to be in preprocessor stage. It could also be a CMake flag to generate projects in the right way, for example. However, I think compilers must be aware of this technique somehow, to make this possible.

like image 930
danijar Avatar asked Feb 18 '14 07:02

danijar


3 Answers

No; the nearest approach is a collection of -I options on the command line.

Further, if you use SFML, the recommended notation is #include "SFML/System.hpp"; that's what you should write in your code. Then you fix the compilation environment so that -Idependencies/sfml/include is included in the compilation, or you use symlinks (if they're portable enough) to manufacture sub-directories like SFML in the main directory that contains your project's headers.

When software packages like SFML are installed, the headers will be placed into a directory — normally /usr/local/include by default, and usually in a sub-directory under there. That is, there would be a directory /usr/local/include/SFML which would contain the SFML headers. The chances are the same is true of other software packages. You should install these headers in some location under your build area so that the headers can be found as normal — you'll simply specify the base include directory under which the headers are found. (Note: when you install the Bullet Physics library, the headers are placed into a directory .../include/bullet with various sub-directories underneath that, so it too follows this convention.)

Doing otherwise means fighting the system, and when you fight the system, you end up losing. It is harder work than simply going with the flow.

like image 100
Jonathan Leffler Avatar answered Oct 21 '22 02:10

Jonathan Leffler


The short answer is "no".

There are a few different options:

  • Symlinks - set up your own "myincludes" directory, and then link all the relevant files to there, in their relative position.
  • Use more complex -I options to your project.
  • Write your own pre-preprocessor (which translates a given #include into the "actual file in the actual place", given some set of rules)
  • Adjust the install directories of the respective projects.
  • Don't do any of the above, and use the names as they appear on your actual filesystem.

I personally prefer the "don't do this" option. For one thing, moving/changing how files are included is more than likely to confuse some people, and third party code certainly won't be written this way, so you won't be able to use anyone else's code maintaining this style.

like image 4
Mats Petersson Avatar answered Oct 21 '22 01:10

Mats Petersson


I was building everything in one build run (Not in packages) I managed to do exactly what you want using Cmake by doing the following:

In the highest CMakeLists.txt

set(TEMP_INCLUDE_DIR ${CMAKE_BINARY_DIR}/tempIncludes)
file(MAKE_DIRECTORY ${TEMP_INCLUDE_DIR})
target_include_directories(<TARGET_NAME> PUBLIC
  $<BUILD_INTERFACE:${TEMP_INCLUDE_DIR}>
)

This will create a folder in the binary directory (that is removed when you clean your project so it isn't modifying your actual folder structure and I am assuming you are NOT using in-source build)

Then in the CMakeLists.txt for the target library:

set(LIB_NAME <ThirdPartyLibraryName>)
set(INCLUDE_FOLDER <WhatEverThirdPartyIncludeDirectory>)
set(HEADER_FILES
    ${INCLUDE_FOLDER}/<Header1>.h
    ${INCLUDE_FOLDER}/<Header2>.h
)
file(COPY ${HEADER_FILES} DESTINATION ${TEMP_INCLUDE_DIR}/${LIB_NAME}/)

This will make a folder structure with all include files copied into standard directories that will allow you to use the #include "name/file.h" form you want.

like image 3
Sameh Ragheb Avatar answered Oct 21 '22 01:10

Sameh Ragheb