import { remove } from './async/fs';
import * as rust from './rust';
import * as path from 'path';
import Dict from 'ts-dict';
import Crate from './crate';
import BuildSettings from './build-settings';
const LIB_PREFIX: Dict<string> = {
'darwin': "lib",
'freebsd': "lib",
'linux': "lib",
'sunos': "lib",
'win32': ""
};
const LIB_SUFFIX: Dict<string> = {
'darwin': ".dylib",
'freebsd': ".so",
'linux': ".so",
'sunos': ".so",
'win32': ".dll"
};
export type TargetOptions = {
release?: boolean,
arch?: string
};
/** The Rust build artifacts for a single build target of a Neon crate. */
export default class Target {
readonly crate: Crate;
readonly release: boolean;
readonly arch: string;
readonly triple: string;
readonly subdirectory: string;
readonly root: string;
readonly dylib: string;
constructor(crate: Crate, options: TargetOptions = {}) {
let { release = true, arch = process.env.npm_config_arch || process.arch } = options;
this.crate = crate;
this.release = release;
this.arch = arch;
if (process.platform === 'win32') {
this.triple = (arch === 'ia32') ? 'i686-pc-windows-msvc' : 'x86_64-pc-windows-msvc';
} else {
this.triple = '';
}
if (process.env.CARGO_BUILD_TARGET) {
this.triple = process.env.CARGO_BUILD_TARGET;
}
this.subdirectory = path.join(this.triple, release ? 'release' : 'debug');
this.root = path.resolve(crate.project.targetDirectory, this.subdirectory);
let prefix = LIB_PREFIX[process.platform];
let suffix = LIB_SUFFIX[process.platform];
this.dylib = path.resolve(this.root, prefix + crate.name + suffix);
}
async clean() {
// Remove the directory associated with this target.
await remove(path.resolve(this.crate.root, 'target', this.subdirectory));
// If this target was the active target, remove the addon.
if (this.crate.artifacts.haveActivated(this.subdirectory)) {
await this.crate.removeAddon();
}
// Update the build state.
this.crate.artifacts.delete(this.subdirectory);
this.crate.saveArtifacts();
}
async build(toolchain: rust.Toolchain | null,
settings: BuildSettings)
{
let releaseFlags = this.release ? ["--release"] : [];
let targetFlags = this.triple ? ["--target=" + this.triple] : [];
let args = ['build'].concat(releaseFlags, targetFlags);
try {
let result = await rust.spawn("cargo", args, toolchain, {
cwd: this.crate.root,
stdio: 'inherit'
});
if (result !== 0) {
throw new Error("cargo build failed");
}
this.crate.artifacts.activate(this.subdirectory, settings);
return result;
} finally {
this.crate.saveArtifacts();
}
}
inState(settings: BuildSettings) {
let savedSettings = this.crate.artifacts.lookup(this.subdirectory);
return savedSettings && savedSettings.match(settings);
}
};