From 2c74a1438135c1402f43fc866b0158af4c377174 Mon Sep 17 00:00:00 2001 From: Light Date: Fri, 9 Feb 2024 21:33:13 +1100 Subject: [PATCH 1/3] add dev platform features --- v2/cmd/wails/build.go | 75 ++++++++++-------------- v2/cmd/wails/flags/build.go | 32 ++--------- v2/cmd/wails/flags/common.go | 98 ++++++++++++++++++++++++++++++++ v2/cmd/wails/flags/dev.go | 11 +++- v2/cmd/wails/internal/dev/dev.go | 18 +++++- v2/pkg/commands/build/build.go | 5 +- website/src/pages/changelog.mdx | 3 + 7 files changed, 163 insertions(+), 79 deletions(-) diff --git a/v2/cmd/wails/build.go b/v2/cmd/wails/build.go index 7364df8bae5..a71c5d956d5 100644 --- a/v2/cmd/wails/build.go +++ b/v2/cmd/wails/build.go @@ -108,7 +108,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") @@ -145,16 +145,11 @@ func buildApplication(f *flags.Build) error { // 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 @@ -163,17 +158,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 } @@ -182,22 +173,19 @@ 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": @@ -219,32 +207,27 @@ func buildApplication(f *flags.Build) error { pterm.Warning.Println("obfuscated flag overrides skipbindings flag.") buildOptions.SkipBindings = false } + } - if !f.DryRun { - // Start Time - start := time.Now() - - compiledBinary, err := build.Build(buildOptions) - if err != nil { - pterm.Error.Println(err.Error()) - targetErr = err - return - } + if !f.DryRun { + // Start Time + start := time.Now() - buildOptions.IgnoreFrontend = true - buildOptions.CleanBinDirectory = false + compiledBinary, err := build.Build(buildOptions) + if err != nil { + pterm.Error.Println(err.Error()) + return err + } - // Output stats - buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.\n", compiledBinary, time.Since(start).Round(time.Millisecond).String())) + buildOptions.IgnoreFrontend = true + buildOptions.CleanBinDirectory = false - outputBinaries[buildOptions.Platform+"/"+buildOptions.Arch] = compiledBinary - } else { - pterm.Info.Println("Dry run: skipped build.") - } - }) + // Output stats + buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.\n", compiledBinary, time.Since(start).Round(time.Millisecond).String())) - if targetErr != nil { - return targetErr + outputBinaries[buildOptions.Platform+"/"+buildOptions.Arch] = compiledBinary + } else { + pterm.Info.Println("Dry run: skipped build.") } if f.DryRun { diff --git a/v2/cmd/wails/flags/build.go b/v2/cmd/wails/flags/build.go index 974d9c3adc7..28ef6b9764f 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,29 +46,15 @@ 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 +71,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 +124,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..5a81f729d9e 100644 --- a/v2/cmd/wails/flags/common.go +++ b/v2/cmd/wails/flags/common.go @@ -1,5 +1,103 @@ package flags +import ( + "fmt" + "os" + "runtime" + "strings" + + "github.com/leaanthony/slicer" + "github.com/pterm/pterm" + "github.com/wailsapp/wails/v2/internal/system" +) + 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, + 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 t.Platform +} + +func parseTargets(platform string) TargetsCollection { + allowedPlatforms := map[string]bool{ + "windows": true, + "linux": true, + "darwin": true, + } + + if !allowedPlatforms[platform] { + pterm.Error.Println("platform argument must be one of 'windows', 'linux', or 'darwin'") + os.Exit(1) + } + + 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 501450a982e..b581aadb6fd 100644 --- a/v2/cmd/wails/flags/dev.go +++ b/v2/cmd/wails/flags/dev.go @@ -6,7 +6,6 @@ import ( "net/url" "os" "path/filepath" - "runtime" "github.com/samber/lo" "github.com/wailsapp/wails/v2/internal/project" @@ -17,6 +16,7 @@ type Dev struct { BuildCommon AssetDir string `flag:"assetdir" description:"Serve assets from the given directory instead of using the provided asset FS"` + Platform string `flag:"platform" 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 +38,13 @@ 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 } @@ -116,13 +119,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, Devtools: true, - Arch: runtime.GOARCH, + Arch: targets[0].Arch, 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 02022d12132..02ae79b18b9 100644 --- a/v2/cmd/wails/internal/dev/dev.go +++ b/v2/cmd/wails/internal/dev/dev.go @@ -61,7 +61,7 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { } // Run go mod tidy to ensure we're up-to-date - err = runCommand(cwd, false, f.Compiler, "mod", "tidy") + err = runCommand(cwd, false, "go", "mod", "tidy") if err != nil { return err } @@ -268,6 +268,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) { appBinary, err := build.Build(buildOptions) @@ -306,6 +316,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 5bc3051a4a6..c8522e41298 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) { // Extract logger @@ -225,7 +229,6 @@ func GenerateBindings(buildOptions *Options) error { // Generate Bindings output, err := bindings.GenerateBindings(bindings.Options{ - Compiler: buildOptions.Compiler, Tags: buildOptions.UserTags, GoModTidy: !buildOptions.SkipModTidy, TsPrefix: buildOptions.ProjectData.Bindings.TsGeneration.Prefix, diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index b230d367a53..7f6ba4ea100 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Added option to specify platform for dev command. Thanks to [@pylotlight](https://github.com/pylotlight) for the fix ([#3117](https://github.com/wailsapp/wails/pull/3117)). Based on the work of [@evsign](https://github.com/evsign) in [Draft PR](https://github.com/wailsapp/wails/pull/2724). + ## v2.8.0 - 2024-02-08 ### Added From 0f18d2e6dab6e9f41793b4401f52965a105fa4df Mon Sep 17 00:00:00 2001 From: Light Date: Fri, 9 Feb 2024 21:39:01 +1100 Subject: [PATCH 2/3] add feature fixes --- v2/cmd/wails/build.go | 57 ++++++++++++++++++------------------ v2/cmd/wails/flags/common.go | 48 ++++++++---------------------- 2 files changed, 40 insertions(+), 65 deletions(-) diff --git a/v2/cmd/wails/build.go b/v2/cmd/wails/build.go index a71c5d956d5..ba58f74ccc5 100644 --- a/v2/cmd/wails/build.go +++ b/v2/cmd/wails/build.go @@ -207,44 +207,43 @@ func buildApplication(f *flags.Build) error { pterm.Warning.Println("obfuscated flag overrides skipbindings flag.") buildOptions.SkipBindings = false } - } - - if !f.DryRun { - // Start Time - start := time.Now() - compiledBinary, err := build.Build(buildOptions) - if err != nil { - pterm.Error.Println(err.Error()) - return err - } + if !f.DryRun { + // Start Time + start := time.Now() - buildOptions.IgnoreFrontend = true - buildOptions.CleanBinDirectory = false + compiledBinary, err := build.Build(buildOptions) + if err != nil { + pterm.Error.Println(err.Error()) + return err + } - // Output stats - buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.\n", compiledBinary, time.Since(start).Round(time.Millisecond).String())) + buildOptions.IgnoreFrontend = true + buildOptions.CleanBinDirectory = false - outputBinaries[buildOptions.Platform+"/"+buildOptions.Arch] = compiledBinary - } else { - pterm.Info.Println("Dry run: skipped build.") - } + // Output stats + buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.\n", compiledBinary, time.Since(start).Round(time.Millisecond).String())) - if f.DryRun { - return nil - } + outputBinaries[buildOptions.Platform+"/"+buildOptions.Arch] = compiledBinary + } else { + pterm.Info.Println("Dry run: skipped build.") + } - if f.NSIS { - amd64Binary := outputBinaries["windows/amd64"] - arm64Binary := outputBinaries["windows/arm64"] - if amd64Binary == "" && arm64Binary == "" { - return fmt.Errorf("cannot build nsis installer - no windows targets") + if f.DryRun { + return nil } - if err := build.GenerateNSISInstaller(buildOptions, amd64Binary, arm64Binary); err != nil { - return err + if f.NSIS { + amd64Binary := outputBinaries["windows/amd64"] + arm64Binary := outputBinaries["windows/arm64"] + if amd64Binary == "" && arm64Binary == "" { + return fmt.Errorf("cannot build nsis installer - no windows targets") + } + + if err := build.GenerateNSISInstaller(buildOptions, amd64Binary, arm64Binary); err != nil { + return err + } } } - return nil } diff --git a/v2/cmd/wails/flags/common.go b/v2/cmd/wails/flags/common.go index 5a81f729d9e..21fb72c2d4c 100644 --- a/v2/cmd/wails/flags/common.go +++ b/v2/cmd/wails/flags/common.go @@ -6,8 +6,6 @@ import ( "runtime" "strings" - "github.com/leaanthony/slicer" - "github.com/pterm/pterm" "github.com/wailsapp/wails/v2/internal/system" ) @@ -62,42 +60,20 @@ func (t Target) String() string { return t.Platform } -func parseTargets(platform string) TargetsCollection { - allowedPlatforms := map[string]bool{ - "windows": true, - "linux": true, - "darwin": true, - } - - if !allowedPlatforms[platform] { - pterm.Error.Println("platform argument must be one of 'windows', 'linux', or 'darwin'") - os.Exit(1) - } +func parseTargets(platforms string) TargetsCollection { + platformList := strings.Split(platforms, ",") - var result []Target - var targets slicer.StringSlicer + var targets []Target - targets.AddSlice(strings.Split(platform, ",")) - targets.Deduplicate() - - targets.Each(func(platform string) { - target := Target{ - Platform: "", - Arch: "", + for _, platform := range platformList { + parts := strings.Split(platform, "/") + if len(parts) == 1 { + architecture := defaultTarget().Arch + targets = append(targets, Target{Platform: parts[0], Arch: architecture}) + } else if len(parts) == 2 { + targets = append(targets, Target{Platform: parts[0], Arch: parts[1]}) } + } - 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 + return targets } From 003806844d824522d87506dae797cfc183b0a0c3 Mon Sep 17 00:00:00 2001 From: Light Date: Fri, 9 Feb 2024 21:41:27 +1100 Subject: [PATCH 3/3] update changelog pr ref --- website/src/pages/changelog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 7f6ba4ea100..5187cad83d8 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- Added option to specify platform for dev command. Thanks to [@pylotlight](https://github.com/pylotlight) for the fix ([#3117](https://github.com/wailsapp/wails/pull/3117)). Based on the work of [@evsign](https://github.com/evsign) in [Draft PR](https://github.com/wailsapp/wails/pull/2724). +- Added option to specify platform for dev command. Thanks to [@pylotlight](https://github.com/pylotlight) for the fix ([#3248](https://github.com/wailsapp/wails/pull/3248)). Based on the work of [@evsign](https://github.com/evsign) in [Draft PR](https://github.com/wailsapp/wails/pull/2724). ## v2.8.0 - 2024-02-08