From f9476edfc74071224b7ca7231f8a81528a1ddb79 Mon Sep 17 00:00:00 2001 From: Max Waterman Date: Wed, 26 Feb 2014 16:58:01 +0000 Subject: [PATCH] Adding crosswalk targets. --- Gruntfile.js | 118 +++++++++++++++++++++ HACKING.md | 21 ++++ package.json | 5 +- tools/grunt-tasks/grunt-crosswalk.js | 147 +++++++++++++++++++++++++++ 4 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 tools/grunt-tasks/grunt-crosswalk.js diff --git a/Gruntfile.js b/Gruntfile.js index 9074c5d..36b0aee 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,6 +14,119 @@ module.exports = function (grunt) { packageInfo: grunt.file.readJSON('package.json'), chromeInfo: grunt.file.readJSON('platforms/chrome-crx/manifest.json'), + crosswalk: { + arm: { + //"outDir": process.env.HOME+'/z/webapps/webapps-annex/build', + "outDir": 'build', + + verbose: false, + + // display name for the app on the device; + // the sanitisedName used to construct the Locations object later + // is derived from this + name: '<%= packageInfo.name %>', + + // package for the app's generated Java files; this works best if + // you have at least one period character between two character + // strings, and no digits + pkg: 'org.org01.webapps.annex', + + icon: 'icon_128.png', + + fullscreen: true, + + remoteDebugging: true, + + // path to the directory containing your HTML5 app; + // note that this must use the correct path separators for your + // platform: Windows uses '\\' while Linux uses '/' + appRoot: 'build/xpk', + + // relative path from appRoot of the entry HTML file for your app + appLocalPath: 'index.html', + + // embed crosswalk itself into the package + //embedded: true, + + // path to the root of your Android SDK installation; + // on Windows, use the path to the sdk directory inside + // the installation, e.g. 'c:\\android-sdk\\sdk' + // default: automatically obtain from the 'android' command's path + //androidSDKDir: '/opt/android-sdk-linux/', + + // path to the xwalk_app_template directory; you can either + // download and unpack this manually, or use the xwalk_android_dl + // script to do so (part of this project; see the README for details); + // note that path separators specific to your platform must be used + // eg: export XWALK_APP_TEMPLATE=$HOME/Downloads/crosswalk-3.32.53.4-x86 + //xwalkAndroidDir: project/specific/folder + + // architecture of embedded crosswalk + // default: it is obtained from the contents of + // xwalkAndroidDir/native_libs/ if there is only one arch in there, + // else it should be specified as either 'x86' or 'arm' + arch: 'arm', + + // default: automatically obtains latest from androidSDKDir/build-tools + //androidAPIVersion: "18.0.1" + }, + x86: { + //"outDir": process.env.HOME+'/z/webapps/webapps-annex/build', + "outDir": 'build', + + verbose: false, + + // display name for the app on the device; + // the sanitisedName used to construct the Locations object later + // is derived from this + name: '<%= packageInfo.name %>', + + // package for the app's generated Java files; this works best if + // you have at least one period character between two character + // strings, and no digits + pkg: 'org.org01.webapps.annex', + + icon: 'icon_128.png', + + fullscreen: true, + + remoteDebugging: true, + + // path to the directory containing your HTML5 app; + // note that this must use the correct path separators for your + // platform: Windows uses '\\' while Linux uses '/' + appRoot: 'build/xpk', + + // relative path from appRoot of the entry HTML file for your app + appLocalPath: 'index.html', + + // embed crosswalk itself into the package + //embedded: true, + + // path to the root of your Android SDK installation; + // on Windows, use the path to the sdk directory inside + // the installation, e.g. 'c:\\android-sdk\\sdk' + // default: automatically obtain from the 'android' command's path + //androidSDKDir: '/opt/android-sdk-linux/', + + // path to the xwalk_app_template directory; you can either + // download and unpack this manually, or use the xwalk_android_dl + // script to do so (part of this project; see the README for details); + // note that path separators specific to your platform must be used + // eg: export XWALK_APP_TEMPLATE=$HOME/Downloads/crosswalk-3.32.53.4-x86 + //xwalkAndroidDir: project/specific/folder + + // architecture of embedded crosswalk + // default: it is obtained from the contents of + // xwalkAndroidDir/native_libs/ if there is only one arch in there, + // else it should be specified as either 'x86' or 'arm' + arch: 'x86', + + // default: automatically obtains latest from androidSDKDir/build-tools + //androidAPIVersion: "18.0.1" + } + }, + clean: ['build'], release: { @@ -338,4 +451,9 @@ module.exports = function (grunt) { grunt.registerTask('sdk-install', ['sdk', 'install']); grunt.registerTask('default', 'wgt'); + grunt.registerTask('apk', [ + 'xpk', + 'crosswalk:x86', + 'crosswalk:arm' + ]); }; diff --git a/HACKING.md b/HACKING.md index c70d982..65101cd 100644 --- a/HACKING.md +++ b/HACKING.md @@ -103,6 +103,27 @@ CSS, and HTML) using: Note that in both cases, the files comprising the packages are first copied into the build/wgt and build/sdk directories respectively. +To create packages for Android use the 'apk' target: + + grunt apk + +This will first build an 'xpk' target and then package two apks in +build/ named AppName_{x86,arm}.apk. +You can then install the appropriate one to your device as usual - +for example, ```adb install -r build/AppName_x86.apk```. +There are also targets to create packages just for a single architecture. They require the 'xpk' target to be build previously : + + grunt xpk + grunt crosswalk:x86 + +or : + + grunt xpk + grunt crosswalk:arm + +Packaging for Android requires some set up - please see +[crosswalk-apk-generator README.md](https://github.com/crosswalk-project/crosswalk-apk-generator/blob/master/README.md#pre-requisites). + # GUIDE FOR MS WINDOWS USERS AND TIZEN IDE Here are some steps to help people wishing to generate code for use in the Tizen IDE on Microsoft Windows. diff --git a/package.json b/package.json index a6b424c..876435e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,9 @@ "grunt-contrib-imagemin": "~0.1.3", "grunt-contrib-htmlmin": "~0.1.3", "connect": "~2.7.11", - "grunt-release": "~0.6.0" + "grunt-release": "~0.6.0", + "crosswalk-apk-generator": "*", + "which": "~1.0.5", + "semver": "~2.2.1" } } diff --git a/tools/grunt-tasks/grunt-crosswalk.js b/tools/grunt-tasks/grunt-crosswalk.js new file mode 100644 index 0000000..7ecdf89 --- /dev/null +++ b/tools/grunt-tasks/grunt-crosswalk.js @@ -0,0 +1,147 @@ +module.exports = function (grunt) { + var path = require('path'); + var which = require('which'); + var fs = require('fs'); + var semver = require('semver'); + + var Api = require('crosswalk-apk-generator'); + + var generate_apk = function(data,done) { + var outDir = data.outDir || '.'; + var appConfig = {}; + var envConfig = {}; + + // copy user-supplied parameters into envConfig or appConfig + var envProperties = Object.keys(Api.Env.CONFIG_DEFAULTS); + Object.keys(data).forEach(function(property){ + if (envProperties.indexOf(property)!=-1) { + envConfig[property] = data[property]; + } else { + appConfig[property] = data[property]; + } + }); + + // automatically find androidSDKDir from 'android' command in PATH + if (!envConfig.androidSDKDir) { + var androidPath = which.sync('android'); + // up two directories + envConfig.androidSDKDir = path.dirname(path.dirname(androidPath)); + } + + if (!envConfig.xwalkAndroidDir) { + var fromEnvVar = process.env.XWALK_APP_TEMPLATE; + if (fromEnvVar) { + envConfig.xwalkAndroidDir = fromEnvVar; + } else { + grunt.log.error('No xwalk app template specified. Use xwalkAndroidDir in Gruntfile.js or XWALK_APP_TEMPLATE.'); + done(false); + } + } + + // determine arch from xwalkAndroidDir/native_libs/ + if (envConfig.xwalkAndroidDir) { + var nativeLibs = path.join(envConfig.xwalkAndroidDir,'native_libs'); + var arches = fs.readdirSync(nativeLibs); + + if (envConfig.arch) { + // check it matches + var foundArch = arches[0].slice(0,3); + var specified = envConfig.arch.slice(0,3); + if (foundArch!=specified) { + grunt.log.error('\'arch\' property set to ('+specified+') in Gruntfile.js, but no app template for that architecture found.'); + grunt.log.error('architectures found :', arches); + grunt.log.error('have you set xwalkAndroidDir property or XWALK_APP_TEMPLATE correctly?'); + grunt.log.error('XWALK_APP_TEMPLATE: ', process.env.XWALK_APP_TEMPLATE); + done(false); + } + } else { + // use the one in native_libs, if only one + if (arches.length==0) { + grunt.log.error('no architectures found in '+nativeLibs); + done(false); + } else + if (arches.length>1) { + grunt.log.error('multiple architectures found in '+nativeLibs); + grunt.log.error('please specify using the \'arch\' property in your Gruntfile.js'); + done(false); + } + + // use discovered + envConfig.arch = arches[0]; + } + } + + if (!envConfig.androidAPIVersion) { + // get the api latest version from androidSDK/build-tools + var buildToolsDir = path.join(envConfig.androidSDKDir,"build-tools"); + var files = fs.readdirSync(buildToolsDir); + var androidAPIVersions = files.sort(semver.compare); + var length = androidAPIVersions.length; + var latest = androidAPIVersions[length-1]; + envConfig.androidAPIVersion = latest; + } + + var logger = grunt.log; + logger.log = logger.write; // Api.CommandRunner calls logger.log() + + var commandRunner = Api.CommandRunner(data.verbose, logger); + + // create a promise for a configured Env object + var envPromise = Api.Env(envConfig, {commandRunner: commandRunner}); + + // create a promise for a configured App object + var appPromise = Api.App(appConfig); + + // use the Q promises library to synchronise the promises, so we + // can create the objects in "parallel" + Api.Q.all([envPromise, appPromise]) + .then( + function (objects) { + // once the App and Env are constructed, use the Env instance + // to do a build for the App instance + var env = objects[0]; + var app = objects[1]; + + // create a Locations object for this App instance + var locations = Api.Locations(app.sanitisedName, app.pkg, env.arch, outDir); + + // run the build + return env.build(app, locations); + } + ) + .done( + // success + function (finalApk) { + grunt.log.writeln('\n*** DONE\n output apk path is ' + finalApk); + done(); + }, + + // error handler + function (err) { + grunt.log.error('!!! ERROR'); + grunt.log.error(err.stack); + done(false); + } + ); + }; + + /** + * Build an apk + * + * Deps: + * + * Configuration options: + * + * appName - the name of the application; used as the base filename + * outDir - output directory to put the zipfile into + * version - application version + * + */ + grunt.registerMultiTask('crosswalk', 'Tasks for generating apk packages for crosswalk on Android', function (identifier) { + var done = this.async(); + + generate_apk(this.data, done); + }); + +}; +