Golang compile for all platforms in Windows 7 (32 bit) - windows

I'm using windows 7 [32 bit] operating system.
I'm build example go program.
I want to compile this program for all platforms from my windows 7 [32 bit] OS.
I want to compile my program for all Linux [32/64] / Mac OSX [32/64] / Windows[32/64].
Is it possible are not from my single OS ?

Update Go 1.5: see "Cross compilation just got a whole lot better in Go 1.5"
For successful cross compilation you would need
compilers for the target platform, if they differed from your host platform, ie you’re on darwin/amd64 (6g) and you want to compile for linux/arm (5g).
a standard library for the target platform, which included some files generated at the point your Go distribution was built.
With the plan to translate the Go compiler into Go coming to fruition in the 1.5 release the first issue is now resolved.
package main
import "fmt"
import "runtime"
func main() {
fmt.Printf("Hello %s/%s\n", runtime.GOOS, runtime.GOARCH)
}
build for darwin/386
% env GOOS=darwin GOARCH=386 go build hello.go
# scp to darwin host
$ ./hello
Hello darwin/386
Or build for linux/arm
% env GOOS=linux GOARCH=arm GOARM=7 go build hello.go
# scp to linux host
$ ./hello
Hello linux/arm
Original answer (Go 1.4 and before)
You can try a tool like gox
Gox is a simple, no-frills tool for Go cross compilation that behaves a lot like standard go build.
Gox will parallelize builds for multiple platforms.
Gox will also build the cross-compilation toolchain for you.
Before you use Gox, you must build the cross-compilation toolchain. Gox can do this for you. This only has to be done once (or whenever you update Go):
$ gox -build-toolchain
You will also find many cross-platform development tips at "Developing for Multiple Platforms With Go".
Passionate Developer points out below to issue 19, left by the OP Nakka Chandra, even though issue 10 reported making gox run successfully on Windows.

On Windows run the following commands:
C:\Users\user\go\src\myapp> set GOOS=linux
C:\Users\user\go\src\myapp> set GOARCH=amd64
C:\Users\user\go\src\myapp> go build
It worked for me.
Notice, if you get the error:
cmd/go: unsupported GOOS/GOARCH pair linux/amd64
This is because you have a space at the end of the variable.
Example, wrong use is: set GOOS=linux<space>), instead it should be: set GOOS=linux.
This is the full table list (taken from here) for all the other systems:
GOOS - Target Operating System| GOARCH - Target Platform
-------------------------------|--------------------------
| android | arm |
| darwin | 386 |
| darwin | amd64 |
| darwin | arm |
| darwin | arm64 |
| dragonfly | amd64 |
| freebsd | 386 |
| freebsd | amd64 |
| freebsd | arm |
| linux | 386 |
| linux | amd64 |
| linux | arm |
| linux | arm64 |
| linux | ppc64 |
| linux | ppc64le |
| linux | mips |
| linux | mipsle |
| linux | mips64 |
| linux | mips64le |
| netbsd | 386 |
| netbsd | amd64 |
| netbsd | arm |
| openbsd | 386 |
| openbsd | amd64 |
| openbsd | arm |
| plan9 | 386 |
| plan9 | amd64 |
| solaris | amd64 |
| windows | 386 |
| windows | amd64 |
----------------------------------------------------------

You can find the full list of supported GOOS/GOARCH platforms supported by your go by running go tool dist list.
For Go 1.18.1, this shows the following pairs, after filtering based on the target OSes you said you are interested in:
$ go tool dist list | grep -e linux -e darwin -e windows
darwin/amd64
darwin/arm64
linux/386
linux/amd64
linux/arm
linux/arm64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/riscv64
linux/s390x
windows/386
windows/amd64
windows/arm
windows/arm64
If you want to compile your code for all of these, you can do this with the bash/sh script below:
bin_name='example' # Change the binary name as desired
go tool dist list | grep -e linux -e darwin -e windows | while read -r pair; do
# Extract the GOOS and GOARCH from the pair
GOOS="${pair%/*}"
GOARCH="${pair#*/}"
suffix=''
# If GOOS is windows, set suffix to .exe
[ "$GOOS" = 'windows' ] && suffix='.exe'
# Replace <args> with appropriate arguments as needed
GOOS="$GOOS" GOARCH="$GOARCH" \
go build -o "${bin_name}-${GOOS}-${GOARCH}${suffix}" <args>
done
This script will produce an executable for each OS/architecture pair, and append the OS and architecture at the end of the name. It will also append .exe if the OS is Windows.

