diff --git a/v2/cmd/wails/build.go b/v2/cmd/wails/build.go index 7364df8bae5..ba58f74ccc5 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": @@ -227,8 +215,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 @@ -241,27 +228,22 @@ func buildApplication(f *flags.Build) error { } else { pterm.Info.Println("Dry run: skipped build.") } - }) - - if targetErr != nil { - return targetErr - } - if f.DryRun { - return nil - } - - 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/build.go b/v2/cmd/wails/flags/build.go index 05b868ada72..5853b796c43 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" ) @@ -48,29 +45,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 @@ -87,11 +70,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 { @@ -143,10 +123,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..21fb72c2d4c 100644 --- a/v2/cmd/wails/flags/common.go +++ b/v2/cmd/wails/flags/common.go @@ -1,5 +1,79 @@ package flags +import ( + "fmt" + "os" + "runtime" + "strings" + + "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(platforms string) TargetsCollection { + platformList := strings.Split(platforms, ",") + + var targets []Target + + 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]}) + } + } + + return targets +} 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 2f6b10a7396..ac7c84568cf 100644 --- a/v2/cmd/wails/internal/dev/dev.go +++ b/v2/cmd/wails/internal/dev/dev.go @@ -60,6 +60,7 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error { return err } + if !f.SkipModTidy { // Run go mod tidy to ensure we're up-to-date err = runCommand(cwd, false, f.Compiler, "mod", "tidy") @@ -270,6 +271,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) @@ -308,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 31f90878fe0..83e2acd8da1 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 fba49d82db2..51fa5fcc42d 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added mac option `DisableZoom` to remove zoom button. Added by @wizzymore in [PR](https://github.com/wailsapp/wails/pull/3289) - Changed Create a project with changing the default name to the project’s name. Changed by [@Twacqwq](https://github.com/Twacqwq) in [PR](https://github.com/wailsapp/wails/pull/3303) +### Added +- 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 ### Added