Docker Makefile文件结构
来源:互联网 发布:unsw moodle 网络 编辑:程序博客网 时间:2024/06/14 05:40
转自:http://www.tuicool.com/articles/MNNjmiE
这里来分析下docker的Makefile作为之后对于docker实现的一个切入口。
首先是all:
all: build $(DOCKER_RUN_DOCKER) hack/make.sh
build做的操作为:
build: bundles docker build -t "$(DOCKER_IMAGE)" .
bundles做的操作为:
bundles: mkdir bundles
这里有些奇怪,既然我的目的是编译docker,那么这里的docker命令又是哪里来的呢?docker在这里确实很有新意,其编译后并不是安装到本地,而是安装在一个docker container中,因此编译的时候我们得保证有docker安装了才行。
所以这里首先会建立一个bundles目录,然后会执行docker build -t “$(DOCKER_IMAGE)”,也就是生成一个image。默认这个image的名字是docker-dev,也就是这里会从仓库里下载个image。之后DOCKER_RUN_DOCKER,也就是:
DOCKER_RUN_DOCKER := docker run --rm -it --privileged $(DOCKER_ENVS) $(DOCKER_MOUNT) "$(DOCKER_IMAGE)"
会运行这个image,并在里边执行hack/make.sh。因此我们来看下make.sh。
首先是检查下是不是跑在container中:
# We're a nice, sexy, little shell script, and people might try to run us;# but really, they shouldn't. We want to be in a container!if [ "$PWD" != "/go/src/$DOCKER_PKG" ] || [ -z "$DOCKER_CROSSPLATFORMS" ]; then{ echo "# WARNING! I don't seem to be running in the Docker container."echo "# The result of this command might be an incorrect build, and will not be"echo "# officially supported."echo "#"echo "# Try this instead: make all"echo "#"} >&2fiecho
然后是列出了默认要建立的bundle:
# List of bundles to create when no argument is passedDEFAULT_BUNDLES=(validate-dcovalidate-gofmtvalidate-testvalidate-tomlvalidate-vetbinarytest-unittest-integration-clitest-docker-pydynbinarycovercrosstgzubuntu)
接着检查是不是git上拷贝下来的源码:
VERSION=$(< ./VERSION)if command -v git &> /dev/null && git rev-parse &> /dev/null; thenGITCOMMIT=$(git rev-parse --short HEAD)if [ -n "$(git status --porcelain --untracked-files=no)" ]; thenGITCOMMIT="$GITCOMMIT-dirty"fielif [ "$DOCKER_GITCOMMIT" ]; thenGITCOMMIT="$DOCKER_GITCOMMIT"elseecho >&2 'error: .git directory missing and DOCKER_GITCOMMIT not specified'echo >&2 ' Please either build with the .git directory accessible, or specify the'echo >&2 ' exact (--short) commit hash you are building using DOCKER_GITCOMMIT for'echo >&2 ' future accountability in diagnosing build issues. Thanks!'exit 1fi
建立GOPATH目录,我们的可执行文件会被安装到这个下面:
if [ "$AUTO_GOPATH" ]; thenrm -rf .gopathmkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"export GOPATH="${PWD}/.gopath:${PWD}/vendor"fiif [ ! "$GOPATH" ]; thenecho >&2 'error: missing GOPATH; please see https://golang.org/doc/code.html#GOPATH'echo >&2 ' alternatively, set AUTO_GOPATH=1'exit 1fi
检查DOCKER_EXPERIMENTAL是否被设置,如果设置的话打个warning:
if [ "$DOCKER_EXPERIMENTAL" ]; then echo >&2 '# WARNING! DOCKER_EXPERIMENTAL is set: building experimental features' echo >&2 DOCKER_BUILDTAGS+=" experimental"fi
是否要编译daemon:
if [ -z "$DOCKER_CLIENTONLY" ]; then DOCKER_BUILDTAGS+=" daemon"fi
是否是lxc:
if [ "$DOCKER_EXECDRIVER" = 'lxc' ]; then DOCKER_BUILDTAGS+=' test_no_exec'fi
是否能编译btrfs:
# test whether "btrfs/version.h" exists and apply btrfs_noversion appropriatelyif \ command -v gcc &> /dev/null \ && ! gcc -E - &> /dev/null <<<'#include <btrfs/version.h>' \; then DOCKER_BUILDTAGS+=' btrfs_noversion'fi
是否支持延迟remove:
# test whether "libdevmapper.h" is new enough to support deferred remove# functionality.if \ command -v gcc &> /dev/null \ && ! ( echo -e '#include <libdevmapper.h>\nint main() { dm_task_deferred_remove(NULL); }'| gcc -ldevmapper -xc - &> /dev/null ) \; then DOCKER_BUILDTAGS+=' libdm_no_deferred_remove'fi
设置一些编译选项:
# Use these flags when compiling the tests and final binaryIAMSTATIC='true'source "$SCRIPTDIR/make/.go-autogen"if [ -z "$DOCKER_DEBUG" ]; thenLDFLAGS='-w'fiLDFLAGS_STATIC='-linkmode external'# Cgo -H windows is incompatible with -linkmode external.if [ "$(go env GOOS)" == 'windows' ]; thenLDFLAGS_STATIC=''fiEXTLDFLAGS_STATIC='-static'# ORIG_BUILDFLAGS is necessary for the cross target which cannot always build# with options like -race.ORIG_BUILDFLAGS=( -a -tags "netgo static_build $DOCKER_BUILDTAGS" -installsuffix netgo )# see https://github.com/golang/go/issues/9369#issuecomment-69864440 for why -installsuffix is necessary hereBUILDFLAGS=( $BUILDFLAGS "${ORIG_BUILDFLAGS[@]}" )# Test timeout.: ${TIMEOUT:=30m}TESTFLAGS+=" -test.timeout=${TIMEOUT}"# A few more flags that are specific just to building a completely-static binary (see hack/make/binary)# PLEASE do not use these anywhere else.EXTLDFLAGS_STATIC_DOCKER="$EXTLDFLAGS_STATIC -lpthread -Wl,--unresolved-symbols=ignore-in-object-files"LDFLAGS_STATIC_DOCKER="$LDFLAGS_STATIC-extldflags \"$EXTLDFLAGS_STATIC_DOCKER\""
FreeBSD做个特殊处理:
if [ "$(uname -s)" = 'FreeBSD' ]; then# Tell cgo the compiler is Clang, not GCC# https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752export CC=clang# "-extld clang" is a workaround for# https://code.google.com/p/go/issues/detail?id=6845LDFLAGS="$LDFLAGS -extld clang"fi
处理sqlite3.h的路径问题:
# If sqlite3.h doesn't exist under /usr/include,# check /usr/local/include also just in case# (e.g. FreeBSD Ports installs it under the directory)if [ ! -e /usr/include/sqlite3.h ] && [ -e /usr/local/include/sqlite3.h ]; then export CGO_CFLAGS='-I/usr/local/include' export CGO_LDFLAGS='-L/usr/local/lib'fi
根据GO的支持程度设置test相关变量:
HAVE_GO_TEST_COVER=if \ go help testflag | grep -- -cover > /dev/null \ && go tool -n cover > /dev/null 2>&1 \; then HAVE_GO_TEST_COVER=1fi
接着是一些函数定义,大部分都是根据名字就能知道功能的。我们从main开始看:
main() {# We want this to fail if the bundles already exist and cannot be removed.# This is to avoid mixing bundles from different versions of the code.mkdir -p bundlesif [ -e "bundles/$VERSION" ]; thenecho "bundles/$VERSION already exists. Removing."rm -fr "bundles/$VERSION" && mkdir "bundles/$VERSION" || exit 1echofiif [ "$(go env GOHOSTOS)" != 'windows' ]; then# Windows and symlinks don't get along wellrm -f bundles/latestln -s "$VERSION" bundles/latestfiif [ $# -lt 1 ]; thenbundles=(${DEFAULT_BUNDLES[@]})elsebundles=($@)fifor bundle in ${bundles[@]}; doexport DEST="bundles/$VERSION/$(basename "$bundle")"# Cygdrive paths don't play well with go build -o.if [[ "$(uname -s)" == CYGWIN* ]]; thenexport DEST="$(cygpath -mw "$DEST")"fimkdir -p "$DEST"ABS_DEST="$(cd "$DEST" && pwd -P)"bundle "$bundle"echodone}
这里通过for循环一次调用bundle函数,bundle的实现为:
bundle() { local bundle="$1"; shift echo "---> Making bundle: $(basename "$bundle") (in $DEST)" source "$SCRIPTDIR/make/$bundle" "$@"}
bundle数组我们在一开始的时候就列出来了,这里看下binary,对应的文件为hack/make/binary,内容很短:
#!/bin/bashset -eBINARY_NAME="docker-$VERSION"BINARY_EXTENSION="$(binary_extension)"BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"source "${MAKEDIR}/.go-autogen"echo "Building: $DEST/$BINARY_FULLNAME"go build \-o "$DEST/$BINARY_FULLNAME" \"${BUILDFLAGS[@]}" \-ldflags "$LDFLAGS$LDFLAGS_STATIC_DOCKER" \./dockerecho "Created binary: $DEST/$BINARY_FULLNAME"ln -sf "$BINARY_FULLNAME" "$DEST/docker$BINARY_EXTENSION。"hash_files "$DEST/$BINARY_FULLNAME"
可以看到其调用go build直接编译生成docker-$VERSION文件,并做了个软链到$DEST/docker$BINARY_EXTENSION。同时这个命令也告诉了我们编译文件的入口,也就是main文件的位置,就是docker/docker.go。下面要看代码的时候,就从这个docker.go的main开始看咯。
- Docker Makefile文件结构
- android studio 文件结构makefile
- overlay2下docker的文件结构
- Linux内核scripts/Makefile.build文件结构
- NetBSD多文件结构Makefile编写
- 自行编写的Makefile文件的结构
- Makefile结构
- makefile结构
- Makefile 结构
- Docker镜像文件(images)的存储结构
- android 系统 makefile文件(Android.mk)组织结构
- android 系统 makefile文件(Android.mk)组织结构 .
- android 系统 makefile文件(Android.mk)组织结构
- Android 系统 makefile文件(Android.mk)组织结构
- android 系统 makefile文件(Android.mk)组织结构
- android 系统 makefile文件(Android.mk)组织结构
- android 系统 makefile文件(Android.mk)组织结构
- android 系统 makefile文件(Android.mk)组织结构
- CCF NOI1089 高精度运算
- Day 3 网络流
- Spring和MyBatis环境整合
- C++结构体和共用体
- 学习淘淘商城第四十三课(实现从数据库导入数据到索引库)
- Docker Makefile文件结构
- 日历程序
- hibernate里面的一对多和多对一映射
- 卷积
- tomcat结合nginx实现多个tomcat同时运行,tomcat负载均衡
- c++ 字符串分割函数
- Java中的值传递与引用传递详解
- ((n&(n-1))==0)的含义
- 营销红利拐点已至,OV等厂商该如何应对?