From 059c06d25561764bf59eb862454d5ec7191997db Mon Sep 17 00:00:00 2001 From: animetosho Date: Sat, 2 Jan 2021 19:34:56 +1000 Subject: [PATCH] Tweak/fix nexe build script --- README.md | 23 ++++++++--------- nexe/build.js | 71 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 8c045bc..67777f1 100644 --- a/README.md +++ b/README.md @@ -249,8 +249,11 @@ A basic script to compile the Nyuu binary is provided in the *nexe* folder. The 1. If you haven’t done so already, do an `npm install` in Nyuu’s folder to ensure its dependencies are available 2. Enter the *nexe* folder and do an `npm install` to pull down required build packages (note, nexe requires NodeJS 10 or greater) 3. If desired, edit the variables at the top of *nexe/build.js* -4. If you’re building against glibc, be aware that static linking may break DNS resolution. If this is the case, in *nexe/build.js* find `--fully-static` and replace with `--partly-static` to enable libc to be dynamically linked. Note that this executable can only be distributed to systems with the same glibc ABI. -5. Run `node build`. If everything worked, there’ll eventually be a *nyuu* or *nyuu.exe* binary built. +4. Run `node build`. If everything worked, there’ll eventually be a *nyuu* or *nyuu.exe* binary built. + If it fails during compilation, enter the *nexe/build/12.20.0* (or whatever version of NodeJS you’re using) and get more info by: + * Linux: build using the `make` command + * Windows: build using `vcbuild.bat` followed by build options, e.g. `vcbuild nosign x86 noetw intl-none release static no-cctest without-intl ltcg` +5. If building for Linux, optionally `strip` the executable to reduce size ### Building for NodeJS 8.x.x or older @@ -262,33 +265,27 @@ taken: 1. Ensure that *nexe* is installed (doesn’t need to be globally installed) and [its requirements](https://github.com/nexe/nexe#building-requirements) met - 2. Download a Node.js source package. The script has mostly been tested with Node 4.x.x, it may work with other versions - 3. The required Nyuu libraries need to be installed into the *node_modules* folder - 4. Inside the *nexe1* folder (the one containing *build.js*), create the following two folders: *node* and *yencode-src* - 5. Inside the *node* folder, create a folder with the version number of the package you downloaded in step 2, for example “4.9.1”. Inside *this* folder, create one named “\_” and place the downloaded sources in this folder. After - doing this, the file *nexe/node/x.x.x/\_/node.gyp* should exist, where + doing this, the file *nexe1/node/x.x.x/\_/node.gyp* should exist, where *x.x.x* is the node version number - 6. Inside the *yencode-src* folder, copy the source code for the *yencode* (v1.0.x) module - -7. Edit *nexe/build.js*; options that are likely to be edited are at the top of +7. Edit *nexe1/build.js*; options that are likely to be edited are at the top of the file. You’ll likely need to change *nodeVer* to be the version of node you’re using - -8. In the *nexe* folder, run *build.js*. This script patches node to embed the +8. You may need to edit *bin/nyuu.js* to fix the location of nexe’s *package.json* path (search *bin/nyuu.js* for `nexe/package.json` and update if necessary) +9. In the *nexe1* folder, run *build.js*. This script patches node to embed the yencode module, and customises a few compiler options, then calls nexe to build the final executable. If it worked, you should get a binary named - *nyuu* or *nyuu.exe* in the nexe folder + *nyuu* or *nyuu.exe* in the *nexe1* folder Note that this will be built with the `-flto` option on non-Windows platforms. If this causes build failures, your system’s `ar` utility may not support LTO diff --git a/nexe/build.js b/nexe/build.js index e36629c..5c946ef 100644 --- a/nexe/build.js +++ b/nexe/build.js @@ -8,7 +8,8 @@ var buildArch = os.arch(); // x86 or x64 var buildOs = os.platform(); var nexeBase = './build'; var nodeVer = '12.20.0'; - +var staticness = '--fully-static'; // set to '--partly-static' if building with glibc +var vsSuite = null; // if on Windows, and it's having trouble finding Visual Studio, try set this to, e.g. 'vs2019' or 'vs2017' var yencSrc = './node_modules/yencode/'; var nexe = require('nexe'); @@ -48,17 +49,25 @@ let b = browserify(['../bin/nyuu.js'], { // invoke nexe -var configureArgs = ['--fully-static', '--without-dtrace', '--without-etw', '--without-npm', '--with-intl=none', '--without-report', '--without-node-options', '--without-inspector', '--without-siphash', '--dest-cpu=' + buildArch]; +var configureArgs = [staticness, '--without-dtrace', '--without-etw', '--without-npm', '--with-intl=none', '--without-report', '--without-node-options', '--without-inspector', '--without-siphash', '--dest-cpu=' + buildArch]; +var vcbuildArgs = ["nosign", buildArch, "noetw", "intl-none", "release", "static", "no-cctest"]; // --v8-lite-mode ? -if(parseFloat(nodeVer) >= 8) +if(parseFloat(nodeVer) >= 8) { configureArgs.push('--without-intl'); + vcbuildArgs.push('without-intl'); +} if(parseFloat(nodeVer) >= 10) { if(buildOs == 'linux') configureArgs.push('--enable-lto'); - if(buildOs == 'win32') + if(buildOs == 'win32') { configureArgs.push('--with-ltcg'); -} else + vcbuildArgs.push('ltcg'); + } +} else { configureArgs.push('--without-perfctr'); + vcbuildArgs.push('noperfctr'); +} +if(vsSuite) vcbuildArgs.push(vsSuite); nexe.compile({ input: null, // we'll overwrite _third_party_main instead @@ -71,7 +80,7 @@ nexe.compile({ flags: [], // runtime flags configure: configureArgs, make: ['-j', compileConcurrency], - vcBuild: ["nosign", buildArch, "noetw", "noperfctr", "intl-none", "without-intl", "release", "ltcg", "static", "no-cctest"], + vcBuild: vcbuildArgs, snapshot: null, // TODO: consider using this temp: nexeBase, rc: { @@ -87,13 +96,6 @@ nexe.compile({ loglevel: 'info', patches: [ - /* - // fix nexe 3.3.7 breakage on node 12.16.3 - async (compiler, next) => { - await compiler.replaceInFileAsync('src/node.cc', /int exit_code = 0;\/\/ProcessGlobalArgs\([^;]+;/g, "int exit_code = 0;"); - return next(); - }, - */ // remove nexe's boot-nexe code + fix argv async (compiler, next) => { // TODO: is the double'd javascript entry (by nexe) problematic? @@ -113,6 +115,15 @@ nexe.compile({ return next(); }, + // fix for building on Alpine + // https://gitlab.alpinelinux.org/alpine/aports/-/issues/8626 + async (compiler, next) => { + await compiler.replaceInFileAsync('tools/v8_gypfiles/v8.gyp', /('target_defaults': \{)( 'cflags': \['-U_FORTIFY_SOURCE'\],)?/, "$1 'cflags': ['-U_FORTIFY_SOURCE'],"); + await compiler.replaceInFileAsync('node.gyp', /('target_name': '(node_mksnapshot|mkcodecache|<\(node_core_target_name\)|<\(node_lib_target_name\))',)( 'cflags': \['-U_FORTIFY_SOURCE'\],)?/g, "$1 'cflags': ['-U_FORTIFY_SOURCE'],"); + return next(); + }, + + // add yencode into source list async (compiler, next) => { var data = await compiler.readFileAsync('node.gyp'); @@ -176,11 +187,23 @@ void yencode_init(Local exports, Local module, Local con }, // disable exports async (compiler, next) => { - await compiler.replaceInFileAsync('node.gyp', /('use_openssl_def%?':) 1,/, "$1 0,"); await compiler.replaceInFileAsync('src/node.h', /(define (NODE_EXTERN|NODE_MODULE_EXPORT)) __declspec\(dllexport\)/, '$1'); await compiler.replaceInFileAsync('src/node_api.h', /(define (NAPI_EXTERN|NAPI_MODULE_EXPORT)) __declspec\(dllexport\)/, '$1'); + await compiler.replaceInFileAsync('src/node_api.h', /__declspec\(dllexport,\s*/g, '__declspec('); + await compiler.replaceInFileAsync('src/js_native_api.h', /(define NAPI_EXTERN) __declspec\(dllexport\)/, '$1'); await compiler.replaceInFileAsync('common.gypi', /'BUILDING_(V8|UV)_SHARED=1',/g, ''); await compiler.setFileContentsAsync('deps/zlib/win32/zlib.def', 'EXPORTS'); + await compiler.replaceInFileAsync('tools/v8_gypfiles/v8.gyp', /'defines':\s*\["BUILDING_V8_BASE_SHARED"\],/g, ''); + + var data = await compiler.readFileAsync('node.gyp'); + data = data.contents.toString(); + data = data.replace(/('use_openssl_def%?':) 1,/, "$1 0,"); + data = data.replace(/'\/WHOLEARCHIVE:[^']+',/g, ''); + data = data.replace(/'-Wl,--whole-archive',.*?'-Wl,--no-whole-archive',/s, ''); + await compiler.setFileContentsAsync('node.gyp', data); + + await compiler.replaceInFileAsync('node.gypi', /'force_load%': 'true',/, "'force_load%': 'false',"); + return next(); }, // patch build options @@ -188,19 +211,14 @@ void yencode_init(Local exports, Local module, Local con var data = await compiler.readFileAsync('common.gypi'); data = data.contents.toString(); - // MSVC - // enable SSE2 as base - if(buildArch == 'x86') - data = data.replace(/('EnableIntrinsicFunctions':\s*'true',)(\s*)('FavorSizeOrSpeed':,)/, "$1$2'EnableEnhancedInstructionSet': '2',$2$3"); - // disable debug info - data = data.replace(/'GenerateDebugInformation': 'true',/, "'GenerateDebugInformation': 'false',"); + // enable SSE2 as base targeted ISA + if(buildArch == 'x86' || buildArch == 'ia32') { + data = data.replace(/('EnableIntrinsicFunctions':\s*'true',)(\s*)('FavorSizeOrSpeed':)/, "$1$2'EnableEnhancedInstructionSet': '2',$2$3"); + data = data.replace(/('cflags': \[)(\s*'-O3')/, "$1 '-msse2',$2"); + } - // GNU - // SSE2 enable - if(buildArch == 'x86') - data = data.replace(/('cflags': \[)(\s*'-O3')/, "'ldflags': ['-s'], $1 '-msse2',$2"); - else - data = data.replace(/('ldflags': \['-s'\], )?('cflags': \[\s*'-O3')/, "'ldflags': ['-s'], $2"); + // MSVC - disable debug info + data = data.replace(/'GenerateDebugInformation': 'true',/, "'GenerateDebugInformation': 'false',"); await compiler.setFileContentsAsync('common.gypi', data); return next(); @@ -235,6 +253,7 @@ void yencode_init(Local exports, Local module, Local con fs.unlinkSync('../bin/help.json'); // paxmark -m nyuu + // strip nyuu // tar --group=nobody --owner=nobody -cf nyuu-v0.3.8-linux-x86-sse2.tar nyuu ../config-sample.json // xz -9e --x86 --lzma2 *.tar