Jules is a cheater!


#1

Jules! Do you know how many days I spent trying to figure out why producing the 4-file amalgamation wouldn’t work? I was using your amalgamator command line tool, unmodified, built from sources, and installed in to /usr/bin. But for some reason, the files it produced when run on juce_amalgamated1.cpp, etc… from your source tree, would never work. I always got compile errors. I kept trying to fix them but it just produced more errors. And opening those muli-megabyte files and editing them to try to fix it is so slow and painful. I always felt I was doing something wrong. I tried so many different things, at one point I even ran the C preprocessor over the files to see if that would help.

Finally out of desperation I took a close look at Main.cpp from amalgamator to figure out why building the single file amalgamation works and look at what I found

static void mungeJuce (const File& juceFolder)
{
    if (! juceFolder.isDirectory())
    {
        std::cout << " The folder supplied must be the root of your Juce directory!\n\n";
        return;
    }

    const File hppTemplate (juceFolder.getChildFile ("amalgamation/juce_amalgamated_template.h"));
    const File cppTemplate (juceFolder.getChildFile ("amalgamation/juce_amalgamated_template.cpp"));

    const File hppTarget (juceFolder.getChildFile ("juce_amalgamated.h"));
    const File cppTarget (juceFolder.getChildFile ("juce_amalgamated.cpp"));

    StringArray alreadyIncludedFiles, includesToIgnore;

    if (! munge (hppTemplate, hppTarget, "*.h", alreadyIncludedFiles, includesToIgnore))
    {
        return;
    }

    findAllFilesIncludedIn (hppTemplate, alreadyIncludedFiles);
    includesToIgnore.add (hppTarget.getFileName());

    munge (cppTemplate, cppTarget, "*.cpp;*.c;*.h;*.mm;*.m", alreadyIncludedFiles, includesToIgnore);
}

You cheated! The amalgamator code has a special case for building Juce. The reason that the Juce amalgamation works, but trying to use amalgamator on juce_amalgamated1.cpp fails, is because mungeJuce() has a special feature not available to regular people. It munges the header file, and fills in the variables alreadyIncludedFiles and includesToIgnore, and those values get passed through to the next call to munge() for the .cpp.

The way I got my shell script to work is to rename juce_amalgamated1.cpp, and then run amalgamator in your special-case mode, copy the file out, and then repeat for the remaining files, then put back the original juce_amalgamated.cpp.

If you could please add a feature to amalgamator that allows it to be invoked from the command line in a way that lets it munge two files from the command line in this fashion, that would be really cool. This is what I’m thinking as an additional feature:

[quote]Usage:
amalgamator HeaderFile TemplateFile TargetFile “FileToReplaceWildcard”[/quote]

In this mode, HeaderFile would be munged with the replacement wildcard “*.h”, just like mungeJuce, but there would be no output. The purpose of munging would be just to fill in the variables alreadyIncludedFiles and includesToIgnore. Then, TemplateFile would be munged for real, like normal, except that the two variables alreadyIncludedFiles and includesToIgnore would be filled in properly.

It would also be really cool if there could be a default option for “FileToReplaceWildcard” that replicated the list in mungeJuce (".cpp;.c;.h;.mm;*.m"). Here’s what I’m thinking:

If you want, I can make all these changes myself, test them, and email you a new Main.cpp for amalgamator.


#2

Well, yeah, I did kind of write it to do one specific job! More than happy to look at your changes if you want to send them over, but note that I’ve removed the amalgamator project from the new modules branch to avoid any confusion.

Thinking of ways in which I might want to support amalgamation in the future, I did think that it could be a good alternative for the two current ways of including a module with the introjucer. At the moment, it’ll let you either reference some external module files from your project, or it will create a copy of the module within your project’s folder. There could be another alternative where it copies an amalgamated header and cpp file into your project folder, generating them on the fly. (But of course you hate the introjucer and wouldn’t want that)


#3

:frowning: :frowning: :frowning: How much time to we have before you freeze the old branch? I would like to put in the new amalgamator that has those features I talked about into the old branch before you freeze it, so that it works for that branch. I haven’t written the code yet, but it shouldn’t take more than a few hours to put in and test. If you give me the green light that we can get this new amalgamator into the last revision of the old branch I will get to work on it.

Also, there is one other problem that I forgot to mention. XCode 4 generates two errors when compiling juce_amalgamated_template.cpp, because of these lines:

#if JUCE_BUILD_MISC  // (put these in misc to balance the file sizes and avoid problems in iphone build)
#if JUCE_BUILD_CORE && ! JUCE_ONLY_BUILD_CORE_LIBRARY // do these in the core section to help balance the sizes

The problem is the C++ style comment. In my DspFilters project, I had to delete those two comments in order to get the amalgamation to compile. If you could remove those comments, or move them to the previous line, that would be awesome.

I don’t hate IntroJucer in fact its a pretty cool tool! How awesome is a single cross platform application that lets you manage your source code and automatically produce project files for every build environment? And now, it has integrated source code control. Its not that I hate the tool, it is just that our corporate environment philosophy is to depend on as few custom tools as possible for the build process, to minimize risk.


#4

Sure, when you’re ready, just let me know all the stuff that you had to change in that branch and I’ll do some merging.