Last two months , We have been working on the localization project , hold golang Developed program , Running on domestic platform , Operating systems are basically based on Linux, however CPU Architecture besides x86, also ARM and MIPS, Our usual Golang All run on x86 
&& x64  Architecture CPU upper , So there are many pitfalls in the process of transplantation , Recorded here .
 <>Golang Cross compiling 
 <> Cross compiling 
 stay X64 On ubuntu 16.04 The executable programs of other platforms are compiled on the system 
 <> see Golang Supported platforms and versions 
go tool dist list 
 This command lists all go Language supported operating system and cpu framework 
 <>golang Cross compilation of 
 actually go Cross compiling is very simple , You just need to specify the system and CPU framework , There's basically no problem , After compiling, the file can be copied to the corresponding platform :
GOOS=linux GOARCH=arm64 go build xxx.go #  Sometimes it needs to be added CGO_ENABLE=0 CGO_ENABLE=0 
GOOS=linux GOARCH=arm64 go build xxx.go 
go The cross compiler support of the language is very good , As long as you follow the above steps, there will be no problem . pit , It's mainly in the pit cgo!
 <> use cgo Cross compilation of 
 use cgo, It must be specified CGO_ENABLE=1. And must be specified CC The parameter is the gcc Cross compiler for .
  Suppose we mutate 64 position ARM The program of the platform , You have to download it in advance aarch64 Version of c++ Cross compiler tool 
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=
./aarch64-unknown-linux-gnueabi-5.4.0-2.23-4.4.6/bin/aarch64-unknown-linux-gnueabi-gcc 
go build xxx.go 
 If the CGO Called C The program depends on various libraries , Then the compilation process will report errors for various dependent libraries not found , Various basic functions are undefined . And they are the most basic libraries in the system, such as 
libglibc,libgstream etc .
 The solution is that it must be at compile time , Add the parameters of the link library , The linked library must cross compile the system library of the target platform instead of the current system .
 This is when downloading the cross compiler tool chain , It usually comes with , I put it in the root of the system , And then through C++ The syntax of linking libraries at compile time links libraries in :
  There are three main parameters :-I , -isystem , -L, -l
  The following command is an example , Suppose the project uses phnono,curl,protobuf And other components 
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=
./aarch64-unknown-linux-gnueabi-5.4.0-2.23-4.4.6/bin/aarch64-unknown-linux-gnueabi-gcc 
-Wall -std=c++11 -Llib -isystem/aarch64/usr/include -L/aarch64/lib -ldl 
-lpthread -Wl,-rpath-link,/aarch64/lib -L/aarch64/lib/aarch64-linux-gnu 
-L/aarch64/usr/lib -I/aarch64/usr/include -L/aarch64/usr/lib/aarch64-linux-gnu 
-ldl -lpthread -Wl,-rpath-link,/aarch64/usr/lib/aarch64-linux-gnu -lphonon 
-lcurl -lprotobuf go build xxx.go 
 So far , Basically solve the problem of unable to compile .
 <> Platform differences 
 In compiling ARM Version of the code , Several system calls were not found 
 * undefined: syscall.Dup2
 * undefined: syscall.SYS_FORK 
 Solution : contrast golang Source code implementation :go/src/syscall/zsyscall_linux_amd64.go and 
go/src/syscall/zsyscall_linux_arm64.go
, find arm Platform not implemented Dup2 But it does Dup3, The parameters are slightly different , The solution is to modify where the call is made :
// - syscall.Dup2(oldfd, newfd)  Amend to read : syscall.Dup3(oldfd,newfd,0) 
 and SYS_FORK Call to , Find out golang Of ARM Realization is not realized at all fork System call for , No, SYS_FORK This macro or an alternative .
  I have no choice but to modify the project code , take fork The system call of is changed to another way .
 <>MIPS The size of the problem 
 report errors :go.o: compiled for a big endian system and target is little endian
  Mainly reflected in the size of the end of the byte order , This is me cross compiling Mips A problem of version discovery , A close look at my compile command shows that :
CGO_ENABLED=1 GOOS=linux GOARCH=mips64 CC=
./mips64el-unknown-linux-gnu-5.4.0-2.12-2.6.32/bin/mips64el-unknown-linux-gnu-gcc 
go build xxx.go 
 In the order here :CC What is specified is mips64el Compiler for ,el Represents the small end byte order , and GOARCH=mips64 This is the big endian order , Compilation error caused by inconsistency ,
  Solution :go and gcc Maintaining unity , Subject to the target platform ( Loongson is small end byte order )
 *  take GOARCH Designated as mips64le( Note that le no el)
 *  It's better to add LDFLAG=-EL CGO_ENABLED=1 GOOS=linux GOARCH=mips64le CC=
./mips64el-unknown-linux-gnu-5.4.0-2.12-2.6.32/bin/mips64el-unknown-linux-gnu-gcc 
LDFLAGS=-EL go build xxx.go 
 <>Tips
 in summary :
 * golang Program development uses less native system calls syscall
 *  It works go Solved , Don't use it as much as possible cgo
 *  If there is a module, it must pass C/C++ call , recommend C++ and golang separate ,C++ and Golang Use between programs socket And so on  
Technology