Skip to content
This repository was archived by the owner on Sep 19, 2025. It is now read-only.

Commit c3cbd58

Browse files
authored
Merge pull request #326 from google/static-linking-linux
On linux, statically link all libraries including GLIBC
2 parents a82d2d5 + cc55fa7 commit c3cbd58

File tree

3 files changed

+104
-68
lines changed

3 files changed

+104
-68
lines changed

.github/workflows/build.yml

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ jobs:
3939
disk-cache: ${{ github.workflow }}
4040
# Share repository cache between workflows.
4141
repository-cache: true
42-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
42+
- name: Checkout repo
43+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
4344
with:
4445
submodules: recursive
4546
ref: ${{ inputs.release-tag || '' }}
@@ -88,24 +89,58 @@ jobs:
8889
env:
8990
NODE_VERSION: '20.x'
9091
FORCE_COLOR: '1'
92+
MUSL_HOME: ${{ github.workspace }}/musl-toolchain
9193
steps:
92-
- name: Setup Java
93-
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
94-
with:
95-
distribution: adopt-hotspot
96-
java-version: 21
97-
java-package: jdk
98-
architecture: x64
99-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
94+
- name: Checkout repo
95+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
10096
with:
10197
ref: ${{ inputs.release-tag || '' }}
98+
- name: Checkout musl
99+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
100+
with:
101+
repository: kraj/musl
102+
ref: c47ad25ea3b484e10326f933e927c0bc8cded3da # patched 1.2.5 version
103+
path: musl
104+
clean: false
105+
- name: Checkout zlib
106+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
107+
with:
108+
repository: madler/zlib
109+
ref: 04f42ceca40f73e2978b50e93806c2a18c1281fc # v1.2.13
110+
path: zlib
111+
clean: false
112+
- name: Build musl and zlib
113+
run: |
114+
# See https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/
115+
# We have to build MUSL from source to ensure recent CVEs are patched
116+
117+
# Build musl from source
118+
pushd musl
119+
./configure --prefix=$MUSL_HOME --static
120+
sudo make && make install
121+
popd
122+
123+
# Install a symlink for use by native-image
124+
ln -s $MUSL_HOME/bin/musl-gcc $MUSL_HOME/bin/x86_64-linux-musl-gcc
125+
126+
# Extend the system path and confirm that musl is available by printing its version
127+
export PATH="$MUSL_HOME/bin:$PATH"
128+
echo "$path" >> $GITHUB_PATH
129+
x86_64-linux-musl-gcc --version
130+
131+
# Build zlib with musl from source and install into the MUSL_HOME directory
132+
pushd zlib
133+
CC=musl-gcc ./configure --prefix=$MUSL_HOME --static
134+
make && make install
135+
popd
102136
- name: Use Node.js ${{ env.NODE_VERSION }}
103137
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
104138
with:
105139
node-version: ${{ env.NODE_VERSION }}
106-
- uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
140+
- name: Install GraalVM
141+
uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
107142
with:
108-
java-version: 21
143+
java-version: 24
109144
distribution: 'graalvm-community'
110145
github-token: ${{ secrets.GITHUB_TOKEN }}
111146
native-image-job-reports: 'true'
@@ -139,6 +174,7 @@ jobs:
139174
- name: Build image
140175
working-directory: packages/google-closure-compiler-linux
141176
run: |
177+
export PATH="$MUSL_HOME/bin:$PATH"
142178
cp ../google-closure-compiler-java/compiler.jar compiler.jar
143179
yarn run build
144180
- name: Tests
@@ -160,23 +196,18 @@ jobs:
160196
NODE_VERSION: '20.x'
161197
FORCE_COLOR: '1'
162198
steps:
163-
- name: Setup Java
164-
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
165-
with:
166-
distribution: adopt-hotspot
167-
java-version: 21
168-
java-package: jdk
169-
architecture: x64
170-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
199+
- name: Checkout repo
200+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
171201
with:
172202
ref: ${{ inputs.release-tag || '' }}
173203
- name: Use Node.js ${{ env.NODE_VERSION }}
174204
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
175205
with:
176206
node-version: ${{ env.NODE_VERSION }}
177-
- uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
207+
- name: Setup GraalVM
208+
uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
178209
with:
179-
java-version: 21
210+
java-version: 24
180211
distribution: 'graalvm-community'
181212
github-token: ${{ secrets.GITHUB_TOKEN }}
182213
native-image-job-reports: 'true'
@@ -229,23 +260,18 @@ jobs:
229260
NODE_VERSION: '22.x'
230261
FORCE_COLOR: '1'
231262
steps:
232-
- name: Setup Java
233-
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
234-
with:
235-
distribution: adopt-hotspot
236-
java-version: 21
237-
java-package: jdk
238-
architecture: x64
239-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
263+
- name: Checkout repo
264+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
240265
with:
241266
ref: ${{ inputs.release-tag || '' }}
242267
- name: Use Node.js ${{ env.NODE_VERSION }}
243268
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
244269
with:
245270
node-version: ${{ env.NODE_VERSION }}
246-
- uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
271+
- name: Setup GraalVM
272+
uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
247273
with:
248-
java-version: 21
274+
java-version: 24
249275
distribution: 'graalvm-community'
250276
github-token: ${{ secrets.GITHUB_TOKEN }}
251277
native-image-job-reports: 'true'
@@ -298,23 +324,18 @@ jobs:
298324
NODE_VERSION: '22.x'
299325
FORCE_COLOR: '1'
300326
steps:
301-
- name: Setup Java
302-
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
303-
with:
304-
distribution: adopt-hotspot
305-
java-version: 21
306-
java-package: jdk
307-
architecture: x64
308-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
327+
- name: Checkout repo
328+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
309329
with:
310330
ref: ${{ inputs.release-tag || '' }}
311331
- name: Use Node.js ${{ env.NODE_VERSION }}
312332
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
313333
with:
314334
node-version: ${{ env.NODE_VERSION }}
315-
- uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
335+
- name: Setup GraalVM
336+
uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # 1.3.3
316337
with:
317-
java-version: 21
338+
java-version: 24
318339
distribution: 'graalvm-community'
319340
github-token: ${{ secrets.GITHUB_TOKEN }}
320341
native-image-job-reports: 'true'
@@ -377,7 +398,8 @@ jobs:
377398
- build-macos
378399
- build-windows
379400
steps:
380-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
401+
- name: Checkout repo
402+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
381403
with:
382404
ref: ${{ inputs.release-tag || '' }}
383405
- name: Use Node.js ${{ env.NODE_VERSION }}

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ node_modules
22
npm-debug.log
33
yarn-error.log
44
/lerna-debug.log
5+
/musl-toolchain
56
/packages/google-closure-compiler/contrib/
67
/packages/google-closure-compiler/externs/
78
/packages/google-closure-compiler-java/compiler.jar
@@ -12,6 +13,7 @@ yarn-error.log
1213
/packages/google-closure-compiler-macos/compiler.jar
1314
/packages/google-closure-compiler-macos/compiler
1415
/packages/google-closure-compiler-windows/compiler.*
15-
/temp
1616
/publish-log.txt
17+
/temp
18+
/zlib
1719
.npmrc

