@@ -620,6 +620,12 @@ int main(int argc, const char* argv[]) {
620620 std::string outputSourceMapFilename;
621621 std::string outputSourceMapUrl;
622622
623+ // We can write wasm-split manifests that can later be fed to wasm-split to
624+ // split the merged module back up along the lines of the original modules.
625+ // Map modules to their functions so we can write the manifest.
626+ std::string manifestFile;
627+ std::unordered_map<Name, std::vector<Name>> moduleFuncs;
628+
623629 const std::string WasmMergeOption = " wasm-merge options" ;
624630
625631 ToolOptions options (" wasm-merge" ,
@@ -687,6 +693,16 @@ Input source maps can be specified by adding an -ism option right after the modu
687693 [&outputSourceMapUrl](Options* o, const std::string& argument) {
688694 outputSourceMapUrl = argument;
689695 })
696+ .add (" --output-manifest" ,
697+ " " ,
698+ " Write a wasm-split manifest to the specified file. This manifest can "
699+ " be given to wasm-split to split the merged module along the lines of "
700+ " the original modules." ,
701+ WasmMergeOption,
702+ Options::Arguments::One,
703+ [&manifestFile](Options* o, const std::string& argument) {
704+ manifestFile = argument;
705+ })
690706 .add (" --rename-export-conflicts" ,
691707 " -rec" ,
692708 " Rename exports to avoid conflicts (rather than error)" ,
@@ -780,6 +796,16 @@ Input source maps can be specified by adding an -ism option right after the modu
780796 // This is a later module: do a full merge.
781797 mergeInto (*currModule, inputFileName);
782798
799+ // The functions in the module have been renamed and copied rather than
800+ // moved, so we can get their final names directly. (We don't need this
801+ // for the first module because it does not appear in the manifest.)
802+ auto & funcs = moduleFuncs[inputFileName];
803+ for (auto & func : currModule->functions ) {
804+ if (!func->imported ()) {
805+ funcs.push_back (func->name );
806+ }
807+ }
808+
783809 // Validate after each merged module, when we are in pass-debug mode
784810 // (this can be quadratic time).
785811 if (PassRunner::getPassDebug ()) {
@@ -822,6 +848,25 @@ Input source maps can be specified by adding an -ism option right after the modu
822848 }
823849
824850 // Output.
851+ if (!manifestFile.empty ()) {
852+ std::ofstream manifest (manifestFile);
853+ // Skip module 0 because it will be the primary module for the split and
854+ // does not need to appear in the manifest.
855+ for (size_t i = 1 ; i < inputFileNames.size (); i++) {
856+ auto moduleName = inputFileNames[i];
857+ const auto & funcs = moduleFuncs[moduleName];
858+ if (funcs.empty ()) {
859+ continue ;
860+ }
861+
862+ manifest << moduleName << " \n " ;
863+ for (auto func : funcs) {
864+ manifest << func << " \n " ;
865+ }
866+ manifest << " \n " ;
867+ }
868+ }
869+
825870 if (options.extra .count (" output" ) > 0 ) {
826871 ModuleWriter writer (options.passOptions );
827872 writer.setBinary (emitBinary);
0 commit comments