0

I'm very new to system programming.

I have a Go program which uses net/http and starts an http server.

When I build a Windows binary and tried on a target Windows machine, nothing worked except Printfs before it starts the server.

As soon as I installed Go on the target Windows machine, everything started working!

Here is my program:

package main

import (
    "fmt"
    "log"
    "os/exec"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there @%s!", r.URL.Path[1:])
}

func main() {

    path, err := exec.LookPath("go")
    if err != nil {
        log.Fatal("Go is not your fortune :|")
    }
    fmt.Printf("Go is available at %s\n", path)

    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

If go doesn't build all the dependencies with its program then how do I do it? If it does, why it is not working?

Does target systems have to have go installed prior to run any Go programs?

Please help! Thanks.

icza
  • 389,944
  • 63
  • 907
  • 827
Mehulkumar
  • 836
  • 2
  • 10
  • 23
  • Looks like it crashed on loading dynamic libraries. Perhaps after you've installed `go` the necessary binaries ended up in win32/wow64 directory, hence it worked? You could try adding the necessary runtime dynamic libraries to the binary directory (or PATH) and see if that's enough. – hauron Jul 25 '16 at 13:45
  • 1
    The runtime does not require the source to be installed. You need to show how you build the binary and what output you received. – JimB Jul 25 '16 at 13:46
  • @JimB I've added my program. In case `Go` is not installed, it just logs the err and exits! – Mehulkumar Jul 25 '16 at 14:09
  • 2
    Your program is looking for the `go` binary, so of course Go needs to be installed. Why are you doing `exec.LookPath("go")`? – JimB Jul 25 '16 at 14:13
  • @JimB I need checking on whether some commands exists on target system, so that was my test! Thanks so much for your help!! – Mehulkumar Jul 25 '16 at 14:38
  • 1
    change log.Fatal() to log.Printf(), and it should work (and you probably don't need to `exec.LookPath("go")` since Go does not have to be installed on the target machine) – dmitris Jul 25 '16 at 15:29
  • @dmitris Yes! My program will require some commands to be run on target machine so `exec.LookPath("go")` was just a test to check if it works. I'll probably also require `log.Fatal()` as well because without some commands on target machine(not `go`), my program will not run. – Mehulkumar Jul 26 '16 at 04:57

2 Answers2

2

Your app doesn't work without Go because you call log.Fatal() if it doesn't find the go tool, and log.Fatal() terminates your app:

Fatal is equivalent to Print() followed by a call to os.Exit(1).

Your executable binary will contain everything it needs if you build it from the source you posted either with go build or go install (see What does go build build? for details). Just don't call log.Fatal() and it should work.

And on a side note: you should check and print errors returned by http.ListenAndServe(), e.g.:

panic(http.ListenAndServe(":8080", nil))

Because if this fails, you won't know why it doesn't work (e.g. you already started the app and the port is taken / in use).

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
2

No, the target system does not have to have the Go compiler installed for the executable compiled with Go to run. You can compile your program with go install or go build on one Windows computer, copy it to another one where Go is not installed and run it there.

Make sure the program that you compile starts with the package main statement - otherwise only a library file will be compiled.

Make sure to check whether the user that runs your program has rights to listen on the port that the http server uses. The ports 0-1023 - "Well Known Ports" - "can only be used by system (or root) processes or by programs executed by privileged users" (https://support.microsoft.com/en-us/kb/174904), so try to start your program as a privileged user (for example, Administrator) or use a non-privileged port >= 1024 (ex. http.ListenAndServe(":8080", nil) should start the server on a non-privilege port. Take a very simple example - for example from https://golang.org/doc/articles/wiki/ - and see if you can get it to work.

dmitris
  • 1,441
  • 1
  • 12
  • 13