Creating build rules for custom file types
Tell Xcode how to build your project’s custom file types, and provide dependency information to optimize the build process for each file.
Overview
The code and resource files in a project are typically in an editable format that a running app can’t use directly. During a build, Xcode transforms the files you’ve been editing into a suitable runtime format. For example, it compiles your code files into machine instructions for a specific device. Each transformation requires a specific tool, and Xcode uses your project’s build rules, or the built-in build rules, to select the correct tool for each file type.
A build rule maps a specific file type to the tools Xcode needs to generate the required output for that file. For example, one build rule compiles .swift files into executable code using the Swift compiler. Xcode contains built-in rules for many file types, including both code files and resource files. You can create additional rules to transform other file types into an appropriate final form, or override a built-in rule to use a different tool.
Add a new build rule for a custom file type
If your project contains file types not covered by Xcode’s built-in build rules, you can add new build rules to address those types. To create a new build rule:
In the project editor, select the target that contains your custom files.
Click the Build Rules tab.
Click the Add button (+) to create a new rule.
In the Process field, specify a filename matching string.
In the script text field, specify your custom script code.
[Image]
A build rule can use either a custom shell script or an existing tool to process files. If you use an existing tool to handle your custom file types, select that tool from the build rule’s Using field. For example, if your input files contain source code that a built-in compiler can handle, select the compiler from the list.
Specify the match criteria for source files
To match custom file types, select the “Source files with names matching” option in the Process field and specify a custom pattern string. Specify pattern strings that follow the same rules as the fnmatch function in the Standard C library. For example, to match all files with the names myfile.c and myfile.h, specify the string */myfile.c */myfile.h. During a build, Xcode compares the full path of each project file against the specified pattern. When a match occurs, the system executes your custom script code.
For information about pattern matching using the fnmatch function, see the man page for that function.
Specify the input and output files for your shell script
When Xcode detects one of your custom file types, it executes the shell script associated with the matching build rule. In your script, get the path to the source file from the SCRIPT_INPUT_FILE environment variable, and begin processing the file. If your script requires additional input data, such as build configuration files, specify those files in the Input Files section of your build rule, and access them using environment variables.
Your script code takes an input source file and generates an appropriate output file. For example, a script that compiles source code might generate an object file with machine instructions. You specify the output files for your script in the Output Files section of your build rule. Most scripts generate only one output file, but you can specify multiple files when appropriate. Xcode determines when to rebuild your source files based on the output files that you declare. When the source file is newer than the output files, Xcode rebuilds it. If you don’t specify any output files, Xcode builds your source file every time, regardless of whether the source file changed.
When you specify input and output files in your build rule, use the following variables to compose the path and filename information. For example, you might use $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).compiledData to specify an output file based on the name of the original source file.
Variable | Description |
|---|---|
| The root directory of your project’s source files. |
| The directory in which to place generated output files. The build system manages this directory and can clean it when needed. |
| The base name of the script’s input file. For example, if the path to the input file is |
| The name of the input file, including the filename extension. For example, if the path to the input file is |
| The directory that contains the input file. For example, if the path to the input file is |
| The complete path to the input file. |
Access script-related files from environment variables
Shell scripts have access to the current target’s build settings and the input and output files associated with the build rule. Before executing your build rule’s script, Xcode configures the shell environment with several environment variables. To access the build rule’s input and output files, use the environment variables in the following table.
Variable | Description |
|---|---|
| The absolute path of the file to process. |
| Additional command-line flags you assigned to the file in the Compile Sources build phase. |
| The number of paths in the Input Files section of your build rule. |
| The absolute path to one of the files in the Input Files section of your build rule. Xcode creates an environment variable for each file, starting with |
| The number of paths in the Output Files section of your build rule. |
| The absolute path to one of the files in the Output Files section of your build rule. Xcode creates an environment variable for each file, starting with |
| A string that indicates a header’s visibility. If the current file is in the public or private section of the target’s Headers build phase, this string contains the value |
| The directory in which to copy header files. If the current file is in a Headers build phase, copy the file to the location in this environment variable. |
For a list of build setting environment variables, see Build settings reference.
Specify additional build dependencies for your source file
To improve performance during incremental builds, Xcode rebuilds only the files that require a rebuild. To determine whether a file requires a rebuild, Xcode evaluates the following criteria:
Did the contents of the source file change?
Does the source file depend on any other files that changed?
Xcode determines whether a source file changed by comparing the modification date of that file to the modification date of its output file. If the source file is newer, or if the output file doesn’t exist, Xcode builds the source file.
Analyzing the dependencies between source files is more complicated, but is important to ensure builds are correct. If a source file imports headers or other files, the tool that builds the source file reports the relationship to Xcode. For your custom file types, you report dependencies by generating a set of makefile rules for Xcode to execute.
To report dependency rules for your custom source files, enable the “Use discovered dependency file” option in your build rule. Xcode suggests a default naming pattern for your dependency files, but you can change the name to match your tool’s output. In your script code, create the dependency file during each build cycle, and save the file with the appropriate name.
Create the actual files in your script code when you build custom files. Fill the contents of each dependencies file with a set of makefile rules. The Xcode build system analyzes these rules at build time to determine whether it needs to rebuild the matching source file.