Introduction

The Build Automation feature is used to automatically run specific tasks when you run or build your project. These tasks are called Build Steps. There are three build steps available: Copy Files, Script and External Script.

Overview

To add a Build Step to your project, select Insert > Build Step from the main toolbar and then choose a type from the Build Step submenu. Build Steps added to the CONTENTS area of the Navigator are inactive by default.

To activate a Build step, you need to move it to a build target. You do this by dragging the Build Step from the Contents area of the Navigator to the Build Settings area of the Navigator. Drop the Build Step onto one of the targets (macOS, Windows, Linux or iOS) and the Build Step becomes active when running or building for that target.

You can turn off a Build Step that is on a build target by changing the "Applies To" property to "None".

Once you add a Build Step to the target, the target can be expanded to see the build step. When you expand it you will see the build step and an item called Build. The Build item allows you to specify whether the Build Step occurs before the project is built or after. Drag the Build Step before the Build item to have it be processed before the Build is done and drag it after the Build item to have it be built after the Build is done.

Each Build Step has an “Applies to” setting (in the Inspector) that allows you to specify: Both, Debug, Release, None.

  • Both: The Build Step is always processed.

  • Debug: The Build Step is processed only when doing a Debug Run.

  • Release: The Build Step is processed only when doing a standalone release Build.

  • None: The Build Step is not processed (disabled).

Note

For macOS Universal builds, build steps run just once before and after the build process rather than once for each executable built.

Copy files

The Copy Files step allows you to copy a file, files or a folder to a specified location during the build process. Drag the files you want copied to the empty area (or use the toolbar buttons to add files or folders). To remove something from the list, select it and press Delete on the keyboard or use the delete button on the toolbar. You can right-click on a file in the list to display a menu with: Open File and Show on Disk. Use Open File to open the file in the OS default viewer. Show on Disk displays the file using the default file system viewer (such as Finder or Explorer).

For each of these files you can also specify a subdirectory for them to be copied to by entering a value in the Subdirectory property of the Inspector. You can also specify the destination location for the files by using the Destination property in the Inspector. The choices are: App Parent Folder, Resources Folder, Frameworks Folder, Bundle Folder Parent and Contents Folder.

  • App Parent Folder: For Windows and Linux, the specified files are copied alongside the app executable. For Mac, the files are copied next to the executable in the App Bundle (Contents > MacOS).

  • Resources Folder: The specified files are copied to a Resources folder. For Windows and Linux the Resources folder is created alongside the app itself. For Mac, the Resources folder is contained within the App Bundle (Contents/Resources). In all cases, you should consider the contents of this folder to be read-only. If you need to write to these files, first copy them out to a location with write access (usually SpecialFolder.ApplicationSupport). You can get access to the Resources folder by using the SpecialFolder.Resource method.

  • Frameworks Folder: For Windows and Linux, the files are copied to the Libs folder for the app. For Mac, the files are copied to the Frameworks folder in the App Bundle (Contents/Frameworks).

  • Bundle Parent Folder: For Windows and Linux, the files are copied to the folder containing the executable (same as App Parent Folder). For Mac, the files are copied to the folder containing the App Bundle itself.

  • Contents Folder: For Windows and Linux, the file are copied to the folder containing the executable (same as App Parent Folder). For Mac, the files are copied to the App Bundle (Contents).

On iOS, there is an additional step added by default that is called "Sign". Any Copy File Build Steps that you add should be before the "Sign" step so that the files you have copied into the app bundle are properly signed for submission to the App Store.

Accessing files

In most situations, you will use the Resources destination to copy files to the Resources folder for use by your app. To access files in this folder, you can use the SpecialFolder.Resource method to get a FolderItem that points to a file. For example, to get to a database that was copied to the Resources destination, you would use this code:

Var bundleFile As Folderitem
bundleFile = SpecialFolder.Resource("AppDatabase.sqlite")

For accessing files in other locations, you will have to directly access the path yourself, starting with DesktopApplication.ExecutableFile, WebApplication.ExecutableFile, or ConsoleApplication.ExecutableFile and use the Child or Parent methods of FolderItem to work from there.

Script and external script

Scripting is a powerful way to automated your app builds. Scripts can contain a wide variety of commands to control the build process. You can choose to add an inline Script as a Build Step. This adds an item that is a Script Editor. Here you can directly enter the code for your script. You can also add an External Script which lets you reference a script file that is saved in a file. This can be useful if you want to re-use the same script with Windows, macOS and Linux builds.

All the scripting commands are listed in the IDE Scripting section, but some useful ones include: DoCommand, DoShellCommand and Speak. DoCommand is used to run built-in IDE commands, perhaps the most useful is to save your project before it is run:

DoCommand("SaveFile")

To add such a script to your build process, add a Script Build Step using the Insert menu or Insert button. The script is added to the Navigator and the Script Editor appears. In the Script Editor, enter the code:

DoCommand("SaveFile")

Now you can drag the script to a target in the BUILD section of the Navigator so that it runs. If you want the script to run before the build is started, then drag it before the "Build" item. If you want it to run after, then drag it after the "Build" item.

The Speak command uses the built-in voice to speak the supplied text. You can use this to let you know when a build has finished.

Speak("Build Complete.")

DoShellCommand allows you to run a shell command. You can run any shell command that is available in the Terminal or Command Shell of the operating system. A shell command might be used for more robust file management, to manipulate permissions, run commands to digitally code sign your app or anything else that you want.

This example runs the code sign command on a Mac:

Var command As String
command = "codesign -f --deep -s ""Developer ID Application: YourName "" ""YourXojoApp.app """
Var result As String
result = DoShellCommand(command)

Note that when you code sign your app, you must have all the files for your build already in place. If you copy of modify files in the build after you code sign then that will invalidate the signature.

An external script works the same except the script is stored in an external text file that you select. You would use an External Script if you have a script that you share across multiple projects or multiple build targets.