Skip to content

Commit

Permalink
buildx: add build speed for LC
Browse files Browse the repository at this point in the history
Add a tag '_speed_buildx_for_cgo_alpine' for Dockerfiles:
1. require golang with CGO_ENABLED=1
2. use alpine image.

So used in 'build/lc/Dockerfile'

Signed-off-by: llhuii <[email protected]>
llhuii committed Nov 4, 2021

Verified

This commit was signed with the committer’s verified signature. The key has expired.
mgorny Michał Górny
1 parent 7230d06 commit afdd6a2
Showing 2 changed files with 65 additions and 14 deletions.
6 changes: 2 additions & 4 deletions build/lc/Dockerfile
Original file line number Diff line number Diff line change
@@ -13,10 +13,8 @@
# limitations under the License.

# Add cross buildx improvement
# Because LC has built sqlite3 which requires CGO with CGO_ENABLED=1,
# and CGO can't support cross compilation,
# NO speed support for LC.
# TODO: add https://musl.cc/ cross compilation tool
# LC has built sqlite3 which requires CGO with CGO_ENABLED=1
# _speed_buildx_for_cgo_alpine_
FROM golang:1.14-alpine3.11 AS builder
LABEL stage=builder

73 changes: 63 additions & 10 deletions hack/lib/buildx.sh
Original file line number Diff line number Diff line change
@@ -36,21 +36,73 @@ sedna::buildx::prepare_env() {
docker buildx use $builder_instance
}

_speed_buildx_for_go_() {
# docker speed build command for go
echo 'go env -w GOOS="$TARGETOS" GOARCH="$TARGETARCH"' | _feed_to_dockerfile_RUN_command
}

_speed_buildx_for_cgo_alpine_() {
# docker speed build command for go with CGO_ENABLED=1 and alpine image

cat <<'EOF' | _feed_to_dockerfile_RUN_command
# download cc(cross compiler) from https://musl.cc
# the example url: https://musl.cc/aarch64-linux-musl-cross.tgz
apk add curl
# translate some architecture names
arch=$(echo $TARGETARCH | sed "s@arm64@aarch64@")
cc_url=$(curl musl.cc | grep /${arch}-${TARGETOS}-.*-cross)
cc_filename=$(basename $cc_url) # aarch64-linux-musl-cross.tgz
cc_name=$(echo $cc_filename | cut -f1 -d.) # aarch64-linux-musl-cross
# download and extract
curl -O $cc_url; tar xf $cc_filename
# find the real cc name
cc_bin=$PWD/$cc_name/bin # aarch64-linux-musl-cross/bin
export PATH="$cc_bin:$PATH"
# cc=aarch64-linux-musl-cc
# set CC path, and enable CGO
go env -w CC=$(echo $cc_bin/$arch-$TARGETOS-*-cc) CGO_ENABLED=1
go env -w GOOS="$TARGETOS" GOARCH="$TARGETARCH"
EOF
}

_feed_to_dockerfile_RUN_command() {
# add '; \' for each command line
speed_switch_cmd='RUN test "$TARGETPLATFORM" = "$BUILDPLATFORM" || ('
printf "$speed_switch_cmd"
while read run_cmd; do
run_cmd=$(echo "$run_cmd" | sed 's@^\s*@@;s@\s*$@@;') # skip leading/trailing spaces
run_cmd="${run_cmd%# *}" # skip comment
run_cmd="${run_cmd%#;}" # skip trailing ';'

# skip empty command
[ -n "${run_cmd}" ] && {
echo "$run_cmd; \\\\"
}
done
printf ")"
}

sedna::buildx:generate-speed-dockerfile() {
# Add buildx improvement for cross compilation if Dockerfile is added by the specified tag
# see more details for buildx https://github.com/docker/buildx#building-multi-platform-images
local input_dockerfile=${1}

local -a build_tags_and_cmds=(
local -a speed_tags=(
# The cross buildx tag in Dockerfile, it should be placed at the line before FROM instruction
# e.g. from build/gm/Dockerfile
# # _speed_buildx_for_go_
# FROM golang:1.14-alpine3.11 AS builder

'# _speed_buildx_for_go_'
# go speed tag
_speed_buildx_for_go_

# the coresponding cross build commands
'RUN test -z "$TARGETPLATFORM" || go env -w GOOS="$TARGETOS" GOARCH="$TARGETARCH"'
# go speed tag with CGO_ENABLED=1 and alpine image
_speed_buildx_for_cgo_alpine_
)

local base_cmds='
@@ -65,24 +117,25 @@ RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM(=$TARGETO
local from_pattern='^\s*FROM\s' # 0+ leading whitespace, 'FROM' word, a whitespace
local from_part='FROM --platform=$BUILDPLATFORM ' # note tailing space

for((i=0;i<${#build_tags_and_cmds[@]};i+=2)); do
lang_tag_pattern="^${build_tags_and_cmds[i]}"
lang_cmds=${build_tags_and_cmds[i+1]}
for speed_tag in "${speed_tags[@]}"; do
speed_tag_pattern="^# ${speed_tag}$"

if ! grep -q "$lang_tag_pattern" "$input_dockerfile"; then
if ! grep -q "$speed_tag_pattern" "$input_dockerfile"; then
continue
fi

speed_cmds="$($speed_tag)"

cross_cmds="
# generated by sedna::buildx
$base_cmds
$lang_cmds
$speed_cmds
# end generated by sedna::buildx
"

awk -v cross_cmds="$cross_cmds" -v from_part="$from_part" \
"{
if (/$lang_tag_pattern/) {
if (/$speed_tag_pattern/) {
tag_found = 1
}
if (tag_found && sub(/$from_pattern/, from_part)) {

0 comments on commit afdd6a2

Please sign in to comment.