Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Reduce Go build times #615

Merged
merged 6 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
8 changes: 1 addition & 7 deletions sdk/go/tools/modus-go-build/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,14 @@ 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))

// 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, ".")

Expand Down
15 changes: 5 additions & 10 deletions sdk/go/tools/modus-go-build/extractor/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
52 changes: 49 additions & 3 deletions sdk/go/tools/modus-go-build/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,108 @@ 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"
"github.com/hypermodeinc/modus/sdk/go/tools/modus-go-build/compiler"
"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)
if err != nil {
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)
}

Expand Down
10 changes: 1 addition & 9 deletions sdk/go/tools/modus-go-build/metagen/metagen.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ package metagen
import (
"fmt"
"path"
"path/filepath"

"os"

Expand All @@ -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"
Expand All @@ -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)
}

Expand Down
5 changes: 5 additions & 0 deletions sdk/go/tools/modus-go-build/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
47 changes: 0 additions & 47 deletions sdk/go/tools/modus-go-build/wasm/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
Loading