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

Added possibility to specify platform for dev command #3117

Merged
merged 10 commits into from
Dec 17, 2023
75 changes: 29 additions & 46 deletions v2/cmd/wails/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand All @@ -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
}
Expand All @@ -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":
Expand All @@ -219,32 +207,27 @@ func buildApplication(f *flags.Build) error {
pterm.Warning.Println("obfuscated flag overrides skipbindings flag.")
buildOptions.SkipBindings = false
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing the loop already here results in only calling the compilation compiledBinary, err := build.Build(buildOptions) for the last target in the targets list. Therefore multi platform builds now only build the last platform. This e.g. is preventing users from building a NSIS installer that contains a windows arm64 and amd64 build wails build --nsis --platform windows/arm64,windows/amd64.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah moved a bracket which should fix this one.


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 {
Expand Down
32 changes: 4 additions & 28 deletions v2/cmd/wails/flags/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
98 changes: 98 additions & 0 deletions v2/cmd/wails/flags/common.go
Original file line number Diff line number Diff line change
@@ -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] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This checks breaks the ability to cross compile to another platform with a specific architecture (e.g. --platform windows/arm64 or --platform darwin/universal), because the argument platform is the arg cli --platform arg.
It also prevents the ability to compile for multiple platforms --platform windows/am64,windows/arm64.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR to resolve this one:
#3245

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
}
11 changes: 8 additions & 3 deletions v2/cmd/wails/flags/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net/url"
"os"
"path/filepath"
"runtime"

"github.com/samber/lo"
"github.com/wailsapp/wails/v2/internal/project"
Expand All @@ -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"`
Expand All @@ -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
}
Expand Down Expand Up @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions v2/cmd/wails/internal/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions v2/pkg/commands/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading