Skip to content

Commit bccb50f

Browse files
committed
Merge pull request #328 from brunobowden/docs
Docs: initial user experience + refactor project dependencies
2 parents ad50db0 + 0416f3b commit bccb50f

File tree

2 files changed

+143
-78
lines changed

2 files changed

+143
-78
lines changed

FAQ.md

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ Make sure your arguments are separate strings, not a single space-concatenated s
3333

3434
### Why is my clean build failing?
3535

36-
This is a [known issue](https://github.com/j2objc-contrib/j2objc-gradle/issues/306) if you don't
37-
have any tests.
38-
If you are doing `./gradlew clean build`, try instead `./gradlew clean && ./gradlew build`.
36+
This is a [known issue](https://github.com/j2objc-contrib/j2objc-gradle/issues/306)
37+
if you don't have any tests. If you are doing `./gradlew clean build`, try instead
38+
`./gradlew clean && ./gradlew build`.
3939

4040
When you don't have any test source files, The plugin creates a placeholder to force the
4141
creation of a test binary; this is done during project configuration phase, but `clean` deletes
@@ -44,10 +44,10 @@ this file before `build` can use it.
4444

4545
### How do I include Java files from additional source directories?
4646

47-
In order to include source files from sources different than ``src/main/java`` you have to
47+
In order to include source files from sources different than `src/main/java` you have to
4848
[modify the Java plugin's sourceSet(s)](https://docs.gradle.org/current/userguide/java_plugin.html#N11FD1).
49-
For example, if you want to include files from ``src-gen/base`` both into your JAR and (translated) into
50-
your Objective C libraries, then add to your ``build.gradle``:
49+
For example, if you want to include files from `src-gen/base` both into your JAR and (translated) into
50+
your Objective C libraries, then add to your `shared/build.gradle`:
5151

5252
sourceSets {
5353
main {
@@ -64,16 +64,16 @@ To work with Swift in Xcode, you need to configure a [bridging header](https://d
6464
Within that bridging header, include the file needed for using the JRE and any classes that you'd like
6565
to access from Swift code.
6666

67-
```
68-
// File: IOS-APP-bridging-header.h
67+
// File: ios/IOS-APP/IOS-APP-bridging-header.h
6968

70-
// Required for Swift initialization of Java objects (they all inherit from JavaObject)
71-
#import "JreEmulation.h"
69+
// J2ObjC requirement for Java Runtime Environment
70+
// Included from /J2OBJC_HOME/include
71+
#import "JreEmulation.h"
7272

73-
// Swift accessible j2objc translated classes, referenced from `shared/build/j2objcOutputs/src/main/objc`
74-
#import "MyClassOne.h"
75-
#import "MyClassTwo.h"
76-
```
73+
// Swift accessible J2ObjC translated classes
74+
// Included from `shared/build/j2objcOutputs/src/main/objc`
75+
#import "MyClassOne.h"
76+
#import "MyClassTwo.h"
7777

7878

7979
### How do I enable ARC for my Objective-C classes?
@@ -89,7 +89,7 @@ Add the following to your configuration block. [See](https://developer.apple.com
8989
### How do I call finalConfigure()?
9090

9191
You must always call `finalConfigure()` at the end of `j2objcConfig {...}` within your project's
92-
`build.gradle` file. You need to include an otherwise empty j2objcConfig { } block with this
92+
`build.gradle` file. You need to include an otherwise empty `j2objcConfig {...}` block with this
9393
call even if you do not need to customize any other `j2objConfig` option.
9494

9595
j2objcConfig {
@@ -106,60 +106,71 @@ See: [How do I enable ARC for my Objective-C classes?](#how-do-i-enable-arc-for-
106106
### How do I disable a plugin task?
107107

108108
You can disable tasks performed by the plugin using the following configuration block in your
109-
`build.gradle`. This is separate and alongside the j2objcConfig settings. For example, to
109+
`build.gradle`. This is separate and alongside the `j2objcConfig` settings. For example, to
110110
disable the `j2objcTest` task, do the following:
111111

112+
// File: shared/build.gradle
112113
j2objcTest {
113114
enabled = false
114115
}
115-
116116
j2objcConfig {
117117
...
118118
}
119119

120120

121-
### How do I setup multiple related J2ObjC or native projects?
121+
### How do I setup dependencies with J2ObjC?
122122

123-
You can express three kinds of dependencies within j2objcConfig:
123+
See the following FAQ answers...
124124

125-
1. The common case is that Java and j2objc Project B depends on Java and J2ObjC Project A,
126-
and you need the Project B J2ObjC generated library to depend on the Project A J2ObjC
127-
generated library. In this case add to B.gradle:
128125

129-
```
126+
### How do I setup a dependency on a Gradle Java project?
127+
128+
If project `shared` depends on Gradle Java Project A, and you want J2Objc generated Project
129+
`shared` to depend on J2ObjC generated Project A. Add to `shared/build.gradle`:
130+
131+
// File: shared/build.gradle
130132
j2objcConfig {
131133
dependsOnJ2objc project(':A')
132134
}
133-
```
134135

135-
This kind of dependency should be inferred automatically from the corresponding Java
136-
dependency in the future.
136+
Project A needs to have the J2objc Gradle Plugin applied and the `j2objcConfig` with the
137+
`finalConfigure()` call. This applies transitively, so in turn it may need `dependsOnJ2objc`
138+
again. Alternatively you can try building using `--build-closure` (TODO: need item on this).
139+
The library will be linked in and the headers available for inclusion. Project A will be
140+
built first.
137141

138-
2. Java and j2objc project B depends on a
139-
[custom native library](https://docs.gradle.org/current/userguide/nativeBinaries.html#N15F82)
140-
called someLibrary in native project A. Add to B.gradle:
142+
In the future, this kind of dependency should be inferred automatically from the corresponding
143+
Java dependency - [issue 41](https://github.com/j2objc-contrib/j2objc-gradle/issues/41).
141144

142-
```
143-
j2objcConfig {
144-
extraNativeLib project: ':A', library: 'someLibrary', linkage: 'static'
145-
}
146-
```
147145

148-
3. Java and j2objc project B depends on library libpreBuilt pre-built outside of
149-
Gradle in directory /lib/SOMEPATH, with corresponding headers in /include/SOMEPATH.
150-
Add to B.gradle:
146+
### How do I setup a dependency on a prebuilt native library?
151147

152-
```
148+
For a Java and J2ObjC project `shared` that depends on library libpreBuilt pre-built outside
149+
of Gradle in directory /lib/SOMEPATH, with corresponding headers in /include/SOMEPATH.
150+
Add to `shared/build.gradle`:
151+
152+
// File: shared/build.gradle
153153
j2objcConfig {
154154
extraObjcCompilerArgs '-I/include/SOMEPATH'
155155
extraLinkerArgs '-L/lib/SOMEPATH'
156156
extraLinkerArgs '-lpreBuilt'
157157
}
158-
```
159158

160-
In (1) and (2), A's library will be linked in and A's headers will be available for inclusion, and
161-
B will automatically build after A. (3) is not supported by Gradle's dependency management
162-
capabilities; you must ensure preBuilt's binary and headers are available before project B is built.
159+
The library will be linked in and the headers available for inclusion. All prebuilt libraries
160+
must be fat binaries with the architectures defined by `supportedArchs` in
161+
[j2objcConfig.groovy](https://github.com/j2objc-contrib/j2objc-gradle/blob/master/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy).
162+
163+
164+
### How do I setup a dependency on a Gradle native library project?
165+
166+
If project `shared` depends on a
167+
[custom native library](https://docs.gradle.org/current/userguide/nativeBinaries.html#N15F82)
168+
called someLibrary from native project A. Add to `shared/build.gradle`:
169+
170+
// File: shared/build.gradle
171+
j2objcConfig {
172+
extraNativeLib project: ':A', library: 'someLibrary', linkage: 'static'
173+
}
163174

164175

165176
### Cycle Finder Basic Setup
@@ -173,6 +184,7 @@ The basic setup will implicitly check for 40 memory cycles - this is the expecte
173184
of erroneous matches with `jre_emul` library for J2ObjC version 0.9.6.1. This may cause
174185
issues if this number changes with future versions of J2ObjC libraries.
175186

187+
// File: shared/build.gradle
176188
j2objcCycleFinder {
177189
enabled = true
178190
}
@@ -194,10 +206,11 @@ and building the J2ObjC source:
194206

195207
`(cd jre_emul && make java_sources_manifest)`
196208

197-
3. Configure j2objcConfig in build.gradle so CycleFinder uses the annotated J2ObjC source
198-
and whitelist. Note how this gives and expected cycles of zero.
209+
3. Configure j2objcConfig in `shared/build.gradle` so CycleFinder uses the annotated J2ObjC
210+
source and whitelist. Note how this gives and expected cycles of zero.
199211

200212
```
213+
// File: shared/build.gradle
201214
j2objcConfig {
202215
cycleFinderArgs '--whitelist', 'J2OBJC_REPO/jre_emul/cycle_whitelist.txt'
203216
cycleFinderArgs '--sourcefilelist', 'J2OBJC_REPO/jre_emul/build_result/java_sources.mf'

README.md

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@ At HEAD, this plugin is in a state of significant flux as we refactor it into a
1515
Gradle plugin for our beta. You may wish to wait for the beta release as we may make backwards
1616
incompatible changes before that point.
1717

18-
You should start with a clean java only project without any android dependencies. It suggested that
19-
this project is named `'shared'`. It must be buildable using Gradle's standard `'java'` plugin.
20-
It may start as an empty project and allows you to gradually shift over code from an existing
21-
Android application. See the section below on [Folder Structure](#folder-structure).
18+
You should start with a clean java only project without any android dependencies.
19+
It is suggested that the project is named `shared`. It must be buildable using the standard
20+
[Gradle Java plugin](https://docs.gradle.org/current/userguide/java_plugin.html).
21+
Starting as an empty project allows you to gradually shift over code from an existing
22+
Android application. This if beneficial for separation between the application model
23+
and user interface and a project which can easily be used server side as well.
2224

23-
This is how to configure the build.gradle in your java only project. Please follow the link to
24-
find the latest version number of the plugin:
25+
The Android app, shared Java project and Xcode should be sibling directories, i.e children
26+
of the same root level folder. Suggested names are `android, shared & ios` respectivey.
27+
See the section below on [Folder Structure](#folder-structure).
28+
29+
Configure `shared/build.gradle` in your Java only project:
2530

2631
// File: shared/build.gradle
2732
plugins {
@@ -31,61 +36,117 @@ find the latest version number of the plugin:
3136

3237
// Plugin settings:
3338
j2objcConfig {
34-
xcodeProjectDir '../ios' // Xcode workspace directory
35-
xcodeTarget 'IosApp' // iOS app target name
39+
xcodeProjectDir '../ios' // Xcode workspace directory (suggested name)
40+
xcodeTarget 'IOS-APP' // iOS app target name (replace with existing app name)
3641

3742
// Other Settings:
3843
// https://github.com/j2objc-contrib/j2objc-gradle/blob/master/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy#L30
3944

4045
finalConfigure() // Must be last call to configuration
4146
}
4247

43-
Within the Android application's project `build.gradle`, make it dependent on the `shared` project:
48+
Within the Android application's `android/build.gradle`, make it dependent on
49+
the `shared` project:
4450

4551
// File: android/build.gradle
4652
dependencies {
4753
compile project(':shared')
4854
}
4955

5056

57+
### J2ObjC Installation
58+
59+
Download the latest version from the [J2ObjC Releases](https://github.com/google/j2objc/releases).
60+
Find the local.properties in your root folder and add the path to the unzipped folder:
61+
62+
// File: local.properties
63+
j2objc.home=/J2OBJC_HOME
64+
65+
66+
### Build Commands
67+
68+
The plugin will output the generated source and libaries to the `build/j2objcOutputs`
69+
directory. It is integrated with Gradle's Java build plugin and may be run as follows:
70+
71+
./gradlew shared:build
72+
73+
To update an existing Xcode project to load the libraries and header files, use this
74+
additional command:
75+
76+
./gradlew shared:j2objcXcode
77+
78+
Typically they should both be used together:
79+
80+
./gradlew shared:build shared:j2objcXcode
81+
82+
5183
### NOTE: Open .xcworkspace in Xcode
5284

53-
When using the j2objcXcodeTask, open the `.xcworkspace` file in Xcode. If the `.xcodeproj` file
85+
When using the `j2objcTask`, open the `.xcworkspace` file in Xcode. If the `.xcodeproj` file
5486
is opened in Xcode then CocoaPods will fail. This will appear as an Xcode build time error:
5587

5688
library not found for -lPods-*-j2objc-shared
5789

90+
Also see the FAQ note on [developing with Swift](https://github.com/j2objc-contrib/j2objc-gradle/blob/master/FAQ.md#how-do-i-develop-with-swift).
91+
92+
93+
### Build Speed
94+
95+
You can reduce the build time by 50% by skipping the release binaries by adding the
96+
following to your root level `local.properties` file:
97+
98+
j2objc.release.enabled=false
99+
100+
This is helpful for a tight modify-compile-test loop and using only debug binaries.
101+
You can also do this for `j2objc.debug.enabled`.
102+
103+
104+
### J2ObjC Standard Libraries
105+
106+
A number of standard libraries are included with the J2ObjC releases and linked
107+
by default when using the plugin. To add other libraries, see the FAQ
108+
[dependency on a Java project](FAQ.md#how-do-i-setup-a-dependency-on-a-java-project).
109+
The standard libraries are:
110+
111+
guava
112+
javax_inject
113+
jsr305
114+
junit
115+
mockito
116+
protobuf_runtime - TODO: https://github.com/j2objc-contrib/j2objc-gradle/issues/327
117+
58118

59119
### Folder Structure
60120

61121
This is the suggested folder structure. It also shows a number of generated files and
62-
folders that aren't committed to your repository. Files are shown before folders, so it
63-
is not in strict alphabetical order.
122+
folders that aren't committed to your repository (marked with .gitignore). Files are
123+
shown before folders, so it is not in strict alphabetical order.
64124

65125
workspace
66-
├── .gitignore // Should exclude: local.properties, settings.gradle, build/, ...
126+
├── .gitignore // Add Ignores: local.properties, build/, Pod/
67127
├── build.gradle
68-
├── local.properties // sdk.dir=<Android SDK> and j2objc.home=<J2ObjC>, .gitignore exclude
128+
├── local.properties // sdk.dir=<Android SDK> and j2objc.home=<J2ObjC>, .gitignore
69129
├── settings.gradle // include ':android', ':shared'
70130
├── android
71131
│ ├── build.gradle // dependencies { compile project(':shared') }
72132
│ └── src/... // src/main/java/... and more, only Android specific code
73133
├── ios
74-
│ ├── iosApp.xcworkspace // Xcode workspace
75-
│ ├── iosApp.xcodeproj // Xcode project, which is modified by j2objcXcode / CocoaPods
134+
│ ├── IOS-APP.xcworkspace // Xcode workspace
135+
│ ├── IOS-APP.xcodeproj // Xcode project, which is modified by j2objcXcode / CocoaPods
76136
│ ├── Podfile // j2objcXcode modifies this file for use by CocoaPods, committed
77-
│ ├── iosApp/... // j2objcXcode configures dependency on j2objcOutputs/{libs|src}
78-
│ ├── iosAppTests/... // j2objcXcode configures as above but with "debug" buildType
79-
│ └── Pods/... // generated by CocoaPods for Xcode, .gitignore exclude
137+
│ ├── IOS-APP/... // j2objcXcode configures dependency on j2objcOutputs/{libs|src}
138+
│ ├── IOS-APPTests/... // j2objcXcode configures as above but with "debug" buildType
139+
│ └── Pods/... // generated by CocoaPods for Xcode, .gitignore
80140
└── shared
81141
├── build.gradle // apply 'java' then 'j2objc' plugins
82-
├── build // generated build directory, .gitignore exclude
142+
├── build // generated build directory, .gitignore
83143
│ ├── ... // other build output
84144
│ ├── binaries/... // Contains test binary: testJ2objcExecutable/debug/testJ2objc
85145
│ ├── j2objc-shared.podspec // j2objcXcode generates these settings to modify Xcode
86146
│ └── j2objcOutputs/... // j2objcAssemble copies libraries and headers here
87147
├── lib // library dependencies, must have source code for translation
88-
│ └── lib-with-src.jar // library with source can be translated
148+
│ ├── lib-with-src.jar // library with source can be translated, see FAQ on how to use
149+
│ └── libpreBuilt.a // library prebuilt for ios, see FAQ on how to use
89150
└── src/... // src/main/java/... shared code for translation
90151

91152

@@ -100,20 +161,12 @@ These are the main tasks for the plugin:
100161
j2objcBuild - Runs j2objcTest and j2objcAssemble, doesn't run j2objcXcode
101162
j2objcXcode - Xcode updated with libraries, headers & resources (uses CocoaPods)
102163

103-
Note that you can use the Gradle shorthand of `$ gradlew jA` to do the `j2objcAssemble` task.
164+
Running the `build` task from the Gradle Java plugin will automatically run the j2objcBuild command
165+
and all the previous tasks (which it depends on). Only the `j2objcXcode` task needs to be manually
166+
run. Note that you can use the Gradle shorthand of `$ gradlew jA` to do the `j2objcAssemble` task.
104167
The other shorthand expressions are `jCF, jTr, jA, jTe, jB and jX`.
105168

106169

107-
### Faster Development Cycle
108-
109-
If you are developing in a tight modify-compile-test loop and using only debug binaries, you
110-
may want to disable the release build temporarily by adding to your `local.properties` file:
111-
112-
j2objc.release.enabled=false
113-
114-
This should cut the J2ObjC build time up to 50%. You can also do this for `j2objc.debug.enabled`.
115-
116-
117170
### FAQ
118171

119172
See [FAQ.md](FAQ.md).
@@ -125,5 +178,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md#quick-start).
125178

126179
### License
127180

128-
This library is distributed under the Apache 2.0 license found in the
129-
[LICENSE](./LICENSE) file.
181+
This library is distributed under the Apache 2.0 license found in the [LICENSE](./LICENSE) file.

0 commit comments

Comments
 (0)