organizing external libraries and include files
- by stijn
Over the years my projects use more and more external libraries, and the way I did it starts feeling more and more awkward (although, that has to be said, it does work flawlessly). I use VS on Windows, CMake on others, and CodeComposer for targetting DSPs on Windows. Except for the DSPs, both 32bit and 64bit platforms are used.
Here's a sample of what I am doing now; note that as shown, the different external libraries themselves are not always organized in the same way. Some have different lib/include/src folders, others have a single src folder. Some came ready-to-use with static and/or shared libraries, others were built
/path/to/projects
/projectA
/projectB
/path/to/apis
/apiA
/src
/include
/lib
/apiB
/include
/i386/lib
/amd64/lib
/path/to/otherapis
/apiC
/src
/path/to/sharedlibs
/apiA_x86.lib -->some libs were built in all possible configurations
/apiA_x86d.lib
/apiA_x64.lib
/apiA_x64d.lib
/apiA_static_x86.lib
/apiB.lib -->other libs have just one import library
/path/to/dlls -->most of this directory also gets distributed to clients
/apiA_x86.dll and it's in the PATH
/apiB.dll
Each time I add an external libary, I roughly use this process:
build it, if needed, for different configurations (release/debug/platform)
copy it's static and/or import libraries to 'sharedlibs'
copy it's shared libraries to 'dlls'
add an environment variable, eg 'API_A_DIR' that points to the root for ApiA, like '/path/to/apis/apiA'
create a VS property sheet and a CMake file to state include path and eventually the library name, like include = '$(API_A_DIR)/Include' and lib = apiA.lib
add the propertysheet/cmake file to the project needing the library
It's especially step 4 and 5 that are bothering me. I am pretty sure I am not the only one facing this problem, and would like see how others deal with this.
I was thinking to get rid of the environment variables per library, and use just one 'API_INCLUDE_DIR' and populating it with the include files in an organized way:
/path/to/api/include
/apiA
/apiB
/apiC
This way I do not need the include path in the propertysheets nor the environment variables. For libs that are only used on windows I even don't need a propertysheet at all as I can use #pragmas to instruct the linker what library to link to.
Also in the code it will be more clear what gets included, and no need for wrappers to include files having the same name but are from different libraries:
#include <apiA/header.h>
#include <apiB/header.h>
#include <apiC_version1/header.h>
The withdrawal is off course that I have to copy include files, and possibly** introduce duplicates on the filesystem, but that looks like a minor price to pay, doesn't it?
** actually once libraries are built, the only thing I need from them is the include files and thie libs. Since each of those would have a dedicated directory, the original source tree is not needed anymore so can be deleted..