From dd3f8f46424594db5262420ddf6dbd2fd28093bf Mon Sep 17 00:00:00 2001 From: Yizhi <946185759@qq.com> Date: Fri, 28 Mar 2025 14:18:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- thirdpart/build_libs.js | 262 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 thirdpart/build_libs.js diff --git a/thirdpart/build_libs.js b/thirdpart/build_libs.js new file mode 100644 index 0000000..03c444c --- /dev/null +++ b/thirdpart/build_libs.js @@ -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", +]);