Creating a project without generating JuceHeader but with auto generated ProjectInfo?

In order to keep recompilation times low after header file changes in a big project, we are trying to go away from the #include <JuceHeader.h> everywhere approach and include only the needed module headers.

One problem arising from that: There is no single header file to include that contains the ProjectInfo block, since it is hardcoded to the auto generated JuceHeader.h file. I don’t see any reason why it should not be possible to auto-generate a small project info only header file containing it and also include it per default in the header.

Is this already possible and I’m overlooking something here? Or if not, could this be made possible? Would be great!

If the ProjectInfo is not used in the juce source code (and I think it isn’t), what stops you from creating your own ProjectInfo.h and including that?

This is what I ended up doing for now to work it around, and of course implementing an auto generated header from within CMake should also not be too hard.

But I think the automatic generation of a header like that from the project setup as created in CMake is a useful thing that worked quite well with the JuceHeader. Tying that functionality exclusively to the usage of JuceHeader including all the auto generated includes of all module headers and optional global using namespace juce which I both don’t want seems a bit unrelated to me :slight_smile:

So why reinventing the wheel / implementing an auto generated header generation when JUCE already invented it?

Ah ok, so there were more things in JuceHeader you were interested in, got it.

You could still call juce_generate_juce_header() but only include it where you need it.

But I agree there are probably nicer solutions

Well no, I am actually only interested in the project info, while the JuceHeader combines multiple not strictly related things, where everything can be replaced in another way – except for the auto generated project info, where I would need to make up my own header generation script. :wink:

I know, but actually I’d like to avoid this in order to friendly “force” a team of 9 developers to write code that does not rely on a JuceHeader being present :smiley:

All in all, this is no big deal or showstopper – just something that I thought could be decoupled easily in JUCE

Is the idea just that we’d separate the ProjectInfo into its own standalone header? If so, I don’t see any major drawbacks of that approach, so I’ll see how feasible this is to implement.

That being said, I think it’s possible to do a bit better than the existing ProjectInfo design, especially if you’re using CMake. You might want to roll your own approach, even if we end up making the suggested change.

The current design will force you to recompile any TU which includes the ProjectInfo definitions, whenever the definitions change. However, we can shuffle things around a bit, so that your header just includes the data declarations (we’ll use a struct while we’re at it, we don’t need to use argument dependent lookup here):

struct ProjectInfo
{
    static const char* const  projectName;
    static const char* const  companyName;
    static const char* const  versionString;
    static const int          versionNumber;
};

Then, we can use CMake’s file configuration tools to generate a matching .cpp. This way, if any of the project info changes, we will only need to recompile this single tiny .cpp.

Granted this is a bit academic because most of the info is provided in preprocessor definitions, which will also force your project to rebuild completely… but this approach will give you faster incremental builds in parts of your codebase which don’t depend on JUCE and its preprocessor flags, but do depend on the project info.

Also, managing this yourself will allow you to extend the struct with other relevant information, such as the current git hash of the repository, the date of the build, and so on.

2 Likes

Thank you for that detailed response!

Basically yes, but at best combined with the option to generate it independently from the JuceHeader. I thought of something like juce_generate_project_info (my_target) which will then only generate that header. juce_generate_juce_header would then call generate project info internally and the JuceHeader would include the project info header.

I also totally get the point with just putting the declarations into the header and all this rework that involves moving away from the “include everything with juce header approach” is basically driven by the aim for faster incremental build times. Especially since we already have a script generating a git hash header etc. as you mentioned it might be indeed a good idea to unify all this into a custom solution in the long run. But do I also get you right that in case you’ll implement a standalone project info header in JUCE it won’t follow this design?

I’m not keen on adding yet another header-related option to the Projucer, things are already quite confusing there. If we added this, it would probably be an always-on option. From the sounds of things, this might not be a satisfactory solution.

It sounds like using configure_file to create a purpose-built projectinfo .h/.cpp pair is the best solution in this case. For now I think it makes sense to leave things as they are in JUCE, given that I don’t think that the complexity of the feature you’re suggesting is justified, and that the simpler solution wouldn’t be useful to you.

Of course, if there is more support from the community to split up the JuceHeader I’ll reconsider. I hope that all makes sense.

This totally makes sense! I also see that supporting two individual build systems adds a lot of complexity to such requests that seem easy at the first glance when e.g. looking at it from a CMake only perspective.

Also thanks for pointing me towards configure_file – I didn’t know of it until now! I will try to build a CMake function tailored to our specific in-house needs with it (and will maybe even get rid of some pre build python scripts currently involved with that)