- Created .gitignore to exclude build artifacts and dependencies. - Added package.json and package-lock.json for project dependencies and scripts. - Included pnpm workspace configuration for managing packages. - Implemented TypeScript configuration in tsconfig.json. - Added README.md with project description and usage instructions. - Introduced native code for DES encryption and decryption in C/C++. - Created initial decoded data structure for handling scan results. - Established basic file structure for decoded outputs and native builds.
114 lines
3.1 KiB
JavaScript
114 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
"use strict";
|
|
|
|
const { spawnSync } = require("child_process");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const os = require("os");
|
|
|
|
const root = path.resolve(__dirname, "..");
|
|
const bin = path.join(root, "bin");
|
|
const isWin = process.platform === "win32";
|
|
const isMac = process.platform === "darwin";
|
|
|
|
fs.mkdirSync(bin, { recursive: true });
|
|
|
|
function run(cmd, args, opts = {}) {
|
|
console.log(`$ ${cmd} ${args.join(" ")}`);
|
|
const result = spawnSync(cmd, args, { stdio: "inherit", ...opts });
|
|
if (result.error) {
|
|
throw result.error;
|
|
}
|
|
if (result.status !== 0) {
|
|
process.exit(result.status || 1);
|
|
}
|
|
}
|
|
|
|
function which(cmd) {
|
|
const probe = isWin ? "where" : "which";
|
|
const result = spawnSync(probe, [cmd], { encoding: "utf8" });
|
|
return result.status === 0;
|
|
}
|
|
|
|
function compileCpu() {
|
|
const out = path.join(bin, isWin ? "med_cpu.exe" : "med_cpu");
|
|
const cpp = path.join(root, "native", "cpu", "med_cpu.cpp");
|
|
const csrc = path.join(root, "native", "common", "des.c");
|
|
const obj = path.join(bin, isWin ? "des.obj" : "des.o");
|
|
const compilers = isWin
|
|
? [
|
|
["clang++", () => {
|
|
run("clang", ["-O2", "-c", csrc, "-o", obj]);
|
|
run("clang++", ["-O2", "-std=c++17", "-pthread", cpp, obj, "-o", out]);
|
|
}],
|
|
["g++", () => {
|
|
run("gcc", ["-O2", "-c", csrc, "-o", obj]);
|
|
run("g++", ["-O2", "-std=c++17", "-pthread", cpp, obj, "-o", out]);
|
|
}],
|
|
["cl", () => {
|
|
run("cl", ["/nologo", "/O2", "/c", `/Fo${obj}`, csrc]);
|
|
run("cl", ["/nologo", "/O2", "/EHsc", "/std:c++17", `/Fe:${out}`, cpp, obj]);
|
|
}],
|
|
]
|
|
: [
|
|
["c++", () => {
|
|
run("cc", ["-O2", "-c", csrc, "-o", obj]);
|
|
run("c++", ["-O2", "-std=c++17", "-pthread", cpp, obj, "-o", out]);
|
|
}],
|
|
];
|
|
|
|
let lastErr = null;
|
|
for (const [cmd, fn] of compilers) {
|
|
if (cmd !== "c++" && !which(cmd)) {
|
|
continue;
|
|
}
|
|
try {
|
|
fn();
|
|
console.log(`[native] CPU runner -> ${out}`);
|
|
return;
|
|
} catch (err) {
|
|
lastErr = err;
|
|
}
|
|
}
|
|
throw lastErr || new Error("no C++ compiler found for med_cpu");
|
|
}
|
|
|
|
function compileMetal() {
|
|
if (!isMac) {
|
|
console.log("[native] skip Metal (not macOS)");
|
|
return;
|
|
}
|
|
const out = path.join(bin, "med_gpu");
|
|
run("clang", [
|
|
"-O2",
|
|
"-fobjc-arc",
|
|
"-framework",
|
|
"Metal",
|
|
"-framework",
|
|
"Foundation",
|
|
path.join(root, "native", "metal", "med_gpu.m"),
|
|
"-o",
|
|
out,
|
|
]);
|
|
console.log(`[native] Metal runner -> ${out}`);
|
|
}
|
|
|
|
function compileCuda() {
|
|
if (!isWin && process.env.FORCE_CUDA !== "1") {
|
|
console.log("[native] skip CUDA (Windows-only unless FORCE_CUDA=1)");
|
|
return;
|
|
}
|
|
if (!which("nvcc")) {
|
|
console.warn("[native] nvcc not found; CUDA backend skipped (CPU still works)");
|
|
return;
|
|
}
|
|
const out = path.join(bin, isWin ? "med_cuda.exe" : "med_cuda");
|
|
run("nvcc", ["-O2", "-std=c++17", "-o", out, path.join(root, "native", "cuda", "med_cuda.cu")]);
|
|
console.log(`[native] CUDA runner -> ${out}`);
|
|
}
|
|
|
|
compileCpu();
|
|
compileMetal();
|
|
compileCuda();
|
|
console.log(`[native] done (${os.platform()} ${os.arch()})`);
|