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

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 .

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.

golang binary not running on mips

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.

How to cross compile solaris 32-bit

We are currently building our Go executables for several platforms including Solaris 64-bit. We have requests for a 32-bit Solaris executable version as well and I am unable to get this to work (the person who setup the Solaris 64-bit cross compiler is gone and unreachable).
I tried just setting -m32 flag on go build using our existing solaris cross compilation, but that didn't work, so I am attempting to build a Solaris 32-bit specific cross compiler.
I googled and found some vague examples, so I am following this process:
Copy headers and libraries from a 32-bit Solaris machine to my Linux build machine.
D/L and build binutils and gcc pointing SYSROOT to the downloaded 32-bit Solaris headers and libraries where:
$TARGET=sparc-sun-solaris2.10
$SYSROOT=/path/to/solaris32/includes
$PREFIX=/path/to/gcc-output
binutils-2.31/configure -target=$TARGET --prefix=$PREFIX -with-sysroot=$SYSROOT -v
gcc-8.2.0/configure --target=$TARGET --with-gnu-as --with-gnu-ld --prefix=$PREFIX -with-sysroot=$SYSROOT --disable-libgcj --enable-languages=c,c++,go -v
Create a symlink to gogcc and put GCC on the path
Compile a trivial test go program like this:
go build --compiler gccgo --gccgoflags "-m32 -O3 -static-libgo -Wl,-dy -lnsl -lsocket -lrt -lsendfile" -o ${GOTOOLS}/${BINARIES}/${PROJECT_NAME}/test/solaris_sparc32 test/main.go
This fails as follows:
go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags
command-line-arguments
gccgo: error: may not use both -m32 and -m64
Clearly I don't know what I'm doing. Can anyone point me in the right direction?
Solaris 32-bit does not appear to be supported, according to the list of supported OS/arch targets:
The valid combinations of $GOOS and $GOARCH are:
$GOOS $GOARCH
...
solaris amd64
...
That is, Solaris 64-bit is explicitly listed as a supported platform but Solaris 32-bit is not listed.
As such, there is good reason to believe that go programs will not run reliably on Solaris 32-bit systems and you probably should not agree to support that platform (if you do happen to get that cross compilation working) mainly because the go team itself does not support it!

Mac OSX 10.6 compiler: a puzzling experience with 32 vs 64 bit

I have trouble understanding the gcc compiler provided by OSX 10.6 snow leopard, mainly because of my lack of experience with 64 bits environments.
$ cat >foo.c
main() {}
$ gcc foo.c -o foo
$ file foo
foo: Mach-O 64-bit executable x86_64
$ lipo -detailed_info foo
input file foo is not a fat file
Non-fat file: foo is architecture: x86_64
However, my architecture is seen as an intel i386 type (I have one of the latest Intel Core2 duo MacBook)
$ arch
i386
and the compiler targets i686-apple-darwin10
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)
Of course, if I compile 32 bits I get a 32 bit executable.
$ gcc -m32 foo.c -o foo
$ file foo
foo: Mach-O executable i386
but I don't get the big picture. The default setup for the compiler is to produce x86_64 executables, even if I have arch saying I have a 32 bit machine (why? Core2 is 64); even if (I guess) I am running a 32 bit kernel; even if I have a compiler targeting the i686-apple-darwin platform. Why? How can they run ? Should I compile 64 or 32 ?
This question is due to my attempt to compile gcc 4.2.3 on the mac, but I am having a bunch of issues with gmp, mpfr and libiberty getting (in some cases) compiled for x86_64. Should I compile everything x86_64 ? If so, what's the target (not i686-apple-darwin10 I guess)?
Thanks for the help
The default compiler on Snow Leopard is gcc4.2, and its default architecture is x86_64. The typical way to build Mac software is to build multiple architectures in separate passes, then use lipo to combine the results. (lipo only compiles single-arch files into a multiple-arch file, or strips archs out of a multi-arch file. It has no utility on single-arch files, as you discovered.)
The bitness of the compiler has nothing to do with anything. You can build 32-bit binaries with a 64-bit compiler, and vice versa. (What you think is the "target" of the compiler is actually its executable, which is different.)
The bitness of the kernel has nothing to do with anything. You can build and run 64-bit binaries when booted on a 32-bit kernel, and vice versa.
What matters is when you link, whether you have the appropriate architectures for linking. You can't link 32-bit builds against 64-bit binaries or vice versa. So the important thing is to see what the architectures of your link libraries are, make sure they're coherent, then build your binary of the same architecture so you can link against the libraries you have.
i686-apple-darwin10.0.0 contains an x86_64 folder which is not understood by most versions of autotools. In other words, I'd say that the gcc compiler is unfortunately nothing short of a joke on Snow Leopard. Why you would bundle 32-bit and 64-bit libraries into i686-apple-darwin10.0.0 is beyond me.
$ ls /usr/lib/gcc
i686-apple-darwin10 powerpc-apple-darwin10
You need to change all your autotools configure files to handle looking in *86-darwin directories and then looking for 64-bit libraries I'd imagine.
As with your system, my mac mini says its i386 even though its obviously using a 64-bit platform, again another mistake since its distributed with 64-bit hardware.
$arch
i386
Apple toolchains support multiple architectures. If you want to create a fat binary that contains x86 and x86_64 code, then you have to pass the parameters -arch i386 -arch x86_64 to gcc. The compiler will compile your code twice for both platforms in one go.
Adding -arch i386 -arch x86_64 to CFLAGS may allow you to compile gmp, mpfr, and whatnot for multiple archs in one go. Building libusb that way worked for me.
This answer is wrong, but see comments below
The real question is... how did you get a 32-bit version of OSX? I wasn't aware that Snow Leopard had a 32-bit version, as all of Apple's Intel chips are Core 2 or Xeon, which support the x86_64 architecture.
Oh, and Snow Leopard only works on Intel chips.
Edit: Apparently Snow Leopard starts in 32-bit mode.

Building crti.o for i386

I am trying to build a cross-compiler with x86_64 being the host and i386 being the target. I'm getting the (all to common) crti.o: No such file error. Instead of grabbing an already built crti.o and crtn.o from a distro... how might I go about building these files explicitly from glibc (or possibly gcc) sources?
FYI, I am well aware of the -m32 option for x86_64 compilers. I'd prefer to just have a 32bit-only compiler environment. Also, the reason I don't want to use any of the gazillion already build i386 compilers is because I plan on mixing and matching glibc/binutils/gcc versions depending on my testing needs.
Thanks,
Chenz
Here's one possibility (from here)
You need to install your distro's 32
bit libc-dev package, or you need to
--disable-multilib which will result in a compiler that doesn't support 32
bit mode.
Are you sure you're using configuring the cross-compile correctly? It should be
CBUILD = CHOST = x86_64-pc-linux-gnu
CTARGET = i386-pc-linux-gnu
as you're running a build on an x86_64, for a compiler to run on an x86_64, which generates code for an i386.
If you used CHOST = i386-pc-linux-gnu, you'll be trying to generate 32-bit binaries, which will need to link with a 32-bit libc. Which is fine, if you already have a 32-bit libc, but it sounds like you don't.
i.e.
$ tar xvjf gcc-*.tar.bz2
$ cd gcc-*/
$ mkdir build
$ cd build
$ ../configure --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=i386-pc-linux-gnu

Resources