emsdk-env 0.7.0 → 0.8.0

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.
@@ -1,17 +1,17 @@
1
1
  /*!
2
2
  * name: emsdk-env
3
- * version: 0.7.0
3
+ * version: 0.8.0
4
4
  * description: Emscripten environment builder
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/emsdk-env
8
- * git.commit.hash: ddec7e7cc6c59a23b5c87cbd7f99f44e4da3e4b7
8
+ * git.commit.hash: 8c3f97866a85cc6c99383eff3526c04077032eac
9
9
  */
10
10
 
11
11
  import { mkdir, access, constants, mkdtemp, rename, rm, readFile } from "fs/promises";
12
12
  import { homedir, tmpdir } from "os";
13
13
  import { glob } from "glob";
14
- import { join, resolve, isAbsolute, dirname, relative } from "path";
14
+ import { join, resolve, isAbsolute, dirname, relative, parse } from "path";
15
15
  import { spawn } from "child_process";
16
16
  const __NOOP_HANDLER = () => {
17
17
  };
@@ -578,20 +578,100 @@ const normalizePrepareOptions = (options) => {
578
578
  ...rest
579
579
  };
580
580
  };
581
+ const parseKeyValueInput = (values) => {
582
+ const parsed = {};
583
+ for (const entry of values) {
584
+ const index = entry.indexOf("=");
585
+ if (index === -1) {
586
+ parsed[entry] = void 0;
587
+ continue;
588
+ }
589
+ const key = entry.slice(0, index);
590
+ const value = entry.slice(index + 1);
591
+ parsed[key] = value;
592
+ }
593
+ return parsed;
594
+ };
595
+ const isKeyValueMap = (value) => value instanceof Map;
596
+ const normalizeKeyValueInput = (input) => {
597
+ if (!input) {
598
+ return {};
599
+ }
600
+ if (Array.isArray(input)) {
601
+ return parseKeyValueInput(input);
602
+ }
603
+ if (isKeyValueMap(input)) {
604
+ return Object.fromEntries(input);
605
+ }
606
+ return { ...input };
607
+ };
581
608
  const mergeDefines = (common, target) => ({
582
- ...common != null ? common : {},
583
- ...target != null ? target : {}
609
+ ...normalizeKeyValueInput(common),
610
+ ...normalizeKeyValueInput(target)
584
611
  });
612
+ const mergeLinkDirectives = (common, target) => mergeDefines(common, target);
585
613
  const resolveWasmOptEnabled = (common, target) => {
586
614
  var _a, _b;
587
615
  return (_b = (_a = target == null ? void 0 : target.enable) != null ? _a : common == null ? void 0 : common.enable) != null ? _b : false;
588
616
  };
589
617
  const resolveWasmOptArgs = (common, target, env) => {
590
618
  var _a, _b;
591
- const commonArgs = (_a = common == null ? void 0 : common.args) != null ? _a : DEFAULT_WASM_OPT_ARGS;
592
- const targetArgs = (_b = target == null ? void 0 : target.args) != null ? _b : [];
619
+ const commonArgs = (_a = common == null ? void 0 : common.options) != null ? _a : DEFAULT_WASM_OPT_ARGS;
620
+ const targetArgs = (_b = target == null ? void 0 : target.options) != null ? _b : [];
593
621
  const mergedArgs = [...commonArgs, ...targetArgs];
594
- return expandArray(mergedArgs, env, "wasmOpt.args");
622
+ return expandArray(mergedArgs, env, "wasmOpt.options");
623
+ };
624
+ const stripOuterQuotes = (value) => {
625
+ const trimmed = value.trim();
626
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
627
+ return trimmed.slice(1, -1);
628
+ }
629
+ return trimmed;
630
+ };
631
+ const extractWasmBinaryFile = (value) => {
632
+ if (value.startsWith("WASM_BINARY_FILE=")) {
633
+ return value.slice("WASM_BINARY_FILE=".length);
634
+ }
635
+ const match = value.match(/^(?:-s|--settings)(?:=)?WASM_BINARY_FILE=(.+)$/);
636
+ if (match) {
637
+ return match[1];
638
+ }
639
+ return void 0;
640
+ };
641
+ const resolveWasmBinaryFileFromLinkOptions = (linkOptions) => {
642
+ for (let index = 0; index < linkOptions.length; index += 1) {
643
+ const option = linkOptions[index];
644
+ if (!option) {
645
+ continue;
646
+ }
647
+ if (option === "-s" || option === "--settings") {
648
+ const next = linkOptions[index + 1];
649
+ if (!next) {
650
+ continue;
651
+ }
652
+ const extracted2 = extractWasmBinaryFile(next);
653
+ if (extracted2) {
654
+ return stripOuterQuotes(extracted2);
655
+ }
656
+ }
657
+ const extracted = extractWasmBinaryFile(option);
658
+ if (extracted) {
659
+ return stripOuterQuotes(extracted);
660
+ }
661
+ }
662
+ return void 0;
663
+ };
664
+ const resolveWasmOptInputFile = (resolvedOutFile, resolvedLinkOptions) => {
665
+ const wasmBinaryFile = resolveWasmBinaryFileFromLinkOptions(resolvedLinkOptions);
666
+ if (wasmBinaryFile) {
667
+ return isAbsolute(wasmBinaryFile) ? wasmBinaryFile : resolve(dirname(resolvedOutFile), wasmBinaryFile);
668
+ }
669
+ const parsed = parse(resolvedOutFile);
670
+ if (parsed.ext.toLowerCase() === ".wasm") {
671
+ return resolvedOutFile;
672
+ }
673
+ const baseName = parsed.name.toLowerCase().endsWith(".wasm") ? parsed.name : `${parsed.name}.wasm`;
674
+ return join(parsed.dir, baseName);
595
675
  };
