Add a fully static "linuxstatic" variant

Bug: #72
This commit is contained in:
Jesse Chan 2021-04-12 20:53:10 +08:00
parent 21ab8a26c8
commit b5d926af84
6 changed files with 83 additions and 15 deletions

View File

@ -31,6 +31,7 @@ jobs:
TARGET_TOOLCHAIN_ARCH=${{ matrix.target-toolchain }}
PKG_FETCH_OPTION_a=${{ matrix.target-arch }}
PKG_FETCH_OPTION_n=node${{ matrix.target-node }}
PKG_FETCH_OPTION_p=alpine
context: .
file: ./Dockerfile.alpine
platforms: linux/amd64

47
.github/workflows/build-linuxstatic.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: Build Node binaries for Linux static
on:
workflow_dispatch:
jobs:
linuxstatic:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
target-node: [8, 10, 12, 14]
target-arch: [x64, arm64]
include:
- target-arch: x64
target-toolchain: x86_64
- target-arch: arm64
target-toolchain: aarch64
steps:
- uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2
with:
build-args: |
TARGET_TOOLCHAIN_ARCH=${{ matrix.target-toolchain }}
PKG_FETCH_OPTION_a=${{ matrix.target-arch }}
PKG_FETCH_OPTION_n=node${{ matrix.target-node }}
PKG_FETCH_OPTION_p=linuxstatic
context: .
file: ./Dockerfile.alpine
platforms: linux/amd64
outputs: type=tar,dest=../out.tar
- name: Extract binaries from Docker image
run: |
tar xvf ../out.tar root/pkg-fetch/dist
- uses: actions/upload-artifact@v2
with:
name: node${{ matrix.target-node }}-linuxstatic-${{ matrix.target-arch }}
path: root/pkg-fetch/dist/*

View File

@ -4,6 +4,7 @@ FROM muslcc/x86_64:$TARGET_TOOLCHAIN_ARCH-linux-musl
ARG PKG_FETCH_OPTION_a
ARG PKG_FETCH_OPTION_n
ARG PKG_FETCH_OPTION_p
USER root:root
@ -34,4 +35,4 @@ COPY . ./
RUN yarn install
RUN yarn start --force-build --arch $PKG_FETCH_OPTION_a --node-range $PKG_FETCH_OPTION_n --output dist
RUN yarn start --force-build --arch $PKG_FETCH_OPTION_a --node-range $PKG_FETCH_OPTION_n --platform $PKG_FETCH_OPTION_p --output dist

View File

@ -21,7 +21,7 @@ function getMajor(nodeVersion: string) {
return Number(version) | 0;
}
function getConfigureArgs(major: number): string[] {
function getConfigureArgs(major: number, targetPlatform: string): string[] {
const args: string[] = [];
// first of all v8_inspector introduces the use
@ -40,6 +40,10 @@ function getConfigureArgs(major: number): string[] {
args.push('--partly-static');
}
if (targetPlatform === 'linuxstatic') {
args.push('--fully-static');
}
// Link Time Optimization
if (major >= 12) {
if (hostPlatform === 'linux' || hostPlatform === 'alpine') {
@ -113,10 +117,14 @@ async function applyPatches(nodeVersion: string) {
}
}
async function compileOnWindows(nodeVersion: string, targetArch: string) {
async function compileOnWindows(
nodeVersion: string,
targetArch: string,
targetPlatform: string
) {
const args = ['/c', 'vcbuild.bat', targetArch];
const major = getMajor(nodeVersion);
const config_flags = getConfigureArgs(major);
const config_flags = getConfigureArgs(major, targetPlatform);
// Event Tracing for Windows
args.push('noetw');
@ -154,7 +162,11 @@ async function compileOnWindows(nodeVersion: string, targetArch: string) {
const { MAKE_JOB_COUNT = os.cpus().length } = process.env;
async function compileOnUnix(nodeVersion: string, targetArch: string) {
async function compileOnUnix(
nodeVersion: string,
targetArch: string,
targetPlatform: string
) {
const args = [];
const cpu = {
x86: 'ia32',
@ -176,7 +188,7 @@ async function compileOnUnix(nodeVersion: string, targetArch: string) {
args.push('--cross-compiling');
}
args.push(...getConfigureArgs(getMajor(nodeVersion)));
args.push(...getConfigureArgs(getMajor(nodeVersion), targetPlatform));
// TODO same for windows?
spawnSync('./configure', args, { cwd: nodePath, stdio: 'inherit' });
@ -199,15 +211,19 @@ async function compileOnUnix(nodeVersion: string, targetArch: string) {
return output;
}
async function compile(nodeVersion: string, targetArch: string) {
async function compile(
nodeVersion: string,
targetArch: string,
targetPlatform: string
) {
log.info('Compiling Node.js from sources...');
const win = hostPlatform === 'win';
if (win) {
return compileOnWindows(nodeVersion, targetArch);
return compileOnWindows(nodeVersion, targetArch, targetPlatform);
}
return compileOnUnix(nodeVersion, targetArch);
return compileOnUnix(nodeVersion, targetArch, targetPlatform);
}
async function hash(filePath: string): Promise<string> {
@ -233,6 +249,7 @@ async function hash(filePath: string): Promise<string> {
export default async function build(
nodeVersion: string,
targetArch: string,
targetPlatform: string,
local: string
) {
await fs.remove(buildPath);
@ -242,7 +259,7 @@ export default async function build(
await gitResetHard(nodeVersion);
await applyPatches(nodeVersion);
const output = await compile(nodeVersion, targetArch);
const output = await compile(nodeVersion, targetArch, targetPlatform);
const outputHash = await hash(output);
await fs.mkdirp(path.dirname(local));

View File

@ -145,9 +145,11 @@ export async function need(opts: NeedOptions) {
}
if (hostPlatform !== platform) {
throw wasReported(
`Not able to build for '${opts.platform}' here, only for '${hostPlatform}'`
);
if (hostPlatform !== 'alpine' || platform !== 'linuxstatic') {
throw wasReported(
`Not able to build for '${opts.platform}' here, only for '${hostPlatform}'`
);
}
}
if (knownArchs.indexOf(arch) < 0) {
@ -160,7 +162,7 @@ export async function need(opts: NeedOptions) {
return 'built';
}
await build(nodeVersion, arch, built);
await build(nodeVersion, arch, platform, built);
return built;
}

View File

@ -68,7 +68,7 @@ function getHostPlatform() {
}
function getKnownPlatforms() {
return ['alpine', 'freebsd', 'linux', 'macos', 'win'];
return ['alpine', 'freebsd', 'linux', 'linuxstatic', 'macos', 'win'];
}
export function toFancyArch(arch: string) {