Faster compilation with cache

Posted on

Compilation cache effect

You can speed up the compilation of all future projects if you initialize “compilation cache”. Underneath, it means we will just compile all CGE units to a special “cache” directory (stored inside user directory, independent from the current project) and we start compilation of each project by taking all CGE precompiled units from this cache.

The effect: your compilation can be lighting fast. In my tests, if the cache is initialized,

  • It takes 2.5 seconds to build a Linux application.
  • It takes 10 seconds to build an Android APK.

And these are times of the first build, on a newly created project.

How to initialize cache?

In CGE editor, use the menu command “Run -> Cache (Precompile Engine For Current Platform)”. By default it will cache compilation for current platform (e.g. Linux or Windows where you run the editor). Switch the platform using “Run -> Platform (To Build And Run) -> …” menu item, and redo the “Run -> Cache (Precompile Engine For Current Platform)” for each platform.

Note: The menu commands to initialize the cache are only available when you have some project, any project, open. This is just a consequence of our current UI (we already have output console, and platform choice, when the project is open). But the created cache is actually independent from the project.

Or you can do it using the command-line CGE build tool, if you prefer (and your compiler, like FPC, is available on PATH environment variable). Just execute something like this:

castle-engine cache # cache for current platform
castle-engine cache --target=android # add cache for Android, both 32-bit and 64-bit

Why like this?

Right now: Without the cache if you compile the project for the first time, we actually always compile the engine too. Moreover (with or without the cache) all the compilation output (like .o, .ppu files) is stored in project-specific castle-engine-output.

Why?

  • This makes things simple. It means that we just provide to the compilers your main source code (program or library) and the paths to all sources (of your project, and of the engine). And the compiler (FPC or Delphi) just does whatever is necessary.

  • It means that switching compilers, FPC versions etc. is not an issue. Again, the compiler will just do what it should. E.g. the compiler should realize that standard units have changed compared to previous compilation.

  • It is friendly to engine developers šŸ™‚ Changing the engine unit has the same effect as changing your project source code. In both cases, the compiler just figures out the minimal set of units to recompile.

  • The debug/release modes change not only the compilation options of your application, but also of CGE units. This is helpful e.g. to activate certain additional assertions and range checks in the engine.

  • It allows you to set, within each project, some defines that affect engine compilation. For example you can change CastleWindow backend by using appropriate define. In general we want to make this use-case not important (it would be e.g. cleaner to switch CastleWindow backend by using a particular unit, it would also make it better for cache) but it is still practically useful for now.

We have designed the cache mechanism to not interfere with these advantages:

  1. The current cache contents (.o, .ppu files) are copied over but without overwriting the current .o, .ppu files in the project. So the precompiled units from cache are a starting point to your project’s compilation directory. But the precompiled units do not overwrite the existing ones, moreover the compiler will overwrite them (in the project) if e.g. you have changed CGE since making the cache. So the cache tries hard not to conflict with what you’re doing.

  2. There is a separate cache for each mode (debug,release,valgrind).

Start the discussion at Castle Game Engine Forum