596
676
  const resolvePath = (rootDir, value) => isAbsolute(value) ? value : resolve(rootDir, value);
597
677
  const expandPlaceholders = (value, env, label) => value.replace(/\{([A-Z0-9_]+)\}/g, (_match, key) => {
@@ -613,6 +693,17 @@ const resolveDefines = (defines, env) => {
613
693
  }
614
694
  return resolved;
615
695
  };
696
+ const resolveLinkDirectives = (directives, env) => {
697
+ const resolved = {};
698
+ for (const [key, value] of Object.entries(directives)) {
699
+ if (typeof value === "string") {
700
+ resolved[key] = expandPlaceholders(value, env, `linkDirectives.${key}`);
701
+ } else {
702
+ resolved[key] = value;
703
+ }
704
+ }
705
+ return resolved;
706
+ };
616
707
  const resolveIncludeDirs = (includeDirs, env, rootDir) => {
617
708
  const expanded = expandArray(includeDirs, env, "includeDirs");
618
709
  return expanded.map((value) => resolvePath(rootDir, value));
@@ -631,7 +722,17 @@ const resolveSourcesFromPatterns = async (patterns, env, srcDir, label) => {
631
722
  sources.sort();
632
723
  return sources;
633
724
  };
634
- const buildDefineFlags = (defines) => Object.entries(defines).map(([key, value]) => `-D${key}=${String(value)}`);
725
+ const buildDefineFlags = (defines) => Object.entries(defines).flatMap(
726
+ ([key, value]) => value === null || value === void 0 ? [`-D${key}`] : [`-D${key}=${String(value)}`]
727
+ );
728
+ const buildLinkDirectiveFlags = (directives) => {
729
+ if (Object.keys(directives).length === 0) {
730
+ return [];
731
+ }
732
+ return Object.entries(directives).flatMap(
733
+ ([key, value]) => value === null || value === void 0 ? ["-s", key] : ["-s", `${key}=${String(value)}`]
734
+ );
735
+ };
635
736
  const buildExportFlags = (exports$1) => {
636
737
  if (exports$1.length === 0) {
637
738
  return [];
@@ -917,6 +1018,11 @@ const buildWasm = async (options) => {
917
1018
  `linkOptions is not supported for archive target: ${targetName}`
918
1019
  );
919
1020
  }
1021
+ if (target.linkDirectives !== void 0) {
1022
+ throw new Error(
1023
+ `linkDirectives is not supported for archive target: ${targetName}`
1024
+ );
1025
+ }
920
1026
  if (target.exports !== void 0) {
921
1027
  throw new Error(
922
1028
  `exports is not supported for archive target: ${targetName}`
@@ -932,6 +1038,7 @@ const buildWasm = async (options) => {
932
1038
  ...ensureArray(common.linkOptions),
933
1039
  ...ensureArray(target.linkOptions)
934
1040
  ];
1041
+ const mergedLinkDirectives = targetType === "archive" ? {} : mergeLinkDirectives(common.linkDirectives, target.linkDirectives);
935
1042
  const mergedExports = targetType === "archive" ? [] : [...ensureArray(common.exports), ...ensureArray(target.exports)];
936
1043
  const wasmOptEnabled = targetType === "archive" ? false : resolveWasmOptEnabled(common.wasmOpt, target.wasmOpt);
937
1044
  const baseCompileOptions = [
@@ -991,7 +1098,12 @@ const buildWasm = async (options) => {
991
1098
  const targetBuildDir = resolve(buildRunDir, targetName);
992
1099
  await rm(targetBuildDir, { recursive: true, force: true });
993
1100
  await ensureDirectory(targetBuildDir);
994
- const resolvedLinkOptions = targetType === "archive" ? [] : expandArray(mergedLinkOptions, targetEnv, "linkOptions");
1101
+ const resolvedLinkDirectives = targetType === "archive" ? {} : resolveLinkDirectives(mergedLinkDirectives, targetEnv);
1102
+ const linkDirectiveArgs = buildLinkDirectiveFlags(resolvedLinkDirectives);
1103
+ const resolvedLinkOptions = targetType === "archive" ? [] : [
1104
+ ...linkDirectiveArgs,
1105
+ ...expandArray(mergedLinkOptions, targetEnv, "linkOptions")
1106
+ ];
995
1107
  const resolvedExports = targetType === "archive" ? [] : expandArray(mergedExports, targetEnv, "exports");
996
1108
  const exportArgs = buildExportFlags(resolvedExports);
997
1109
  const resolvedWasmOptArgs = wasmOptEnabled ? resolveWasmOptArgs(common.wasmOpt, target.wasmOpt, targetEnv) : [];
@@ -1003,7 +1115,6 @@ const buildWasm = async (options) => {
1003
1115
  rootDir
1004
1116
  );
1005
1117
  const groupCompileArgs = sourceGroups.map((group) => {
1006
- var _a3;
1007
1118
  const groupOptions = [
1008
1119
  ...baseCompileOptions,
1009
1120
  ...ensureArray(group == null ? void 0 : group.options)
@@ -1012,7 +1123,7 @@ const buildWasm = async (options) => {
1012
1123
  ...baseIncludeDirs,
1013
1124
  ...ensureArray(group == null ? void 0 : group.includeDirs)
1014
1125
  ];
1015
- const groupDefines = mergeDefines(baseDefines, (_a3 = group == null ? void 0 : group.defines) != null ? _a3 : {});
1126
+ const groupDefines = mergeDefines(baseDefines, group == null ? void 0 : group.defines);
1016
1127
  return buildCompileArgs(
1017
1128
  groupOptions,
1018
1129
  groupIncludeDirs,
@@ -1129,9 +1240,18 @@ const buildWasm = async (options) => {
1129
1240
  emsdkOptions.signal
1130
1241
  );
1131
1242
  if (wasmOptEnabled) {
1132
- const tempOutFile = `${resolvedOutFile}.opt`;
1133
- const wasmOptArgs = [
1243
+ const wasmOptInput = resolveWasmOptInputFile(
1134
1244
  resolvedOutFile,
1245
+ resolvedLinkOptions
1246
+ );
1247
+ if (!await pathExists(wasmOptInput)) {
1248
+ throw new Error(
1249
+ `wasm-opt enabled but wasm binary not found: ${wasmOptInput}`
1250
+ );
1251
+ }
1252
+ const tempOutFile = `${wasmOptInput}.opt`;
1253
+ const wasmOptArgs = [
1254
+ wasmOptInput,
1135
1255
  "-o",
1136
1256
  tempOutFile,
1137
1257
  ...resolvedWasmOptArgs
@@ -1146,8 +1266,8 @@ const buildWasm = async (options) => {
1146
1266
  buildEnv,
1147
1267
  emsdkOptions.signal
1148
1268
  );
1149
- await rm(resolvedOutFile, { force: true });
1150
- await rename(tempOutFile, resolvedOutFile);
1269
+ await rm(wasmOptInput, { force: true });
1270
+ await rename(tempOutFile, wasmOptInput);
1151
1271
  }
1152
1272
  }
1153
1273
  outFiles[targetName] = resolvedOutFile;
@@ -1171,4 +1291,4 @@ export {
1171
1291
  createConsoleLogger as c,
1172
1292
  prepareEmsdk as p
1173
1293
  };
1174
- //# sourceMappingURL=build-Btgi1orl.js.map
1294
+ //# sourceMappingURL=build-DzrgEC4A.js.map