castle-engine compile
Together with the engine we include a tool to help with building and packaging your programs for various platforms (standalone, mobile, consoles…).
Just download Castle Game Engine and the build tool is included inside.
In most cases, you will use Castle Game Engine Editor (bin/castle-editor
executable) that automatically uses build tool described here, under the hood. Alternatively, you can execute the build tool directly, on the command-line, using bin/castle-engin
executable.
Open a terminal (command-line), and enter the directory containing CastleEngineManifest.xml
file. This is the main project directory.
Run this command to compile the project (for the current operating system and processor):
castle-engine compile
Run this to compile and also package (again, for the current operating system and processor):
castle-engine package
By default we compile in release mode. Use option --mode=debug
to compile a debug version (slower, but more friendly for various debuggers).
That’s it, you can now use our "build tool" to easily compile and package your games for various platforms:) Read on to learn about more useful commands of the build tool.
You need a CastleEngineManifest.xml
file in your project’s directory. See the CastleEngineManifest.xml examples page for samples and documentation. The manifest file describes your project’s name, source code, what files to include in the package and such.
In most cases, the starting contents of the CastleEngineManifest.xml
file will be created when creating the project. You can use editor to create a new project or build tool castle-engine create …
command.
Once you have a project, call castle-engine
from within your project’s directory (or any subdirectory, we automatically look for CastleEngineManifest.xml
in parent directories) to quickly compile, package or clean the project. See the description of command-line parameters to castle-engine
below. The tool is integrated with our engine, so it can automatically compile the code correctly, and package it following our usual conventions. The data for the game is automatically packaged. On Windows the required DLL files are automatically included (see also the description of <dependencies> in CastleEngineManifest.xml). On Android the required Java wrappers and libraries are automatically used.
Create a new project. Provide the project name as a required parameter, like this:
castle-engine create new-project-name
The new-project-name
determines a few things:
It is the project name set in CastleEngineManifest.xml.
Thus is determines various output file names (e.g. executable name).
It also determines the directory name where the project will be placed.
There are also optional parameters:
Use the given template to create the project. Available template names correspond to subdirectories of project_templates in engine, right now they are:
empty
(default) - an empty project, with a view that just shows FPS, nothing else.
2d_game
- a simple 2D game.
3d_fps_game
- a simple 3D first-person shooter game.
3d_model_viewer
- a 3D model viewer.
By default subdirectory new-project-name
will be created in the current directory. Use this option to specify a different directory.
The project caption set in CastleEngineManifest.xml. This is a human-readable name of the project, shown in various places by default (window title, application icon on mobile desktops…). Default is equal to project name.
Name of the initial design and Pascal unit. Affects only some templates (empty
, 3d_model_viewer
for now). Default just Main
.
Note
|
At the end, this command also generates program files just like the generate-program command. So there’s no point in calling generate-program right after create .
|
Compile the project, with the syntax options and optimizations suggested for programs using our engine.
By default we compile for your current OS (operating system) and processor, so if you’re on 32-bit Windows -> you will compile a 32-bit Windows binary, if you’re on 64-bit Linux -> you will compile a 64-bit Linux binary and so on. You can use --os
and/or --cpu
options to cross-compile. Underneath, proper cross-compilation options will be passed to FPC.
For example:
Call castle-engine compile --cpu=x86_64
to compile a 64-bit version for the current operating system.
Call castle-engine compile --os=linux --cpu=x86_64
to compile a 64-bit version for Linux.
Windows is a little weird (due to historical conventions beyond FPC), and you have to use castle-engine compile --os=win64 --cpu=x86_64
(thus, you request 64-bit "twice" in the command-line) to get a 64-bit version on Windows. Use castle-engine compile --os=win32 --cpu=i386
to get a 32-bit executable for Windows.
Instead of --os
and/or --cpu
options, you can also use --target
. A target is a collection of OS and CPU combinations that typically are distributed together. Right now, these targets are available:
custom
(the default target), which means that we look at --os
and/or --cpu
options, and compile for this single OS/CPU.
android
, which consists of 2 combinations of OS/CPU: Android OS on ARM (32-bit) and Android on Aarch64 aka Arm64 (64-bit).
ios
. By default this consists of 2 combinations of OS/CPU, to include 32-bit and 64-bit iOS devices. Add the --ios-simulator
option to include 2 more combinations of OS/CPU to include also support for the iOS simulator. See iOS to learn more.
nintendo-switch
, which builds an application for Nintendo Switch.
Use --mode=debug
or --mode=release
or --mode=valgrind
for a specific compilation mode. By default, it is "release". The "valgrind" mode is for profiling (speed, memory usage) using the excellent Valgrind tool.
In all cases, your programs will be compiled with the same options as engine units. We turn the same optimizations as for the engine core. In FPC it which means that we use ObjFpc syntax mode by default.
By default we auto-detect the compiler: using the compiler indicated in CastleEngineManifest.xml by compiler="xxx"
option, otherwise using FPC or Delphi (whichever first is found). You can use --compiler
command-line option to override the compiler choice, like --compiler=fpc
or --compiler=delphi
.
You can customize what options we pass to the compiler by:
Adding options to the <custom_options>
in CastleEngineManifest.xml. This is the good place to define options specific to your project (that should be used by all developers working with this project).
Using --compiler-option
command-line option. For example, --compiler-option=-dMY_DEFINE
or --compiler-option=-gl --compiler-option=-gh
. This is the good place to pass options specific to your development system or preferences, that should not be shared by all developers working on this project.
Use --plugin
to compile a web browser plugin.
Use --output DIR
to place the output files (executable, temporary castle-engine-output
subdirectory) in a specified directory. When not given, they are placed in the current project directory. This option is also available for other commands, like package
, install
and run
.
Compiling on Windows will also copy the necessary .dll
files from the engine to be alongside your .exe
file. This allows to run the executable afterwards, in any way.
Note
|
This is not the only possible way to compile programs using our engine (for example, you can also compile and run using Lazarus, which is OK for desktop applications). |
Create an installable package with your application.
Use --cpu
, --os
or --target
options to specify target operating system/processor. By default, we package for current standalone platform.
Use --compiler
to override compiler for building, just as for compile
command.
What exactly is produced by this command depends on the target platform and the --package-format
option used.
--package-format=default
(used also when no --package-format=...
was specified):
For the standalone platforms, we package to a simple zip
/ tar.gz
archive containing the executable, libraries and data. For Windows, we create zip
, otherwise tar.gz
.
For the Android (when --target=android
or --os=android --cpu=arm/aarch64
), we create a complete apk with your application, ready to be installed and uploaded to Google Play!
For iOS (when --target=ios
), we create an Xcode project, that you can run and publish using Xcode.
--package-format=zip
: Pack files into a zip file.
--package-format=tar.gz
: Pack files into a tar.gz file.
--package-format=deb
: Pack files into a Debian Package (deb).
--package-format=directory
: Put files into a directory. This is useful if you plan to further process this directory, e.g. pack it with your own scripts.
Android formats:
--package-format=android-apk
: Create an APK file. This is right now the equivalent to --package-format=default
and it is just the default behavior when target/OS is Android. It’s the standard way to build applications for Android. It also allows you to manually install the app on your Android device.
--package-format=android-app-bundle
: Create an Android App Bundle (AAB). This is a new format recommended for submitting a release to Google Play Store. Android App Bundle may contain multiple precompiled versions of the app and assets, and Google Play Store internally generates an installable APK for every specific user depending on user device configuration (such as Android version or screen resolution). AAB format is strictly required to upload a project larger than 100Mb to Play Store.
iOS formats:
--package-format=ios-xcode-project
: Create the Xcode project. This is the default package method for iOS. You can open the resulting project in Xcode and build/deploy the application for iOS device or AppStore.
--package-format=ios-archive-ad-hoc
: Archive and export using the ad-hoc method, which results in an IPA file of the application. To install on designated devices, upload to TestFairy etc.
--package-format=ios-archive-development
: Archive and export using the development method. See the Xcode documentation (and try these options from Xcode interactively) for details.
--package-format=ios-archive-app-store
: Archive and export for the TestFlight and the AppStore. See the Xcode documentation (and try these options from Xcode interactively) for details. Note that this does not upload to the TestFlight / AppStore (although we’d like to extend this someday to do it).
macOS formats:
--package-format=mac-app-bundle-zip
: Application bundle on macOS, packed into zip
. Default format for macOS.
--package-format=mac-app-bundle
: Application bundle on macOS, not packed (so it is just a directory like MyApplication.app
).
Nintendo Switch format: --package-format=nintendo-switch
.
When target is iOS
you can also use --ios-simulator
option to include iOS simulator support (see iOS).
By default output filename contains a version number. Sometimes this is not comfortable, use --package-name-no-version
to avoid it.
You can use --mode=xxx
option when packaging, just like when compiling. Use --mode=debug
or --mode=release
for a specific compilation mode. By default, it is "release". You can use --mode=debug
to package a debug release, which may be useful to distribute to users interested in beta-testing.
In some cases, the --mode
also affects the packaging wrapper. For example, on Android, a debug apk is generated. Also, only a debug apk may use a debug signing key (our build tool will automatically fallback from release apk to debug apk if you did not provide a release key in AndroidSigningProperties.txt).
To make sure that we recompile everything in the current mode (e.g. a release mode), this does clean
, and then compile
, and only then actually packages the result. You can change this behavior:
Use --fast
to make the compilation step faster — we will recompile only what changed.
By default, without --fast
, the package
command first cleans all the compilation results, and then builds from scratch (engine and your code). This is safest (makes sure that everything is rebuild with latest compilation options) but slow, and usually not necessary (Pascal compilers are generally excellent at detecting what needs to be recompiled, FPC even handles changes to include files reliably). For the final release builds, we advise to not use this option.
Using --fast
is suitable during the development, if you call the package
command often.
Use --assume-compiled
to say that you already compiled the application in proper mode before calling the package
action. We will not do clean
and compile
in this case at all. This is obviously much faster, but you need to make sure to call compile
beforehand yourself.
Another (independent) way to make packaging faster is to use --update-only-code
. For now this is meaningful only for iOS. If specified, it means that the build tool can assume that only the Pascal code have changed (so you did not change e.g. data/
directory, or project settings in CastleEngineManifest.xml
). We can then recompile the code (and update the relevant file in the project, like libxxx.a
) without changing anything else. This means that the package
command will finish much faster. It will also be more comfortable — e.g. no need to close and reopen the project in Xcode, Visual Studio or whatever other software is used to handle the final project.
Install the application created by previous "package" call.
This is useful when OS is "android", it installs and runs the apk package created by previous "package" call for Android. Useful for quick testing of your app on a device connected through USB. Note: it’s best to first test do you see your device using SDK tools, for example execute adb devices
and see is your device listed.
Use --plugin to install a web browser plugin. We install the compiled plugin such that it should be visible by all web browsers supporting NPAPI. (On Windows, this means installing proper registry entries. On Unix, it means copying the library to special directory.)
Pass also additional options reflecting the OS/architecture, mode and package name format. In general, pass to install
exactly the same values as you used for package
, so that we know which package to install:
Use --os
, --cpu
or --target
to specify target operating system/processor (by default, we install for the current standalone platform).
Use --mode=xxx
to specify debug or release package.
Use --package-format
, --package-name-no-version
to determine the package name.
Run the application.
The log of the application (whatever you write using WritelnLog, WritelnWarning) will be the output of this command. On some platforms, you can also use regular Writeln
, but to be cross-platform better stick to CGE WritelnLog
/ WritelnWarning
, they will work in all cases (Android, iOS, Windows GUI applications etc.).
As usual, use --os
, --cpu
or --target
options to specify target operating system/processor. By default, we run the normal (exe) application on the current platform.
On some platforms, it requires packaging and installing the application first. This applies to Android: we install and run on a device connected through USB. Use the "package" and "install" commands before this. For example, on Android you can package and install and run your application like this:
castle-engine package --target=android castle-engine install --target=android castle-engine run --target=android
On other platforms (e.g. standalone Windows, Linux, macOS…), this simply runs the last compiled application. So just "compile" the application first, like this:
castle-engine compile castle-engine run
You can specify parameters to pass to the application after the special "--" parameter. For example,
castle-engine run -- --fullscreen
This will run your application with command-line parameters --fullscreen
. In your application, you can read command-line parameters with the help of CastleParameters
unit. (The --fullscreen
option, used as an example here, is actually handled automatically, if only your program calls Application.ParseStandardParameters
.) The command-line parameters are not supported in non-desktop environments (e.g. there’s no way to pass them to an Android or iOS application).
On Unix desktop platforms (like Linux, FreeBSD..), we can run your game through a "wrapper script". This is useful e.g. to set LD_LIBRARY_PATH
before running the application. The build tool simply looks for run.sh
or <application_name>_run.sh
script in the project directory, and executes it if found (instead of executing the compiled binary directly).
Package source code, which means just to package whole project directory (cleaned up first).
It creates xxx-VERSION-src.tar.gz archive, with VERSION obtained following the <version> element in the CastleEngineManifest.xml.
It accepts the --package-format
and --package-name-no-version
options, just like the package
command. By default we just pack to zip (that is, --package-format=zip
is equivalent to --package-format=zip
).
Clean compilation and packaging temporary stuff. This does not remove final packaging files.
Compile the Object Pascal file (unit/program/library) given as a parameter. This does not search for the Castle Game Engine project’s manifest in the CastleEngineManifest.xml
file. It merely calls "fpc" with proper command-line options for units/programs/libraries using our engine.
Use this instead of "compile" only if there’s some good reason you don’t want to use CastleEngineManifest.xml
to manage your project.
Create GPU-compressed versions of textures, and downscaled textures, for the textures mentioned in <auto_generated_textures>
inside the file data/material_properties.xml
. Such GPU-compressed and downscaled textures can then be automatically used in your application. See instructions how to use it and example data/material_properties.xml
.
If the output textures are already created, they are updated only if the output timestamp is earlier than input. This usually allows to automatically do only the necessary work, similar to how Makefiles operate. To force recreating all textures, just call castle-engine auto-generate-clean --all
first.
The information about created textures is stored in data/CastleAutoGenerated.xml
file. If you use version control, you should either:
ignore the data/CastleAutoGenerated.xml
file and ignore all auto_generated
directories.
or commit both the data/CastleAutoGenerated.xml
file and all auto_generated
directories.
Clear auto_generated
subdirectories. They should contain only the output created by castle-engine auto-generate-textures
target. In the future, it is possible that more things will be placed there (for example, modern GPUs allow mesh data compression).
Run without any arguments to only clean the unused files in auto_generated
subdirectories. This may be useful after moving/renaming some subdirectories, as the castle-engine auto-generate-textures
command never removes previous files, it only adds new files. Having unused files is not a problem — but they waste disk space, and can be safely removed.
Run with --all
argument to clean all files from the auto_generated
subdirectories. This is useful e.g. if you want to force regenerating them all by next castle-engine auto-generate-textures
command.
Generates:
standalone (desktop) Pascal program code in the file xxx_standalone.dpr
. It uses the game_units
defined in the CastleEngineManifest.xml to determine the correct uses
clause of the program file.
You can use this program code to compile the project using any tool you want, not necessarily our build tool. E.g. maybe you like using Lazarus or fpmake
. You can use it as a standalone_source
in the CastleEngineManifest.xml
to make sure build tool also uses it (in case you will modify it), although build tool can also generate such source code automatically.
If the standalone_source
is specified in CastleEngineManifest.xml, then we overwrite it, regardless if it is called xxx_standalone.dpr
or not.
Lazarus project information in the file xxx_standalone.lpi
.
Together with xxx_standalone.dpr
, this allows you to open this project in Lazarus to edit, compile, debug and run it from Lazarus. You can also compile it using lazbuild
.
If the standalone_source
is specified in CastleEngineManifest.xml, then we overwrite the respective LPI file, regardless if it is called xxx_standalone.lpi
or not.
Delphi project information in the file xxx_standalone.dproj
.
Together with xxx_standalone.dpr
, this allows you to open this project in Delphi to edit, compile, debug and run it from Delphi.
If the standalone_source
is specified in CastleEngineManifest.xml, then we overwrite the respective DPROJ file, regardless if it is called xxx_standalone.dproj
or not.
CastleAutoGenerated
unit in castleautogenerated.pas
unit. It is used by the program file created above (xxx_standalone.dpr
) and also by all program or library files created automatically by the build tool to build project on all platforms. It defines some project properties, to parse standard command-line properties, to initialize logging.
Run the Castle Game Engine Editor within this project. The executed editor will include possible project-specific components.
In simple cases, this is just a shortcut for running castle-editor
and opening the current project, which can also be done by calling castle-editor ../path-to-project/CastleEngineManifest.xml
.
If your CastleEngineManifest.xml contains editor_units
attribute, then this automatically builds and runs a custom CGE editor (a fork of the CGE editor, for use in your project), with your custom components included.
The custom editor is compiled and present inside castle-engine-output/editor/
, so it is tied to your project, cleared with castle-engine clean
and so on. You should always execute it using castle-engine editor
command. Or using the "Project -> Restart Editor (may rebuild editor with custom controls)" menu from the CGE editor (vanilla build or custom build, doesn’t matter, the "Restart editor" will always build custom editor if project uses editor_units
).
Precompile CGE units, to speed up future compilation of all projects (with the current compiler and engine version).
By default we prepare cache for compilation on the current platform. The options --os
, --cpu
, --target
switch the platform, as usual. E.g. you can use castle-engine cache --target android
to speedup future Android compilations.
The precompiled units are stored in user files, and will be reused by all subsequent compilations of any CGE project for matching platform. The precompiled units from cache are simply copied over (as a starting point) to your project’s compilation directory. 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.
The cache is always prepared for all possible modes: debug
, release
, valgrind
. This command ignores the --mode
option.
The --compiler
option is taken into account, but for now for Delphi we merely answer with an error. The code to use cache is now only for FPC. In the future we plan to extend this to Delphi.
The --ios-simulator
option is honored, it changes what castle-engine cache --target=iOS
does (for what platforms does it prepare cache).
Remove all the cached files created by cache
(for all platforms).
This reclaims the disk space used by cache and it implies that future compilations will be done without using the cache.
Perform simple analysis of data files that are possibly unused in your project.
If they are really unused, avoid packaging these files, to keep the application smaller to download for the user. To do this:
Exclude them from being packaged. Note that files like *.blend*
are excluded by default.
Move them out of data
subdirectory (to some other project directory like data-for-possible-future-usage
).
Or just delete them. Because you use a version control system and you are not afraid of removing things, right?
Warning
|
Right now, this analysis is using some quick assumptions and heuristics. The data files are just "grepped" (not intelligently analyzed) for the filenames they use. Do not trust this detection 100% — sometimes files may be detected as used when they are not, or the other way around. |
Create CastleEngineManifest.xml file if it does not exist yet, guessing the project name based on directory name. You can use this CastleEngineManifest.xml
as a starting point.
This is deprecated — too little practical usage. Report if you find this useful.
To improve this documentation just edit this page and create a pull request to cge-www repository.