How to Build Upstream Docker on Ubuntu for Power (ppc64) Servers

With the latest version of gcc (version 5.0 onwards) for Go language having all the required Power (ppc64) architecture specific support, now part of Ubuntu 15.04 LE (ppc64el), its very easy to build upstream docker sources. Note that official gccgo based build support for docker is still work in progress. Consequently you’ll need out-of-tree gccgo build scripts for docker.

Here are the steps.

Install build essentials

$sudo apt-get install gccgo-5 binutils libsqlite3-dev btrfs-tools libdevmapper-dev

Note that the gccgo package is named as gccgo-5.

Create symlinks for gccgo-5, go-5 and gofmt-5

$sudo ln -s /usr/bin/gccgo-5 /usr/bin/gccgo
$sudo ln -s /usr/bin/go-5 /usr/bin/go
$sudo ln -s /usr/bin/gofmt-5 /usr/bin/gofmt

Setup required directories

$mkdir -p ~/docker.bld/src/github.com/docker

Clone the docker source in the appropriate location

$cd ~/docker.bld/src/github.com/docker

$git clone https://github.com/docker/docker.git

 

[ Update – Initial gccgo build support is now part of docker with merging of the following PR – https://github.com/docker/docker/pull/11298

You need to simply run ./project/make.sh dyngccgo to build docker daemon with gccgo ]

 

The steps below will work with the latest commit [52f6da223839a5ac1fc003b259b74f6a02fc2858] as of this writing.

The patch is very simple and can be easily ported to any new version till gccgo build support is part of mainline docker code.

Basically the patch sets few global variables to use gccgo and uses the right build options for gccgo.

diff --git a/project/make.sh b/project/make.sh
index 0db70a7..a337ae2 100755
--- a/project/make.sh
+++ b/project/make.sh
@@ -77,6 +77,12 @@ else
 	exit 1
 fi
 
+case `uname -m` in
+        ppc64*)
+                USE_GCCGO=1;;
+esac
+
+
 if [ "$AUTO_GOPATH" ]; then
 	rm -rf .gopath
 	mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
diff --git a/project/make/.dockerinit b/project/make/.dockerinit
index f98158d..5b9d52d 100644
--- a/project/make/.dockerinit
+++ b/project/make/.dockerinit
@@ -5,15 +5,27 @@ IAMSTATIC="true"
 source "$(dirname "$BASH_SOURCE")/.go-autogen"
 
 # dockerinit still needs to be a static binary, even if docker is dynamic
-go build \
-	-o "$DEST/dockerinit-$VERSION" \
-	"${BUILDFLAGS[@]}" \
-	-ldflags "
-		$LDFLAGS
-		$LDFLAGS_STATIC
-		-extldflags \"$EXTLDFLAGS_STATIC\"
-	" \
-	./dockerinit
+if [ -z "$USE_GCCGO" ]; then
+	go build \
+		-o "$DEST/dockerinit-$VERSION" \
+		"${BUILDFLAGS[@]}" \
+		-ldflags "
+			$LDFLAGS
+			$LDFLAGS_STATIC
+			-extldflags \"$EXTLDFLAGS_STATIC\"
+		" \
+		./dockerinit
+else
+	go build -compiler gccgo \
+		-o "$DEST/dockerinit-$VERSION" \
+		"${BUILDFLAGS[@]}" \
+		-gccgoflags "
+			-g
+			$EXTLDFLAGS_STATIC_DOCKER
+		" \
+		./dockerinit
+fi
+
 echo "Created binary: $DEST/dockerinit-$VERSION"
 ln -sf "dockerinit-$VERSION" "$DEST/dockerinit"
 
diff --git a/project/make/binary b/project/make/binary
index 06d640d..5b6da8d 100755
--- a/project/make/binary
+++ b/project/make/binary
@@ -13,14 +13,29 @@ fi
 
 source "$(dirname "$BASH_SOURCE")/.go-autogen"
 
-go build \
-	-o "$DEST/$BINARY_FULLNAME" \
-	"${BUILDFLAGS[@]}" \
-	-ldflags "
-		$LDFLAGS
-		$LDFLAGS_STATIC_DOCKER
-	" \
-	./docker
+if [ -z "$USE_GCCGO" ]; then
+	go build \
+		-o "$DEST/$BINARY_FULLNAME" \
+		"${BUILDFLAGS[@]}" \
+		-ldflags "
+			$LDFLAGS
+			$LDFLAGS_STATIC_DOCKER
+		" \
+		./docker
+else
+	go build -compiler gccgo \
+		-o "$DEST/docker-$VERSION" \
+		"${BUILDFLAGS[@]}" \
+		-gccgoflags "
+			$EXTLDFLAGS_STATIC_DOCKER
+			-ldl
+			-lselinux
+			-lsepol
+			-lpcre
+		" \
+		./docker
+fi
+
 echo "Created binary: $DEST/$BINARY_FULLNAME"
 ln -sf "$BINARY_FULLNAME" "$DEST/docker$BINARY_EXTENSION"
 
diff --git a/project/make/dynbinary b/project/make/dynbinary
index 861a192..8061824 100644
--- a/project/make/dynbinary
+++ b/project/make/dynbinary
@@ -16,6 +16,7 @@ fi
 (
 	export IAMSTATIC="false"
 	export LDFLAGS_STATIC_DOCKER=''
+	export EXTLDFLAGS_STATIC_DOCKER=''
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
 	source "$(dirname "$BASH_SOURCE")/binary"


Export environment variables

$export GOPATH=~/docker.bld/src/github.com/docker/docker/vendor:~/docker.bld/
$export DOCKER_BUILDTAGS=”btrfs_noversion”

Build dynamically linked docker binary

$curl https://github.com/docker/docker/compare/master…bpradipt:gccgo-build-2.patch | patch -p1

$cd ~/docker.bld/src/github.com/docker/docker

$project/make.sh dynbinary

docker and dockerinit binaries will be available in bundles/1.5.0-dev/dynbinary.

Pretty straight forward.

Pradipta Kumar Banerjee

I'm a Cloud and Linux/ OpenSource enthusiast, with 16 years of industry experience at IBM. You can find more details about me here - Linkedin

You may also like...