neon-cli
Version:
Build and load native Rust/Neon modules.
116 lines (96 loc) • 3.03 kB
text/typescript
import * as rust from "./rust";
import path from "path";
import Crate from "./crate";
import BuildSettings from "./build-settings";
import { rimraf } from "./async/rimraf";
const LIB_PREFIX: Record<string, string> = {
darwin: "lib",
freebsd: "lib",
linux: "lib",
sunos: "lib",
win32: "",
};
const LIB_SUFFIX: Record<string, 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.
const absolutePathSubdir = path.resolve(
this.crate.root,
"target",
this.subdirectory
);
await rimraf(absolutePathSubdir);
// 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,
settings: BuildSettings,
additionalArgs: string[]
) {
let releaseFlags = this.release ? ["--release"] : [];
let targetFlags = this.triple ? ["--target=" + this.triple] : [];
let args = ["build"].concat(releaseFlags, targetFlags, additionalArgs);
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);
}
}