Skip to content

Commit

Permalink
android: use helper script to call npm on macOS
Browse files Browse the repository at this point in the history
On macOS, if Android Studio is not started through the command line,
the PATH environment variable will probably not contain npm's
location due to macOS environment variables in Windowed Applications
not being the same. This commit adds a cordova hook to create a
helper script that calls npm after adding the PATH elements that are
available during the Cordova project's prepare step, so that npm can
be called when the Gradle build is started by Android Studio.
  • Loading branch information
jaimecbernardo committed Feb 27, 2018
1 parent ff19463 commit 7fec514
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
28 changes: 28 additions & 0 deletions install/hooks/android/after-prepare-create-macOS-builder-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const fs = require('fs');
const path = require('path');

// Adds a helper script to run "npm rebuild" with the current PATH.
// This workaround is needed for Android Studio on macOS when it is not started
// from the command line, as npm probably won't be in the PATH at build time.
function buildMacOSHelperNpmBuildScript(context, platform)
{
var platformPath = path.join(context.opts.projectRoot, 'platforms', platform);
var platformAPI = require(path.join(platformPath, 'cordova', 'Api'));
var platformAPIInstance = new platformAPI();
var wwwPath = platformAPIInstance.locations.www;
var helperMacOSBuildScriptPath = path.join(wwwPath, 'build-native-modules-MacOS-helper-script.sh');
fs.writeFileSync( helperMacOSBuildScriptPath,`#!/bin/bash
export PATH=$PATH:${process.env.PATH}
npm $@
`, {"mode": 0o755}
);
}

module.exports = function(context)
{
if (context.opts.platforms.indexOf('android') >= 0) {
if (process.platform === 'darwin') {
buildMacOSHelperNpmBuildScript(context, 'android');
}
}
}
1 change: 1 addition & 0 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<hook type="before_plugin_install" src="install/hooks/android/before-plugin-install.js" />
<hook type="before_build" src="install/hooks/android/before-build.js" />
<hook type="after_prepare" src="install/hooks/both/after-prepare-patch-npm-packages.js" />
<hook type="after_prepare" src="install/hooks/android/after-prepare-create-macOS-builder-helper.js" />

<config-file target="res/xml/config.xml" parent="/*">
<feature name="NodeJS">
Expand Down
32 changes: 31 additions & 1 deletion src/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ android {
cdvPluginPostBuildExtras += { ->
// gzip files will cause errors with aapt. Remove them for improved npm compatibility.
android.aaptOptions.ignoreAssetsPattern += ":!*.gz";
// The MacOS builder helper script is not needed inside the APK.
android.aaptOptions.ignoreAssetsPattern += ":!build-native-modules-MacOS-helper-script.sh";
};

import org.gradle.internal.os.OperatingSystem;
Expand All @@ -64,6 +66,27 @@ if (shouldRebuildNativeModules==null) {

if ("1".equals(shouldRebuildNativeModules)) {

String npmCommandName = 'npm';
if (OperatingSystem.current().isMacOsX()) {
// On macOS, npm's location may not be in the PATH environment variable if gradle is being run
// by Android Studio. We need npm to build native modules, so we use a helper script that
// is created by a Cordova prepare hook to run npm with the PATH members that were available
// during the prepare event.
try {
def commandResult = exec {
commandLine 'command', '-v', 'npm'
ignoreExitValue = true
}
if ( commandResult.getExitValue() != 0 ) {
// If npm is not found by command, use the helper script.
logger.warn("Couldn't find npm in the PATH for building native modules. Will try to use a helper script.");
npmCommandName = '../build-native-modules-MacOS-helper-script.sh';
}
} catch ( Exception e ) {
throw new GradleException('Something went wrong looking for npm by running "command".', e)
}
}

android.defaultConfig.ndk.abiFilters.each { abi_name ->
String temp_arch = {
switch (abi_name) {
Expand Down Expand Up @@ -150,6 +173,13 @@ if ("1".equals(shouldRebuildNativeModules)) {
from "${project.projectDir}/assets/www/nodejs-project/"
into "${rootProject.buildDir}/nodejs-native-assets-temp-build/nodejs-native-assets-${abi_name}/nodejs-project/"
}
if (OperatingSystem.current().isMacOsX()) {
// Copy the helper script for calling npm when building in Android Studio on macOS.
copy {
from "${project.projectDir}/assets/www/build-native-modules-MacOS-helper-script.sh"
into "${rootProject.buildDir}/nodejs-native-assets-temp-build/nodejs-native-assets-${abi_name}/"
}
}
new File("${rootProject.buildDir}/nodejs-native-assets-temp-build/nodejs-native-assets-${abi_name}/copy.timestamp").text = "${new Date().format('yyyy-MM-dd HH:mm:ss')}"
}
}
Expand All @@ -168,7 +198,7 @@ if ("1".equals(shouldRebuildNativeModules)) {
outputs.file "${rootProject.buildDir}/nodejs-native-assets-temp-build/nodejs-native-assets-${abi_name}/nodejs-project/"
description = "Building native modules for ${abi_name}."
workingDir "${rootProject.buildDir}/nodejs-native-assets-temp-build/nodejs-native-assets-${abi_name}/nodejs-project/"
commandLine 'npm', '--verbose', 'rebuild', '--build-from-source'
commandLine npmCommandName, '--verbose', 'rebuild', '--build-from-source'
//environment ('PATH', "${npm_toolchain_add_to_path}" + System.getProperty("path.separator") + "${System.env.PATH}")
environment ('npm_config_node_engine', 'v8' )
environment ('npm_config_nodedir', "${project.projectDir}/src/com/janeasystems/cdvnodejsmobile/jni/libnode/" )
Expand Down

0 comments on commit 7fec514

Please sign in to comment.