I have a large code base under source control (was subversion, now git). To compile the code and run the tests I use a set of 3rd party libraries. These libraries can be divided into few categoriesL
Each library has its {Windows, Linux} X {debug, release} X {32bit, 64bit} configurations. In addition these libraries evolve with time and different versions of my project use different versions/builds of these libraries.
My question is what is the best way to store these 3rd parties?
Here is my set of preferences:
I tried and thought of several solutions but neither was satisfactory:
It is clear to me that the 3rd party sources need to be stored in git in a vendor branch, but the binaries and headers are a different story.
A fair solution for my problem is git-subtree which was recently merged into mainline git. It provides a fair balance between my requirements and the platform limitations. Now I have multiple repositories for the externals (each has a vendor branch as well as local changes branch) and each project repository takes parts of these externals into sub-folders. To keep things organized I maintain a 'bin' and 'lib' folders which contains soft links to the appropriate files/folders in the externals sub-folder.
git-subtree allows to merge a sub-tree from an external repository into a sub-folder. The sub-folder can be merged back and forth with the external repository.
Pros/Cons:
Small repository - The repository is not as small as I would like it to be but it contains only the necessary parts from the external repositories. To save space I try to keep the external trees small. I consider it a good price to pay when in return I get simplicity and robustness; as loading and updating a project is a simple git pull and all project related data is contained in a single repository
Project/Externals sync - As the project and externals are versioned in the same repository, I can checkout any branch/tag I want and expect it to be working.
Simplicity - Day-by-day work is straight forward. Updating external repository, creating a new one or switching to a different version of the external may be tricky and requires special syntax. However this does happen too much. The best thing is that one can add a new external to this project first and only afterwards split it (using git-subtree) into its own repository.
Cross platform - Well it's git
Structure:
/root
/External
/External1 (git-subtree from [email protected]:External1 v1.0)
/External2 (git-subtree from [email protected]:External2 v0.7)
/lib
/libExternal1.a -> ../External/External1/libExternal1.a
/libExternal2.a -> ../External/External1/libExternal2.a
/include
/External1 -> ../External/External1/include
/External2 -> ../External/External2/include