-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build external Java libs into standalone native libs. #431
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,19 +15,44 @@ | |
*/ | ||
|
||
package com.github.j2objccontrib.j2objcgradle | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.PackageScope | ||
import org.gradle.api.InvalidUserDataException | ||
import org.gradle.api.Project | ||
import org.gradle.api.artifacts.Dependency | ||
import org.gradle.api.artifacts.ProjectDependency | ||
import org.gradle.api.artifacts.SelfResolvingDependency | ||
import org.gradle.api.file.DuplicatesStrategy | ||
import org.gradle.api.plugins.JavaPlugin | ||
import org.gradle.api.plugins.JavaPluginConvention | ||
import org.gradle.api.tasks.Copy | ||
import org.gradle.api.tasks.SourceSet | ||
import org.gradle.api.tasks.bundling.AbstractArchiveTask | ||
|
||
import org.gradle.api.tasks.util.PatternSet | ||
/** | ||
* Resolves `j2objcTranslation` and 'j2objcLinkage' dependencies into their `j2objc` constructs. | ||
* Resolves `j2objc*` dependencies into their `j2objc` constructs: | ||
* <p/> | ||
* <ul> | ||
* <li><b>j2objcTranslationClosure</b> - The plugin will translate only the subset of | ||
* the configuration's source jars that are actually used by this project's | ||
* code (via --build-closure), and | ||
* compile and link the translated code directly into this project's libraries. | ||
* Note that if multiple projects use j2objcTranslationClosure with the same | ||
* external library, you will likely get duplicate symbol definition errors | ||
* when linking them together. Consider instead creating a separate Gradle | ||
* project for that external library using j2objcTranslation. | ||
* </li> | ||
* <li><b>j2objcTranslation</b> - The plugin will translate the entire source jar | ||
* provided in this configuration. Usually, this configuration is used | ||
* to translate a single external Java library into a standalone Objective C library, that | ||
* can then be linked (via j2objcLinkage) into your projects. | ||
* </li> | ||
* <li><b>j2objcLinkage</b> - The plugin will include the headers of, and link to | ||
* the static library within, the referenced project. Usually this configuration | ||
* is used with other projects (your own, or external libraries translated | ||
* with j2objcTranslation) that the J2ObjC Gradle Plugin has also been applied to. | ||
* </li> | ||
* </ul> | ||
*/ | ||
@PackageScope | ||
@CompileStatic | ||
|
@@ -42,20 +67,59 @@ class DependencyResolver { | |
} | ||
|
||
void configureAll() { | ||
project.configurations.getByName('j2objcTranslationClosure').each { File it -> | ||
// These are the resolved files, NOT the dependencies themselves. | ||
// Usually source jars. | ||
visitTranslationClosureFile(it) | ||
} | ||
project.configurations.getByName('j2objcTranslation').each { File it -> | ||
// These are the resolved files, NOT the dependencies themselves. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
visitTranslateFile(it) | ||
// Usually source jars. | ||
visitTranslationSourceJar(it) | ||
} | ||
project.configurations.getByName('j2objcLinkage').dependencies.each { | ||
visitLink(it) | ||
} | ||
} | ||
|
||
protected void visitTranslateFile(File depFile) { | ||
protected void visitTranslationClosureFile(File depFile) { | ||
j2objcConfig.translateSourcepaths(depFile.absolutePath) | ||
j2objcConfig.enableBuildClosure() | ||
} | ||
|
||
private static final String EXTRACTION_TASK_NAME = 'j2objcTranslatedLibraryExtraction' | ||
|
||
/** | ||
* Adds to the main java sourceSet a to-be-generated directory that contains the contents | ||
* of `j2objcTranslation` dependency libraries (if any). | ||
*/ | ||
static void configureSourceSets(Project project) { | ||
JavaPluginConvention javaConvention = project.getConvention().getPlugin(JavaPluginConvention) | ||
SourceSet sourceSet = javaConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) | ||
String dir = "${project.buildDir}/translationExtraction" | ||
sourceSet.java.srcDirs(project.file(dir)) | ||
Copy copy = project.tasks.create(EXTRACTION_TASK_NAME, Copy, | ||
{Copy task -> | ||
task.into(project.file(dir)) | ||
// If two libraries define the same file, fail early. | ||
task.duplicatesStrategy = DuplicatesStrategy.FAIL | ||
}) | ||
project.tasks.getByName(sourceSet.compileJavaTaskName).dependsOn(copy) | ||
} | ||
|
||
// Copy contents of sourceJarFile to build/translationExtraction | ||
protected void visitTranslationSourceJar(File sourceJarFile) { | ||
if (!sourceJarFile.absolutePath.endsWith('.jar')) { | ||
String msg = "`j2objcTranslation` dependencies can only handle " + | ||
"source jar files, not ${sourceJarFile.absolutePath}" | ||
throw new InvalidUserDataException(msg) | ||
} | ||
PatternSet pattern = new PatternSet() | ||
pattern.include('**/*.java') | ||
Copy copy = project.tasks.getByName(EXTRACTION_TASK_NAME) as Copy | ||
copy.from(project.zipTree(sourceJarFile).matching(pattern)) | ||
} | ||
|
||
protected void visitLink(Dependency dep) { | ||
if (dep instanceof ProjectDependency) { | ||
visitLinkProjectDependency((ProjectDependency) dep) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -323,11 +323,12 @@ class J2objcConfig { | |
/** | ||
* @see #dependsOnJ2objcLib(org.gradle.api.Project) | ||
* @deprecated Use `dependencies { j2objcLinkage project(':beforeProjectName') }` or | ||
* `autoConfigDeps = true` instead. | ||
* `autoConfigureDeps = true` instead. | ||
*/ | ||
// TODO: Do this automatically based on project dependencies. | ||
@Deprecated | ||
void dependsOnJ2objcLib(String beforeProjectName) { | ||
//noinspection GrDeprecatedAPIUsage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious, what was deprecated, anything we need worry about for the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is calling our own deprecated method bellow. |
||
dependsOnJ2objcLib(project.project(beforeProjectName)) | ||
} | ||
|
||
|
@@ -346,10 +347,10 @@ class J2objcConfig { | |
* is preferable and sufficient. | ||
* | ||
* @deprecated Use `dependencies { j2objcLinkage project(':beforeProjectName') }` or | ||
* `autoConfigDeps=true` instead. | ||
* `autoConfigureDeps=true` instead. | ||
*/ | ||
// TODO: Phase this API out, and have J2ObjC-applied project dependencies controlled | ||
// solely via `j2objcLink` configuration. | ||
// solely via `j2objcLinkage` configuration. | ||
@CompileStatic(TypeCheckingMode.SKIP) | ||
@Deprecated | ||
void dependsOnJ2objcLib(Project beforeProject) { | ||
|
@@ -671,6 +672,7 @@ class J2objcConfig { | |
void testingOnlyPrepConfigurations() { | ||
// When testing we don't always want to apply the entire plugin | ||
// before calling finalConfigure. | ||
project.configurations.create('j2objcTranslationClosure') | ||
project.configurations.create('j2objcTranslation') | ||
project.configurations.create('j2objcLinkage') | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
apply plugin: 'java' | ||
apply plugin: 'com.github.j2objccontrib.j2objcgradle' | ||
|
||
repositories { | ||
jcenter() | ||
} | ||
|
||
dependencies { | ||
// Intentionally testing e2e use of a built-in j2objc library, Guava. | ||
compile 'com.google.guava:guava:17.0' | ||
// Normally we would reference this as compile "com.google.code.gson:gson:2.3.1" | ||
compile project(':third_party_gson') | ||
testCompile 'junit:junit:4.12' | ||
} | ||
|
||
j2objcConfig { | ||
autoConfigureDeps true | ||
|
||
finalConfigure() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.example; | ||
|
||
import com.google.common.base.Joiner; | ||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
|
||
public class Cube { | ||
|
||
protected final int dimension; | ||
|
||
public Cube(int dimension) { | ||
this.dimension = dimension; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.format("[Cube %d]", dimension); | ||
} | ||
|
||
public String exerciseGuava() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Create a separate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
return Joiner.on(' ').join('a', 'b', 'c'); | ||
} | ||
|
||
public String exerciseGson() { | ||
Gson gson = new GsonBuilder().create(); | ||
return gson.toJson(new String[]{"a", "b", "c"}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.example; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
public class CubeTest { | ||
|
||
@Test | ||
public void testToString() { | ||
Assert.assertEquals("[Cube 7]", new Cube(7).toString()); | ||
} | ||
|
||
@Test | ||
public void testExerciseGuava() { | ||
Assert.assertEquals("a b c", new Cube(7).exerciseGuava()); | ||
} | ||
|
||
@Test | ||
public void testExerciseGson() { | ||
Assert.assertEquals("[\"a\",\"b\",\"c\"]", new Cube(7).exerciseGson()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
buildscript { | ||
repositories { | ||
jcenter() | ||
} | ||
dependencies { | ||
// This is the build output of the plugin itself. | ||
classpath fileTree(dir: '../../build/libs', include: ['*.jar']) | ||
} | ||
} | ||
|
||
allprojects { | ||
apply plugin: 'java' | ||
test { | ||
testLogging { | ||
// Provide full exception info on failure, instead | ||
// of just pointing to an HTML file. | ||
exceptionFormat = 'full' | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve explanation:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, but for DependencyConverter I just detailed how compile and testCompile get converted.
The definitions of j2objcLinkage, etc. are now in DependencyResolver's javadoc.