Introjucer - MSVC Precompiled Header


#1

It’s largely untested, and not entirely user-friendly (no message if you make a mistake). Also, this is for VS2010 and up because I’m not sure if the options are the same for VS2008 and VS2005.

Feel free to correct what I’ve done!


#2

Thanks!

Just attempting to tidy this up, but am confused about how it’s supposed to work… I don’t understand what your create/use flag is supposed to do? How can the whole project be set to either create or to use a PCH? Surely that’s something that needs to be set on a file-by-file basis? Or am I misunderstanding something?

And I don’t see what you were trying to do with that “if (pchFile != validFile)” statement, where pchFile is always an empty string (?!?)


#3

It seems that VS expects to either create/use a PCH file on-the-fly, or use a pre-existing one, if required… I’m not a PCH guy and have not the time to look into it, so someone else may have better answers. I just setup the XML - so it’s somewhere to start at least!

Son of a…

I think I was trying to do something like below - but still not liking the way I laid it out (especially that const_cast). I did it hastily…

String pchFile (config.getPrecompiledHeaderName());

if (pchOption == "Create" || pchOption == "Use")
{
    String validFile (File::createLegalFileName (pchFile));

    if (validFile.isEmpty())
        validFile = "stdafx.h";

    if (! validFile.endsWith (".h"))
        validFile += ".h";

    if (pchFile != validFile)
    {
        jassertfalse; //You seem to have improperly formatted the information required to create the pre-comp. file!
        pchFile = validFile;
        const_cast<MSVCBuildConfiguration&> (config).getPrecompiledHeaderNameValue() = pchFile;
    }
}
else
{
    pchFile = String::empty;
}

#4

Cheers! I’m also not much of an expert on how it VC handles this stuff, but it seems to me that what should probably happen is that you’d set two filenames: one with the name of the .h file for the PCH, and another which is the name of the cpp file to use to actually compile it. Then it’d probably need to set different create/use flags on a per-file basis, i.e. for the cpp file, it’d be “create” and for all other cpps that include the .h, they’d be set to use it. (?)


#5

It’s simple really, you designate one file that when compiled, created the PCH file, usualy stdafx.cpp, this is triggered via flag /Yc

/Yc"StdAfx.h"

I set a global flag for the entire project to use the precompiled header stdafx.pch (the /Fp flags set’s the filename if you don’t do that the default is something like ProjectName-x64.pch)

/Yu"stdafx.h" /Fp"stdafx.pch"

For JUCE files i set flags NOT to use PCH files, i don’t see a command line argument in the project file but i think it’s

/Y-

#6

It seems to be a VS project’s property; not the creation of independent files. Here’s a visual of a VS project’s options for PCH usage/generation: [attachment=0]PCH Options.png[/attachment]


#7

It's a little sad, that this discussion seems to have died. So I'd like to ask if there are plans to support precompiled headers with the introjucer.

Currently I'm working on two different projects using JUCE. For one project I don't use the Introjucer at all and take care for the project files myself. Of course I use precompiled headers on Windows. The other project is managed with the Introjucer and does not use precompiled headers.

For the first project compile times are similar on Mac and PC. For the second project the windows compile times are way longer, so nobody in the projects wants to work on windows.

I would enable precompiled headers, but I don't see a way to set different compile options for different files with the introjucer. Did I miss something?

I know, that it is not as easy as just enabling a single option, but I think precompiled headers are a really important feature for windows users.

Since I don't see a reason why anyone would not want to use them, offering no option for precompiled headers and just do it, could also be a way to go.

From my experience, the following would do:

1) Let the JuceHeader.h file be the precompiled header.

2) The introjucer could add a little cpp file that is only compiled on windows and contains just one line: #include<JuceHeaders.h>. This file would get the /Yc option to create the precompiled header.

3) The whole project gets the /Yu option to use the precompiled header.

4) All juce cpp files get the option /Y- because they won't compile if the headers are included before.

The only drawback of this is, that developers have to take care that every cpp file in the project starts with #include<JuceHeaders.h>.

 


#8

I'd also like to get precompiling working, as it'd be useful to me too, but I think it'd involve extending the introjucer to have some kind of extra per-file flag to say whether each file should use precompiling or not.


#9

Reviving this old thread... I had the exact same problem - Win builds of the same project (manually created, not with Introjucer) took waaay longer to build than on the Mac.  I enabled precompiled headers using the instructions from dnop above (thanks!), and it cut the build time by 2/3!  Also, regarding this:

The only drawback of this is, that developers have to take care that every cpp file in the project starts with #include<JuceHeaders.h>.

I was able to make it work without having to edit all the .cpp files by setting the project "Forced Include File" to JuceHeader.h.  This setting is in the C/C++ Advanced page.


#10

You seem to be suggesting that adding in a per-file capability into the Introjucer would be a lot of work.  As far as I can see the issue, there might be an inelegant way of adding this capability, without adding per-file properties to the Introjucer.

First, on a per-configuration basis, add a checkmark to Introjucer to enable or disable precompiled headers for that configuration.

Second, add one file path, with an optional wildcard, as the Create Precompilation File option, per configuration.  Here you would enter the path to a specific file, or to a pattern that matches exactly one file.   This file would be precompiled with /Yc in Visual Studio.

Third, add another list of list of file paths with optional wildcards as the Ignore Files for Precompilation list, again per configuration.  Any file matching a wildcard on this list would not be precompiled.  By default, all juce C++ files would not be precompiled; you could add others here.

This design violates the DRY principle, but it permits precompiled headers to be implemented in a platform-independent way without giving the Introjucer an entirely new per-file panel.  The concept could be extended in a straightforward manner to gcc and llvm.  Additionally, this design does not cover all use cases, such as situations in which projects would need more than one precompiled file header.  For that you would definitely need per-file settings in Introjucer.

I am tempted to do the work myself, but it's not a trivial undertaking.  I feel if someone more knowledgeable about Juce did the work, you might get precompiled header support on most or all platforms for free.


#11

I took a couple hours and bashed together a proof-of-concept precompiled header system for Visual Studio.  Image upload seems to be broken on this site, so I uploaded a screenshot to http://snag.gy/AB1Tv.jpg .  The Create and Use fields insert the appropriate XML into the project file, and the Other Precompiled Flags sets the /Fp and other flags manually.  It is ugly, but works as intended.  It could probably use a pulldown selector for the filenames, instead of having to type them in manually.  I can also confirm that the compilation speedups are significant for projects that use a lot of C++ templates.

Juce C++ files are automatically filtered out by detecting their "juce_" prefix.

Although I implemented this mostly in the juce_ProjectExportMSVC.h file, I also had to add a few new IDs for the new fields in question.

Interestingly, I think there is little that is truly Visual Studio dependent in this implementation.  I feel that fields like this should probably go into the main ProjectExport structure, and then exported per target platform type.  I'm pretty sure that a similar approach can be taken for Mac and other targets.

The patch had several moving parts, and it's not clear what JUCE's patch policy is, or how patches should be submitted, or even if this is a JUCE-worthy solution to the problem, so I'll hold back on redistributing until Jules or someone from ROLI comments.


#12

Hi,

It looks quite odd to me to have one option called "Generate precompiled headers" and another "Create precompiled headers" directly underneath. Is that a Visual Studio thing? If the value of a property is a filename, I'd name the property something like "xxx file" or "xxx file to use" ore something like that.


#13

Yeah, it’s a Visual Studio thing. Now that I’m deep into Mac work, I’ll see if I can rethink this to be cross-platform for MSVC, clang and gcc at least.