Xcode Build Rules
Stay organized with collections
Save and categorize content based on your preferences.
Most Xcode project types support build rules, which allow developers to modify
how existing file types are built, and to define how new file types are built.
The J2ObjC scripts are intentionally designed to plug into build systems like Xcode.
The j2objc-sample-reversi project is
an example of how to add Java sources to a simple iOS game.
A minimal build requires updating build settings and then adding an J2ObjC build rule.
Update the Build Settings
- Click the project in the Project Navigator to open the Project Editor and ensure the
application target is selected.
- Click the Build Settings tab.
- Link the JRE emulation library (
jre_emul
) by adding -ljre_emul
to Other Linker Flags.
It should look like this:

- Click the + to and select Add User-Defined Setting.
- Name the setting
J2OBJC_HOME
and set its value to the location of J2ObjC. This should
either be the folder resulting from unzipping the release zip
or the j2objc/dist
folder if you compiled from source and your root is j2objc
.
- Under Search Paths modify the following:
- Framework Search Paths add
${J2OBJC_HOME}/frameworks
- Library Search Paths add
${J2OBJC_HOME}/lib
(for each build configuration).
- User Header Search Paths add
${J2OBJC_HOME}/include
.
- Confirm your settings by searching for
J2OBJC_HOME
. You should see something similar to this:

Adding a J2ObjC Build Rule
Determine the root directory of your Java source files, which we'll call
$source-root
. The root directory is the directory that contains the top
package of your source files.
If you using git and would like to pull in your Java files from another git project, you can
add a submodule tracking the project with your Java
sources. For example, suppose your Xcode project (xcodeproj) is in ~/dev/MyProject
then you
likely have another MyProject
directory with your Objective-C source. In the
~/dev/MyProject/MyProject
directory run git submodule add git@github.com:user/javaproject
to
create a ~/dev/MyProject/MyProject/javaproject
directory with source for your Java project
right along side your Objective-C sources. You can then drag that folder into your Xcode project
under the MyProject
group, which has Xcode mirroring your filesystem.
${PROJECT_DIR}/MyProject/javaproject/src
is the $source-root
.
If your Java sources are in a group or directory in your Xcode project, the $source-root
is ${PROJECT_DIR}/__group_or_directory_name__
.
If in doubt, right click on that group or directory and select Show in Finder to see the
directory and use the absolute path.
For example, if you have a Java package foo.bar
in a directory called ~/myproject/src
,
that package's Java files should be in ~/myproject/src/foo/bar/**.java
-- that means
~/myproject/src
is the root directory for your project.
If the Java source files are external to the Xcode project, enter the full path used when
listing them in a Terminal window.
Click the project in the Project Navigator to open the Project Editor and ensure the
application target is selected.
Click the Build Rules tab.
Click the + to add a build rule.
For the new rule's Process option, select "Java source files". The Using option should be "Custom script:".
In the custom script text box, add the following (remember to substitute $source-root
):
if [ ! -f "${J2OBJC_HOME}/j2objc" ]; then echo "J2OBJC_HOME is not correctly defined, currently set to '${J2OBJC_HOME}'"; exit 1; fi;
"${J2OBJC_HOME}/j2objc" -d ${DERIVED_FILE_DIR} -sourcepath "$source-root" --no-package-directories -g ${INPUT_FILE_PATH};
In the Output Files panel, click the + button and add: ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.h
.
Click the + button again, and add ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.m
.
When you are finished, the settings panel should look something like this (note: as of 10.2, Xcode still defines the
DERIVED_FILES_DIR variable the same as DERIVED_FILE_DIR for backwards compatibility):

