I can totally understand that. This is why I separate my demo application from the libraries. Note that VFLib doesn’t come with JUCE:
It does follow the same directory structure as JUCE. You add the root directory to your include paths, and then you can do:
#include "modules/vf_core/vf_core.h"
If JUCE is also in your path then yes you will have two directories called “modules”. One in JUCE and one in VFLib. This is fine, since the child directory names don’t conflict (unless someone does something silly like call their module juce_core). Prefixing your modules would of course help: “modules/drow_core”, “modules/drow_audio”, etc…
When I create a demonstration application, I put it into a separate repository and use git-subtree to add the library repository directly to the demo repo. I also git-subtree the JUCEAmalgam sources into the demo repo. AppletJUCE has both JUCEAmalgam and VFLib as subtrees:
https://github.com/vinniefalco/AppletJUCE
A git-subtree is independent of the original repo. The files are added to the destination repository and become part of it. This is different from submodules, and easier to maintain. Since they are regular files, the repository can be cloned without hassle.
LuaBridgeDemo brings in JUCEAmalgam (in Demo/) and LuaBridge as subtrees:
When VFLib changes, bringing in the commits to the AppletJUCE project is as easy as:
git subtree pull -P VFLib vflib master --squash
You could even git-subtree the JUCE repository into your repo like this:
git remote add juce git://github.com/julianstorer/JUCE.git
git subtree add -P JUCE juce master
There is the objection that it now becomes necessary to update JUCE frequently in all the repositories that use it, instead of keeping just one copy of JUCE on the local developer’s machine and sharing the code. I will argue that this is not a problem, in fact it is superior. JUCE usage falls into two cases:
- Demo application code
- Production code
For #1, it is not important that JUCE always be kept up to date. As long as the version of JUCE used is one that supports all the features of the demo (and without bugs), a repository can happily stay at an older version of JUCE. Once in a while, JUCE will make a breaking change and the underlying library (drowAudio in this case) might need to change. Then it would be necessary to also pull the latest JUCE tip into the demo project. As these are infrequent events, the benefit of having a self contained and independent repository outweighs the cost. Note that DSP Filters uses a JUCE that is months old. And yet the demo still compiles, works, and does everything it needs to do.
For #2, it will be necessary to make more frequent updates to JUCE in order to pick up bug fixes, or important features in the critical path of development. Even in this case, adding JUCE as a subtree to your existing repository (which is presumably private since it is commercial software) makes more sense. One obvious benefit of subtree-ing in the JUCE repo is that you can make changes, branch it, tag it, and have the development timeline synchronized to your application’s source tree.
For example, if you create a beta release candidate you can tag the version, and the exact snapshot of the JUCE sources used to build the executable will become part of the tag. This is not possible when using the traditional IntroJucer workflow (where the JUCE sources are not under revision control, and downloaded automatically by IntroJucer).
NO professional software company could ever put out reliable products if they do not freeze the JUCE library code during the testing stage, or else product that ships would be different from the one that was tested! What happens if JULES makes a ton of unrelated changes to JUCE and you need to cherry pick just one or two commits? It is not possible when the sources are shared by multiple projects on the same machine. And then if you need to make changes to JUCE they aren’t revision controlled, etc…
Adding JUCE as a subtree, amalgamated or otherwise, has a lot of benefits and little disadvantage.