Skip to content

Instantly share code, notes, and snippets.

@advayDev1
Created September 8, 2015 17:42
Show Gist options
  • Save advayDev1/2bdf04f05c2bafd7df25 to your computer and use it in GitHub Desktop.
Save advayDev1/2bdf04f05c2bafd7df25 to your computer and use it in GitHub Desktop.
Native library project to link with j2objc-gradle
apply plugin: 'objective-cpp'
// See https://github.com/j2objc-contrib/j2objc-gradle
// Modified version of j2objc-gradle NativeCompilation.groovy.
// Original notice follows.
/*
* 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.
*/
import org.gradle.api.InvalidUserDataException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.nativeplatform.NativeExecutableSpec
import org.gradle.nativeplatform.NativeLibraryBinary
import org.gradle.nativeplatform.NativeLibrarySpec
import org.gradle.nativeplatform.toolchain.Clang
/**
* Compilation of libraries for debug/release and architectures listed below.
*/
class NativeCompilation {
static final String[] ALL_SUPPORTED_ARCHS = ['ios_arm64', 'ios_armv7', 'ios_armv7s',
'ios_i386', 'ios_x86_64']
private final Project project
NativeCompilation(Project project) {
this.project = project
}
void apply() {
project.with {
// Wire up dependencies with tasks created dynamically by native plugin(s).
tasks.whenTaskAdded { Task task ->
// Only static libraries are needed, so disable shared libraries dynamically.
// There is no way to do this within the native binary model.
if ((task.name =~ /^.*SharedLibrary.*$/).matches()) {
task.enabled = false
}
}
String[] osxClangArgs = [
'-isysroot',
'/Applications/Xcode.app/Contents/Developer/Platforms/' +
'MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk',
'-mmacosx-version-min=10.10',
'-DFIXED_POINT', '-fmessage-length=0',
]
String[] simulatorClangArgs = [
'-isysroot',
'/Applications/Xcode.app/Contents/Developer/Platforms/' +
'iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk',
'-mios-simulator-version-min=8.3',
]
String[] iphoneClangArgs = [
'-isysroot',
'/Applications/Xcode.app/Contents/Developer/Platforms/' +
'iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk',
'-miphoneos-version-min=8.3',
]
model {
buildTypes {
debug
release
}
toolChains {
// Modify clang command line arguments since we need them to vary by target.
// https://docs.gradle.org/current/userguide/nativeBinaries.html#withArguments
clang(Clang) {
target('ios_arm64') {
String[] iosClangArgs = [
'-arch',
'arm64']
iosClangArgs += iphoneClangArgs
objcppCompiler.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
}
target('ios_armv7') {
String[] iosClangArgs = [
'-arch',
'armv7']
iosClangArgs += iphoneClangArgs
objcppCompiler.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
}
target('ios_armv7s') {
String[] iosClangArgs = [
'-arch',
'armv7s']
iosClangArgs += iphoneClangArgs
objcppCompiler.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
}
target('ios_i386') {
String[] iosClangArgs = [
'-arch',
'i386']
iosClangArgs += simulatorClangArgs
objcppCompiler.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
}
target('ios_x86_64') {
String[] iosClangArgs = [
'-arch',
'x86_64']
iosClangArgs += simulatorClangArgs
objcppCompiler.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
iosClangArgs.each { String arg ->
args << arg
}
}
}
target('x86_64') {
String[] clangArgs = [
'-arch',
'x86_64']
clangArgs += osxClangArgs
objcppCompiler.withArguments { List<String> args ->
clangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
clangArgs.each { String arg ->
args << arg
}
}
linker.withArguments { List<String> args ->
args << '-framework'
args << 'ExceptionHandling'
}
}
}
}
platforms {
x86_64 {
architecture 'x86_64'
}
// The rest of this list must match ALL_SUPPORTED_ARCHS.
ios_arm64 {
architecture 'ios_arm64'
}
ios_armv7 {
architecture 'ios_armv7'
}
ios_armv7s {
architecture 'ios_armv7s'
}
ios_i386 {
architecture 'ios_i386'
}
ios_x86_64 {
architecture 'ios_x86_64'
}
}
components {
__YOURLIBRARY__(NativeLibrarySpec) {
sources {
objcpp {
source {
// **** FIX THIS ****
srcDirs "src/__YOURLIBRARY__"
include "**/*.m"
}
exportedHeaders {
// **** FIX THIS ****
srcDirs "src/__YOURLIBRARY__"
}
}
}
ALL_SUPPORTED_ARCHS.each { String arch ->
targetPlatform arch
}
// Always need x86_64 for Mac OS X.
targetPlatform 'x86_64'
}
}
}
// We need to run clang with the arguments that j2objcc would usually pass.
binaries.all {
// Only want to modify the Objective-C toolchain, not the JDK one.
if (toolChain in Clang) {
objcppCompiler.args '-Werror', '-Wno-parentheses', '-fno-strict-overflow', '-Wall'
objcppCompiler.args '-ferror-limit=5000'
if (buildType == buildTypes.debug) {
objcppCompiler.args "-g"
} else {
objcppCompiler.args "-O2"
}
linker.args '-ljre_emul'
// **** FIX THIS ****
objcppCompiler.args '-I/Users/NAME/localbin/j2objc-0.9.8.1/include'
linker.args '-L/Users/NAME/localbin/j2objc-0.9.8.1/lib'
}
}
// Marker tasks to build all Objective-C libraries.
// See Gradle User Guide: 54.14.5. Building all possible variants
// https://docs.gradle.org/current/userguide/nativeBinaries.html#N161B3
task('buildObjcDebug').configure {
dependsOn binaries.withType(NativeLibraryBinary).matching { NativeLibraryBinary lib ->
lib.buildable && lib.buildType.name == 'debug'
}
}
task('buildObjcRelease').configure {
dependsOn binaries.withType(NativeLibraryBinary).matching { NativeLibraryBinary lib ->
lib.buildable && lib.buildType.name == 'release'
}
}
}
}
}
new NativeCompilation(project).apply()
// Modified version of j2objc-gradle PackLibrariesTask.groovy.
// Original notice follows.
/*
* 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.
*/
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.file.ConfigurableFileCollection
/**
* Uses 'lipo' binary to combine multiple architecture flavors of a library into a
* single 'fat' library.
*/
class PackLibrariesTask extends DefaultTask {
// Generated ObjC binaries
@InputFiles
ConfigurableFileCollection getInputLibraries() {
String staticLibraryPath = "${project.buildDir}/binaries/__YOURLIBRARY__StaticLibrary"
return project.files(getSupportedArchs().collect { String arch ->
"$staticLibraryPath/$arch$buildType/lib__YOURLIBRARY__.a"
})
}
@OutputDirectory
File getOutputLibDir() {
return project.file("${project.buildDir}/packedBinaries/__YOURLIBRARY__StaticLibrary/ios$buildType")
}
// Debug or Release for each library
@Input
String buildType
@Input
List<String> getSupportedArchs() { return NativeCompilation.ALL_SUPPORTED_ARCHS }
@TaskAction
void lipoLibraries() {
if (getOutputLibDir().exists()) {
// Clear it out.
getOutputLibDir().deleteDir()
getOutputLibDir().mkdirs()
}
ByteArrayOutputStream output = new ByteArrayOutputStream()
try {
project.exec {
executable 'xcrun'
args 'lipo'
args '-create', '-output', "${outputLibDir}/lib__YOURLIBRARY__.a"
getInputLibraries().each { File libFile ->
args libFile.absolutePath
}
errorOutput output
standardOutput output
}
} catch (Exception exception) {
String outputStr = output.toString()
logger.error "$name failed, output: "
logger.error outputStr
throw exception
}
logger.debug "$name output: "
logger.debug output.toString()
}
}
// Modified version of j2objc-gradle J2objcPlugin.groovy.
// See /third_party/j2objc-gradle. Original notice follows.
/*
* 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.
*/
tasks.create(name: 'packIosLibrariesDebug', type: PackLibrariesTask,
dependsOn: 'buildObjcDebug') {
group 'build'
description 'Packs multiple architectures into a single debug static library'
buildType = 'Debug'
}
tasks.create(name: 'packIosLibrariesRelease', type: PackLibrariesTask,
dependsOn: 'buildObjcRelease') {
group 'build'
description 'Packs multiple architectures into a single release static library'
buildType = 'Release'
}
assemble.dependsOn packIosLibrariesDebug
assemble.dependsOn packIosLibrariesRelease
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment