bootsnap 1.13.0 → 1.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +151 -8
- data/LICENSE.txt +2 -1
- data/README.md +75 -19
- data/ext/bootsnap/bootsnap.c +480 -201
- data/ext/bootsnap/extconf.rb +21 -13
- data/lib/bootsnap/bundler.rb +1 -1
- data/lib/bootsnap/cli/worker_pool.rb +73 -1
- data/lib/bootsnap/cli.rb +22 -45
- data/lib/bootsnap/compile_cache/iseq.rb +192 -80
- data/lib/bootsnap/compile_cache/ruby_bug_22023_canary.rb +1 -0
- data/lib/bootsnap/compile_cache/yaml.rb +44 -50
- data/lib/bootsnap/compile_cache.rb +13 -22
- data/lib/bootsnap/explicit_require.rb +5 -0
- data/lib/bootsnap/load_path_cache/cache.rb +18 -13
- data/lib/bootsnap/load_path_cache/change_observer.rb +7 -1
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +13 -8
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +4 -4
- data/lib/bootsnap/load_path_cache/path.rb +37 -30
- data/lib/bootsnap/load_path_cache/path_scanner.rb +84 -32
- data/lib/bootsnap/load_path_cache/store.rb +9 -6
- data/lib/bootsnap/load_path_cache.rb +23 -14
- data/lib/bootsnap/rake.rb +14 -0
- data/lib/bootsnap/setup.rb +1 -1
- data/lib/bootsnap/version.rb +1 -1
- data/lib/bootsnap.rb +89 -39
- metadata +10 -13
- data/ext/bootsnap/bootsnap.h +0 -6
- data/lib/bootsnap/compile_cache/json.rb +0 -93
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c89c653bbd5db473e06179c6606268271c8c540a588cca938662f168d64f2d39
|
|
4
|
+
data.tar.gz: 449c08c79a258dea90e56646c9d62a06e1d696c065ce96c38a7f50ef2fb83f7b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ea80faffec0206b9bb7b3d19c1419b2e7eefc2dc5f4eb03352862b83afa07ed293d0b15f04fc069d89dac1cd4d4636770626e90e6129ffad77f0cfcb8c3f676
|
|
7
|
+
data.tar.gz: 82dcb1a4c934a9de29a8aa935ffe2d1a7c6e23ebf36ea743c3d29a4d9a1d8bd42696cdefd37dacdd21a4102f88f0b605d1cc6faef9c15ccdc6d99eef15f4483e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,148 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 1.24.6
|
|
4
|
+
|
|
5
|
+
* Fix detection of Ruby bug #22023 on some patch versions of Ruby 3.4, and properly apply the workaround.
|
|
6
|
+
|
|
7
|
+
# 1.24.5
|
|
8
|
+
|
|
9
|
+
* No longer load the config file by default when setup is done manually. This is so cli applications like homebrew
|
|
10
|
+
don't mistakenly load another app's boostnap config.
|
|
11
|
+
|
|
12
|
+
# 1.24.4
|
|
13
|
+
|
|
14
|
+
* Fix several compatibility issues with Ruby `4.0.4`, particularly the `should not compile with coverage` error. See #547.
|
|
15
|
+
* Fix `Bootsnap.enable_frozen_string_literal` to work even when coverage is enabled. Unfortunately only possible on Ruby `4.0.4+`.
|
|
16
|
+
On older rubies if coverage is enabled a warning will be issued and the feature won't work.
|
|
17
|
+
* Reduced cache files header size from 64 to 32 bytes, and got rid of the random padding element.
|
|
18
|
+
* Avoid leaking a private method in `Object` when testing for Parse.y bugs.
|
|
19
|
+
|
|
20
|
+
# 1.24.3
|
|
21
|
+
|
|
22
|
+
* Fix the `1.24.2` workaround to parse Ruby files with UTF-8 even when the `LANG` environment variable
|
|
23
|
+
is unset or set to `C`.
|
|
24
|
+
|
|
25
|
+
# 1.24.2
|
|
26
|
+
|
|
27
|
+
* Workaround two Ruby bugs in `RubyVM::InstructionSequence.compile_file`, that were causing
|
|
28
|
+
files to be loaded with the old Ruby parser instead of Prism, causing issues with some pattern matching syntax.
|
|
29
|
+
Ref: https://bugs.ruby-lang.org/issues/22023
|
|
30
|
+
|
|
31
|
+
# 1.24.1
|
|
32
|
+
|
|
33
|
+
* Fix encoding of Ruby source files loaded when `BOOTSNAP_READONLY` is set.
|
|
34
|
+
Files would incorectly be loaded in `ASCII-8BIT` causing literal strings outside
|
|
35
|
+
the pure ASCII range to have `ASCII-8BIT` encoding instead of `UTF-8`.
|
|
36
|
+
This bug was introduced in `1.24.0`.
|
|
37
|
+
|
|
38
|
+
# 1.24.0
|
|
39
|
+
|
|
40
|
+
* Added a hook API to customize Ruby compilation.
|
|
41
|
+
|
|
42
|
+
# 1.23.0
|
|
43
|
+
|
|
44
|
+
* Require Ruby 2.7.
|
|
45
|
+
* Fix support for absolute paths in `BOOTSNAP_IGNORE_DIRECTORIES`.
|
|
46
|
+
|
|
47
|
+
# 1.22.0
|
|
48
|
+
|
|
49
|
+
* Better fix for the `opendir` crash.
|
|
50
|
+
* Add `bootsnap/rake` for cleaning the bootsnap cache as part of `rake clobber`.
|
|
51
|
+
|
|
52
|
+
# 1.21.1
|
|
53
|
+
|
|
54
|
+
* Prevent a Ruby crash while scanning load path if `opendir` fails without setting `errno`.
|
|
55
|
+
According to the C spec this should not happen, but according to user reports, it did.
|
|
56
|
+
|
|
57
|
+
# 1.21.0
|
|
58
|
+
|
|
59
|
+
* Fix the `require` decorator to handle `Bootsnap.unload_cache!` being called.
|
|
60
|
+
* Minor optimization: Eagerly clear cache buffers to appease the GC.
|
|
61
|
+
|
|
62
|
+
# 1.20.1
|
|
63
|
+
|
|
64
|
+
* Handle broken symlinks in load path scanning code.
|
|
65
|
+
Should fix `Errno::ENOENT fstatat` issues some users have encountered after upgrading to 1.20.0.
|
|
66
|
+
|
|
67
|
+
# 1.20.0
|
|
68
|
+
|
|
69
|
+
* Optimized load path scanning with a C extension. Should be about 2x faster on supported platforms.
|
|
70
|
+
|
|
71
|
+
# 1.19.0
|
|
72
|
+
|
|
73
|
+
* Remove JSON parsing cache. Recent versions of the `json` gem are as fast as `msgpack` if not faster.
|
|
74
|
+
|
|
75
|
+
# 1.18.6
|
|
76
|
+
|
|
77
|
+
* Fix cgroup CPU limits detection in CLI.
|
|
78
|
+
|
|
79
|
+
# 1.18.5
|
|
80
|
+
|
|
81
|
+
* Attempt to detect a QEMU bug that can cause `bootsnap precompile` to hang forever when building ARM64 docker images
|
|
82
|
+
from x86_64 machines. See #495.
|
|
83
|
+
* Improve CLI to detect cgroup CPU limits and avoid spawning too many worker processes.
|
|
84
|
+
|
|
85
|
+
# 1.18.4
|
|
86
|
+
|
|
87
|
+
* Allow using bootsnap without bundler. See #488.
|
|
88
|
+
* Fix startup failure if the cache directory points to a broken symlink.
|
|
89
|
+
|
|
90
|
+
# 1.18.3
|
|
91
|
+
|
|
92
|
+
* Fix the cache corruption issue in the revalidation feature. See #474.
|
|
93
|
+
The cache revalidation feature remains opt-in for now, until it is more battle tested.
|
|
94
|
+
|
|
95
|
+
# 1.18.2
|
|
96
|
+
|
|
97
|
+
* Disable stale cache entries revalidation by default as it seems to cause cache corruption issues. See #471 and #474.
|
|
98
|
+
Will be re-enabled in a future version once the root cause is identified.
|
|
99
|
+
* Fix a potential compilation issue on some systems. See #470.
|
|
100
|
+
|
|
101
|
+
# 1.18.1
|
|
102
|
+
|
|
103
|
+
* Handle `EPERM` errors when opening files with `O_NOATIME`.
|
|
104
|
+
|
|
105
|
+
# 1.18.0
|
|
106
|
+
|
|
107
|
+
* `Bootsnap.instrumentation` now receive `:hit` events.
|
|
108
|
+
* Add `Bootsnap.log_stats!` to print hit rate statistics on process exit. Can also be enabled with `BOOTSNAP_STATS=1`.
|
|
109
|
+
* Revalidate stale cache entries by digesting the source content.
|
|
110
|
+
This should significantly improve performance in environments where `mtime` isn't preserved (e.g. CI systems doing a git clone, etc).
|
|
111
|
+
See #468.
|
|
112
|
+
* Open source files and cache entries with `O_NOATIME` when available to reduce disk accesses. See #469.
|
|
113
|
+
* `bootsnap precompile --gemfile` now look for `.rb` files in the whole gem and not just the `lib/` directory. See #466.
|
|
114
|
+
|
|
115
|
+
# 1.17.1
|
|
116
|
+
|
|
117
|
+
* Fix a compatibility issue with the `prism` library that ships with Ruby 3.3. See #463.
|
|
118
|
+
* Improved the `Kernel#require` decorator to not cause a method redefinition warning. See #461.
|
|
119
|
+
|
|
120
|
+
# 1.17.0
|
|
121
|
+
|
|
122
|
+
* Ensure `$LOAD_PATH.dup` is Ractor shareable to fix a conflict with `did_you_mean`.
|
|
123
|
+
* Allow to ignore directories using absolute paths.
|
|
124
|
+
* Support YAML and JSON CompileCache on TruffleRuby.
|
|
125
|
+
* Support LoadPathCache on TruffleRuby.
|
|
126
|
+
|
|
127
|
+
# 1.16.0
|
|
128
|
+
|
|
129
|
+
* Use `RbConfig::CONFIG["rubylibdir"]` instead of `RbConfig::CONFIG["libdir"]` to check for stdlib files. See #431.
|
|
130
|
+
* Fix the cached version of `YAML.load_file` being slightly more permissive than the default `Psych` one. See #434.
|
|
131
|
+
`Date` and `Time` values are now properly rejected, as well as aliases.
|
|
132
|
+
If this causes a regression in your application, it is recommended to load *trusted* YAML files with `YAML.unsafe_load_file`.
|
|
133
|
+
|
|
134
|
+
# 1.15.0
|
|
135
|
+
|
|
136
|
+
* Add a readonly mode, for environments in which the updated cache wouldn't be persisted. See #428 and #423.
|
|
137
|
+
|
|
138
|
+
# 1.14.0
|
|
139
|
+
|
|
140
|
+
* Require Ruby 2.6.
|
|
141
|
+
* Add a way to skip directories during load path scanning.
|
|
142
|
+
If you have large non-ruby directories in the middle of your load path, it can severely slow down scanning.
|
|
143
|
+
Typically this is a problem with `node_modules`. See #277.
|
|
144
|
+
* Fix `Bootsnap.unload_cache!`, it simply wouldn't work at all because of a merge mistake. See #421.
|
|
145
|
+
|
|
3
146
|
# 1.13.0
|
|
4
147
|
|
|
5
148
|
* Stop decorating `Kernel.load`. This used to be very useful in development because the Rails "classic" autoloader
|
|
@@ -17,7 +160,7 @@
|
|
|
17
160
|
|
|
18
161
|
* Stop decorating `Module#autoload` as it was only useful for supporting Ruby 2.2 and older.
|
|
19
162
|
|
|
20
|
-
* Remove `uname` and other
|
|
163
|
+
* Remove `uname` and other platform specific version from the cache keys. `RUBY_PLATFORM + RUBY_REVISION` should be
|
|
21
164
|
enough to ensure bytecode compatibility. This should improve caching for alpine based setups. See #409.
|
|
22
165
|
|
|
23
166
|
# 1.11.1
|
|
@@ -34,7 +177,7 @@
|
|
|
34
177
|
|
|
35
178
|
* Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
|
|
36
179
|
This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
|
|
37
|
-
|
|
180
|
+
|
|
38
181
|
* Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
|
|
39
182
|
|
|
40
183
|
# 1.10.3
|
|
@@ -160,7 +303,7 @@
|
|
|
160
303
|
* Adds an instrumentation API to monitor cache misses.
|
|
161
304
|
* Allow to control the behavior of `require 'bootsnap/setup'` using environment variables.
|
|
162
305
|
* Deprecate the `disable_trace` option.
|
|
163
|
-
* Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
|
|
306
|
+
* Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
|
|
164
307
|
|
|
165
308
|
# 1.6.0
|
|
166
309
|
|
|
@@ -180,12 +323,12 @@
|
|
|
180
323
|
|
|
181
324
|
# 1.4.9
|
|
182
325
|
|
|
183
|
-
* [Windows support](https://github.com/
|
|
184
|
-
* [Fix potential crash](https://github.com/
|
|
326
|
+
* [Windows support](https://github.com/rails/bootsnap/pull/319)
|
|
327
|
+
* [Fix potential crash](https://github.com/rails/bootsnap/pull/322)
|
|
185
328
|
|
|
186
329
|
# 1.4.8
|
|
187
330
|
|
|
188
|
-
* [Prevent FallbackScan from polluting exception cause](https://github.com/
|
|
331
|
+
* [Prevent FallbackScan from polluting exception cause](https://github.com/rails/bootsnap/pull/314)
|
|
189
332
|
|
|
190
333
|
# 1.4.7
|
|
191
334
|
|
|
@@ -198,7 +341,7 @@
|
|
|
198
341
|
required if a different file with the same name was already being required
|
|
199
342
|
|
|
200
343
|
Example:
|
|
201
|
-
|
|
344
|
+
|
|
202
345
|
require 'foo'
|
|
203
346
|
require 'foo.en'
|
|
204
347
|
|
|
@@ -252,7 +395,7 @@
|
|
|
252
395
|
|
|
253
396
|
# 1.3.0
|
|
254
397
|
|
|
255
|
-
* Handle cases where load path entries are symlinked (https://github.com/
|
|
398
|
+
* Handle cases where load path entries are symlinked (https://github.com/rails/bootsnap/pull/136)
|
|
256
399
|
|
|
257
400
|
# 1.2.1
|
|
258
401
|
|
data/LICENSE.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2017-
|
|
3
|
+
Copyright (c) 2017-2025 Shopify, Inc.
|
|
4
|
+
Copyright (c) 2025-present Rails Foundation
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Bootsnap [](https://github.com/rails/bootsnap/actions)
|
|
2
2
|
|
|
3
|
-
Bootsnap is a library that plugs into Ruby, with optional support for `YAML`,
|
|
3
|
+
Bootsnap is a library that plugs into Ruby, with optional support for `YAML` and `JSON`,
|
|
4
4
|
to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
|
|
5
5
|
|
|
6
6
|
#### Performance
|
|
@@ -41,7 +41,7 @@ getting progressively slower, this is almost certainly the cause.**
|
|
|
41
41
|
It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
|
|
42
42
|
important to load Bootsnap as early as possible to get maximum performance improvement.
|
|
43
43
|
|
|
44
|
-
You can see how this require works [here](https://github.com/
|
|
44
|
+
You can see how this require works [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/setup.rb).
|
|
45
45
|
|
|
46
46
|
If you are not using Rails, or if you are but want more control over things, add this to your
|
|
47
47
|
application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
|
|
@@ -52,31 +52,39 @@ require 'bootsnap'
|
|
|
52
52
|
env = ENV['RAILS_ENV'] || "development"
|
|
53
53
|
Bootsnap.setup(
|
|
54
54
|
cache_dir: 'tmp/cache', # Path to your cache
|
|
55
|
+
ignore_directories: ['node_modules'], # Directory names to skip.
|
|
55
56
|
development_mode: env == 'development', # Current working environment, e.g. RACK_ENV, RAILS_ENV, etc
|
|
56
57
|
load_path_cache: true, # Optimize the LOAD_PATH with a cache
|
|
57
58
|
compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
|
|
58
|
-
compile_cache_yaml: true
|
|
59
|
+
compile_cache_yaml: true, # Compile YAML into a cache
|
|
60
|
+
readonly: true, # Use the caches but don't update them on miss or stale entries.
|
|
59
61
|
)
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
**Protip:** You can replace `require 'bootsnap'` with `BootLib::Require.from_gem('bootsnap',
|
|
63
|
-
'bootsnap')` using [this trick](https://github.com/
|
|
65
|
+
'bootsnap')` using [this trick](https://github.com/rails/bootsnap/wiki/Bootlib::Require). This
|
|
64
66
|
will help optimize boot time further if you have an extremely large `$LOAD_PATH`.
|
|
65
67
|
|
|
66
68
|
Note: Bootsnap and [Spring](https://github.com/rails/spring) are orthogonal tools. While Bootsnap
|
|
67
69
|
speeds up the loading of individual source files, Spring keeps a copy of a pre-booted Rails process
|
|
68
70
|
on hand to completely skip parts of the boot process the next time it's needed. The two tools work
|
|
69
|
-
well together
|
|
71
|
+
well together.
|
|
70
72
|
|
|
71
73
|
### Environment variables
|
|
72
74
|
|
|
73
75
|
`require 'bootsnap/setup'` behavior can be changed using environment variables:
|
|
74
76
|
|
|
75
77
|
- `BOOTSNAP_CACHE_DIR` allows to define the cache location.
|
|
78
|
+
- `BOOTSNAP_CONFIG` allows to change the default config location (`config/bootsnap.rb`).
|
|
76
79
|
- `DISABLE_BOOTSNAP` allows to entirely disable bootsnap.
|
|
77
80
|
- `DISABLE_BOOTSNAP_LOAD_PATH_CACHE` allows to disable load path caching.
|
|
78
81
|
- `DISABLE_BOOTSNAP_COMPILE_CACHE` allows to disable ISeq and YAML caches.
|
|
82
|
+
- `BOOTSNAP_READONLY` configure bootsnap to not update the cache on miss or stale entries.
|
|
79
83
|
- `BOOTSNAP_LOG` configure bootsnap to log all caches misses to STDERR.
|
|
84
|
+
- `BOOTSNAP_STATS` log hit rate statistics on exit. Can't be used if `BOOTSNAP_LOG` is enabled.
|
|
85
|
+
- `BOOTSNAP_IGNORE_DIRECTORIES` a comma separated list of directories that shouldn't be scanned.
|
|
86
|
+
Useful when you have large directories of non-ruby files inside `$LOAD_PATH`.
|
|
87
|
+
It defaults to ignore any directory named `node_modules`.
|
|
80
88
|
|
|
81
89
|
### Environments
|
|
82
90
|
|
|
@@ -92,8 +100,8 @@ Bootsnap cache misses can be monitored though a callback:
|
|
|
92
100
|
Bootsnap.instrumentation = ->(event, path) { puts "#{event} #{path}" }
|
|
93
101
|
```
|
|
94
102
|
|
|
95
|
-
`event` is either `:miss` or `:
|
|
96
|
-
log all events to STDERR.
|
|
103
|
+
`event` is either `:hit`, `:miss`, `:stale` or `:revalidated`.
|
|
104
|
+
You can also call `Bootsnap.log!` as a shortcut to log all events to STDERR.
|
|
97
105
|
|
|
98
106
|
To turn instrumentation back off you can set it to nil:
|
|
99
107
|
|
|
@@ -113,6 +121,7 @@ into two broad categories:
|
|
|
113
121
|
compilation.
|
|
114
122
|
* `YAML.load_file` is modified to cache the result of loading a YAML object in MessagePack format
|
|
115
123
|
(or Marshal, if the message uses types unsupported by MessagePack).
|
|
124
|
+
* `JSON.load_file` is modified to cache the result of loading a JSON object in MessagePack format
|
|
116
125
|
|
|
117
126
|
### Path Pre-Scanning
|
|
118
127
|
|
|
@@ -161,7 +170,7 @@ The only directories considered "stable" are things under the Ruby install prefi
|
|
|
161
170
|
"volatile".
|
|
162
171
|
|
|
163
172
|
In addition to the [`Bootsnap::LoadPathCache::Cache`
|
|
164
|
-
source](https://github.com/
|
|
173
|
+
source](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
|
|
165
174
|
this diagram may help clarify how entry resolution works:
|
|
166
175
|
|
|
167
176
|

|
|
@@ -179,13 +188,13 @@ result too, raising a `LoadError` without touching the filesystem at all.
|
|
|
179
188
|
|
|
180
189
|
Ruby has complex grammar and parsing it is not a particularly cheap operation. Since 1.9, Ruby has
|
|
181
190
|
translated ruby source to an internal bytecode format, which is then executed by the Ruby VM. Since
|
|
182
|
-
2.3.0, Ruby [exposes an API](https://ruby-
|
|
191
|
+
2.3.0, Ruby [exposes an API](https://docs.ruby-lang.org/en/master/RubyVM/InstructionSequence.html) that
|
|
183
192
|
allows caching that bytecode. This allows us to bypass the relatively-expensive compilation step on
|
|
184
193
|
subsequent loads of the same file.
|
|
185
194
|
|
|
186
|
-
We also noticed that we spend a lot of time loading YAML documents during our application boot, and
|
|
187
|
-
that MessagePack and Marshal are *much* faster at deserialization than YAML, even with a fast
|
|
188
|
-
implementation. We use the same strategy of compilation caching for YAML documents, with the
|
|
195
|
+
We also noticed that we spend a lot of time loading YAML and JSON documents during our application boot, and
|
|
196
|
+
that MessagePack and Marshal are *much* faster at deserialization than YAML and JSON, even with a fast
|
|
197
|
+
implementation. We use the same strategy of compilation caching for YAML and JSON documents, with the
|
|
189
198
|
equivalent of Ruby's "bytecode" format being a MessagePack document (or, in the case of YAML
|
|
190
199
|
documents with types unsupported by MessagePack, a Marshal stream).
|
|
191
200
|
|
|
@@ -228,14 +237,15 @@ This may look worse at a glance, but underlies a large performance difference.
|
|
|
228
237
|
useful. [This ruby patch](https://bugs.ruby-lang.org/issues/13378) optimizes them out when coupled
|
|
229
238
|
with bootsnap.)*
|
|
230
239
|
|
|
231
|
-
Bootsnap writes a cache file containing a
|
|
240
|
+
Bootsnap writes a cache file containing a 32 byte header followed by the cache contents. The header
|
|
232
241
|
is a cache key including several fields:
|
|
233
242
|
|
|
234
|
-
* `
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
243
|
+
* `ruby_version_digest`, a digest of:
|
|
244
|
+
* The `RUBY_DESCRIPTION` constant e.g. `"ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]"`.
|
|
245
|
+
* Bootsnap's cache version. Hardcoded in bootsnap. Essentially a schema version;
|
|
246
|
+
* The content of `RubyVM::InstructionSequence.compile_option`.
|
|
238
247
|
* `size`, the size of the source file;
|
|
248
|
+
* `digest`, a fnv1a_64 hash of the source file;
|
|
239
249
|
* `mtime`, the last-modification timestamp of the source file when it was compiled; and
|
|
240
250
|
* `data_size`, the number of bytes following the header, which we need to read it into a buffer.
|
|
241
251
|
|
|
@@ -312,6 +322,38 @@ open /c/nope.bundle -> -1
|
|
|
312
322
|
# (nothing!)
|
|
313
323
|
```
|
|
314
324
|
|
|
325
|
+
## Custom Compilers
|
|
326
|
+
|
|
327
|
+
Bootsnap allows substituing the default Ruby compiler by another one.
|
|
328
|
+
This can be configured from the bootsnap config file (defaults to `config/bootsnap.rb`).
|
|
329
|
+
|
|
330
|
+
The main use case is to programmatically enable frozen string literals for your project without impacting dependencies:
|
|
331
|
+
|
|
332
|
+
```ruby
|
|
333
|
+
Bootsnap.enable_frozen_string_literal(app_only: true)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
But it can also be used for more fine grained logic, or to implement all sort of Ruby code preprocessing:
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
# config/bootsnap.rb
|
|
340
|
+
gems_root = File.join(Bundler.bundle_path.cleanpath, "")
|
|
341
|
+
app_root = File.join(Dir.pwd, "")
|
|
342
|
+
Bootsnap::CompileCache::ISeq.compiler_selector = ->(path) do
|
|
343
|
+
# Enable `frozen_string_literal: true` for app code, but not gems.
|
|
344
|
+
|
|
345
|
+
if path.start_with?(app_root) && !path.start_with?(gems_root)
|
|
346
|
+
Bootsnap::CompileCache::ISeq::FROZEN_STRING_LITERAL
|
|
347
|
+
else
|
|
348
|
+
Bootsnap::CompileCache::ISeq::DEFAULT
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
*Important note*: This feature is only fully supported by Ruby `4.0.4` and newer.
|
|
354
|
+
On older rubies the feature work except if the `Coverage` module is enabled, in which case a warning will be emitted
|
|
355
|
+
and the default Ruby compiler will be used.
|
|
356
|
+
|
|
315
357
|
## Precompilation
|
|
316
358
|
|
|
317
359
|
In development environments the bootsnap compilation cache is generated on the fly when source files are loaded.
|
|
@@ -322,9 +364,23 @@ To do so you can use the `bootsnap precompile` command.
|
|
|
322
364
|
Example:
|
|
323
365
|
|
|
324
366
|
```bash
|
|
325
|
-
$ bundle exec bootsnap precompile --gemfile app/ lib/
|
|
367
|
+
$ bundle exec bootsnap precompile --gemfile app/ lib/ config/
|
|
326
368
|
```
|
|
327
369
|
|
|
370
|
+
## Known issues
|
|
371
|
+
|
|
372
|
+
### QEMU environments
|
|
373
|
+
|
|
374
|
+
When building cross-platform Docker images, QEMU is often used for emulation and can be the source of a limitation that causes forked processes to hang. While Bootsnap includes automatic detection for this issue (as of [PR #501](https://github.com/rails/bootsnap/pull/501)), the detection may not always be sufficient.
|
|
375
|
+
|
|
376
|
+
If you encounter hangs during precompilation in QEMU-based environments (such as when using Docker buildx for cross-platform builds), you can work around this by disabling parallelization with the `-j 0` option:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
$ bundle exec bootsnap precompile -j 0 --gemfile app/ lib/ config/
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
See [Issue #495](https://github.com/rails/bootsnap/issues/495) for more details about this QEMU-related issue.
|
|
383
|
+
|
|
328
384
|
## When not to use Bootsnap
|
|
329
385
|
|
|
330
386
|
*Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
|