Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): always generate typedef file even native code never changes #1489

Merged
merged 1 commit into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 38 additions & 28 deletions cli/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { execSync } from 'child_process'
import { createHash } from 'crypto'
import { existsSync, mkdirSync } from 'fs'
import { tmpdir } from 'os'
import { join, parse, sep } from 'path'
Expand Down Expand Up @@ -289,7 +290,6 @@ export class BuildCommand extends Command {
additionalEnv['XWIN_ARCH'] = 'x86'
}
const cargoCommand = `${cargo} build ${externalFlags}`
const intermediateTypeFile = join(tmpdir(), `type_def.${Date.now()}.tmp`)
debug(`Run ${chalk.green(cargoCommand)}`)

const rustflags = process.env.RUSTFLAGS
Expand Down Expand Up @@ -439,32 +439,7 @@ export class BuildCommand extends Command {
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${process.env.PATH}`,
})
}
try {
execSync(cargoCommand, {
env: {
...process.env,
...additionalEnv,
TYPE_DEF_TMP_PATH: intermediateTypeFile,
},
stdio: 'inherit',
cwd,
})
} catch (e) {
if (cargo === 'cargo-xwin') {
console.warn(
`You are cross compiling ${chalk.underline(
triple.raw,
)} target on ${chalk.green(process.platform)} host`,
)
} else if (isCrossForLinux || isCrossForMacOS) {
console.warn(
`You are cross compiling ${chalk.underline(
triple.raw,
)} on ${chalk.green(process.platform)} host`,
)
}
throw e
}

const { binaryName, packageName } = getNapiConfig(this.configFileName)
let cargoArtifactName = this.cargoName
if (!cargoArtifactName) {
Expand Down Expand Up @@ -494,6 +469,42 @@ export class BuildCommand extends Command {
debug(`Dylib name: ${chalk.greenBright(cargoArtifactName)}`)
}

const intermediateTypeFile = join(
tmpdir(),
`${cargoArtifactName}-${createHash('sha256')
.update(process.cwd())
.digest('hex')
.substring(0, 8)}.napi_type_def.tmp`,
)
debug(`intermediate type def file: ${intermediateTypeFile}`)

try {
execSync(cargoCommand, {
env: {
...process.env,
...additionalEnv,
TYPE_DEF_TMP_PATH: intermediateTypeFile,
},
stdio: 'inherit',
cwd,
})
} catch (e) {
if (cargo === 'cargo-xwin') {
console.warn(
`You are cross compiling ${chalk.underline(
triple.raw,
)} target on ${chalk.green(process.platform)} host`,
)
} else if (isCrossForLinux || isCrossForMacOS) {
console.warn(
`You are cross compiling ${chalk.underline(
triple.raw,
)} on ${chalk.green(process.platform)} host`,
)
}
throw e
}

const platform = triple.platform
let libExt = ''

Expand Down Expand Up @@ -787,7 +798,6 @@ async function processIntermediateTypeFile(
}\n`
: ''

await unlinkAsync(source)
await writeFileAsync(
target,
dtsHeader + externalDef + topLevelDef + namespaceDefs,
Expand Down
26 changes: 26 additions & 0 deletions crates/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern crate quote;

#[cfg(not(feature = "noop"))]
use std::env;
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(all(feature = "type-def", not(feature = "noop")))]
use std::{
fs,
Expand All @@ -35,6 +36,17 @@ use syn::Item;
#[cfg(feature = "compat-mode")]
use syn::{fold::Fold, parse_macro_input, ItemFn};

/// a flag indicate whether or never at least one `napi` macro has been expanded.
/// ```ignore
/// if BUILT_FLAG
/// .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
/// .is_ok() {
/// // logic on first macro expansion
/// }
///
/// ```
static BUILT_FLAG: AtomicBool = AtomicBool::new(false);

/// ```ignore
/// #[napi]
/// fn test(ctx: CallContext, name: String) {
Expand All @@ -44,6 +56,20 @@ use syn::{fold::Fold, parse_macro_input, ItemFn};
#[cfg(not(feature = "noop"))]
#[proc_macro_attribute]
pub fn napi(attr: RawStream, input: RawStream) -> RawStream {
if BUILT_FLAG
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
.is_ok()
{
// logic on first macro expansion
#[cfg(feature = "type-def")]
if let Ok(type_def_file) = env::var("TYPE_DEF_TMP_PATH") {
if let Err(_e) = fs::remove_file(type_def_file) {
// should only input in debug mode
// println!("Failed to manipulate type def file: {:?}", e);
}
}
}

match expand(attr.into(), input.into()) {
Ok(tokens) => {
if env::var("DEBUG_GENERATED_CODE").is_ok() {
Expand Down