Hi I have a simple question perhaps it has been answered before.
In order to develop JUCE plugins it seems necessary to download JUCE and the projucer and then to target the path to JUCE and build your plugin. Then a year later you have old plugins targeting an old version of JUCE. Everything may now be broken as the systems you target are moving so you need to use a newer version of JUCE. How do people manage this problem? Like git checkout an old version to work on old code ? Then checkout a new version and try something new? Letâs say I want to build something from scratch now what should I do ? I know this is kind of a sogtware development 101 kind of question not really a JUCE question. Just wondering how people manage this ? My last project I ended up using cmakelists.txt files to target an LV2 build. Someone pointed my in the direction of pamplejuce which looked interesting but perhaps a lot of overhead. Sorry just ranting nothing specific but I would interested to see how people manage older projects. I mostly develop on an M2 mac. Changing JUCE versions requires reconfiguring XCODE etc. If anyone has any widsom here it might be useful to me thanks Sean
Like this documentation just says âdownload JUCEâ
"Getting started
Download JUCE. Unpack the JUCE folder and place it to some location on your computer. Your user home folder is a convenient place.
Go into the JUCE folder you just installed. Launch the Projucer, which is located there."
Is that what people normally do ? They donât clone the repo ?
It is much easier to manage versions if you use a proper build system like CMake instead of the Projucer. With CMake, your project script can specify an exact juce version, meaning that the project simply wouldnât generate properly if the correct juce version couldnât be found (or you can also have cmake simply download the correct version of juce from GitHub).
thanks Ben then how do you debug your code without XCODE ?
I use xcode. cmake can generate xcode projects
aah thanks Ben do you have some âvanilla JUCEâ cmake project as a starting point?
I donât have a public project template. Pamplejuce is a good one, and thereâs also this one
In general, this problem of âthe toolchain expects to find this thing installed in the system, how do I ensure itâs a specific version?â is an interesting question.
When the âthingâ in question is a library, I definitely recommend CMake FetchContent as a starting point, which you pin to a git tag, commit, or branch. Then if you want, on top of that you can add a package manager such as Conan or vcpkg (but tbh most projects are fine with just some FetchContent calls). JUCE helps you here by implementing proper CMake package support, keeping their package version number the same as the git tag name, and also being very strict that even the point release number matches the requested version.
In the case of programs/executables (which applies to the original question about versioning of the Projucer), using containers is a good approach to be able to have a reproducible build environment (this works for libraries too, you can install them to the containerâs system directories). Thereâs also ASDF which is a tool that creates directory-specific program âshimsâ, allowing you to for example always use Clang 19.1 in directory A but Clang 19.0 in directory B. Itâs a cool tool but unfortunately no Windows support yet.
If you want to stick with Projucer, you could try one of these approaches for versioning the PJ executable within your build environment, but really my advice is that switching to cmake is definitely worth the learning curve & time investment, it makes it easier to do all sorts of software engineering tasks, such as building tests, docs, packaging, etc. Iâve even got some cmake custom targets that compile papers using Latex.
Actually JUCE is already version controlled as itâs a git repository.
Ideally you can:
- as suggested use CMake. Keep in mind though Android wonât use CMake as the primary build system.
- Make your own project a git and make JUCE a submodule. This wonât stop building if you change anything but you can check the git status.
submodule.
If you need to make changes to the juce codebase you can make forks and manage the merging of later juce updates as they arrive.
I also think thatâs the simplest and most effective. I fork JUCE in a separate repository, make it stable for my needs, sometimes tweak a thing or two and add it as a submodule to the plugin projects. This would allow me to build those projects even if the JUCE repository stopped being available for whatever reason.
I personally find all the CMake scripting stuff an unnecessary hassle and an extra thing to maintain.
git submodule add git@github.com:juce-framework/JUCE.git juce
We do that in each projects git repo. It adds the latest version of JUCE as a subfolder of your project but without duplicating JUCE and keeps the link back to the JUCE github so you can update/pick a specific version.
Git submodules are a bit of a headscratcher when you first use them. But it guarantees youâll get the version you want when you pull and build your poject.
Maybe CMake FetchContent is easier? But weâve always done it with git submodule.
Fetch content is useful when you have a small team and donât want to have to teach your colleagues how to use git - but otherwise, it adds a lot to compile times in a CI pipeline.
Git submodule is usually better, as long as you remember to maintain the submodules for your project (âgit submodule update âinit ârecursiveâ after cloning the main repo..) - but it can also be frustrating to have so many JUCE copies all over your filesystem, if youâre not careful, or if you work on multiple projects.
Having a âone JUCE directory for everythingâ approach can work - but here again, you must be diligent about maintaining the link when working on different projects, and it can get in the way when you want to try a different JUCE version for things (I am staying on 7.0.12 for now, but enjoy catching up with -develop when thereâs news of new things being pushed upstream).
In general, it pays to work on your CMake and git competency when working on a JUCE project .. I was not really much of a fan of CMake-based projects for a few years, but after some time spent in JUCE development Iâve come to appreciate it a lot more.. and Iâve now become much more enamoured with it as a solution for many things.
But you do need to invest time to learn these tools and the methods that will keep things hygienic - without some strong tooling/methodology policies, you can mess things up immensely.
There is light at the end of the tunnel: CMake and competent git habits are very useful when the time comes to do continuous integration/automated builds/packaging/signing/notarization. There is something very satisfying about pushing to a branch, waiting a few minutes, and having a fully-functioning distributable .zip or .exe spit out at the end of the pipeline, somewhere. Good CMake and git habits will get you to that point, rapidlyâŠ
Why would git submodule have better build times than FetchContent?
If you have quite simple plugin projects (that can be professional, commercial products), CMake is overkill.
If you want to learn and use it, please do, but for simple projects you really do not need it.
The Projucer can generate your Visual Studio solution file and Xcode project file, and can be used as a command-line tool in a CI/CD environment.
I agree about CMAKE. For really large complex projects it can be actually incredibly tricky to convert from Projucer to CMAKE. Remember Matchbox Ben?
Re: submodules, we literally have a separate copy of juce for every project, maintained as a submodule in each project repo. We absolutely need to know that build 123 of my product X uses version 345 of juce. I can switch back to any earlier commit in my repo and know I have exactly the original version of juce.
A single system wide copy of JUCE is crazy.
Youâre right that cmake can get difficult/complex with larger projects, typically the greatest difficulty happens when trying to integrate large, complex dependencies that do not themselves support cmake (ffmpeg is a good example). Itâs possible but basically requires doing custom scripting to call the projectâs configure & makefile steps, which might be different on each OS, etc. This complexity also exists in the non-cmake case too, though, you must have some custom scripts that are building your dependencies.
But as far as just simply using juce and getting reliably the correct juce version, thatâs quite easy. If you write a FetchContent call asking for Juce 7.0.9 (for example), then cmake will first check if that exact version happens to be present in system dirs, and if not then will git clone it at configure time. You can also configure it to always use git and never system packages.
FWIW downloading the zips from the JUCE Releases and unzipping them is much faster than using any method involving git. Cloning with git (directly, or through submoduling) comes with a lot of baggage that you probably donât need unless your build system actually needs to do git-related things with JUCE. The JUCE repo is ~264MB while the macOS zip is ~44MB.
E.g. compare the time taken to run these two commands:
$ git clone git@github.com:juce-framework/JUCE.git
...
Receiving objects: 100% (263321/263321), 264.37 MiB | 2.06 MiB/s, done.
$ curl -L -H "Accept: application/octet-stream" -o juce.zip https://api.github.com/repos/juce-framework/JUCE/releases/assets/219387682
% Total % Received % Xferd Average Speed Time Time Time Current
...
100 44.2M 100 44.2M 0 0 1888k 0 0:00:23 0:00:23 --:--:-- 2035k
If youâre on GitHub Actions, or have the GitHub CLI you can also use:
$ gh release download 8.0.6 -p '*-osx.zip'
You could add --depth=1 if you donât care about the commit history. Though the total time still depends on your web connect quality.
More info: How to make shallow git submodules? - Stack Overflow. I have never tried though.
I donât agree with the negative statements about CMake. Faffing around with Projucer is a serious time sync, too. If you get your tools set up, CMake is just another source file to maintain, and it is very easy to do so. Plus, changes to CMake are a lot more readable over time/commits to a repo, than changes to a .jucer file. And if you use an IDE such as CLion, you get code completion and CMake module navigation, just like any other source in your project. CMake knowledge extends beyond JUCE, too. Thereâs a reason its commonly adopted in other projects - its very, very effective.
I am yet to encounter a .jucer file that canât be rapidly and efficiently converted to CMakeLists.txt with an LLM. Every single .jucer file Iâve found in the awesome-JUCE list, for example, has been easily converted to a functioning CMakeLists.txt file with an LLM in seconds. That trouble is so over, folks.
Using FetchContent can impact build times in CI because it gets triggered with every build - whereas having a git submodule config means JUCE is outside the build-tree. Having JUCE as a submodule in your project is preferable because you can more directly control the JUCE version youâre building with, and when you push to your repo, this version is part of your repo forever.
In this day and age, if youâre not using git effectively, youâre just making excuses not to adopt a good methodology. I get it, its just another thing to learn, but taking the time to learn good tooling and methodology is an easy investment for any development, pro or otherwise, to make.
Projucer has its place - but for newcomers to software development though, it can actually be more of a burden to dive into .jucer terminology than just learning CMake. The cyclomatic complexity of a project is increased by the Projucer scaffolding - it is reduced with CMake. That can impact developer productivity in both directions - CMake is more future-proof and versatile. Want to include a git hash in your projects version string that identifies the very commit of your release? Really easy with CMake. Not so easy with Projucer.
But either way, for anyone reading this thread and working out which to invest time in, both tools essentially do the same thing. You just get more hand-holding with Projucer, and that can be important if youâre just starting out.
Eventually though, converting to CMake is very easy, and effective when you get to the point of doing CI-based builds and automated releases.
Itâs quite interesting to observe the diversity of opinions though. Mine is just one opinion in the stream ⊠but I will never agree that downloading .zip files is superior to git, in any way whatsoever. ![]()