build-scripts/graal.js

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,44 @@ process.on('unhandledRejection', error => {
3434
process.exit(1);
3535
});
3636

37-
const NATIVE_IMAGE_BUILD_ARGS = [
38-
'-H:+UnlockExperimentalVMOptions',
39-
'-H:IncludeResourceBundles=org.kohsuke.args4j.Messages',
40-
'-H:IncludeResourceBundles=org.kohsuke.args4j.spi.Messages',
41-
'-H:IncludeResourceBundles=com.google.javascript.jscomp.parsing.ParserConfig',
42-
'-H:+AllowIncompleteClasspath',
43-
`-H:ReflectionConfigurationFiles=${path.resolve(__dirname, 'reflection-config.json')}`,
44-
'-H:IncludeResources=externs\.zip',
45-
'-H:IncludeResources=.*\.typedast',
46-
'-H:IncludeResources=com/google/javascript/.*\.js',
47-
'-H:IncludeResources=com/google/javascript/.*\.txt',
48-
'-H:IncludeResources=lib/.*\.js',
49-
'-H:IncludeResources=META-INF/.*\.txt',
50-
'-H:+ReportExceptionStackTraces',
51-
// '-H:+GenerateEmbeddedResourcesFile', // Available on Graal JDK 24 and newer
52-
'--report-unsupported-elements-at-runtime',
53-
'--initialize-at-build-time',
54-
'--color=always',
55-
'-jar',
56-
path.resolve(process.cwd(), 'compiler.jar')
57-
];
37+
const flagsByPlatformAndArch = new Map([
38+
// Statically link libraries when supported. Allows usage on systems
39+
// which are missing or have incompatible versions of GLIBC.
40+
// Only linux x86 architectures can fully statically link
41+
// See https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/
42+
['linux-x86', ['--static', '--libc=musl']],
43+
['linux-x64', ['--static', '--libc=musl']],
44+
['linux-arm64', ['--static-nolibc']],
45+
]);
5846

59-
const spawnOpts = {};
60-
if (process.platform === 'win32') {
61-
spawnOpts.shell = true;
62-
}
47+
const NATIVE_IMAGE_BUILD_ARGS = ['-H:+UnlockExperimentalVMOptions'].concat(
48+
flagsByPlatformAndArch.get(`${process.platform}-${process.arch}`) || [],
49+
[
50+
'-H:IncludeResourceBundles=org.kohsuke.args4j.Messages',
51+
'-H:IncludeResourceBundles=org.kohsuke.args4j.spi.Messages',
52+
'-H:IncludeResourceBundles=com.google.javascript.jscomp.parsing.ParserConfig',
53+
'-H:+AllowIncompleteClasspath',
54+
`-H:ReflectionConfigurationFiles=${path.resolve(__dirname, 'reflection-config.json')}`,
55+
'-H:IncludeResources=externs\.zip',
56+
'-H:IncludeResources=.*\.typedast',
57+
'-H:IncludeResources=com/google/javascript/.*\.js',
58+
'-H:IncludeResources=com/google/javascript/.*\.txt',
59+
'-H:IncludeResources=lib/.*\.js',
60+
'-H:IncludeResources=META-INF/.*\.txt',
61+
'-H:+ReportExceptionStackTraces',
62+
// '-H:+GenerateEmbeddedResourcesFile',
63+
'-J--sun-misc-unsafe-memory-access=allow', // See https://github.com/google/closure-compiler/issues/4229
64+
'--initialize-at-build-time',
65+
'-march=compatibility',
66+
'--color=always',
67+
'-jar',
68+
path.resolve(process.cwd(), 'compiler.jar'),
69+
],
70+
);
71+
72+
const spawnOpts = {
73+
...(process.platform === 'win32' ? { shell: true } : {}),
74+
};
6375

6476
runCommand(`native-image${process.platform === 'win32' ? '.cmd' : ''}`, NATIVE_IMAGE_BUILD_ARGS, spawnOpts)
6577
.catch(e => {

0 commit comments

Comments
 (0)