emsdk-env 0.2.0 → 0.4.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.2.0
3
+ * version: 0.4.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: e7a4478d462904c71937847aef2de1f460ffc0d5
8
+ * git.commit.hash: cd0d8e53bf52b98940dd50343a9d3a39200306bd
9
9
  */
10
10
 
11
- import { mkdir, access, constants, mkdtemp, rename, rm } from "fs/promises";
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, relative } from "path";
14
+ import { join, resolve, isAbsolute, dirname, relative } from "path";
15
15
  import { spawn } from "child_process";
16
16
  const __NOOP_HANDLER = () => {
17
17
  };
@@ -501,6 +501,22 @@ const resolveEmccCommand = async (env, emsdkRoot) => {
501
501
  }
502
502
  return "emcc";
503
503
  };
504
+ const resolveEmarCommand = async (env, emsdkRoot) => {
505
+ if (env.EMAR) {
506
+ return env.EMAR;
507
+ }
508
+ if (env.EMSCRIPTEN) {
509
+ const candidate = join(env.EMSCRIPTEN, "emar");
510
+ if (await pathExists(candidate)) {
511
+ return candidate;
512
+ }
513
+ }
514
+ const fallback = join(emsdkRoot, "upstream", "emscripten", "emar");
515
+ if (await pathExists(fallback)) {
516
+ return fallback;
517
+ }
518
+ return "emar";
519
+ };
504
520
  const createConsoleLogger = (prefix) => {
505
521
  return {
506
522
  debug: (msg) => console.debug(`[${prefix}]: ${msg}`),
@@ -510,7 +526,11 @@ const createConsoleLogger = (prefix) => {
510
526
  };
511
527
  };
512
528
  const DEFAULT_WASM_SRC_DIR = "wasm";
529
+ const DEFAULT_WASM_INCLUDE_DIR = "include";
513
530
  const DEFAULT_WASM_OUT_DIR = join("src", "wasm");
531
+ const DEFAULT_WASM_LIB_DIR = "lib";
532
+ const DEFAULT_IMPORT_INCLUDE_DIR = "include";
533
+ const DEFAULT_IMPORT_LIB_DIR = "lib";
514
534
  const DEFAULT_WASM_BUILD_DIR = join(tmpdir(), "emsdk-env");
515
535
  const DEFAULT_EMSDK_TARGET_VERSION = "latest";
516
536
  let buildSequence = 0;
@@ -530,7 +550,8 @@ const createBuildId = () => {
530
550
  const seq = String(buildSequence).padStart(4, "0");
531
551
  return `${timestamp}_${seq}_${process.pid}`;
532
552
  };
533
- const ensureArray = (value) => value ? [...value] : [];
553
+ const ensureArray = (value) => value != null ? value : [];
554
+ const resolveTargetType = (value) => value != null ? value : "wasm";
534
555
  const normalizePrepareOptions = (options) => {
535
556
  const { targetVersion, ...rest } = options != null ? options : {};
536
557
  return {
@@ -570,9 +591,15 @@ const resolveOutFile = (outFile, env, outDir) => {
570
591
  const expanded = expandPlaceholders(outFile, env, "outFile");
571
592
  return resolvePath(outDir, expanded);
572
593
  };
573
- const resolveSourcePatterns = (patterns, env, srcDir) => {
574
- const expanded = expandArray(patterns, env, "sources");
575
- return expanded.map((value) => resolvePath(srcDir, value));
594
+ const resolveSourcesFromPatterns = async (patterns, env, srcDir, label) => {
595
+ const expanded = expandArray(patterns, env, label);
596
+ const resolvedPatterns = expanded.map((value) => resolvePath(srcDir, value));
597
+ const results = await Promise.all(
598
+ resolvedPatterns.map((pattern) => glob(pattern, { nodir: true }))
599
+ );
600
+ const sources = results.flat();
601
+ sources.sort();
602
+ return sources;
576
603
  };
577
604
  const buildDefineFlags = (defines) => Object.entries(defines).map(([key, value]) => `-D${key}=${String(value)}`);
578
605
  const buildExportFlags = (exports$1) => {
@@ -586,33 +613,165 @@ const createEnvForBuild = (baseEnv, overrides) => ({
586
613
  ...baseEnv,
587
614
  ...overrides
588
615
  });
589
- const resolveTargetOutFile = (targetName, targetOutFile, env, outDir) => {
616
+ const resolveTargetOutFile = (targetName, targetOutFile, env, baseDir, extension) => {
590
617
  if (targetOutFile) {
591
- return resolveOutFile(targetOutFile, env, outDir);
618
+ return resolveOutFile(targetOutFile, env, baseDir);
592
619
  }
593
- return resolve(outDir, `${targetName}.wasm`);
620
+ return resolve(baseDir, `${targetName}.${extension}`);
594
621
  };
595
622
  const resolveTargetSources = async (targetSources, env, srcDir) => {
596
623
  const patterns = targetSources && targetSources.length > 0 ? targetSources : [join(srcDir, "**", "*.c"), join(srcDir, "**", "*.cpp")];
597
- const resolvedPatterns = resolveSourcePatterns(patterns, env, srcDir);
598
- const results = await Promise.all(
599
- resolvedPatterns.map((pattern) => glob(pattern, { nodir: true }))
624
+ return resolveSourcesFromPatterns(patterns, env, srcDir, "sources");
625
+ };
626
+ const toSafeObjectName = (rootDir, sourcePath, groupIndex) => {
627
+ const baseName = relative(rootDir, sourcePath).replace(/[\\/]/g, "_").replace(/[^A-Za-z0-9._-]/g, "_");
628
+ if (groupIndex === void 0) {
629
+ return baseName;
630
+ }
631
+ return `${baseName}__g${groupIndex}`;
632
+ };
633
+ const dedupeSources = (sources) => {
634
+ const seen = /* @__PURE__ */ new Set();
635
+ const deduped = [];
636
+ for (const source of sources) {
637
+ if (seen.has(source)) {
638
+ continue;
639
+ }
640
+ seen.add(source);
641
+ deduped.push(source);
642
+ }
643
+ return deduped;
644
+ };
645
+ const dedupeValues = (values) => {
646
+ const seen = /* @__PURE__ */ new Set();
647
+ const deduped = [];
648
+ for (const value of values) {
649
+ if (seen.has(value)) {
650
+ continue;
651
+ }
652
+ seen.add(value);
653
+ deduped.push(value);
654
+ }
655
+ return deduped;
656
+ };
657
+ const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
658
+ const resolvePackageJsonPath = async (startPath, packageName) => {
659
+ let current = dirname(startPath);
660
+ for (; ; ) {
661
+ const candidate = join(current, "package.json");
662
+ if (await pathExists(candidate)) {
663
+ return candidate;
664
+ }
665
+ const parent = dirname(current);
666
+ if (parent === current) {
667
+ throw new Error(`package.json not found for import: ${packageName}`);
668
+ }
669
+ current = parent;
670
+ }
671
+ };
672
+ const loadPackageJson = async (packageJsonPath, packageName) => {
673
+ try {
674
+ const raw = await readFile(packageJsonPath, "utf8");
675
+ const parsed = JSON.parse(raw);
676
+ if (!isRecord(parsed)) {
677
+ throw new Error("package.json must be an object.");
678
+ }
679
+ return parsed;
680
+ } catch (error) {
681
+ const message = error instanceof Error ? error.message : String(error);
682
+ throw new Error(
683
+ `Failed to read package.json for import ${packageName}: ${message}`
684
+ );
685
+ }
686
+ };
687
+ const resolveImportPaths = async (resolver, packageName) => {
688
+ let resolvedEntry;
689
+ try {
690
+ resolvedEntry = resolver.resolve(packageName);
691
+ } catch (error) {
692
+ const message = error instanceof Error ? error.message : String(error);
693
+ throw new Error(`Failed to resolve import ${packageName}: ${message}`);
694
+ }
695
+ const packageJsonPath = await resolvePackageJsonPath(
696
+ resolvedEntry,
697
+ packageName
600
698
  );
601
- const sources = results.flat();
602
- sources.sort();
603
- return sources;
699
+ const packageRoot = dirname(packageJsonPath);
700
+ const packageJson = await loadPackageJson(packageJsonPath, packageName);
701
+ const emsdkConfigRaw = packageJson["emsdk-env"];
702
+ if (emsdkConfigRaw !== void 0 && !isRecord(emsdkConfigRaw)) {
703
+ throw new Error(
704
+ `Invalid emsdk-env config for import ${packageName}: expected an object.`
705
+ );
706
+ }
707
+ const includeRaw = isRecord(emsdkConfigRaw) ? emsdkConfigRaw.include : void 0;
708
+ if (includeRaw !== void 0 && typeof includeRaw !== "string") {
709
+ throw new Error(
710
+ `Invalid emsdk-env include for import ${packageName}: expected a string.`
711
+ );
712
+ }
713
+ const libRaw = isRecord(emsdkConfigRaw) ? emsdkConfigRaw.lib : void 0;
714
+ if (libRaw !== void 0 && typeof libRaw !== "string") {
715
+ throw new Error(
716
+ `Invalid emsdk-env lib for import ${packageName}: expected a string.`
717
+ );
718
+ }
719
+ const includeRel = includeRaw != null ? includeRaw : DEFAULT_IMPORT_INCLUDE_DIR;
720
+ const libRel = libRaw != null ? libRaw : DEFAULT_IMPORT_LIB_DIR;
721
+ const includeDir = resolve(packageRoot, includeRel);
722
+ const libDir = resolve(packageRoot, libRel);
723
+ const includeExists = await pathExists(includeDir);
724
+ const libExists = await pathExists(libDir);
725
+ if (!includeExists && !libExists) {
726
+ throw new Error(
727
+ `Import ${packageName} does not provide include or lib directories.`
728
+ );
729
+ }
730
+ return {
731
+ includeDir: includeExists ? includeDir : void 0,
732
+ libDir: libExists ? libDir : void 0
733
+ };
734
+ };
735
+ const resolveImportDirectories = async (rootDir, imports) => {
736
+ if (imports.length === 0) {
737
+ return { includeDirs: [], libDirs: [] };
738
+ }
739
+ const moduleApi = await import("./__vite-browser-external-2Ng8QIWW.js");
740
+ const resolver = moduleApi.createRequire(resolve(rootDir, "package.json"));
741
+ const includeDirs = [];
742
+ const libDirs = [];
743
+ for (const packageName of imports) {
744
+ const resolved = await resolveImportPaths(resolver, packageName);
745
+ if (resolved.includeDir) {
746
+ includeDirs.push(resolved.includeDir);
747
+ }
748
+ if (resolved.libDir) {
749
+ libDirs.push(resolved.libDir);
750
+ }
751
+ }
752
+ return {
753
+ includeDirs: dedupeValues(includeDirs),
754
+ libDirs: dedupeValues(libDirs)
755
+ };
756
+ };
757
+ const buildCompileArgs = (options, includeDirs, defines, env, rootDir) => {
758
+ const resolvedOptions = expandArray(options, env, "options");
759
+ const includeArgs = resolveIncludeDirs(includeDirs, env, rootDir).map(
760
+ (dir) => `-I${dir}`
761
+ );
762
+ const defineArgs = buildDefineFlags(resolveDefines(defines, env));
763
+ return { resolvedOptions, includeArgs, defineArgs };
604
764
  };
605
- const toSafeObjectName = (rootDir, sourcePath) => relative(rootDir, sourcePath).replace(/[\\/]/g, "_").replace(/[^A-Za-z0-9._-]/g, "_");
606
765
  const buildWasm = async (options) => {
607
- var _a, _b, _c, _d, _e, _f, _g, _h;
766
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
608
767
  if (!options) {
609
768
  throw new TypeError("options must be provided.");
610
769
  }
611
770
  if (!options.rule || !options.rule.targets) {
612
771
  throw new TypeError("rule targets must be provided.");
613
772
  }
614
- const targets = Object.entries(options.rule.targets);
615
- if (targets.length === 0) {
773
+ const targetEntries = Object.entries(options.rule.targets);
774
+ if (targetEntries.length === 0) {
616
775
  throw new TypeError("rule targets must not be empty.");
617
776
  }
618
777
  const logger = (_a = options.logger) != null ? _a : createConsoleLogger("emsdk-env");
@@ -629,56 +788,118 @@ const buildWasm = async (options) => {
629
788
  baseEnv,
630
789
  "srcDir"
631
790
  );
791
+ const rawIncludeDir = expandPlaceholders(
792
+ (_d = options.includeDir) != null ? _d : DEFAULT_WASM_INCLUDE_DIR,
793
+ baseEnv,
794
+ "includeDir"
795
+ );
632
796
  const rawOutDir = expandPlaceholders(
633
- (_d = options.outDir) != null ? _d : DEFAULT_WASM_OUT_DIR,
797
+ (_e = options.outDir) != null ? _e : DEFAULT_WASM_OUT_DIR,
634
798
  baseEnv,
635
799
  "outDir"
636
800
  );
801
+ const rawLibDir = expandPlaceholders(
802
+ (_f = options.libDir) != null ? _f : DEFAULT_WASM_LIB_DIR,
803
+ baseEnv,
804
+ "libDir"
805
+ );
637
806
  const rawBuildDir = expandPlaceholders(
638
- (_e = options.buildDir) != null ? _e : DEFAULT_WASM_BUILD_DIR,
807
+ (_g = options.buildDir) != null ? _g : DEFAULT_WASM_BUILD_DIR,
639
808
  baseEnv,
640
809
  "buildDir"
641
810
  );
642
811
  const srcDir = resolvePath(rootDir, rawSrcDir);
812
+ const includeDir = resolvePath(rootDir, rawIncludeDir);
643
813
  const outDir = resolvePath(rootDir, rawOutDir);
814
+ const libDir = resolvePath(rootDir, rawLibDir);
644
815
  const buildDir = resolvePath(rootDir, rawBuildDir);
645
816
  const buildId = createBuildId();
646
817
  const buildRunDir = resolve(buildDir, buildId);
647
- const cleanupBuildDir = (_f = options.cleanupBuildDir) != null ? _f : true;
648
- const parallel = (_g = options.parallel) != null ? _g : true;
818
+ const cleanupBuildDir = (_h = options.cleanupBuildDir) != null ? _h : true;
819
+ const parallel = (_i = options.parallel) != null ? _i : true;
649
820
  const envWithDirs = {
650
821
  ...emsdkEnv,
651
822
  ROOT: rootDir,
652
823
  SRC_DIR: srcDir,
824
+ INCLUDE_DIR: includeDir,
653
825
  OUT_DIR: outDir,
826
+ LIB_DIR: libDir,
654
827
  BUILD_DIR: buildDir
655
828
  };
656
829
  const emccCommand = await resolveEmccCommand(envWithDirs, emsdkRoot);
657
- const common = (_h = options.rule.common) != null ? _h : {};
830
+ const common = (_j = options.rule.common) != null ? _j : {};
831
+ const commonIncludeDirs = common.includeDirs === void 0 ? [includeDir] : common.includeDirs;
832
+ const importDirectories = await resolveImportDirectories(
833
+ rootDir,
834
+ ensureArray(options.imports)
835
+ );
836
+ const importIncludeDirs = importDirectories.includeDirs;
837
+ const importLibDirs = importDirectories.libDirs;
838
+ const linkLibDirs = dedupeValues([libDir, ...importLibDirs]);
839
+ logger.debug(`Detected rootDir: '${rootDir}'`);
840
+ logger.debug(`Detected srcDir: '${srcDir}'`);
841
+ logger.debug(`Detected outDir: '${outDir}'`);
842
+ logger.debug(`Detected libDir: '${libDir}'`);
843
+ logger.debug(`Detected buildDir: '${buildDir}'`);
844
+ logger.debug(`Detected buildId: '${buildId}'`);
845
+ logger.debug(`Detected buildRunDir: '${buildRunDir}'`);
846
+ logger.debug(`Detected cleanupBuildDir: ${cleanupBuildDir}`);
847
+ logger.debug(`Detected parallel: ${parallel}`);
848
+ logger.debug(`Detected emccCommand: '${emccCommand}'`);
849
+ logger.debug(
850
+ `Detected importIncludeDirs: [${importIncludeDirs.map((p) => `'${p}'`).join(",")}]`
851
+ );
852
+ logger.debug(
853
+ `Detected importLibDirs: [${importLibDirs.map((p) => `'${p}'`).join(",")}]`
854
+ );
658
855
  await ensureDirectory(outDir);
856
+ await ensureDirectory(libDir);
659
857
  await ensureDirectory(buildDir);
660
858
  await rm(buildRunDir, { recursive: true, force: true });
661
859
  await ensureDirectory(buildRunDir);
860
+ const hasArchiveTargets = targetEntries.some(
861
+ ([, target]) => resolveTargetType(target.type) === "archive"
862
+ );
863
+ const emarCommand = hasArchiveTargets ? await resolveEmarCommand(envWithDirs, emsdkRoot) : void 0;
864
+ if (emarCommand) {
865
+ logger.debug(`Detected emarCommand: '${emarCommand}'`);
866
+ }
662
867
  const outFiles = {};
663
- try {
664
- for (const [targetName, target] of targets) {
665
- const mergedOptions = [
666
- ...ensureArray(common.options),
667
- ...ensureArray(target.options)
668
- ];
669
- const mergedLinkOptions = [
868
+ const buildTargets = async (expectedType) => {
869
+ var _a2;
870
+ for (const [targetName, target] of targetEntries) {
871
+ const targetType = resolveTargetType(target.type);
872
+ if (targetType !== expectedType) {
873
+ continue;
874
+ }
875
+ if (targetType === "archive") {
876
+ if (target.linkOptions !== void 0) {
877
+ throw new Error(
878
+ `linkOptions is not supported for archive target: ${targetName}`
879
+ );
880
+ }
881
+ if (target.exports !== void 0) {
882
+ throw new Error(
883
+ `exports is not supported for archive target: ${targetName}`
884
+ );
885
+ }
886
+ }
887
+ const mergedLinkOptions = targetType === "archive" ? [] : [
670
888
  ...ensureArray(common.linkOptions),
671
889
  ...ensureArray(target.linkOptions)
672
890
  ];
673
- const mergedExports = [
674
- ...ensureArray(common.exports),
675
- ...ensureArray(target.exports)
891
+ const mergedExports = targetType === "archive" ? [] : [...ensureArray(common.exports), ...ensureArray(target.exports)];
892
+ const baseCompileOptions = [
893
+ ...ensureArray(common.options),
894
+ ...ensureArray(target.options)
676
895
  ];
677
- const mergedIncludeDirs = [
678
- ...ensureArray(common.includeDirs),
679
- ...ensureArray(target.includeDirs)
896
+ const baseIncludeDirs = [
897
+ ...ensureArray(commonIncludeDirs),
898
+ ...ensureArray(target.includeDirs),
899
+ ...importIncludeDirs
680
900
  ];
681
- const mergedDefines = mergeDefines(common.defines, target.defines);
901
+ const baseDefines = mergeDefines(common.defines, target.defines);
902
+ const sourceGroups = (_a2 = target.sourceGroups) != null ? _a2 : [];
682
903
  const targetEnv = {
683
904
  ...envWithDirs,
684
905
  TARGET_NAME: targetName
@@ -688,52 +909,90 @@ const buildWasm = async (options) => {
688
909
  targetName,
689
910
  target.outFile,
690
911
  targetEnv,
691
- outDir
912
+ targetType === "archive" ? libDir : outDir,
913
+ targetType === "archive" ? "a" : "wasm"
692
914
  );
693
915
  const sources = await resolveTargetSources(
694
916
  target.sources,
695
917
  targetEnv,
696
918
  srcDir
697
919
  );
698
- if (sources.length === 0) {
920
+ const groupSources = sourceGroups.map(() => []);
921
+ const groupSourceSet = /* @__PURE__ */ new Set();
922
+ for (let index = 0; index < sourceGroups.length; index += 1) {
923
+ const group = sourceGroups[index];
924
+ if (!group) {
925
+ continue;
926
+ }
927
+ const resolved = await resolveSourcesFromPatterns(
928
+ group.sources,
929
+ targetEnv,
930
+ srcDir,
931
+ `sourceGroups[${index}].sources`
932
+ );
933
+ const deduped = dedupeSources(resolved);
934
+ groupSources[index] = deduped;
935
+ for (const source of deduped) {
936
+ groupSourceSet.add(source);
937
+ }
938
+ }
939
+ const baseSources = sources.filter(
940
+ (source) => !groupSourceSet.has(source)
941
+ );
942
+ const groupedSources = groupSources.flat();
943
+ if (baseSources.length + groupedSources.length === 0) {
699
944
  throw new Error(`No sources matched for target: ${targetName}`);
700
945
  }
701
946
  const targetBuildDir = resolve(buildRunDir, targetName);
702
947
  await rm(targetBuildDir, { recursive: true, force: true });
703
948
  await ensureDirectory(targetBuildDir);
704
- const resolvedOptions = expandArray(mergedOptions, targetEnv, "options");
705
- const resolvedLinkOptions = expandArray(
706
- mergedLinkOptions,
707
- targetEnv,
708
- "linkOptions"
709
- );
710
- const resolvedExports = expandArray(mergedExports, targetEnv, "exports");
949
+ const resolvedLinkOptions = targetType === "archive" ? [] : expandArray(mergedLinkOptions, targetEnv, "linkOptions");
950
+ const resolvedExports = targetType === "archive" ? [] : expandArray(mergedExports, targetEnv, "exports");
711
951
  const exportArgs = buildExportFlags(resolvedExports);
712
- const includeArgs = resolveIncludeDirs(
713
- mergedIncludeDirs,
952
+ const baseCompileArgs = buildCompileArgs(
953
+ baseCompileOptions,
954
+ baseIncludeDirs,
955
+ baseDefines,
714
956
  targetEnv,
715
957
  rootDir
716
- ).map((dir) => `-I${dir}`);
717
- const defineArgs = buildDefineFlags(
718
- resolveDefines(mergedDefines, targetEnv)
719
958
  );
720
- logger.info(`Compiling target: ${targetName}`);
721
- const compileSource = async (source) => {
722
- const objectName = toSafeObjectName(rootDir, source);
959
+ const groupCompileArgs = sourceGroups.map((group) => {
960
+ var _a3;
961
+ const groupOptions = [
962
+ ...baseCompileOptions,
963
+ ...ensureArray(group == null ? void 0 : group.options)
964
+ ];
965
+ const groupIncludeDirs = [
966
+ ...baseIncludeDirs,
967
+ ...ensureArray(group == null ? void 0 : group.includeDirs)
968
+ ];
969
+ const groupDefines = mergeDefines(baseDefines, (_a3 = group == null ? void 0 : group.defines) != null ? _a3 : {});
970
+ return buildCompileArgs(
971
+ groupOptions,
972
+ groupIncludeDirs,
973
+ groupDefines,
974
+ targetEnv,
975
+ rootDir
976
+ );
977
+ });
978
+ const compileSource = async (source, args, groupIndex) => {
979
+ const objectName = toSafeObjectName(rootDir, source, groupIndex);
723
980
  const outputObject = resolve(targetBuildDir, `${objectName}.o`);
724
- const args = [
981
+ const compileArgs = [
725
982
  "-c",
726
983
  source,
727
984
  "-o",
728
985
  outputObject,
729
- ...resolvedOptions,
730
- ...includeArgs,
731
- ...defineArgs
986
+ ...args.resolvedOptions,
987
+ ...args.includeArgs,
988
+ ...args.defineArgs
732
989
  ];
733
- logger.debug(`emcc ${args.join(" ")}`);
990
+ const sourcePath = relative(rootDir, source);
991
+ logger.info(`Compiling source: ${sourcePath} --> $tmp/${objectName}.o`);
992
+ logger.debug(`emcc ${compileArgs.join(" ")}`);
734
993
  await runCommandWithEnv(
735
994
  emccCommand,
736
- args,
995
+ compileArgs,
737
996
  rootDir,
738
997
  buildEnv,
739
998
  emsdkOptions.signal
@@ -742,30 +1001,94 @@ const buildWasm = async (options) => {
742
1001
  };
743
1002
  const buildObjectsSequential = async () => {
744
1003
  const objectFiles2 = [];
745
- for (const source of sources) {
746
- objectFiles2.push(await compileSource(source));
1004
+ for (const source of baseSources) {
1005
+ objectFiles2.push(
1006
+ await compileSource(source, baseCompileArgs, void 0)
1007
+ );
1008
+ }
1009
+ for (let index = 0; index < groupSources.length; index += 1) {
1010
+ const sourcesInGroup = groupSources[index];
1011
+ if (!sourcesInGroup) {
1012
+ continue;
1013
+ }
1014
+ const groupArgs = groupCompileArgs[index];
1015
+ if (!groupArgs) {
1016
+ continue;
1017
+ }
1018
+ for (const source of sourcesInGroup) {
1019
+ objectFiles2.push(await compileSource(source, groupArgs, index));
1020
+ }
747
1021
  }
748
1022
  return objectFiles2;
749
1023
  };
750
- const objectFiles = parallel ? await Promise.all(sources.map((source) => compileSource(source))) : await buildObjectsSequential();
751
- logger.info(`Linking target: ${targetName}`);
752
- const linkArgs = [
753
- ...objectFiles,
754
- "-o",
755
- resolvedOutFile,
756
- ...resolvedLinkOptions,
757
- ...exportArgs
758
- ];
759
- logger.debug(`emcc ${linkArgs.join(" ")}`);
760
- await runCommandWithEnv(
761
- emccCommand,
762
- linkArgs,
763
- rootDir,
764
- buildEnv,
765
- emsdkOptions.signal
1024
+ const compileJobs = [];
1025
+ for (const source of baseSources) {
1026
+ compileJobs.push({
1027
+ source,
1028
+ args: baseCompileArgs,
1029
+ groupIndex: void 0
1030
+ });
1031
+ }
1032
+ logger.info(
1033
+ parallel ? `Building target: '${targetName}' [${compileJobs.length} files, in parallel]` : `Building target: '${targetName}' [${compileJobs.length} files]`
766
1034
  );
1035
+ for (let index = 0; index < groupSources.length; index += 1) {
1036
+ const sourcesInGroup = groupSources[index];
1037
+ if (!sourcesInGroup) {
1038
+ continue;
1039
+ }
1040
+ const groupArgs = groupCompileArgs[index];
1041
+ if (!groupArgs) {
1042
+ continue;
1043
+ }
1044
+ for (const source of sourcesInGroup) {
1045
+ compileJobs.push({ source, args: groupArgs, groupIndex: index });
1046
+ }
1047
+ }
1048
+ const objectFiles = parallel ? await Promise.all(
1049
+ compileJobs.map(
1050
+ (job) => compileSource(job.source, job.args, job.groupIndex)
1051
+ )
1052
+ ) : await buildObjectsSequential();
1053
+ if (targetType === "archive") {
1054
+ if (!emarCommand) {
1055
+ throw new Error("emar command is required for archive targets.");
1056
+ }
1057
+ logger.info(`Archiving target: ${targetName}.a`);
1058
+ const archiveArgs = ["rcs", resolvedOutFile, ...objectFiles];
1059
+ logger.debug(`emar ${archiveArgs.join(" ")}`);
1060
+ await runCommandWithEnv(
1061
+ emarCommand,
1062
+ archiveArgs,
1063
+ rootDir,
1064
+ buildEnv,
1065
+ emsdkOptions.signal
1066
+ );
1067
+ } else {
1068
+ logger.info(`Linking target: ${targetName}.wasm`);
1069
+ const linkArgs = [
1070
+ ...objectFiles,
1071
+ "-o",
1072
+ resolvedOutFile,
1073
+ ...linkLibDirs.map((dir) => `-L${dir}`),
1074
+ ...resolvedLinkOptions,
1075
+ ...exportArgs
1076
+ ];
1077
+ logger.debug(`emcc ${linkArgs.join(" ")}`);
1078
+ await runCommandWithEnv(
1079
+ emccCommand,
1080
+ linkArgs,
1081
+ rootDir,
1082
+ buildEnv,
1083
+ emsdkOptions.signal
1084
+ );
1085
+ }
767
1086
  outFiles[targetName] = resolvedOutFile;
768
1087
  }
1088
+ };
1089
+ try {
1090
+ await buildTargets("archive");
1091
+ await buildTargets("wasm");
769
1092
  } finally {
770
1093
  if (cleanupBuildDir) {
771
1094
  await rm(buildRunDir, { recursive: true, force: true });
@@ -780,4 +1103,4 @@ export {
780
1103
  buildWasm as b,
781
1104
  prepareEmsdk as p
782
1105
  };
783
- //# sourceMappingURL=build-qp0IEBnb.js.map
1106
+ //# sourceMappingURL=build-oSzNI6Av.js.map