diff --git a/CHANGELOG.md b/CHANGELOG.md index 27f6ab01..ba0262c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 2024-11-25 - Go SDK 0.14.2 + +- fix: Reduce Go build times [#615](https://github.com/hypermodeinc/modus/pull/615) + ## 2024-11-25 - CLI 0.13.10 - fix: modus new rename branch to main if not [#613](https://github.com/hypermodeinc/modus/pull/613) diff --git a/sdk/go/tools/modus-go-build/compiler/compiler.go b/sdk/go/tools/modus-go-build/compiler/compiler.go index 437a9b1b..f54e31d0 100644 --- a/sdk/go/tools/modus-go-build/compiler/compiler.go +++ b/sdk/go/tools/modus-go-build/compiler/compiler.go @@ -23,7 +23,7 @@ import ( const minTinyGoVersion = "0.33.0" -func Compile(config *config.Config, final bool) error { +func Compile(config *config.Config) error { args := []string{"build"} args = append(args, "-target", "wasip1") args = append(args, "-o", filepath.Join(config.OutputDir, config.WasmFileName)) @@ -31,12 +31,6 @@ func Compile(config *config.Config, final bool) error { // disable the asyncify scheduler until we better understand how to use it args = append(args, "-scheduler", "none") - if !final { - // We need a fast compile for the first pass. Optimizations aren't necessary. - // Note that -opt=0 would be ok, but it emits a warning and isn't all that much faster than -opt=1 - args = append(args, "-opt", "1") - } - args = append(args, config.CompilerOptions...) args = append(args, ".") diff --git a/sdk/go/tools/modus-go-build/extractor/extractor.go b/sdk/go/tools/modus-go-build/extractor/extractor.go index f5bcaae1..d5367072 100644 --- a/sdk/go/tools/modus-go-build/extractor/extractor.go +++ b/sdk/go/tools/modus-go-build/extractor/extractor.go @@ -16,10 +16,9 @@ import ( "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/config" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/metadata" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/utils" - "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/wasm" ) -func CollectProgramInfo(config *config.Config, meta *metadata.Metadata, wasmFunctions *wasm.WasmFunctions) error { +func CollectProgramInfo(config *config.Config, meta *metadata.Metadata) error { pkgs, err := loadPackages(config.SourceDir) if err != nil { return err @@ -28,17 +27,13 @@ func CollectProgramInfo(config *config.Config, meta *metadata.Metadata, wasmFunc requiredTypes := make(map[string]types.Type) for name, f := range getExportedFunctions(pkgs) { - if _, ok := wasmFunctions.Exports[name]; ok { - meta.FnExports[name] = transformFunc(name, f, pkgs) - findRequiredTypes(f, requiredTypes) - } + meta.FnExports[name] = transformFunc(name, f, pkgs) + findRequiredTypes(f, requiredTypes) } for name, f := range getImportedFunctions(pkgs) { - if _, ok := wasmFunctions.Imports[name]; ok { - meta.FnImports[name] = transformFunc(name, f, pkgs) - findRequiredTypes(f, requiredTypes) - } + meta.FnImports[name] = transformFunc(name, f, pkgs) + findRequiredTypes(f, requiredTypes) } // proxy imports overwrite regular imports diff --git a/sdk/go/tools/modus-go-build/main.go b/sdk/go/tools/modus-go-build/main.go index 72e95f1c..005d1ea1 100644 --- a/sdk/go/tools/modus-go-build/main.go +++ b/sdk/go/tools/modus-go-build/main.go @@ -11,8 +11,10 @@ package main import ( "fmt" + "log" "os" "path/filepath" + "time" "github.com/hypermodeinc/modus/lib/manifest" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/codegen" @@ -20,30 +22,50 @@ import ( "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/config" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/metagen" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/modinfo" + "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/utils" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/wasm" ) func main() { + + start := time.Now() + trace := utils.IsTraceModeEnabled() + if trace { + log.Println("Starting build process...") + } + config, err := config.GetConfig() if err != nil { exitWithError("Error", err) } + if trace { + log.Println("Configuration loaded.") + } + if err := compiler.Validate(config); err != nil { exitWithError("Error", err) } + if trace { + log.Println("Configuration validated.") + } + mod, err := modinfo.CollectModuleInfo(config) if err != nil { exitWithError("Error", err) } + if trace { + log.Println("Module info collected.") + } + if err := codegen.PreProcess(config); err != nil { exitWithError("Error while pre-processing source files", err) } - if err := compiler.Compile(config, false); err != nil { - exitWithError("Error building wasm", err) + if trace { + log.Println("Pre-processing done.") } meta, err := metagen.GenerateMetadata(config, mod) @@ -51,22 +73,46 @@ func main() { exitWithError("Error generating metadata", err) } + if trace { + log.Println("Metadata generated.") + } + if err := codegen.PostProcess(config, meta); err != nil { exitWithError("Error while post-processing source files", err) } - if err := compiler.Compile(config, true); err != nil { + if trace { + log.Println("Post-processing done.") + } + + if err := compiler.Compile(config); err != nil { exitWithError("Error building wasm", err) } + if trace { + log.Println("Wasm compiled.") + } + if err := wasm.WriteMetadata(config, meta); err != nil { exitWithError("Error writing metadata", err) } + if trace { + log.Println("Metadata written.") + } + if err := validateAndCopyManifestToOutput(config); err != nil { exitWithError("Manifest error", err) } + if trace { + log.Println("Manifest copied.") + } + + if trace { + log.Printf("Build completed in %.2f seconds.\n\n", time.Since(start).Seconds()) + } + metagen.LogToConsole(meta) } diff --git a/sdk/go/tools/modus-go-build/metagen/metagen.go b/sdk/go/tools/modus-go-build/metagen/metagen.go index 27bccc7b..75e42e38 100644 --- a/sdk/go/tools/modus-go-build/metagen/metagen.go +++ b/sdk/go/tools/modus-go-build/metagen/metagen.go @@ -12,7 +12,6 @@ package metagen import ( "fmt" "path" - "path/filepath" "os" @@ -21,7 +20,6 @@ import ( "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/gitinfo" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/metadata" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/modinfo" - "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/wasm" ) const sdkName = "modus-sdk-go" @@ -40,13 +38,7 @@ func GenerateMetadata(config *config.Config, mod *modinfo.ModuleInfo) (*metadata meta.SDK += "@" + mod.ModusSDKVersion.String() } - wasmFilePath := filepath.Join(config.OutputDir, config.WasmFileName) - wasmFunctions, err := wasm.GetWasmFunctions(wasmFilePath) - if err != nil { - return nil, fmt.Errorf("error reading wasm functions: %w", err) - } - - if err := extractor.CollectProgramInfo(config, meta, wasmFunctions); err != nil { + if err := extractor.CollectProgramInfo(config, meta); err != nil { return nil, fmt.Errorf("error collecting program info: %w", err) } diff --git a/sdk/go/tools/modus-go-build/utils/utils.go b/sdk/go/tools/modus-go-build/utils/utils.go index 922412ff..f788dcee 100644 --- a/sdk/go/tools/modus-go-build/utils/utils.go +++ b/sdk/go/tools/modus-go-build/utils/utils.go @@ -23,6 +23,11 @@ func IsDebugModeEnabled() bool { return b } +func IsTraceModeEnabled() bool { + b, _ := strconv.ParseBool(os.Getenv("MODUS_TRACE")) + return b +} + func JsonSerialize(v any, ident bool) ([]byte, error) { buf := new(bytes.Buffer) enc := json.NewEncoder(buf) diff --git a/sdk/go/tools/modus-go-build/wasm/wasm.go b/sdk/go/tools/modus-go-build/wasm/wasm.go index 089f028e..13d2de96 100644 --- a/sdk/go/tools/modus-go-build/wasm/wasm.go +++ b/sdk/go/tools/modus-go-build/wasm/wasm.go @@ -15,9 +15,7 @@ import ( "fmt" "os" "path/filepath" - "strings" - "github.com/hypermodeinc/modus/lib/wasmextractor" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/config" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/metadata" "github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/utils" @@ -118,48 +116,3 @@ func getWasmBytes(wasmFilePath string) ([]byte, error) { return wasmBytes, nil } - -type WasmFunctions struct { - Exports map[string]any - Imports map[string]any -} - -func GetWasmFunctions(wasmFilePath string) (*WasmFunctions, error) { - wasmBytes, err := getWasmBytes(wasmFilePath) - if err != nil { - return nil, err - } - - info, err := wasmextractor.ExtractWasmInfo(wasmBytes) - if err != nil { - return nil, err - } - - result := WasmFunctions{} - - shouldIgnore := func(name string) bool { - ignorePrefixes := []string{"wasi", "env", "runtime", "syscall", "gojs"} - for _, prefix := range ignorePrefixes { - if strings.HasPrefix(name, prefix) { - return true - } - } - return false - } - - result.Imports = make(map[string]any, len(info.Imports)) - for _, item := range info.Imports { - if item.Kind == wasmextractor.WasmFunction && !shouldIgnore(item.Name) { - result.Imports[item.Name] = nil - } - } - - result.Exports = make(map[string]any, len(info.Exports)) - for _, item := range info.Exports { - if item.Kind == wasmextractor.WasmFunction && !shouldIgnore(item.Name) { - result.Exports[item.Name] = nil - } - } - - return &result, nil -}