golang binary not running on mips - go

I'm using Go 1.11.4 on Windows 10 and I want to compile code for a MIPS 74Kc processor (Qualcomm Atheros QCA9558) running Linux. I compile with:
GOOS=linux GOARCH=mips go build
Get an executable, upload and run it and get:
Illegal instruction
Try again w/ GOARCH=mipsle and get:
./hello_mipsle_linux: line 1: syntax error: unexpected "("
What am I missing?

My host doing the build had an FPU but the board does not. Adding GOMIPS=softfloat fixed it:
GOOS=linux GOARCH=mips GOMIPS=softfloat go build

To list all possible MIPS architects available to your current build toolchain, use the go tool e.g.
$ go version
go version go1.12 darwin/amd64
$ go tool dist list | grep mips
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
so probably one of the remaining GOARCH permutations you have not tried e.g. mips64 or mips64le.
uname -m would help to determine your target system's machine architecture.

I have a similar issue and it's solved by setting GOARCH=mipsle. This should work
GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build
My core is MIPS 24KEc V5.0, see my blog https://zyfdegh.github.io/post/202002-go-compile-for-mips/
If it's not OK, try these steps
Check the CPU architecture, Big-Endian or Little-Endian, by
$ lscpu | grep "Byte Order"
cat /proc/cpuinfo would also be helpful.
Check kernel info, mips or mips64, for me it's mips (32)
$ uname -a
Linux OpenWrt 4.14.151 #0 Tue Nov 5 14:12:18 2019 mips GNU/Linux
If it's Little-Endian, set GOARCH=mipsle, if it's 64bit Little-Endian, set set GOARCH=mips64le
Another related question Writing and Compiling Program For OpenWrt hope it helps.

Related

How build lib for 386 arch with cgo on windows?

I have a golang library that builds and works well on Linux, MacOs and Windows. The problem comes when I'm trying to build it for 386 on the amd64 Windows VM. I've installed latest golang SDK and mingw, which makes amd64 build work fine, but not the 386:
PS > gcc -v
gcc.exe (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders) 11.2.0
PS > go version
go version go1.18.3 windows/amd64
PS > $Env:GOOS = "windows"; $Env:GOARCH = "386"; $Env:CGO_ENABLED ="1"; go build -v -buildmode=c-shared -ldflags="-s -w" -gcflags="-l" -o xyz_amd64.dll xyz_win_dll.go
...
runtime/cgo
c:/programdata/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible c:/pro
gramdata/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/lib/libmingwthrd.a when searching for -lmingwt
hrd
...
<a lot of skipping incompatible messages here>
collect2.exe: error: ld returned 1 exit status
How to fix it? AFAIK it should be possible to build for both arch on the same box.
Cgo build fail, I solve it by this way: firstly, ensure build C code successfully.
generally, cgo cross compilation require C cross compilation and Go cross compilation . maybe you can add set // #cgo CFLAGS:C_CrossBuild_Parameters.
As you can see, it's not easy. It's why Cross compilation goes out the window
I've found the diff in the project description and switched to https://www.mingw-w64.org/. It contains libs for both arch 386 and x64. Now across compilation works fine to me.

Section `text` will not fit after upgrading `arm-none-eabi-gcc`

