Interesting new idea: Canned juce

Got an interesting little idea that I’ve been tinkering with, and wonder what you all think of it…

By some cunning hackery, I’ve found a way to create two files - juce.h and juce.cpp, which contain the entire library. Yep, the whole thing - all the source, all the 3rd-party libs like zlib, flac, ogg, png, jpeg, etc. The only external files that either of these include are system headers.

So this means that to compile a juce app, you just need to include juce.h and add juce.cpp to your project. No libs to include (well, apart from the necessary frameworks on the mac). No need to build juce itself, just compile your project. The files are about 2MB and 8MB, so they’re big, but not unmanageable.

Advantages I can see are:

  • no need to ever build the juce libs
  • massively faster to compile - on my mac it took me about 5-10 mins to build juce, but to compile the juce_inline.cpp file takes under 30 secs. On my PC it takes under 10 secs.
  • no need to set up any library paths in your project, so things like the juce demo/jucer could build and run on a clean PC without the user needing to manually set anything up.
  • no need to keep different libraries for different configurations. You might (like me) have 10 different juce apps, each needing a different setup of some juce_Config.h flags, debug, release, OSX version, etc., and that meant doing 10 different builds of the juce library, and somehow keeping track of all the libs that were produced. If it’s just a .cpp file, then each project can just set the config flags it needs, and each build instantly gets its own tailored version.
  • better code generation because the compiler is effectively being tricked into doing whole-program optimisation on the juce classes
  • ability to easily lock your project to a specific version of juce - just make copies of the two files in your project, and archive them along with your own code

Disadvantages

  • more laborious when you’re writing code in the library itself, (but that probably only applies only to me and a handful of other hackers). It’s actually not particularly hard, though - I’ve written a utility that generates the two mega-files, and it only takes a a few seconds to run.
  • slightly more confusing when you need to debug down into juce code (but all the source is still there, just in a big file)
  • will probably break some compilers. I hit a few “internal compiler errors” in XCode, but by random tweaking these were avoidable.

So… am I mad? Is this a stupid way to do things? Or will all programming be done like this in the future? Answers and opinions please!

interesting idea. would be cool if you provide a separate version of the library in the canned version, besides the normal one, as i’m one of those hackerish developers that likes to put his dirty hands inside the library :smiley:

ah, in doing the canned version why not disable by default every JUCE_XXX defines, and one enables it in his project before including the big juce.h so one can choose which things to enable/disable without opening the big juce.h and browse thousands of lines searching for JUCE_DEFINES ?

:slight_smile:

Well I’d still have the library available in its current form - there’d just be a couple of extra files in there that would work on their own.

Not sure I understand what you mean about the defines? What would you have to search for?

I like the idea :smiley:

sqlite guys did the same and it was pretty cool.
Funny thing is that it usually produce faster code.

smaller code too…

Any suggestions for names for this? juce_bottled.cpp? juce_in_a_bottle.cpp? BottleOfJuce.cpp? JuceBottler.exe for the util that builds the big files?

amalgamation ?

more of a conglomeration? juce_incorporated.cpp?

Second that. That’s what SQLite using the same technique is called.

+1 for Amalgamation

Really like this idea as it has worked very well for SQLite. In fact SQLite now recommends the amalgamation version to be preferred version and only fall back to other versions if you have a compelling reason.

Has the single file been preprocessed?

I prefer to have the Juce library in the current form especially for multiplatform debugging and changing/fixing things.
Putting it all together in a single source files might be a good idea for some reasons, but only as alternative. Would this single source file be platform independent or would there be a version for each platform?
The structure of the subversion repository remains as it is now, does it?

Andreas

It’s sounds great, especially this.

We do tinker around in the libray itself…so for us that would be the only downside.

I love the idea! If you’ve made a tool to knock it together for you already, then it would be silly to not see how this ‘new form’ goes with us users :slight_smile:

As for names, I reckon there’s no reason not to go along with the juice [sic ;)] theme. JuceBox? JuceCarton? Dose? Shot? Smoothie?

[quote=“andreas”]I prefer to have the Juce library in the current form especially for multiplatform debugging and changing/fixing things.
Putting it all together in a single source files might be a good idea for some reasons, but only as alternative. Would this single source file be platform independent or would there be a version for each platform?
The structure of the subversion repository remains as it is now, does it?

Andreas[/quote]

I don’t think it makes much difference to debugging, really. You can still debug things, the only difference is that when you want to change something, you need to do it in the original source file, then run the re-amalgamator instead of rebuilding the lib. In fact, this is often quicker than rebuilding libs, especially on the mac.

And yes, there’s only one file, containing all the code for all the platforms.

I, for one vote for keeping the current style. I can’t imagine a monolithic file being other than an intermediate tool. It goes against module / functional separation and I think it’s only good for single-developer projects (I know, you are a one-man show, Jules, but there are those teams with commercial license :slight_smile: ). But I’d certainly love to give it a try. I guess I could use this for freezing easily replacable snapshots of juce, like others have said.

Question coming to mind: do you plan to version control these files? How would svn react to them checked in with each revision (perhaps a non-issue).

I’m not going to get rid of anything, just add these extra files to the build. (And probably update all the example code to use them instead of the old linkage, because it makes all the setup easier).

Don’t think there’d be any issue with source control, as long as it doesn’t mind big files like this.

i mean… you will have the juce_Config.h somewhere inside the big juce_Canned.h no ? how can i disable JUCE_OPENGL for example ? i still need to sed the juce_Canned.h searching where “#define JUCE_OPENGL” is and comment it ? or i can enable it by defining it on my outer project ?

what about adding JuceBottler project inside extras so we can use it for packaging a whole application with it ? with juce, external libraries (provided you have complete code available) and the current application sources ?

you’d just “#define JUCE_OPENGL 0” either in your project settings or a header that’s included in all your files.

Yep, the bottler will be in extras.

I prefer the library approach, as big files usually results in ICE which are a PITA to debug.

Can’t you simply put the agglomerator2000 in the repository, so we can use it on our own ?

Well, I’d say that it should be Condensed Juce, and maybe there should be a global define for JUCE_PULP or JUCE_NOPULP.

Don’t know what they’d do, but that would be cool. Maybe whether juce is the app or is just a helper library. Good to get in it there somewhere. Very important.

But it does sounds good. Would the condensed version stay up to date with the SVN tip? And do you see us compiling all the code right in the app, or still making a static lib?

Bruce