diff --git a/v2/cmd/wails/build.go b/v2/cmd/wails/build.go index 1c6b791ec85..38deae106c5 100644 --- a/v2/cmd/wails/build.go +++ b/v2/cmd/wails/build.go @@ -99,7 +99,7 @@ func buildApplication(f *flags.Build) error { {"Tags", "[" + strings.Join(f.GetTags(), ",") + "]"}, {"Race Detector", bool2Str(f.RaceDetector)}, }...) - if len(buildOptions.OutputFile) > 0 && f.GetTargets().Length() == 1 { + if len(buildOptions.OutputFile) > 0 && len(f.GetTargets()) == 1 { tableData = append(tableData, []string{"Output File", f.OutputFilename}) } pterm.DefaultSection.Println("Build Options") @@ -134,18 +134,12 @@ func buildApplication(f *flags.Build) error { outputBinaries := map[string]string{} - // Allows cancelling the build after the first error. It would be nice if targets.Each would support funcs - // returning an error. - var targetErr error targets := f.GetTargets() - targets.Each(func(platform string) { - if targetErr != nil { - return - } - if !validPlatformArch.Contains(platform) { - buildOptions.Logger.Println("platform '%s' is not supported - skipping. Supported platforms: %s", platform, validPlatformArch.Join(",")) - return + for _, target := range targets { + if !validPlatformArch.Contains(target.Platform) { + buildOptions.Logger.Println("platform '%s' is not supported - skipping. Supported platforms: %s", target.Platform, validPlatformArch.Join(",")) + continue } desiredFilename := projectOptions.OutputFilename @@ -154,17 +148,13 @@ func buildApplication(f *flags.Build) error { } desiredFilename = strings.TrimSuffix(desiredFilename, ".exe") - // Calculate platform and arch - platformSplit := strings.Split(platform, "/") - buildOptions.Platform = platformSplit[0] - buildOptions.Arch = f.GetDefaultArch() - if len(platformSplit) > 1 { - buildOptions.Arch = platformSplit[1] - } + buildOptions.Platform = target.Platform + buildOptions.Arch = target.Arch + banner := "Building target: " + buildOptions.Platform + "/" + buildOptions.Arch pterm.DefaultSection.Println(banner) - if f.Upx && platform == "darwin/universal" { + if f.Upx && target.String() == "darwin/universal" { pterm.Warning.Println("Warning: compress flag unsupported for universal binaries. Ignoring.") f.Upx = false } @@ -173,22 +163,20 @@ func buildApplication(f *flags.Build) error { case "linux": if runtime.GOOS != "linux" { pterm.Warning.Println("Crosscompiling to Linux not currently supported.") - return + continue } case "darwin": if runtime.GOOS != "darwin" { pterm.Warning.Println("Crosscompiling to Mac not currently supported.") - return + continue } - macTargets := targets.Filter(func(platform string) bool { - return strings.HasPrefix(platform, "darwin") - }) - if macTargets.Length() == 2 { + + if targets.MacTargetsCount() == 2 { buildOptions.BundleName = fmt.Sprintf("%s-%s.app", desiredFilename, buildOptions.Arch) } } - if targets.Length() > 1 { + if len(targets) > 1 { // target filename switch buildOptions.Platform { case "windows": @@ -218,8 +206,7 @@ func buildApplication(f *flags.Build) error { compiledBinary, err := build.Build(buildOptions) if err != nil { pterm.Error.Println(err.Error()) - targetErr = err - return + return err } buildOptions.IgnoreFrontend = true @@ -232,10 +219,6 @@ func buildApplication(f *flags.Build) error { } else { pterm.Info.Println("Dry run: skipped build.") } - }) - - if targetErr != nil { - return targetErr } if f.DryRun { diff --git a/v2/cmd/wails/flags/build.go b/v2/cmd/wails/flags/build.go index 974d9c3adc7..6e30844ec73 100644 --- a/v2/cmd/wails/flags/build.go +++ b/v2/cmd/wails/flags/build.go @@ -2,13 +2,10 @@ package flags import ( "fmt" - "os" "os/exec" - "runtime" "strings" "github.com/leaanthony/slicer" - "github.com/wailsapp/wails/v2/internal/system" "github.com/wailsapp/wails/v2/pkg/commands/build" "github.com/wailsapp/wails/v2/pkg/commands/buildtags" ) @@ -49,30 +46,17 @@ type Build struct { compilerPath string userTags []string wv2rtstrategy string // WebView2 runtime strategy - defaultArch string // Default architecture } func (b *Build) Default() *Build { - defaultPlatform := os.Getenv("GOOS") - if defaultPlatform == "" { - defaultPlatform = runtime.GOOS - } - defaultArch := os.Getenv("GOARCH") - if defaultArch == "" { - if system.IsAppleSilicon { - defaultArch = "arm64" - } else { - defaultArch = runtime.GOARCH - } - } + target := defaultTarget() result := &Build{ - Platform: defaultPlatform + "/" + defaultArch, + Platform: target.Platform, WebView2: "download", GarbleArgs: "-literals -tiny -seed=random", - - defaultArch: defaultArch, } + result.BuildCommon = result.BuildCommon.Default() return result } @@ -88,11 +72,8 @@ func (b *Build) GetWebView2Strategy() string { return b.wv2rtstrategy } -func (b *Build) GetTargets() *slicer.StringSlicer { - var targets slicer.StringSlicer - targets.AddSlice(strings.Split(b.Platform, ",")) - targets.Deduplicate() - return &targets +func (b *Build) GetTargets() TargetsCollection { + return parseTargets(b.Platform) } func (b *Build) GetCompilerPath() string { @@ -144,10 +125,6 @@ func (b *Build) GetBuildModeAsString() string { return "production" } -func (b *Build) GetDefaultArch() string { - return b.defaultArch -} - /* _, _ = fmt.Fprintf(w, "Frontend Directory: \t%s\n", projectOptions.GetFrontendDir()) _, _ = fmt.Fprintf(w, "Obfuscated: \t%t\n", buildOptions.Obfuscated) diff --git a/v2/cmd/wails/flags/common.go b/v2/cmd/wails/flags/common.go index e58eff41192..0897a88c3dd 100644 --- a/v2/cmd/wails/flags/common.go +++ b/v2/cmd/wails/flags/common.go @@ -1,5 +1,90 @@ package flags +import ( + "fmt" + "github.com/leaanthony/slicer" + "github.com/wailsapp/wails/v2/internal/system" + "os" + "runtime" + "strings" +) + type Common struct { NoColour bool `description:"Disable colour in output"` } + +type Target struct { + Platform string + Arch string +} + +func defaultTarget() Target { + defaultPlatform := os.Getenv("GOOS") + if defaultPlatform == "" { + defaultPlatform = runtime.GOOS + } + defaultArch := os.Getenv("GOARCH") + if defaultArch == "" { + if system.IsAppleSilicon { + defaultArch = "arm64" + } else { + defaultArch = runtime.GOARCH + } + } + + return Target{ + Platform: defaultPlatform + "/" + defaultArch, + Arch: defaultArch, + } +} + +type TargetsCollection []Target + +func (c TargetsCollection) MacTargetsCount() int { + count := 0 + + for _, t := range c { + if strings.HasPrefix(t.Platform, "darwin") { + count++ + } + } + + return count +} + +func (t Target) String() string { + if t.Arch != "" { + return fmt.Sprintf("%s/%s", t.Platform, t.Arch) + } + + return fmt.Sprintf("%s", t.Platform) +} + +func parseTargets(platform string) TargetsCollection { + var result []Target + var targets slicer.StringSlicer + + targets.AddSlice(strings.Split(platform, ",")) + targets.Deduplicate() + + targets.Each(func(platform string) { + target := Target{ + Platform: "", + Arch: "", + } + + platformSplit := strings.Split(platform, "/") + + target.Platform = platformSplit[0] + + if len(platformSplit) > 1 { + target.Arch = platformSplit[1] + } else { + target.Arch = defaultTarget().Arch + } + + result = append(result, target) + }) + + return result +} diff --git a/v2/cmd/wails/flags/dev.go b/v2/cmd/wails/flags/dev.go index 7e5e6239c74..f282bc68bd9 100644 --- a/v2/cmd/wails/flags/dev.go +++ b/v2/cmd/wails/flags/dev.go @@ -2,21 +2,20 @@ package flags import ( "fmt" + "github.com/samber/lo" + "github.com/wailsapp/wails/v2/internal/project" + "github.com/wailsapp/wails/v2/pkg/commands/build" "net" "net/url" "os" "path/filepath" - "runtime" - - "github.com/samber/lo" - "github.com/wailsapp/wails/v2/internal/project" - "github.com/wailsapp/wails/v2/pkg/commands/build" ) type Dev struct { BuildCommon AssetDir string `flag:"assetdir" description:"Serve assets from the given directory instead of using the provided asset FS"` + Platform string `description:"Platform to target"` Extensions string `flag:"e" description:"Extensions to trigger rebuilds (comma separated) eg go"` ReloadDirs string `flag:"reloaddirs" description:"Additional directories to trigger reloads (comma separated)"` Browser bool `flag:"browser" description:"Open the application in a browser"` @@ -38,10 +37,14 @@ type Dev struct { } func (*Dev) Default() *Dev { + target := defaultTarget() + result := &Dev{ Extensions: "go", Debounce: 100, + Platform: target.Platform, } + result.BuildCommon = result.BuildCommon.Default() return result } @@ -118,13 +121,15 @@ func (d *Dev) loadAndMergeProjectConfig() error { // GenerateBuildOptions creates a build.Options using the flags func (d *Dev) GenerateBuildOptions() *build.Options { + targets := parseTargets(d.Platform) + result := &build.Options{ OutputType: "dev", Mode: build.Dev, + Arch: targets[0].Arch, Devtools: true, - Arch: runtime.GOARCH, Pack: true, - Platform: runtime.GOOS, + Platform: targets[0].Platform, LDFlags: d.LdFlags, Compiler: d.Compiler, ForceBuild: d.ForceBuild, diff --git a/v2/cmd/wails/internal/dev/dev.go b/v2/cmd/wails/internal/dev/dev.go index 80d7a6d875c..7011be331a6 100644 --- a/v2/cmd/wails/internal/dev/dev.go +++ b/v2/cmd/wails/internal/dev/dev.go @@ -269,6 +269,16 @@ func runFrontendDevWatcherCommand(frontendDirectory string, devCommand string, d }, viteServerURL, viteVersion, nil } +func isWsl() bool { + version, err := os.ReadFile("/proc/version") + + if err != nil { + return false + } + + return strings.Contains(strings.ToLower(string(version)), "wsl") +} + // restartApp does the actual rebuilding of the application when files change func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int, legacyUseDevServerInsteadofCustomScheme bool) (*process.Process, string, error) { @@ -309,6 +319,12 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process os.Setenv("devserver", f.DevServer) os.Setenv("frontenddevserverurl", f.FrontendDevServerURL) + if buildOptions.IsWindowsTargetPlatform() && isWsl() { + // In the case of building a Windows executable under WSL, we need to specify this variable with a list of + // variables that will be passed through + os.Setenv("WSLENV", "loglevel/w:frontenddevserverurl/w:devserver/w:assetdir/w") + } + // Start up new binary with correct args newProcess := process.NewProcess(appBinary, args...) err = newProcess.Start(exitCodeChannel) diff --git a/v2/pkg/commands/build/build.go b/v2/pkg/commands/build/build.go index a29840b1bde..d1063b95890 100644 --- a/v2/pkg/commands/build/build.go +++ b/v2/pkg/commands/build/build.go @@ -71,6 +71,10 @@ type Options struct { SkipBindings bool // Skip binding generation } +func (o *Options) IsWindowsTargetPlatform() bool { + return strings.Contains(strings.ToLower(o.Platform), "windows") +} + // Build the project! func Build(options *Options) (string, error) {