I have an open source micromouse robot project. For easier compilation, I use containers (both Podman and Docker should be fine):
make image
make libopencm3
make
This works just fine and generates a main.elf file about 874 kB in size. But that is as long as I fix the arm-none-eabi-gcc-cs to 7.4.0 in the Dockerfile.
If I remove the specific version or set it to 9.2.0, then I get the following error:
$ make
/usr/lib/gcc/arm-none-eabi/9.2.0/../../../../arm-none-eabi/bin/ld: main.elf section `.text' will not fit in region `rom'
/usr/lib/gcc/arm-none-eabi/9.2.0/../../../../arm-none-eabi/bin/ld: region `rom' overflowed by 5288 bytes
collect2: error: ld returned 1 exit status
make: *** [opencm3/libopencm3.rules.mk:204: main.elf] Error 1
What could have changed between those versions?
If I add this line to my Makefile:
LDFLAGS += -specs=nano.specs
Then it compiles just fine with version 9.2.0 and generates a main.elf file about 885 kB in size. But I wonder if the performance would be the same (or equivalent) as before.
Update
I am expecting some performance differences, of course, just like I was expecting some differences in the binary size. But I was wondering if I could expect a higher than 20% difference in performance (specially if it could be now 20% slower).
The new binary is less than 2% bigger, and I would consider this to be "the same" as before. :-D
I do perfectly understand you want to use the latest and greatest toolchain from your prefered, mainstream Linux distribution, but this is not always going well.
In my humble opinion, you should:
stick to Linaro or ARM gcc toolchains,
in the case of your specific cortex-m related project, stick to a gcc toolchain more specifically targeting the cortex-m, i.e. the so called 'GNU Arm Embedded Toolchain'.
Some remarks:
There are probably excellent reasons why ARM itself is providing two specifics toolchains for the two profiles,
Latest GCC toolchain version available from Linaro is 7.4.1, but if they used to point to it by default on this page, they now pointing to version 7.2.1, which may (or not) ring a bell regarding 7.4.1 - there are no official 9.2 versions available yet.
Latest GCC toolchain available from ARM is 8.3.1 for cortex-m, and 8.3 for cortex-a - there are no official 9.2 versions available yet.
Back to your specific issue now: I was able to compile your project using the following steps:
wget "https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2019q3/RC1.1/gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2?revision=c34d758a-be0c-476e-a2de-af8c6e16a8a2?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,8-2019-q3-update" -O gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2
mkdir -p /opt/arm
tar jxf gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2 -C /opt/arm
export PATH=/opt/arm/gcc-arm-none-eabi-8-2019-q3-update/bin:$PATH
Command which arm-none-eabi-gcc should display /opt/arm/gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi-gcc.
git clone --recurse-submodules https://github.com/Bulebots/bulebule.git
cd bulebule
scripts/setup_libopencm3.sh
make -s -C src/
Command arm-none-eabi-size ./src/main.elf should display:
text data bss dec hex filename
55152 3336 7100 65588 10034 ./src/main.elf
Please note that there is a Docker file for the latest GCC toolchain from ARM targeting the cortex-m profile here. You may want to use it in your own Docker file and remove those two lines:
arm-none-eabi-gcc-cs-7.4.0 \
arm-none-eabi-newlib-3.1.0-2.fc30 \
I hope this helps.

Cross-compile to ARMv7 failed

I try to compile a go program on my Linux desktop (Linux desktop 4.10.0-28-generic #32-Ubuntu SMP Fri Jun 30 05:32:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux), go version go version go1.8.3 linux/amd64 to arm:
$ GOPATH=/home/xrfang/git/hermes/ GOARM=7 GOARCH=arm go build .
the executable is generated, but seems NOT ARMv7:
$ file hermes
hermes: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
It shows EABI5. How can I cross-compile to ARMv7? Is there anything missing on my Linux Desktop so that the cross-compile fallback to a lower ARM version?
Thanks.
I believe, it is not ARMv5. I was trying to do the same on MAC OS and 'file' command on Mac is saying v7, but the 'file' command on Linux don't. However, I do know that v7 has some good improvements and may boost the performance of your program.
But, that is out of scope of this question and you may need to dig deeper into what you're doing and why a performance improvement is expected.
All I can say is, it is compiled for v7.

How do I make `go get` to build against x86_64 instead of i386

I am trying to use either go-qml or gotk3 to build a very simple desktop app that can run under OS X. However when I try to use go get to install either library, it will try to build for i386 and skip the libraries that were build against x86_64. I could try to get the 32 bit version of those libraries, but I would prefer to build for 64bit. How do I instruct go get to do so?
The warnings that are followed by errors look lie this:
go get gopkg.in/qml.v1
# gopkg.in/qml.v1
ld: warning: ld: warning: ld: warning: ignoring file /usr/local/Cellar/qt5/5.3.2/lib/QtWidgets.framework/QtWidgets, file was built for x86_64 which is not the architecture being linked (i386): /usr/local/Cellar/qt5/5.3.2/lib/QtWidgets.framework/QtWidgetsignoring file /usr/local/Cellar/qt5/5.3.2/lib/QtGui.framework/QtGui, file was built for x86_64 which is not the architecture being linked (i386): /usr/local/Cellar/qt5/5.3.2/lib/QtGui.framework/QtGuiignoring file /usr/local/Cellar/qt5/5.3.2/lib/QtQuick.framework/QtQuick, file was built for x86_64 which is not the architecture being linked (i386): /usr/local/Cellar/qt5/5.3.2/lib/QtQuick.framework/QtQuick
Set the environment variable GOARCH to the value amd64. This instructs the go command to generate files for amd64. Other valid values for GOARCH are 386 and arm.
F.Y.I.
The Go compilers support the following instruction sets:
amd64, 386
The x86 instruction set, 64- and 32-bit.
arm64, arm
The ARM instruction set, 64-bit (AArch64) and 32-bit.
mips64, mips64le, mips, mipsle
The MIPS instruction set, big- and little-endian, 64- and 32-bit.
ppc64, ppc64le
The 64-bit PowerPC instruction set, big- and little-endian.
riscv64
The 64-bit RISC-V instruction set.
s390x
The IBM z/Architecture.
wasm
WebAssembly.
(from: Introduction | Installing Go from source | Doc # golang.org)
Also, you can go tool dist list to check the available architectures to build in your machine.
$ go tool dist list
aix/ppc64
android/386
android/amd64
android/arm
android/arm64
darwin/amd64
darwin/arm64
dragonfly/amd64
freebsd/386
(* snip *)
To build a static binary for macOS (Intel/ARM64) would be as below. In this manner, I suppose GOOS="darwin" GOARCH="arm64" combination will be for M1 architecture.
MyVar="foo"
CGO_ENABLED=0 \
GOOS="darwin" \
GOARCH="amd64" \
GOARM="" \
go build \
-ldflags="-s -w -extldflags \"-static\" -X 'main.myVar=${MyVar}'" \
-o="/path/to/export/bin/myApp" \
"/path/to/main.go"
To compile for Linux on ARM v6, such as RaspberryPi Zero W, the combination would be as below.
$ CGO_ENABLED=0 GOOS="linux" GOARCH="arm" GOARM="6" go build .

bash: ./mips-linux-gnu-gcc: cannot execute binary file error

I've recently installed a mips-linux-gnu-gcc crosstool in my linux machine which is based on i686. When I want to compile some codes, it showed me that error.
Every installing step was followed by http://developer.mips.com/tools/compilers/open-source-toolchain-linux/
After I installed the crosstool, I wrote a simple helloworld C file like this:
#include<stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
But when I run:
/mips-linux-gnu-gcc hello.c -o hello -static
The compiler just print error:
bash: ./mips-linux-gnu-gcc: cannot execute binary file
I'm wondering maybe I've made some mistakes in some steps, but I can't figure it out.
Maybe some of you can help me, I'm confused by the problem.
The compiler you downloaded from MIPS is a 64-bit executable. Are you running a 32-bit host?
If you need a cross compiler for a 32-bit host targeting MIPS GNU/Linux, consider using the Sourcery CodeBench Lite compiler for MIPS GNU/Linux targets:
Sourcery CodeBench Lite for MIPS GNU/Linux
The link to the Sourcery CodeBench tools above comes from the MIPS pages just one level up from the link you provided:
MIPS Compilers Page
It looks like the mips-linux-gnu-gcc binary does not match the architecture of the machine you are trying to run it on. This might be something like a 32/64 bit mismatch.
Try using the free Mentor/Codesourcery MIPS gnu/gcc cross compilation tool chain instead. You can download from here.

Resources