Related

Getting latest version of Android from sdkmanager automatically

I was trying to make a bash script to automatically install flutter and android sdk without Android Studio.
I managed to get the latest version of build-tools using the following sequence
btversion=`sdkmanager --list | tac | sed "/build-tools/q" | tac | sed -n 1p`
btversion=${btversion% *}
btversion=${btversion:2}
I am trying to do something similar to install platforms;android-%version%, except doing something like this lead me to a dead end:
sdkmanager --list | tac | sed "/platforms;android-[0-9]+/g"
The [0-9]+ filter is necessary as packages such as platforms;android-TiramisuPrivacySandbox show up in the list.
I would like to know what would be a better filter. For reference, this is how the output of sdkmanager --list sort of looks like
platforms;android-27 | 3 | Android SDK Platform 27
platforms;android-28 | 6 | Android SDK Platform 28
platforms;android-29 | 5 | Android SDK Platform 29
platforms;android-30 | 3 | Android SDK Platform 30
platforms;android-31 | 1 | Android SDK Platform 31
platforms;android-32 | 1 | Android SDK Platform 32
platforms;android-33 | 2 | Android SDK Platform 33
It would be like
sdkmanager --list | egrep -i 'platforms;android-[0-9]{2}' | tac | head -n 1 | sed 's/\(platforms;android-[0-9]\+\).*/\1/'
or
sdkmanager --list | egrep -i 'platforms;android-[0-9]{2}' | sed 's/\(platforms;android-[0-9]\+\).*/\1/' | tail -1

How to use local jdk in SDKMAN! script

