I have GO 1.7 installed on my Windows 10. I created test program and it works perfectly in Windows. Next step is to try to run it on my docker virtual machine with Ubuntu.
I found here some info about the way to do it
set GOARCH=amd64
set GOOS=linux
go tool dist install -v pkg/runtime
go install -v -a std
I run line 1 and 2 in cmd and there is no problem. At line 3 I have an error
go tool dist: open C:\Go\src\pkg\runtime: The system cannot find the path specified.
I check manually this folder and there is a runtime only for windows
The question is where and how can I download it for linux? Or maybe thats I'm doing is completely wrong way...
UPDATE 09/02/2017
I ran like it was suggested
set GOARCH=amd64
set GOOS=linux
go build -o "myapp"
After I copied this file to shared folder, copied form there to another not shared folder (to avoid an issue described here) and executed
root@7dd1655ae5db:/__notshared# ./myapp
bash: ./myapp: cannot execute binary file: Exec format error
After I downloaded file package checked my file
root@7dd1655ae5db:/__notshared# file myapp
myapp: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
It seems that during build not linux executable was created.
That other question is a bit old (from 2013).
Cross-platform support evolved a lot, all you need to do is change the environment variables (GOARCH
and GOOS
) and run go build
.
Navigate to the folder of the main
package, then:
set GOARCH=amd64
set GOOS=linux
go build
You may change the name of the result binary like this:
go build -o "myapp"
Note that in Linux to compile the app for Windows amd64, a single command is enough (in the folder of the main
package):
GOOS=windows GOARCH=amd64 go build
This is also confirmed in blog post: Dave Cheney: Cross compilation with Go 1.5:
To cross compile a Go program using Go 1.5 the process is as follows:
set GOOS
and GOARCH
to be the values for the target operating system and architecture.
run go build -v YOURPACKAGE
Notes
You don't have to, and you shouldn't run go install
, as that will compile and install the packages in your GOPATH
, which is often not wanted. Doing cross compilation is not for developing / testing your app and packages. It is to produce a single binary which you will run on another system / computer.
go build
will not install anything, it will just produce the executable binary. For details, see What does go build build?
Also confirmed in blog post: Dave Cheney: Cross compilation with Go 1.5:
When cross compiling, you should use go build
, not go install
. This is the one of the few cases where go build
is preferable to go install
.
The reason for this is go install
always caches compiled packages, .a
files, into the pkg/
directory that matches the root of the source code.
I found a problem and a solution of it.
In my Windows 10 these commands
set GOARCH=amd64
set GOOS=linux
in cmd and also in powershell console did really nothing! Only the way it works is that I need to open Control Panel -> System -> System Advanced Settings -> Environment Variables and add them there manually.
If you use Visual Studio Code for development, do not forget to restart it.
UPDATE 24/02/2017
Instead all above you can set variable in windows powershell like this
$env:GOOS = "linux"
and read it to console
$env:GOOS
What worked for me, on Windows 10 with Go 1.14, is the following:
go env -w GOARCH=amd64
go env -w GOOS=linux
go build -o test-linux test.go
That's it.
I tried this in both Windows command prompt and Windows PowerShell. There's no difference in results.
If you open the binary file in a text editor, you should see that it begins with ELF (Linux), and not MZ (Windows).
I ran it on a Linux machine (RHEL 7.3) with the given architecture, and it worked properly. It gave correct output.
After copying the file to the Linux machine, I had to make it executable:
$ chmod +x test-linux
Then I was able to run it:
$ ./test-linux
You can also run the following command on Linux, to get more detail about the file:
$ file test-linux
test-linux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
Of course, if your architecture is amd64
already, then you don't have to set it again. You can just set the GOOS
.
You can also revert GOOS
to windows
after you're done with cross-compiling. When I closed the Windows command prompt and PowerShell, and ran go env
to see the list of Go environment variables, and GOOS
kept the linux
value. I didn't try with restarting Windows. So, if you now want to compile for Windows again:
go env -w GOOS=windows
You need to use the correct casing, as shown here. For example, Windows
or Linux
won't work.