This commit is contained in:
2025-03-28 14:18:06 +08:00
parent ec9f322bcd
commit dd3f8f4642

262
thirdpart/build_libs.js Normal file
View File

@ -0,0 +1,262 @@
const fs = require("fs");
const path = require("path");
const os = require("os");
const cp = require("child_process");
const THIRD_PART_DIR = __dirname;
const SOURCE_DIR = path.join(THIRD_PART_DIR, "_source");
const env = {};
function setEnv(key, value) { env[key] = value; }
function rmEnv(key) { delete env[key]; }
function appendEnv(key, value) { env[key] = env[key] ? `${env[key]}:${value}` : value; }
function addPkgConfig(pathname) { appendEnv("PKG_CONFIG_PATH", pathname); }
function addLibdir(dirname) { appendEnv("LD_LIBRARY_PATH", dirname); }
/**
*
* @param {string} command
* @param {string[]} args
* @param {cp.SpawnSyncOptionsWithBufferEncoding} options
*/
function spawnSync(command, args, options) {
return cp.spawnSync(command, args, {
stdio: "inherit",
...options,
env: {
...process.env,
...env,
}
})
}
function pkgconfig(name, tag) {
const args = [name];
if (tag.includes("l")) args.push("--libs");
if (tag.includes("i")) args.push("--cflags");
const res = spawnSync("pkg-config", args, { cwd: SOURCE_DIR, stdio: "pipe" });
assert(res.status == 0, `Failed to run pkg-config ${args}`);
return res.stdout.toString().trim();
}
function assert(val, msg) {
if (!val) {
console.error(msg);
process.exit(1);
}
}
function check(...paths) {
return fs.existsSync(path.join(...paths));
}
function wget(url, savename) {
savename ??= path.basename(new URL(url).pathname);
assert(0 == spawnSync("wget", [url, "-O", savename], { cwd: SOURCE_DIR }).status, "Failed to download from " + url);
}
function clone(repo, branch, dirname) {
assert(0 == spawnSync("git", ["clone", repo, "-b", branch, dirname]).status, `Failed to clone ${repo}`);
}
function uncompress(filename) {
if (filename.endsWith(".xz")) {
assert(0 == spawnSync("xz", ["-f", "-d", filename], { cwd: SOURCE_DIR }).status, `Failed to uncompress ${filename}`);
filename = filename.slice(0, -3);
}
if (filename.endsWith(".gz")) {
assert(0 == spawnSync("gunzip", ["-f", filename], { cwd: SOURCE_DIR }).status, `Failed to uncompress ${filename}`);
filename = filename.slice(0, -3);
}
if (filename.endsWith(".tar")) assert(0 == spawnSync("tar", ["-xvf", filename], { cwd: SOURCE_DIR }).status, `Failed to uncompress ${filename}`);
if (filename.endsWith(".tgz")) assert(0 == spawnSync("tar", ["-xzvf", filename], { cwd: SOURCE_DIR }).status, `Failed to uncompress ${filename}`);
}
function configure(sourceDir, args) {
const configureFile = path.join(sourceDir, "configure");
if (!fs.existsSync(configureFile)) {
if (fs.existsSync(path.join(sourceDir, "configure.ac"))) assert(0 == spawnSync("autoconf", [], { cwd: sourceDir }).status, `Failed to configure ${sourceDir}`);
}
assert(0 == spawnSync(configureFile, [...args], { cwd: sourceDir }).status, `Failed to configure ${sourceDir}`);
}
function make(sourceDir) {
assert(0 == spawnSync("make", ["-j", os.cpus().length.toString()], { cwd: sourceDir }).status, `Failed to make ${path.dirname(sourceDir)}`);
assert(0 == spawnSync("make", ["install"], { cwd: sourceDir }).status, `Failed to make install ${path.dirname(sourceDir)}`);
}
function cmake(sourceDir, prefix, args) {
assert(0 == spawnSync("cmake", [
"-B", path.join(sourceDir, "build"),
sourceDir,
`-DCMAKE_INSTALL_PREFIX=${prefix}`,
`-DCMAKE_BUILD_TYPE=Release`,
...args,
], { cwd: sourceDir }).status, `Failed to cmake ${sourceDir}`);
assert(0 == spawnSync("cmake", [
"--build", path.join(sourceDir, "build"),
"--parallel", os.cpus().length.toString(),
"--config", "Release",
"--target", "install",
]).status, `Failed to make install ${path.dirname(sourceDir)}`);
}
function where(name) {
if (os.platform() === "linux") {
const out = spawnSync("whereis", ["-b", name], { stdio: "pipe" }).stdout.toString();
const bin = out.substring(out.indexOf(":") + 1).trim();
if (fs.existsSync(bin)) return bin;
return null;
}
}
//必要依赖
// if (os.platform() === "linux") {
// if (where("apt-get")) {
// assert(0 == spawnSync("apt-get", ["install", "-y", "m4", "libgnutls28-dev"]).status, "Failed to install dependencies");
// }
// else if (where("pacman")) {
// assert(0 == spawnSync("pacman", ["-S", "m4", "libgnutls-devel"]).status, "Failed to install dependencies")
// }
// }
//libgme
const LIBGME_SRC = path.join(SOURCE_DIR, "libgme-0.6.4");
const LIBGME_DIST = path.join(THIRD_PART_DIR, "libgme-0.6.4");
if (!check(LIBGME_SRC, "CMakeLists.txt")) clone("https://github.com/libgme/game-music-emu.git", "0.6.4", LIBGME_SRC);
if (!check(LIBGME_DIST, "lib/libgme.a")) cmake(LIBGME_SRC, LIBGME_DIST, ["-DGME_BUILD_EXAMPLES=OFF"]);
addPkgConfig(path.join(LIBGME_DIST, "lib/pkgconfig"));
//libsndfile
const LIBSNDFILE_SRC = path.join(SOURCE_DIR, "libsndfile-1.2.2");
const LIBSNDFILE_DIST = path.join(THIRD_PART_DIR, "libsndfile-1.2.2");
if (!check(LIBSNDFILE_SRC, "CMakeLists.txt")) clone("https://github.com/libsndfile/libsndfile.git", "1.2.2", LIBSNDFILE_SRC);
if (!check(LIBSNDFILE_DIST, "lib/libsndfile.a")) cmake(LIBSNDFILE_SRC, LIBSNDFILE_DIST, []);
addPkgConfig(path.join(LIBSNDFILE_DIST, "lib/pkgconfig"));
//ladspa
const LADSPA_SRC = path.join(SOURCE_DIR, "ladspa_sdk_1.17");
const LADSPA_DIST = path.join(THIRD_PART_DIR, "ladspa_sdk_1.17");
if (!check(LADSPA_SRC, "src/Makefile")) {
wget("http://www.ladspa.org/download/ladspa_sdk_1.17.tgz");
uncompress("ladspa_sdk_1.17.tgz");
}
if (!fs.existsSync(path.join(LADSPA_SRC, "src/Makefile.bak"))) fs.cpSync(path.join(LADSPA_SRC, "src/Makefile"), path.join(LADSPA_SRC, "src/Makefile.bak"));
const makefile = fs.readFileSync(path.join(LADSPA_SRC, "src/Makefile.bak"), "utf8")
.replace(/^(INSTALL_PLUGINS_DIR\s*=\s*)(.*)$/m, `$1${LADSPA_DIST}`)
.replace(/^(INSTALL_INCLUDE_DIR\s*=\s*)(.*)$/m, `$1${LADSPA_DIST}/include`)
.replace(/^(INSTALL_BINARY_DIR\s*=\s*)(.*)$/m, `$1${LADSPA_DIST}/bin`)
.replace(/^(INCLUDES\s*=\s*.*)$/m, `$1 -I${path.join(LIBSNDFILE_DIST, "include")}`)
.replace(/^(LIBRARIES\s*=\s*.*)$/m, `$1 -L${path.join(LIBSNDFILE_DIST, "lib")}`);
fs.writeFileSync(path.join(LADSPA_SRC, "src/Makefile"), makefile);
make(path.join(LADSPA_SRC, "src"));
console.log(makefile)
return
// //GMP
// const GMP_SRC = path.join(SOURCE_DIR, "gmp-6.3.0");
// const GMP_DIST = path.join(THIRD_PART_DIR, "gmp-6.3.0");
// if (!check(GMP_SRC, "configure")) {
// wget("https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz");
// uncompress("gmp-6.3.0.tar.xz");
// }
// if (!check(GMP_DIST, "lib/libgmp.a")) {
// configure(GMP_SRC, [`--prefix=${GMP_DIST}`, "--enable-cxx", "--enable-shared=no"])
// make(GMP_SRC);
// }
// addPkgConfig(path.join(GMP_DIST, "lib/pkgconfig"));
// addLibdir(path.join(GMP_DIST, "lib"));
// //nettle
// const NETTLE_SRC = path.join(SOURCE_DIR, "nettle-3.10");
// const NETTLE_DIST = path.join(THIRD_PART_DIR, "nettle-3.10");
// if (!check(NETTLE_SRC, "configure")) {
// wget("https://ftp.gnu.org/gnu/nettle/nettle-3.10.tar.gz");
// uncompress("nettle-3.10.tar.gz");
// }
// if (!check(NETTLE_DIST, "lib/libnettle.a")) {
// configure(NETTLE_SRC, [
// `--prefix=${NETTLE_DIST}`,
// "--enable-public-key",
// "--enable-mini-gmp",
// `--libdir=${path.join(NETTLE_DIST, "lib")}`
// ]);
// make(NETTLE_SRC);
// }
// addPkgConfig(path.join(NETTLE_DIST, "lib/pkgconfig"));
// //Libtasn1
// const LIBTASN1_SRC = path.join(SOURCE_DIR, "libtasn1-4.20.0");
// const LIBTASN1_DIST = path.join(THIRD_PART_DIR, "libtasn1-4.20.0");
// if (!check(LIBTASN1_SRC, "configure")) {
// wget("https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.20.0.tar.gz");
// uncompress("libtasn1-4.20.0.tar.gz");
// }
// if (!check(LIBTASN1_DIST, "lib/libtasn1.a")) {
// configure(LIBTASN1_SRC, [`--prefix=${LIBTASN1_DIST}`]);
// make(LIBTASN1_SRC);
// }
// addPkgConfig(path.join(LIBTASN1_DIST, "lib/pkgconfig"));
// //Libunistring
// const LIBUNISTRING_SRC = path.join(SOURCE_DIR, "libunistring-1.3");
// const LIBUNISTRING_DIST = path.join(THIRD_PART_DIR, "libunistring-1.3");
// if (!check(LIBUNISTRING_SRC, "configure")) {
// wget("https://ftp.gnu.org/gnu/libunistring/libunistring-1.3.tar.gz");
// uncompress("libunistring-1.3.tar.gz");
// }
// if (!check(LIBUNISTRING_DIST, "lib/libunistring.a")) {
// configure(LIBUNISTRING_SRC, [`--prefix=${LIBUNISTRING_DIST}`]);
// make(LIBUNISTRING_SRC);
// }
// addPkgConfig(path.join(LIBUNISTRING_DIST, "lib/pkgconfig"));
// const P11_KIT_SRC = path.join(SOURCE_DIR, "p11-kit-0.25.5");
// const P11_KIT_DIST = path.join(THIRD_PART_DIR, "p11-kit-0.25.5");
// if (!check(P11_KIT_SRC, "configure")) {
// wget("https://github.com/p11-glue/p11-kit/releases/download/0.25.5/p11-kit-0.25.5.tar.xz");
// uncompress("p11-kit-0.25.5.tar.xz");
// }
// configure(P11_KIT_SRC, [`--prefix=${P11_KIT_DIST}`]);
// make(P11_KIT_SRC);
// //https://github.com/p11-glue/p11-kit/releases/download/0.25.5/p11-kit-0.25.5.tar.xz
// return;
// // gnutls
// const GNUTLS_SRC = path.join(SOURCE_DIR, "gnutls-3.7.11");
// const GNUTLS_DIST = path.join(THIRD_PART_DIR, "gnutls-3.7.11");
// if (!check(GNUTLS_SRC, "configure")) {
// wget("https://www.gnupg.org/ftp/gcrypt/gnutls/v3.7/gnutls-3.7.11.tar.xz");
// uncompress("gnutls-3.7.11.tar.xz");
// }
// if (!check(GNUTLS_DIST, "lib/libgnutls.a")) {
// setEnv("GMP_LIBS", pkgconfig("gmp", "l"));
// configure(GNUTLS_SRC, [
// `--prefix=${GNUTLS_DIST}`, "--with-included-unistring",
// ]);
// rmEnv("GMP_LIBS");
// make(GNUTLS_SRC);
// }
// addPkgConfig(path.join(GNUTLS_DIST, "lib/pkgconfig"));
//FFmpeg
const FFMPEG_SRC = path.join(SOURCE_DIR, "ffmpeg-7.1.1");
const FFMPEG_DIST = path.join(THIRD_PART_DIR, "ffmpeg-7.1.1");
if (!check(FFMPEG_SRC, "configure")) {
wget("https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.xz");
uncompress("ffmpeg-7.1.1.tar.xz");
}
configure(FFMPEG_SRC, [
`--prefix=${FFMPEG_DIST}`,
"--enable-static", "--enable-small", "--disable-x86asm",
"--enable-gnutls", "--enable-libgme", "--enable-ladspa",
]);