My script changes to a jdk installed with sdkman but not to a local one. How can I change into my local oracle 8 v261 jdk in a script with sdkman?
The script
#!/bin/bash
. /usr/local/sdkman/bin/sdkman-init.sh
sdk ls java
for i in {"8_261-oracle", "9.0.4-open"}
do
sdk u java $i
done
gives as output
[...]
| | 9.0.4 | open | installed | 9.0.4-open
| >>> | 8.0.265 | open | installed | 8.0.265-open
| | 8.0.232 | open | local only | 8.0.232-open
[...]
Unclassified | | 8_261 | none | local only | 8_261-oracle
================================================================================
Use the Identifier for installation:
$ sdk install java 11.0.3.hs-adpt
================================================================================
Stop! java 8_261-oracle, is not installed.
Using java version 9.0.4-open in this shell.
I was inspired by How to use SDKMAN! to install packages from within scripts.
You could parse the output of sdkman to retrieve the list of installed sdks as follows:
#!/bin/bash
sdks=`sdk list java | grep installed | awk -F"|" '{print $6}'`
for sdk in ${sdks[#]}; do
sdk use java $sdk
### YOUR CODE HERE
done
I have omitted the . /usr/local/sdkman/bin/sdkman-init.sh part because I suggest to set it up in bashrc/zshrc as suggested in sdkman doc.
An example from my ~/.zshrc:
#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="$YOUR_PATH/.sdkman"
[[ -s "$YOUR_PATH/.sdkman/bin/sdkman-init.sh" ]] && source "$YOUR_PATH/.sdkman/bin/sdkman-init.sh"

parse qmake output from bash script

How can I extract the Qt version from a bash script using
qmake -v?
[newton#plex .home] qmake -v
Qmake version: 1.07a (Qt 3.3.6)
Qmake is free software from Trolltech AS.
[newton#plex .home]
edit
sorry, i'm looking for 2.3.6
qmake -v | grep -m1 -o -P "\(Qt [^\)]+" | cut -d" " -f2

Graphviz and ascii output

Is it possible to draw ASCII diagram using Graphviz?
Something like that:
digraph
{
this -> is
this -> a
a -> test
}
Gives undesired result.
Instead, I would like to get similar ASCII representation:
this
/ \
is a
|
test
How to draw ascii diagrams from dot-files format?
If you are not perl averse, graph-easy (and the associated Graph::Easy package) can do exactly that:
http://search.cpan.org/~tels/Graph-Easy/
http://search.cpan.org/~tels/Graph-Easy/bin/graph-easy
On Mac you can install this with Homebrew and cpan:
brew install cpanminus
cpan Graph::Easy
It's easy to invoke after installation:
cat dotfile.dot | /opt/local/libexec/perl5.12/sitebin/graph-easy
Here is equivalent commands for linux:
First install cpanminus
sudo apt install cpanminus
After you can install GraphEasy
sudo cpanm Graph::Easy
Here is a sample usage
cat input.dot | graph-easy --from=dot --as_ascii
By now, in ubuntu, you can install and use graph-easy directly:
> sudo apt install libgraph-easy-perl
[...]
> graph-easy dotfile.dot
+----+ +------+
| is | <-- | this |
+----+ +------+
|
|
v
+------+
| a |
+------+
|
|
v
+------+
| test |
+------+
Another option to use Graph::Easy's ASCII functionality is directly from your browser through this small service that I hosted:
https://dot-to-ascii.ggerganov.com
Using graph-easy via docker. You can install whalebrew and use it to run graph-easy without installing too much dependancies on your local machine other than whalebrew and docker.
on MacOS with homebrew install docker
$ brew install docker
$ docker -v # check if docker is running
Install whalebrew - https://github.com/whalebrew/whalebrew (check installation alternatives)
$ brew install whalebrew
Install graph-easy via whalebrew
$ whalebrew install tsub/graph-easy
Now run it via
$ echo '[a]->[b]' | graph-easy
+---+ +---+
| a | --> | b |
+---+ +---+

How can I specify a display?

When I run some programs over SSH, such as firefox &, I get an error
Error: no display specified
I would like to open many displays, still showing the stdout of each program.
Initial Question: How can I specify the display to get a many-displayed program?
Pablo Santa Cruz gives me the following code as a solution.
I do not understand it.
$ export DISPLAY=yourmachine.yourdomain.com:0.0
$ firefox &
What are yourmachine and yourdomain.com in the command?
The way that X works is the same as the way any network program works. You have a server of some description (in this case, the X display server) which runs on a specific machine, and you have X clients (like firefox) that try to connect to that server to get their information displayed.
Often (on "home" machines), the client and server run on the same box and there's only one server, but X is powerful enough that this doesn't need to happen. It was built with the server/client separation built in from the start.
This allows you to do such wondrous things such as log on to your box (in text mode) halfway around the planet, tell it that the display server is the box you're currently on and, voila, the windows suddenly start appearing locally.
In order for a client to interact with a user, it needs to know how to find the server. There are a number of ways to do this. Many clients allow the -display or --displayoption to specify it:
xeyes -display paxbox1.paxco.com:0.0
Many will use the DISPLAY environment variable if a display isn't specifically given. You can set this variable like any other:
DISPLAY=paxbox1.paxco.com:0.0; export DISPLAY # in .profile
export DISPLAY=paxbox1.paxco.com:0.0 # in your shell
DISPLAY=paxbox1.paxco.com:0.0 firefox & # for that command (shell permitting)
The first part of the DISPLAY variable is just the address of the display server machine. It follows the same rule as any other IP address; it can be a resolvable DNS name (including localhost) or a specific IP address (such as 192.168.10.55).
The second part is X-specific. It gives the X "display" (X server) number and screen number to use. The first (display number) generally refers to a group of devices containing one or more screens but with a single keyboard and mouse (i.e., one input stream). The screen number generally gives the specific screen within that group.
An example would be:
+----------------------------------------+
|paxbox1.paxco.com| |
+-----------------+ |
| |
| +----------+----+ +----------+----+ |
| |Display :0| | |Display :1| | |
| +----------+ | +----------+ | |
| | | | | |
| | +-----------+ | | | |
| | |Screen :0.0| | | | |
| | +-----------+ | | | |
| | +-----------+ | | | |
| | |Screen :0.1| | | | |
| | +-----------+ | | | |
| | +-----------+ | | +-----------+ | |
| | |Screen :0.2| | | |Screen :1.0| | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | |Screen :0.3| | | |Screen :1.1| | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | | Keyboard | | | | Keyboard | | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | | Mouse | | | | Mouse | | |
| | +-----------+ | | +-----------+ | |
| +---------------+ +---------------+ |
| |
+----------------------------------------+
Here you have a single machine (paxbox1.paxco.com) with two display servers. The first has four screens and the second has two. The possibilities are then:
DISPLAY=paxbox1.paxco.com:0.0
DISPLAY=paxbox1.paxco.com:0.1
DISPLAY=paxbox1.paxco.com:0.2
DISPLAY=paxbox1.paxco.com:0.3
DISPLAY=paxbox1.paxco.com:1.0
DISPLAY=paxbox1.paxco.com:1.1
depending on where you want your actual windows to appear and which input devices you want to use.
$ export DISPLAY=yourmachine.yourdomain.com:0.0
$ firefox &
When you are connecting to another machine over SSH, you can enable X-Forwarding in SSH, so that X windows are forwarded encrypted through the SSH tunnel back to your machine. You can enable X forwarding by appending -X to the ssh command line or setting ForwardX11 yes in your SSH config file.
To check if the X-Forwarding was set up successfully (the server might not allow it), just try if echo $DISPLAY outputs something like localhost:10.0.
login to your server via
ssh -X root#yourIP
edit /etc/ssh/sshd_config file, and add this line to it.
X11UseLocalhost no
Restart sshd. for CentOS (check your distribution)
/sbin/service sshd restart
check your DISPLAY
echo $DISPLAY
you should see this
yourIP:10.0
Enjoy
firefox
for more info
Try
export DISPLAY=localhost:0.0
Please do NOT try to set $DISPLAY manually when connecting over SSH.
If you connect via SSH -X and $DISPLAY stays empty, this usually means that no encrypted channel could be established.
Most likely you are missing the package xauth or xorg-x11-xauth. Try to install it on the remote machine using:
sudo apt-get install xauth
or
sudo apt-get install xorg-x11-xauth
After that end and restart your SSH connection. Don't forget to use SSH -X so that X Window output is forwarded to your local machine.
Now try echo $DISPLAYagain to see if $DISPLAY has been set automatically by the SSH demon. It should show you a line with an IP address and a port.
I ran into a similar issue, so maybe this answer will help someone.
The reason for the Error: no display specified error is that Firefox is being launched, but there is no X server (GUI) running on the remote host. You can use X11 forwarding to run Firefox on the remote host, but display it on your local host. On Mac OS X, you will need to download XQuartz in order to use X11 forwarding. Without it, you won't have a $DISPLAY variable set, so if you try and echo $DISPLAY, it will be blank.
Try installing the xorg-x11-xauth package.
I faced similar problem today. So, here's a simple solution:
While doing SSH to the machine, just add Ctrl - Y.
ssh user#ip_address -Y
After login, type firefox &.
And you are good to go.
Even i faced the same in CentOS 6.8.
yum reinstall xorg*
End your current session and open another session in tool like mobiXterm. Make sure session has X11 forwarding enabled in the tool.
I through vnc to understand the X11 more.
To specify the display to get a many-displayed program,
export DISPLAY=IP:DisplayNum.ScreenNum
For example,
vncserver :2
vncserver -list
echo '$DISPLAY'=$DISPLAY
export DISPLAY=:2 # export DISPLAY=IP:DisplayNum or export DISPLAY=:DisplayNum for localhost; So that can vnc connect and see the vnc desktop :2 if $DISPLAY is not :2.
echo '$DISPLAY'=$DISPLAY
I'm using xming server before typing firefox use the following command
export DISPLAY=0:0

Resources