@@ -1204,10 +1204,39 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr,
12041204 // nullptr indicates there's no snapshot data.
12051205 DCHECK_NULL (*snapshot_data_ptr);
12061206
1207+ SnapshotConfig snapshot_config;
1208+ const std::string& config_path =
1209+ per_process::cli_options->per_isolate ->build_snapshot_config ;
1210+ // For snapshot config read from JSON, we fix up process.argv[1] using the
1211+ // "builder" field.
1212+ std::vector<std::string> args_maybe_patched;
1213+ args_maybe_patched.reserve (result->args ().size () + 1 );
1214+ if (!config_path.empty ()) {
1215+ std::optional<SnapshotConfig> optional_config =
1216+ ReadSnapshotConfig (config_path.c_str ());
1217+ if (!optional_config.has_value ()) {
1218+ return ExitCode::kGenericUserError ;
1219+ }
1220+ snapshot_config = std::move (optional_config.value ());
1221+ DCHECK (snapshot_config.builder_script_path .has_value ());
1222+ args_maybe_patched.emplace_back (result->args ()[0 ]);
1223+ args_maybe_patched.emplace_back (
1224+ snapshot_config.builder_script_path .value ());
1225+ if (result->args ().size () > 1 ) {
1226+ args_maybe_patched.insert (args_maybe_patched.end (),
1227+ result->args ().begin () + 1 ,
1228+ result->args ().end ());
1229+ }
1230+ } else {
1231+ snapshot_config.builder_script_path = result->args ()[1 ];
1232+ args_maybe_patched = result->args ();
1233+ }
1234+ DCHECK (snapshot_config.builder_script_path .has_value ());
1235+ const std::string& builder_script =
1236+ snapshot_config.builder_script_path .value ();
12071237 // node:embedded_snapshot_main indicates that we are using the
12081238 // embedded snapshot and we are not supposed to clean it up.
1209- const std::string& main_script = result->args ()[1 ];
1210- if (main_script == " node:embedded_snapshot_main" ) {
1239+ if (builder_script == " node:embedded_snapshot_main" ) {
12111240 *snapshot_data_ptr = SnapshotBuilder::GetEmbeddedSnapshotData ();
12121241 if (*snapshot_data_ptr == nullptr ) {
12131242 // The Node.js binary is built without embedded snapshot
@@ -1219,24 +1248,25 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr,
12191248 return exit_code;
12201249 }
12211250 } else {
1222- // Otherwise, load and run the specified main script.
1251+ // Otherwise, load and run the specified builder script.
12231252 std::unique_ptr<SnapshotData> generated_data =
12241253 std::make_unique<SnapshotData>();
1225- std::string main_script_content ;
1226- int r = ReadFileSync (&main_script_content, main_script .c_str ());
1254+ std::string builder_script_content ;
1255+ int r = ReadFileSync (&builder_script_content, builder_script .c_str ());
12271256 if (r != 0 ) {
12281257 FPrintF (stderr,
1229- " Cannot read main script %s for building snapshot. %s: %s" ,
1230- main_script ,
1258+ " Cannot read builder script %s for building snapshot. %s: %s" ,
1259+ builder_script ,
12311260 uv_err_name (r),
12321261 uv_strerror (r));
12331262 return ExitCode::kGenericUserError ;
12341263 }
12351264
12361265 exit_code = node::SnapshotBuilder::Generate (generated_data.get (),
1237- result-> args () ,
1266+ args_maybe_patched ,
12381267 result->exec_args (),
1239- main_script_content);
1268+ builder_script_content,
1269+ snapshot_config);
12401270 if (exit_code == ExitCode::kNoFailure ) {
12411271 *snapshot_data_ptr = generated_data.release ();
12421272 } else {
@@ -1366,7 +1396,8 @@ static ExitCode StartInternal(int argc, char** argv) {
13661396
13671397 // --build-snapshot indicates that we are in snapshot building mode.
13681398 if (per_process::cli_options->per_isolate ->build_snapshot ) {
1369- if (result->args ().size () < 2 ) {
1399+ if (per_process::cli_options->per_isolate ->build_snapshot_config .empty () &&
1400+ result->args ().size () < 2 ) {
13701401 fprintf (stderr,
13711402 " --build-snapshot must be used with an entry point script.\n "
13721403 " Usage: node --build-snapshot /path/to/entry.js\n " );
0 commit comments