diff --git a/compileopts/config.go b/compileopts/config.go index fa790af6..a06aa8fd 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -245,6 +245,29 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) { return filepath.Join(goenv.Get("GOCACHE"), name+"-"+archname), false } +// DefaultBinaryExtension returns the default extension for binaries, such as +// .exe, .wasm, or no extension (depending on the target). +func (c *Config) DefaultBinaryExtension() string { + parts := strings.Split(c.Triple(), "-") + if parts[0] == "wasm32" { + // WebAssembly files always have the .wasm file extension. + return ".wasm" + } + if len(parts) >= 3 && parts[2] == "windows" { + // Windows uses .exe. + return ".exe" + } + if len(parts) >= 3 && parts[2] == "unknown" { + // There appears to be a convention to use the .elf file extension for + // ELF files intended for microcontrollers. I'm not aware of the origin + // of this, it's just something that is used by many projects. + // I think it's a good tradition, so let's keep it. + return ".elf" + } + // Linux, MacOS, etc, don't use a file extension. Use it as a fallback. + return "" +} + // CFlags returns the flags to pass to the C compiler. This is necessary for CGo // preprocessing. func (c *Config) CFlags() []string { diff --git a/main.go b/main.go index 33489823..dde4c761 100644 --- a/main.go +++ b/main.go @@ -149,6 +149,17 @@ func Build(pkgName, outpath string, options *compileopts.Options) error { } return builder.Build(pkgName, outpath, config, func(result builder.BuildResult) error { + if outpath == "" { + if strings.HasSuffix(pkgName, ".go") { + // A Go file was specified directly on the command line. + // Base the binary name off of it. + outpath = filepath.Base(pkgName[:len(pkgName)-3]) + config.DefaultBinaryExtension() + } else { + // Pick a default output path based on the main directory. + outpath = filepath.Base(result.MainDir) + config.DefaultBinaryExtension() + } + } + if err := os.Rename(result.Binary, outpath); err != nil { // Moving failed. Do a file copy. inf, err := os.Open(result.Binary) @@ -1319,11 +1330,6 @@ func main() { switch command { case "build": - if outpath == "" { - fmt.Fprintln(os.Stderr, "No output filename supplied (-o).") - usage(command) - os.Exit(1) - } pkgName := "." if flag.NArg() == 1 { pkgName = filepath.ToSlash(flag.Arg(0))