Linking Additional Libraries
The link build step (Xcode's "Link Binary With Libraries" build phase) needs
J2ObjC-specific flags, which vary depending on how your application uses translated Java classes.
For a complete list see Required Link Settings. Here are a couple
examples what additional libraries you may need to link:
- To use the
java.util.zip
package you must link the libz.dylib library by adding
-ljre_zip
to your Other Linker Flags.
- To do secure hash generation, you must add the Security Framework to your project.
Debugging Build Problems
If Xcode reports a build failure with these steps, open the Issue Navigator and
click on an error to inspect the details. This will show the details of what command-line
statement was executed. Here are a few common errors:
Class cannot be resolved - Most likely, the $source-path
you used was incorrect.
Look for the -sourcepath
option in the executed command and ensure it points to the
root directory of your Java source files.
"JreEmulation.h" file not found - Most likely, the problem is a bad User Header Search
Paths value. Search the build command for the -I
option with the path; if it looks okay,
copy the path (not the -I) and in a terminal window run ls
with that path to verify there
isn't a typo.
"_IOSClass_FromClass", referenced from: or "_OBJCCLASS$_Java" - Either the Library
Search Paths is incorrect or you forgot to link the JRE emulation library by setting Other
Linker Flags to -ljre_emul
. You may also need to link additional libraries.
Undefined symbols: _iconv* - Link in the required iconv library.
If you still have problems, ask the
j2objc-discuss group.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2024-07-10 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-07-10 UTC."],[[["\u003cp\u003eXcode projects can leverage build rules to manage the compilation of Java files using J2ObjC.\u003c/p\u003e\n"],["\u003cp\u003eThe J2ObjC integration process involves updating build settings to link necessary libraries and define search paths.\u003c/p\u003e\n"],["\u003cp\u003eA dedicated build rule is required for processing Java source files, ensuring they are correctly translated into Objective-C.\u003c/p\u003e\n"],["\u003cp\u003eDevelopers might need to link additional libraries depending on the functionalities used in the translated Java code.\u003c/p\u003e\n"],["\u003cp\u003eTroubleshooting build errors involves analyzing the build command and verifying the configuration settings, particularly search paths and linked libraries.\u003c/p\u003e\n"]]],[],null,["# Xcode Build Rules\n\nMost Xcode project types support build rules, which allow developers to modify\nhow existing file types are built, and to define how new file types are built.\nThe J2ObjC scripts are intentionally designed to plug into build systems like Xcode.\n\u003e The [j2objc-sample-reversi project](https://github.com/tomball/j2objc-sample-reversi) is\n\u003e an example of how to add Java sources to a simple iOS game.\n\nA minimal build requires updating build settings and then adding an J2ObjC build rule.\n\nUpdate the Build Settings\n-------------------------\n\n1. Click the project in the *Project Navigator* to open the *Project Editor* and ensure the application target is selected.\n2. Click the *Build Settings* tab.\n3. Link the JRE emulation library (`jre_emul`) by adding `-ljre_emul` to *Other Linker Flags* . It should look like this:\n4. Click the *+* to and select *Add User-Defined Setting*.\n5. Name the setting `J2OBJC_HOME` and set its value to the location of J2ObjC. This should either be the folder resulting from unzipping the [release zip](https://github.com/google/j2objc/releases) or the `j2objc/dist` folder if you compiled from source and your root is `j2objc`.\n6. Under *Search Paths* modify the following:\n - *Framework Search Paths* add `${J2OBJC_HOME}/frameworks`\n - *Library Search Paths* add `${J2OBJC_HOME}/lib` (for each build configuration).\n - *User Header Search Paths* add `${J2OBJC_HOME}/include`.\n7. Confirm your settings by searching for `J2OBJC_HOME`. You should see something similar to this:\n\nAdding a J2ObjC Build Rule\n--------------------------\n\n1. Determine the root directory of your Java source files, which we'll call\n `$source-root`. The root directory is the directory that contains the top\n package of your source files.\n\n - If you using git and would like to pull in your Java files from another git project, you can\n add a [submodule](https://git-scm.com/docs/git-submodule) tracking the project with your Java\n sources. For example, suppose your Xcode project (xcodeproj) is in `~/dev/MyProject` then you\n likely have another `MyProject` directory with your Objective-C source. In the\n `~/dev/MyProject/MyProject` directory run `git submodule add git@github.com:user/javaproject` to\n create a `~/dev/MyProject/MyProject/javaproject` directory with source for your Java project\n right along side your Objective-C sources. You can then drag that folder into your Xcode project\n under the `MyProject` group, which has Xcode mirroring your filesystem.\n `${PROJECT_DIR}/MyProject/javaproject/src` is the `$source-root`.\n\n - If your Java sources are in a group or directory in your Xcode project, the `$source-root`\n is `${PROJECT_DIR}/__group_or_directory_name__`.\n\n - If in doubt, right click on that group or directory and select Show in Finder to see the\n directory and use the absolute path.\n\n - For example, if you have a Java package `foo.bar` in a directory called `~/myproject/src`,\n that package's Java files should be in `~/myproject/src/foo/bar/**.java` -- that means\n `~/myproject/src` is the root directory for your project.\n\n - If the Java source files are external to the Xcode project, enter the full path used when\n listing them in a Terminal window.\n\n2. Click the project in the *Project Navigator* to open the *Project Editor* and ensure the\n application target is selected.\n\n3. Click the *Build Rules* tab.\n\n4. Click the *+* to add a build rule.\n\n5. For the new rule's *Process* option, select \"Java source files\". The *Using* option should be \"Custom script:\".\n\n6. In the custom script text box, add the following (remember to substitute `$source-root`):\n\n if [ ! -f \"${J2OBJC_HOME}/j2objc\" ]; then echo \"J2OBJC_HOME is not correctly defined, currently set to '${J2OBJC_HOME}'\"; exit 1; fi;\n \"${J2OBJC_HOME}/j2objc\" -d ${DERIVED_FILE_DIR} -sourcepath \"$source-root\" --no-package-directories -g ${INPUT_FILE_PATH};\n\n7. In the Output Files panel, click the *+* button and add: `${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.h`.\n\n8. Click the *+* button again, and add `${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.m`.\n\nWhen you are finished, the settings panel should look something like this (note: as of 10.2, Xcode still defines the\nDERIVED_FILES_DIR variable the same as DERIVED_FILE_DIR for backwards compatibility):\n\nLinking Additional Libraries\n----------------------------\n\nThe link build step (Xcode's \"Link Binary With Libraries\" build phase) needs\nJ2ObjC-specific flags, which vary depending on how your application uses translated Java classes.\nFor a complete list see [Required Link Settings](/j2objc/guides/required-link-flags). Here are a couple\nexamples what additional libraries you may need to link:\n\n- To use the `java.util.zip` package you must link the libz.dylib library by adding `-ljre_zip` to your *Other Linker Flags*.\n- To do secure hash generation, you must add the Security Framework to your project.\n\nDebugging Build Problems\n------------------------\n\nIf Xcode reports a build failure with these steps, open the *Issue Navigator* and\nclick on an error to inspect the details. This will show the details of what command-line\nstatement was executed. Here are a few common errors:\n\n- **Class* cannot be resolved* - Most likely, the `$source-path` you used was incorrect.\n Look for the `-sourcepath` option in the executed command and ensure it points to the\n root directory of your Java source files.\n\n- *\"JreEmulation.h\" file not found* - Most likely, the problem is a bad *User Header Search\n Paths* value. Search the build command for the `-I` option with the path; if it looks okay,\n copy the path (not the -I) and in a terminal window run `ls` with that path to verify there\n isn't a typo.\n\n- *\"_IOSClass_FromClass\", referenced from:* or *\"_OBJC*CLASS*$_Java\"* - Either the *Library\n Search Paths* is incorrect or you forgot to link the JRE emulation library by setting *Other\n Linker Flags* to `-ljre_emul`. You may also need to link additional libraries.\n\n- *Undefined symbols: _iconv\\** - Link in the [required iconv library](/j2objc/guides/required-link-flags).\n\nIf you still have problems, ask the\n[j2objc-discuss group](https://groups.google.com/forum/#!forum/j2objc-discuss)."]]