开发环境介绍

  • 主机操作系统:Ubuntu14.04 64位
  • 目标平台:IMX.6Q ARM Cortex-A9内核
  • 交叉工具链:arm-poky-linux-gnueabi,gcc4.9.1
  • Go版本:go1.13
  • 编译时间:2019.10.26

 

主机系统安装Go1.4

     先下载go1.4的源码。因为go1.4版本之后的go语言版本编译器都是使用go语言编写的,使用go语言编译go,go1.4是最后一个使用gcc来编译的版本。所以为了从源代码编译Go需要先编译一个1.4版本的Go版本。

    下载go1.4-bootstrap链接:mirrors.nju.edu.cn/golang/go1.4-bootstrap-20171003.tar.gz

    下载完成之后将得到一个go1.4-bootstrap-20171003.tar.gz压缩包,接下来进行解压编译安装:

 

xxx@ubuntu:~$ export GO_INSTALL_PATH=/usr/local
xxx@ubuntu:~$ sudo tar -zxvf go1.4-bootstrap-20171003.tar.gz -C $GO_INSTALL_PATH
xxx@ubuntu:~$ cd $GO_INSTALL_PATH/go/src
xxx@ubuntu:/usr/local/go/src$ sudo GOOS=linux GOARCH=amd64 ./make.bash

    编译之后将会在$GO_INSTALL_PATH/go/bin目录下生成go命令二进制文件。查看go的版本

xxx@ubuntu:~$ $GO_INSTALL_PATH/go/bin/go version
go version go1.14 linux/amd64

 

编译目标平台Go(ARM)

   完成Go1.4的编译之后,可以利用Go1.4来编译新版本的Go,这里提供Go源代码下载地址

下载地址:mirrors.nju.edu.cn/golang/go1.13rc2.src.tar.gz

  解压源码:

# 设置编译目录
xxx@ubuntu:~$ export GO_BUILD=~/go_build
# 创建编译目录
xxx@ubuntu:~$ mkdir $GO_BUILD
# 解压源码到编译目录
xxx@ubuntu:~$ tar -xvf go1.13rc2.src.tar.gz  -C $GO_BUILD
# 进入源码目录
xxx@ubuntu:~$ cd $GO_BUILD/go/src

设置环境变量

  编译相关环境变量说明:

参数

说明

GOROOT_FINAL

go语言根目录(可不设置)

GOHOSTARCH

主机编译器系统架构

GOARCH

主机系统架构

GOOS

主机操作系统

GO_GCFLAGS

构建软件包和命令时go工具编译参数

GO_LDFLAGS

构建命令时go工具编译参数

CC

主机C编译器

CC_FOR_TARGET

目标系统C编译器

CXX_FOR_TARGET

目标系统C++编译器

PKG_CONFIG

pkg-config工具的路径

GOROOT_BOOTSTRAP

安装目录

GOARM

使用的浮点运算协处理器版本号,只对arm平台有用,可选值有5,6,7

    GOOS     GOARCH的可设置值:

GOOS

GOARCH

darwin

386

darwin

amd64

dragonfly

386

dragonfly

amd64

freebsd

386

freebsd

amd64

freebsd

arm

linux

386

linux

amd64

inux

arm

netbsd

386

netbsd

amd64

netbsd

arm

openbsd

386

openbsd

amd64

plan9

386

plan9

amd64

solaris

amd64

windows

386

windows

amd64

 在$GO_BUILD/go/src创建arm_gcc.sh和arm_g++.sh文件:

hegaozhi@ubuntu:~/go_build/go/src$ cd $GO_BUILD/go/src
# 创建文件
hegaozhi@ubuntu:~/go_build/go/src$ touch arm_gcc.sh arm_g++.sh

在  arm_gcc.sh文件中写入对应C交叉编译器信息:

#!/bin/sh

exec /opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/opt/poky/1.7/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi "$@"

在  arm_g++.sh文件中写入对应C++交叉编译器信息:

#!/bin/sh

exec /opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/opt/poky/1.7/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi "$@"

在终端中输入以下内容设置环境变量:

# 个人交叉编译器信息,非必须
export SDKTARGETSYSROOT=/opt/poky/1.7/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi
export PATH=/opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin:/opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi:$PATH
export PKG_CONFIG_SYSROOT_DIR=$SDKTARGETSYSROOT
export PKG_CONFIG_PATH=$SDKTARGETSYSROOT/usr/lib/pkgconfig
export CONFIG_SITE=/opt/poky/1.7/site-config-cortexa9hf-vfp-neon-poky-linux-gnueabi
export OECORE_NATIVE_SYSROOT="/opt/poky/1.7/sysroots/x86_64-pokysdk-linux"
export OECORE_TARGET_SYSROOT="$SDKTARGETSYSROOT"
export OECORE_ACLOCAL_OPTS="-I /opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/share/aclocal"
export PYTHONHOME=/opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr

#1.4版本的安装路径
export GOROOT_BOOTSTRAP=$GO_INSTALL_PATH/go
# 目标平台C代码编译器信息
export CC_FOR_TARGET=$GO_BUILD/go/src/arm_gcc.sh
# 目标平台C++代码编译器信息
export CXX_FOR_TARGET=$GO_BUILD/go/src/arm_g++.sh
# 目标平台编译器参数,非必须
export GOGCCFLAGS='-march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/opt/poky/1.7/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi -O2 -pipe -g -feliminate-unused-debug-types -fPIC -m64 -fmessage-length=0'

 编译:

hegaozhi@ubuntu:~/go_build/go/src$ CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 ./make.bash

 提示:当选择开启CGO编译时必须配置CC_FOR_TARGET和CXX_FOR_TARGET两个环境变量

    经过编译之后$GO_BUILD/go目录下会生成arm和amd64两个平台的Go命令和依赖包,所以这个版本编译的Go命令可以进行两个平台的Go应用程序开发。

使用新编译的Go1.13版本替换旧的Go1.4:

cd $GO_BUILD
sudo rm $GO_INSTALL_PATH/go -rf
sudo cp -r go $GO_INSTALL_PATH/

 

设置运行环境变量

 在/etc/bash.bashrc文件中添加如下内容(重启命令行后生效)):

export GOROOT_BOOTSTRAP=/usr/local/go
# 为了可以编译CGO的Go应用程序(ARM版本)必须要保留下面的两个环境变量
export CC_FOR_TARGET=$GOROOT_BOOTSTRAP/src/arm_gcc.sh
export CXX_FOR_TARGET=$GOROOT_BOOTSTRAP/src/arm_g++.sh
export GOROOT=/usr/local/go
export GOPATH=/usr/local/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

 

验证Go

# 查看版本
xxx@ubuntu:~$ go version
go version go1.10.3 linux/amd6

# 查看参数
xxx@ubuntu:~$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/hegaozhi/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/local/gopath"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build791570790=/tmp/go-build -gno-record-gcc-switches"

 

编译Helloworld程序,新建helloworld.go文件,并填入如下内容

package main

import "fmt"

func main() {
    fmt.Println("Hello world")
}

编译ARM版本应用程序

xxx@ubuntu:~$ CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 go build helloworld.go

编译完成之后在当前目录下会生成helloworld,将此文件上传到ARM目标文件系统上执行测试。

查看生成helloworld文件属性:

xxx@ubuntu:~/golang$ file helloworld
helloworld: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

 

网络上golang调C例子