github.com/containers/podman/v4@v4.9.4/Makefile (about)

     1  ###
     2  ### Makefile Navigation
     3  ###
     4  #
     5  # This file is organized based on approximate end-to-end workflow:
     6  #
     7  # 1.  Variables and common definitions are located at the top
     8  #     to make finding them quicker.
     9  # 2.  Main entry-point targets, like "default", "all", and "help"
    10  # 3.  Targets for code formatting and validation
    11  # 4.  Primary build targets, like podman and podman-remote
    12  # 5.  Secondary build targets, shell completions, static and multi-arch.
    13  # 6.  Targets that format and build documentation
    14  # 7.  Testing targets
    15  # 8.  Release and package-building targets
    16  # 9.  Targets that install tools, utilities, binaries and packages
    17  # 10. Uninstall / Cleanup targets
    18  #
    19  ###
    20  ### Variables & Definitions
    21  ###
    22  
    23  # Default shell `/bin/sh` has different meanings depending on the platform.
    24  SHELL := $(shell command -v bash;)
    25  GO ?= go
    26  GO_LDFLAGS:= $(shell if $(GO) version|grep -q gccgo ; then echo "-gccgoflags"; else echo "-ldflags"; fi)
    27  GOCMD = CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO)
    28  COVERAGE_PATH ?= .coverage
    29  DESTDIR ?=
    30  EPOCH_TEST_COMMIT ?= $(shell git merge-base $${DEST_BRANCH:-main} HEAD)
    31  HEAD ?= HEAD
    32  PROJECT := github.com/containers/podman
    33  GIT_BASE_BRANCH ?= origin/main
    34  LIBPOD_INSTANCE := libpod_dev
    35  PREFIX ?= /usr/local
    36  RELEASE_PREFIX = /usr
    37  BINDIR ?= ${PREFIX}/bin
    38  LIBEXECDIR ?= ${PREFIX}/libexec
    39  LIBEXECPODMAN ?= ${LIBEXECDIR}/podman
    40  MANDIR ?= ${PREFIX}/share/man
    41  SHAREDIR_CONTAINERS ?= ${PREFIX}/share/containers
    42  ETCDIR ?= /etc
    43  LIBDIR ?= ${PREFIX}/lib
    44  TMPFILESDIR ?= ${LIBDIR}/tmpfiles.d
    45  USERTMPFILESDIR ?= ${PREFIX}/share/user-tmpfiles.d
    46  MODULESLOADDIR ?= ${LIBDIR}/modules-load.d
    47  SYSTEMDDIR ?= ${LIBDIR}/systemd/system
    48  USERSYSTEMDDIR ?= ${LIBDIR}/systemd/user
    49  SYSTEMDGENERATORSDIR ?= ${LIBDIR}/systemd/system-generators
    50  USERSYSTEMDGENERATORSDIR ?= ${LIBDIR}/systemd/user-generators
    51  REMOTETAGS ?= remote exclude_graphdriver_btrfs btrfs_noversion exclude_graphdriver_devicemapper containers_image_openpgp
    52  BUILDTAGS ?= \
    53  	$(shell hack/apparmor_tag.sh) \
    54  	$(shell hack/btrfs_installed_tag.sh) \
    55  	$(shell hack/btrfs_tag.sh) \
    56  	$(shell hack/systemd_tag.sh) \
    57  	$(shell hack/libsubid_tag.sh) \
    58  	exclude_graphdriver_devicemapper \
    59  	seccomp
    60  # N/B: This value is managed by Renovate, manual changes are
    61  # possible, as long as they don't disturb the formatting
    62  # (i.e. DO NOT ADD A 'v' prefix!)
    63  GOLANGCI_LINT_VERSION := 1.55.2
    64  PYTHON ?= $(shell command -v python3 python|head -n1)
    65  PKG_MANAGER ?= $(shell command -v dnf yum|head -n1)
    66  # ~/.local/bin is not in PATH on all systems
    67  PRE_COMMIT = $(shell command -v bin/venv/bin/pre-commit ~/.local/bin/pre-commit pre-commit | head -n1)
    68  ifeq ($(shell uname -s),FreeBSD)
    69  SED=gsed
    70  GREP=ggrep
    71  MAN_L=	mandoc
    72  else
    73  SED=sed
    74  GREP=grep
    75  MAN_L=	man -l
    76  endif
    77  
    78  # This isn't what we actually build; it's a superset, used for target
    79  # dependencies. Basically: all *.go and *.c files, except *_test.go,
    80  # and except anything in a dot subdirectory. If any of these files is
    81  # newer than our target (bin/podman{,-remote}), a rebuild is
    82  # triggered.
    83  SOURCES = $(shell find . -path './.*' -prune -o \( \( -name '*.go' -o -name '*.c' \) -a ! -name '*_test.go' \) -print)
    84  
    85  BUILDTAGS_CROSS ?= containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
    86  CONTAINER_RUNTIME := $(shell command -v podman 2> /dev/null || echo docker)
    87  OCI_RUNTIME ?= ""
    88  
    89  # The 'sort' below is crucial: without it, 'make docs' behaves differently
    90  # on the first run than on subsequent ones, because the generated .md
    91  MANPAGES_SOURCE_DIR = docs/source/markdown
    92  MANPAGES_MD_IN ?= $(wildcard $(MANPAGES_SOURCE_DIR)/*.md.in)
    93  MANPAGES_MD_GENERATED ?= $(MANPAGES_MD_IN:%.md.in=%.md)
    94  MANPAGES_MD ?= $(sort $(wildcard $(MANPAGES_SOURCE_DIR)/*.md) $(MANPAGES_MD_GENERATED))
    95  MANPAGES ?= $(MANPAGES_MD:%.md=%)
    96  MANPAGES_DEST ?= $(subst markdown,man, $(subst source,build,$(MANPAGES)))
    97  
    98  BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
    99  ZSHINSTALLDIR=${PREFIX}/share/zsh/site-functions
   100  FISHINSTALLDIR=${PREFIX}/share/fish/vendor_completions.d
   101  
   102  SELINUXOPT ?= $(shell test -x /usr/sbin/selinuxenabled && selinuxenabled && echo -Z)
   103  
   104  COMMIT_NO ?= $(shell git rev-parse HEAD 2> /dev/null || true)
   105  GIT_COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),$(call err_if_empty,COMMIT_NO)-dirty,$(COMMIT_NO))
   106  DATE_FMT = %s
   107  ifdef SOURCE_DATE_EPOCH
   108  	BUILD_INFO ?= $(shell date -u -d "@$(call err_if_empty,SOURCE_DATE_EPOCH)" "+$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+$(DATE_FMT)" 2>/dev/null || date -u "+$(DATE_FMT)")
   109  else
   110  	BUILD_INFO ?= $(shell date "+$(DATE_FMT)")
   111  endif
   112  LIBPOD := ${PROJECT}/v4/libpod
   113  GOFLAGS ?= -trimpath
   114  LDFLAGS_PODMAN ?= \
   115  	$(if $(GIT_COMMIT),-X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT),) \
   116  	$(if $(BUILD_INFO),-X $(LIBPOD)/define.buildInfo=$(BUILD_INFO),) \
   117  	-X $(LIBPOD)/config._installPrefix=$(PREFIX) \
   118  	-X $(LIBPOD)/config._etcDir=$(ETCDIR) \
   119  	-X $(PROJECT)/v4/pkg/systemd/quadlet._binDir=$(BINDIR) \
   120  	-X github.com/containers/common/pkg/config.additionalHelperBinariesDir=$(HELPER_BINARIES_DIR)\
   121  	$(EXTRA_LDFLAGS)
   122  LDFLAGS_PODMAN_STATIC ?= \
   123  	$(LDFLAGS_PODMAN) \
   124  	-extldflags=-static
   125  #Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too.
   126  LIBSECCOMP_COMMIT := v2.3.3
   127  # Rarely if ever should integration tests take more than 50min,
   128  # caller may override in special circumstances if needed.
   129  GINKGOTIMEOUT ?= -timeout=90m
   130  # By default, run test/e2e
   131  GINKGOWHAT ?= test/e2e/.
   132  GINKGO_PARALLEL=y
   133  GINKGO ?= ./test/tools/build/ginkgo
   134  # ginkgo json output is only useful in CI, not on developer runs
   135  GINKGO_JSON ?= $(if $(CI),--json-report ginkgo-e2e.json,)
   136  
   137  # Allow control over some Ginkgo parameters
   138  GINKGO_FLAKE_ATTEMPTS ?= 3
   139  GINKGO_NO_COLOR ?= y
   140  
   141  # Conditional required to produce empty-output if binary not built yet.
   142  RELEASE_VERSION = $(shell if test -x test/version/version; then test/version/version; fi)
   143  RELEASE_NUMBER = $(shell echo "$(call err_if_empty,RELEASE_VERSION)" | sed -e 's/^v\(.*\)/\1/')
   144  
   145  # If non-empty, logs all output from server during remote system testing
   146  PODMAN_SERVER_LOG ?=
   147  
   148  # Ensure GOBIN is not set so the default (`go env GOPATH`/bin) is used.
   149  override undefine GOBIN
   150  # This must never include the 'hack' directory
   151  export PATH := $(shell $(GO) env GOPATH)/bin:$(PATH)
   152  
   153  GOMD2MAN ?= ./test/tools/build/go-md2man
   154  
   155  # There are many possibly unexpected places where podman is used.  For example
   156  # by OpenWRT for routers and other similar small "edge" devices.  Testing builds
   157  # for otherwise non-mainstream architectures ensures we catch platform-specific
   158  # toolchain shenanigans early, for example:
   159  # https://github.com/containers/podman/issues/8782
   160  CROSS_BUILD_TARGETS := \
   161  	bin/podman.cross.linux.amd64 \
   162  	bin/podman.cross.linux.ppc64le \
   163  	bin/podman.cross.linux.arm \
   164  	bin/podman.cross.linux.arm64 \
   165  	bin/podman.cross.linux.386 \
   166  	bin/podman.cross.linux.s390x \
   167  	bin/podman.cross.linux.mips \
   168  	bin/podman.cross.linux.mipsle \
   169  	bin/podman.cross.linux.mips64 \
   170  	bin/podman.cross.linux.mips64le \
   171  	bin/podman.cross.linux.riscv64 \
   172  	bin/podman.cross.freebsd.amd64 \
   173  	bin/podman.cross.freebsd.arm64
   174  
   175  # Dereference variable $(1), return value if non-empty, otherwise raise an error.
   176  err_if_empty = $(if $(strip $($(1))),$(strip $($(1))),$(error Required variable $(1) value is undefined, whitespace, or empty))
   177  
   178  # Podman does not work w/o CGO_ENABLED, except in some very specific cases.
   179  # Windows and Mac (both podman-remote client only) require CGO_ENABLED=0.
   180  CGO_ENABLED ?= 1
   181  # Default to the native OS type and architecture unless otherwise specified
   182  NATIVE_GOOS := $(shell env -u GOOS $(GO) env GOOS)
   183  GOOS ?= $(call err_if_empty,NATIVE_GOOS)
   184  # Default to the native architecture type
   185  NATIVE_GOARCH := $(shell env -u GOARCH $(GO) env GOARCH)
   186  GOARCH ?= $(NATIVE_GOARCH)
   187  ifeq ($(call err_if_empty,GOOS),windows)
   188  BINSFX := .exe
   189  SRCBINDIR := bin/windows
   190  CGO_ENABLED := 0
   191  else ifeq ($(GOOS),darwin)
   192  BINSFX :=
   193  SRCBINDIR := bin/darwin
   194  CGO_ENABLED := 0
   195  else ifeq ($(GOOS),freebsd)
   196  BINSFX := -remote
   197  SRCBINDIR := bin
   198  RELEASE_PREFIX = /usr/local
   199  else
   200  BINSFX := -remote
   201  SRCBINDIR := bin
   202  endif
   203  # Necessary for nested-$(MAKE) calls and docs/remote-docs.sh
   204  export GOOS GOARCH CGO_ENABLED BINSFX SRCBINDIR
   205  
   206  # Need to use CGO for mDNS resolution, but cross builds need CGO disabled
   207  # See https://github.com/golang/go/issues/12524 for details
   208  DARWIN_GCO := 0
   209  ifeq ($(call err_if_empty,NATIVE_GOOS),darwin)
   210  ifdef HOMEBREW_PREFIX
   211  	DARWIN_GCO := 1
   212  endif
   213  endif
   214  
   215  # gvisor-tap-vsock version for gvproxy.exe and win-sshproxy.exe downloads
   216  # the upstream project ships pre-built binaries since version 0.7.1
   217  GV_VERSION=v0.7.2
   218  
   219  ###
   220  ### Primary entry-point targets
   221  ###
   222  
   223  .PHONY: default
   224  default: all
   225  
   226  .PHONY: all
   227  all: binaries docs
   228  
   229  .PHONY: binaries
   230  ifeq ($(shell uname -s),FreeBSD)
   231  binaries: podman podman-remote ## Build podman and podman-remote binaries
   232  else ifneq (, $(findstring $(GOOS),darwin windows))
   233  binaries: podman-remote ## Build podman-remote (client) only binaries
   234  else
   235  binaries: podman podman-remote podmansh rootlessport quadlet ## Build podman, podman-remote and rootlessport binaries quadlet
   236  endif
   237  
   238  # Extract text following double-# for targets, as their description for
   239  # the `help` target.  Otherwise These simple-substitutions are resolved
   240  # at reference-time (due to `=` and not `=:`).
   241  _HLP_TGTS_RX = '^[[:print:]]+:.*?\#\# .*$$'
   242  _HLP_TGTS_CMD = $(GREP) -E $(_HLP_TGTS_RX) $(MAKEFILE_LIST)
   243  _HLP_TGTS_LEN = $(shell $(call err_if_empty,_HLP_TGTS_CMD) | cut -d : -f 1 | wc -L 2>/dev/null || echo "PARSING_ERROR")
   244  # Separated condition for Darwin
   245  ifeq ($(shell uname -s)$(_HLP_TGTS_LEN),DarwinPARSING_ERROR)
   246  ifneq (,$(wildcard /usr/local/bin/gwc))
   247  _HLP_TGTS_LEN = $(shell $(call err_if_empty,_HLP_TGTS_CMD) | cut -d : -f 1 | gwc -L)
   248  else
   249  $(warning On Darwin (MacOS) installed coreutils is necessary)
   250  $(warning Use 'brew install coreutils' command to install coreutils on your system)
   251  endif
   252  endif
   253  _HLPFMT = "%-$(call err_if_empty,_HLP_TGTS_LEN)s %s\n"
   254  .PHONY: help
   255  help: ## (Default) Print listing of key targets with their descriptions
   256  	@printf $(_HLPFMT) "Target:" "Description:"
   257  	@printf $(_HLPFMT) "--------------" "--------------------"
   258  	@$(_HLP_TGTS_CMD) | sort | \
   259  		awk 'BEGIN {FS = ":(.*)?## "}; \
   260  			{printf $(_HLPFMT), $$1, $$2}'
   261  
   262  ###
   263  ### Linting/Formatting/Code Validation targets
   264  ###
   265  
   266  .PHONY: .gitvalidation
   267  .gitvalidation:
   268  	@echo "Validating vs commit '$(call err_if_empty,EPOCH_TEST_COMMIT)'"
   269  	GIT_CHECK_EXCLUDE="./vendor:./test/tools/vendor:docs/make.bat:test/buildah-bud/buildah-tests.diff:test/e2e/quadlet/remap-keep-id2.container" ./test/tools/build/git-validation -run short-subject -range $(EPOCH_TEST_COMMIT)..$(HEAD)
   270  
   271  .PHONY: lint
   272  lint: golangci-lint
   273  	@echo "Linting vs commit '$(call err_if_empty,EPOCH_TEST_COMMIT)'"
   274  ifeq ($(PRE_COMMIT),)
   275  	@echo "FATAL: pre-commit was not found, make .install.pre-commit to installing it." >&2
   276  	@exit 2
   277  endif
   278  	$(PRE_COMMIT) run -a
   279  
   280  .PHONY: golangci-lint
   281  golangci-lint: .install.golangci-lint
   282  	hack/golangci-lint.sh run
   283  
   284  .PHONY: test/checkseccomp/checkseccomp
   285  test/checkseccomp/checkseccomp: $(wildcard test/checkseccomp/*.go)
   286  	$(GOCMD) build $(BUILDFLAGS) $(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o $@ ./test/checkseccomp
   287  
   288  .PHONY: test/testvol/testvol
   289  test/testvol/testvol: $(wildcard test/testvol/*.go)
   290  	$(GOCMD) build -o $@ ./test/testvol
   291  
   292  .PHONY: volume-plugin-test-img
   293  volume-plugin-test-img:
   294  	./bin/podman build --network none -t quay.io/libpod/volume-plugin-test-img:$$(date +%Y%m%d) -f ./test/testvol/Containerfile .
   295  
   296  .PHONY: test/goecho/goecho
   297  test/goecho/goecho: $(wildcard test/goecho/*.go)
   298  	$(GOCMD) build $(BUILDFLAGS) $(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' -o $@ ./test/goecho
   299  
   300  # The ./test/version/version binary is executed in other make steps
   301  # so we have to make sure the version binary is built for NATIVE_GOARCH.
   302  test/version/version: version/version.go
   303  	GOARCH=$(NATIVE_GOARCH) $(GO) build -o $@ ./test/version/
   304  
   305  .PHONY: codespell
   306  codespell:
   307  	codespell -S bin,vendor,.git,go.sum,.cirrus.yml,"*.fish,RELEASE_NOTES.md,*.xz,*.gz,*.ps1,*.tar,swagger.yaml,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L passt,bu,hastable,te,clos,ans,pullrequest,uint,iff,od,seeked,splitted,marge,erro,hist,ether,specif -w
   308  
   309  .PHONY: validate
   310  validate: lint .gitvalidation validate.completions man-page-check swagger-check tests-included tests-expect-exit pr-removes-fixed-skips
   311  
   312  .PHONY: build-all-new-commits
   313  build-all-new-commits:
   314  	# Validate that all the commits build on top of $(GIT_BASE_BRANCH)
   315  	git rebase $(call err_if_empty,GIT_BASE_BRANCH) -x "$(MAKE)"
   316  
   317  .PHONY: vendor
   318  vendor:
   319  	$(GO) mod tidy
   320  	$(GO) mod vendor
   321  	$(GO) mod verify
   322  
   323  
   324  # We define *-in-container targets for the following make targets. This allow the targets to be run in a container.
   325  # Note that the PODMANCMD can also be overridden to allow a different container CLI to be used on systems where podman is not already available.
   326  IN_CONTAINER_TARGETS = vendor validate
   327  PODMANCMD ?= podman
   328  IN_CONTAINER = $(patsubst %,%-in-container,$(IN_CONTAINER_TARGETS))
   329  
   330  .PHONY: $(IN_CONTAINER)
   331  $(IN_CONTAINER): %-in-container:
   332  	$(PODMANCMD) run --rm --env HOME=/root \
   333  		-v $(CURDIR):/src -w /src \
   334  		--security-opt label=disable \
   335  		docker.io/library/golang:1.18 \
   336  		make $(*)
   337  
   338  
   339  ###
   340  ### Primary binary-build targets
   341  ###
   342  
   343  # Make sure to warn in case we're building without the systemd buildtag.
   344  bin/podman: $(SOURCES) go.mod go.sum
   345  ifeq (,$(findstring systemd,$(BUILDTAGS)))
   346  	@echo "Podman is being compiled without the systemd build tag. \
   347  		Install libsystemd on Ubuntu or systemd-devel on rpm based \
   348  		distro for journald support."
   349  endif
   350  	$(GOCMD) build \
   351  		$(BUILDFLAGS) \
   352  		$(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' \
   353  		-tags "$(BUILDTAGS)" \
   354  		-o $@ ./cmd/podman
   355  
   356  # Disambiguate Linux vs Darwin/Windows platform binaries under distinct "bin" dirs
   357  $(SRCBINDIR):
   358  	mkdir -p $(SRCBINDIR)
   359  
   360  # '|' is to ignore SRCBINDIR mtime; see: info make 'Types of Prerequisites'
   361  $(SRCBINDIR)/podman$(BINSFX): $(SOURCES) go.mod go.sum | $(SRCBINDIR)
   362  	$(GOCMD) build \
   363  		$(BUILDFLAGS) \
   364  		$(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' \
   365  		-tags "${REMOTETAGS}" \
   366  		-o $@ ./cmd/podman
   367  
   368  $(SRCBINDIR)/podman-remote-static-linux_amd64 $(SRCBINDIR)/podman-remote-static-linux_arm64: $(SRCBINDIR)/podman-remote-static-linux_%: $(SRCBINDIR) $(SOURCES) go.mod go.sum
   369  	CGO_ENABLED=0 \
   370  	GOOS=linux \
   371  	GOARCH=$* \
   372  	$(GO) build \
   373  		$(BUILDFLAGS) \
   374  		$(GO_LDFLAGS) '$(LDFLAGS_PODMAN_STATIC)' \
   375  		-tags "${REMOTETAGS}" \
   376  		-o $@ ./cmd/podman
   377  
   378  .PHONY: podman
   379  podman: bin/podman
   380  
   381  # This will map to the right thing on Linux, Windows, and Mac.
   382  .PHONY: podman-remote
   383  podman-remote: $(SRCBINDIR)/podman$(BINSFX)
   384  
   385  $(SRCBINDIR)/quadlet: $(SOURCES) go.mod go.sum
   386  	$(GOCMD) build \
   387  		$(BUILDFLAGS) \
   388  		$(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' \
   389  		-tags "${BUILDTAGS}" \
   390  		-o $@ ./cmd/quadlet
   391  
   392  .PHONY: quadlet
   393  quadlet: bin/quadlet
   394  
   395  PHONY: podman-remote-static-linux_amd64 podman-remote-static-linux_arm64
   396  podman-remote-static-linux_amd64: $(SRCBINDIR)/podman-remote-static-linux_amd64
   397  podman-remote-static-linux_arm64: $(SRCBINDIR)/podman-remote-static-linux_arm64
   398  
   399  .PHONY: podman-winpath
   400  podman-winpath: $(SOURCES) go.mod go.sum
   401  	CGO_ENABLED=0 \
   402  		GOOS=windows \
   403  		$(GO) build \
   404  		$(BUILDFLAGS) \
   405  		-ldflags -H=windowsgui \
   406  		-o bin/windows/winpath.exe \
   407  		./cmd/winpath
   408  
   409  .PHONY: podman-mac-helper
   410  podman-mac-helper: ## Build podman-mac-helper for macOS
   411  	CGO_ENABLED=0 \
   412  		GOOS=darwin \
   413  		GOARCH=$(GOARCH) \
   414  		$(GO) build \
   415  		$(BUILDFLAGS) \
   416  		-o bin/darwin/podman-mac-helper \
   417  		./cmd/podman-mac-helper
   418  
   419  bin/rootlessport: $(SOURCES) go.mod go.sum
   420  	CGO_ENABLED=$(CGO_ENABLED) \
   421  		$(GO) build \
   422  		$(BUILDFLAGS) \
   423  		-o $@ ./cmd/rootlessport
   424  
   425  .PHONY: rootlessport
   426  rootlessport: bin/rootlessport
   427  
   428  # podmansh calls `podman exec` into the `podmansh` container when used as
   429  # os.Args[0] and is intended to be set as a login shell for users.
   430  # Run: `man 1 podmansh` for details.
   431  podmansh: bin/podman
   432  	if [ ! -f bin/podmansh ]; then ln -s podman bin/podmansh; fi
   433  
   434  ###
   435  ### Secondary binary-build targets
   436  ###
   437  
   438  .PHONY: generate-bindings
   439  generate-bindings:
   440  ifneq ($(GOOS),darwin)
   441  	$(GOCMD) generate ./pkg/bindings/... ;
   442  endif
   443  
   444  # DO NOT USE: use local-cross instead
   445  bin/podman.cross.%:
   446  	TARGET="$*"; \
   447  	GOOS="$${TARGET%%.*}"; \
   448  	GOARCH="$${TARGET##*.}"; \
   449  	CGO_ENABLED=0 \
   450  		$(GO) build \
   451  		$(BUILDFLAGS) \
   452  		$(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' \
   453  		-tags '$(BUILDTAGS_CROSS)' \
   454  		-o "$@" ./cmd/podman
   455  
   456  .PHONY: local-cross
   457  local-cross: $(CROSS_BUILD_TARGETS) ## Cross compile podman binary for multiple architectures
   458  
   459  .PHONY: cross
   460  cross: local-cross
   461  
   462  .PHONY: completions
   463  completions: podman podman-remote
   464  	# key = shell, value = completion filename
   465  	declare -A outfiles=([bash]=%s [zsh]=_%s [fish]=%s.fish [powershell]=%s.ps1);\
   466  	for shell in $${!outfiles[*]}; do \
   467  	    for remote in "" "-remote"; do \
   468  		podman="podman$$remote"; \
   469  		outfile=$$(printf "completions/$$shell/$${outfiles[$$shell]}" $$podman); \
   470  		./bin/$$podman completion $$shell >| $$outfile; \
   471  	    done;\
   472  	done
   473  
   474  ###
   475  ### Documentation targets
   476  ###
   477  
   478  pkg/api/swagger.yaml:
   479  	make -C pkg/api
   480  
   481  $(MANPAGES_MD_GENERATED): %.md: %.md.in $(MANPAGES_SOURCE_DIR)/options/*.md
   482  	hack/markdown-preprocess
   483  
   484  $(MANPAGES): %: %.md .install.md2man docdir
   485  
   486  # This does a bunch of filtering needed for man pages:
   487  #  1. Strip markdown link targets like '[podman(1)](podman.1.md)'
   488  #     to just '[podman(1)]', because man pages have no link mechanism;
   489  #  2. Then remove the brackets: '[podman(1)]' -> 'podman(1)';
   490  #  3. Then do the same for all other markdown links,
   491  #     like '[cgroups(7)](https://.....)'  -> just 'cgroups(7)';
   492  #  4. Remove HTML-ish stuff like '<sup>..</sup>' and '<a>..</a>'
   493  #  5. Replace "\" (backslash) at EOL with two spaces (no idea why)
   494  # Then two sanity checks:
   495  #  1. test for "included file options/blahblah"; this indicates a failure
   496  #     in the markdown-preprocess tool; and
   497  #  2. run 'man -l' against the generated man page, and check for tables
   498  #     with an empty right-hand column followed by an empty left-hand
   499  #     column on the next line. (Technically, on the next-next line,
   500  #     because the next line must be table borders). This is a horrible
   501  #     unmaintainable rats-nest of duplication, obscure grep options, and
   502  #     ASCII art. I (esm) believe the cost of releasing corrupt man pages
   503  #     is higher than the cost of carrying this kludge.
   504  #
   505  	@$(SED) -e 's/\((podman[^)]*\.md\(#.*\)\?)\)//g'    \
   506  	       -e 's/\[\(podman[^]]*\)\]/\1/g'              \
   507  	       -e 's/\[\([^]]*\)](http[^)]\+)/\1/g'         \
   508  	       -e 's;<\(/\)\?\(a\|a\s\+[^>]*\|sup\)>;;g'    \
   509  	       -e 's/\\$$/  /g' $<                         |\
   510  	$(GOMD2MAN) -out $(subst source/markdown,build/man,$@)
   511  	@if grep 'included file options/' docs/build/man/*; then \
   512  		echo "FATAL: man pages must not contain ^^^^"; exit 1; \
   513  	fi
   514  	@if $(MAN_L) $(subst source/markdown,build/man,$@) | $(GREP) -Pazoq '│\s+│\n\s+├─+┼─+┤\n\s+│\s+│'; then  \
   515  		echo "FATAL: $< has a too-long table column; use 'man -l $(subst source/markdown,build/man,$@)' and look for empty table cells."; exit 1; \
   516  	fi
   517  
   518  .PHONY: docdir
   519  docdir:
   520  	mkdir -p docs/build/man
   521  
   522  .PHONY: docs
   523  docs: $(MANPAGES) ## Generate documentation
   524  	@ln -sf $(CURDIR)/docs/source/markdown/links/* docs/build/man/
   525  
   526  # docs/remote-docs.sh requires a locally executable 'podman-remote' binary
   527  # in addition to the target-architecture binary (if different). That's
   528  # what the NATIVE_GOOS make does in the first line.
   529  podman-remote-%-docs: podman-remote
   530  	$(MAKE) clean-binaries
   531  	$(MAKE) podman-remote GOOS=$(NATIVE_GOOS) GOARCH=$(NATIVE_GOARCH)
   532  	$(eval GOOS := $*)
   533  	$(MAKE) docs $(MANPAGES)
   534  	rm -rf docs/build/remote
   535  	mkdir -p docs/build/remote
   536  	ln -sf $(CURDIR)/docs/source/markdown/links docs/build/man/
   537  	docs/remote-docs.sh \
   538  		$(GOOS) \
   539  		docs/build/remote/$* \
   540  		$(if $(findstring windows,$*),docs/source/markdown,docs/build/man)
   541  
   542  .PHONY: man-page-check
   543  man-page-check: bin/podman
   544  	hack/man-page-checker
   545  	hack/xref-helpmsgs-manpages
   546  	hack/man-page-table-check
   547  
   548  .PHONY: swagger-check
   549  swagger-check:
   550  	hack/swagger-check
   551  
   552  .PHONY: swagger
   553  swagger: pkg/api/swagger.yaml
   554  
   555  .PHONY: docker-docs
   556  docker-docs: docs
   557  	(cd docs; ./dckrman.sh ./build/man/*.1)
   558  
   559  # Workaround vim syntax highlighting bug: "
   560  
   561  ###
   562  ### Utility and Testing targets
   563  ###
   564  
   565  .PHONY: validate.completions
   566  validate.completions: SHELL:=/usr/bin/env bash # Set shell to bash for this target
   567  validate.completions:
   568  	# Check if the files can be loaded by the shell
   569  	. completions/bash/podman
   570  	if [ -x /bin/zsh ]; then /bin/zsh completions/zsh/_podman; fi
   571  	if [ -x /bin/fish ]; then /bin/fish completions/fish/podman.fish; fi
   572  
   573  # Note: Assumes test/python/requirements.txt is installed & available
   574  .PHONY: run-docker-py-tests
   575  run-docker-py-tests:
   576  	touch test/__init__.py
   577  	env CONTAINERS_CONF=$(CURDIR)/test/apiv2/containers.conf pytest --disable-warnings test/python/docker/
   578  	rm -f test/__init__.py
   579  
   580  .PHONY: localunit
   581  localunit: test/goecho/goecho test/version/version
   582  	rm -rf ${COVERAGE_PATH} && mkdir -p ${COVERAGE_PATH}
   583  	UNIT=1 $(GINKGO) \
   584  		-r \
   585  		$(TESTFLAGS) \
   586  		--skip-package test/e2e,pkg/bindings,hack,pkg/machine/e2e \
   587  		--cover \
   588  		--covermode atomic \
   589  		--coverprofile coverprofile \
   590  		--output-dir ${COVERAGE_PATH} \
   591  		--tags "$(BUILDTAGS)" \
   592  		--succinct
   593  	$(GO) tool cover -html=${COVERAGE_PATH}/coverprofile -o ${COVERAGE_PATH}/coverage.html
   594  	$(GO) tool cover -func=${COVERAGE_PATH}/coverprofile > ${COVERAGE_PATH}/functions
   595  	cat ${COVERAGE_PATH}/functions | sed -n 's/\(total:\).*\([0-9][0-9].[0-9]\)/\1 \2/p'
   596  
   597  .PHONY: test
   598  test: localunit localintegration remoteintegration localsystem remotesystem  ## Run unit, integration, and system tests.
   599  
   600  .PHONY: ginkgo-run
   601  ginkgo-run: .install.ginkgo
   602  	$(GINKGO) version
   603  	$(GINKGO) -vv $(TESTFLAGS) --tags "$(TAGS) remote" $(GINKGOTIMEOUT) --flake-attempts $(GINKGO_FLAKE_ATTEMPTS) \
   604  		--trace $(if $(findstring y,$(GINKGO_NO_COLOR)),--no-color,) \
   605  		$(GINKGO_JSON) $(if $(findstring y,$(GINKGO_PARALLEL)),-p,) $(if $(FOCUS),--focus "$(FOCUS)",) \
   606  		$(if $(FOCUS_FILE),--focus-file "$(FOCUS_FILE)",) $(GINKGOWHAT) $(HACK)
   607  
   608  .PHONY: ginkgo
   609  ginkgo:
   610  	$(MAKE) ginkgo-run TAGS="$(BUILDTAGS)" HACK=hack/.
   611  
   612  .PHONY: ginkgo-remote
   613  ginkgo-remote:
   614  	$(MAKE) ginkgo-run TAGS="$(REMOTETAGS) remote_testing" HACK=
   615  
   616  .PHONY: testbindings
   617  testbindings: .install.ginkgo
   618  	$(GINKGO) -v $(TESTFLAGS) --tags "$(TAGS) remote" $(GINKGOTIMEOUT) --trace --no-color --timeout 30m  -v -r ./pkg/bindings/test
   619  
   620  .PHONY: localintegration
   621  localintegration: test-binaries ginkgo
   622  
   623  .PHONY: remoteintegration
   624  remoteintegration: test-binaries ginkgo-remote
   625  
   626  .PHONY: localmachine
   627  localmachine: test-binaries .install.ginkgo
   628  	$(MAKE) ginkgo-run GINKGO_PARALLEL=n GINKGOWHAT=pkg/machine/e2e/. HACK=
   629  
   630  .PHONY: localsystem
   631  localsystem:
   632  	# Wipe existing config, database, and cache: start with clean slate.
   633  	$(RM) -rf ${HOME}/.local/share/containers ${HOME}/.config/containers
   634  	if timeout -v 1 true; then PODMAN=$(CURDIR)/bin/podman QUADLET=$(CURDIR)/bin/quadlet bats test/system/; else echo "Skipping $@: 'timeout -v' unavailable'"; fi
   635  
   636  .PHONY: remotesystem
   637  remotesystem:
   638  	# Wipe existing config, database, and cache: start with clean slate.
   639  	$(RM) -rf ${HOME}/.local/share/containers ${HOME}/.config/containers
   640  	# Start podman server using tmp socket; loop-wait for it;
   641  	# test podman-remote; kill server, clean up tmp socket file.
   642  	# podman server spews copious unhelpful output; ignore it.
   643  	rc=0;\
   644  	if timeout -v 1 true; then \
   645  		SOCK_FILE=$(shell mktemp --dry-run --tmpdir podman_tmp_XXXX);\
   646  		export PODMAN_SOCKET=unix://$$SOCK_FILE; \
   647  		./bin/podman system service --timeout=0 $$PODMAN_SOCKET > $(if $(PODMAN_SERVER_LOG),$(PODMAN_SERVER_LOG),/dev/null) 2>&1 & \
   648  		retry=5;\
   649  		while [ $$retry -ge 0 ]; do\
   650  			echo Waiting for server...;\
   651  			sleep 1;\
   652  			./bin/podman-remote --url $$PODMAN_SOCKET info >/dev/null 2>&1 && break;\
   653  			retry=$$(expr $$retry - 1);\
   654  		done;\
   655  		if [ $$retry -lt 0 ]; then\
   656  			echo "Error: ./bin/podman system service did not come up on $$SOCK_FILE" >&2;\
   657  			exit 1;\
   658  		fi;\
   659  		env PODMAN="$(CURDIR)/bin/podman-remote --url $$PODMAN_SOCKET" bats test/system/ ;\
   660  		rc=$$?;\
   661  		kill %1;\
   662  		rm -f $$SOCK_FILE;\
   663  	else \
   664  		echo "Skipping $@: 'timeout -v' unavailable'";\
   665  	fi;\
   666  	exit $$rc
   667  
   668  .PHONY: localapiv2-bash
   669  localapiv2-bash:
   670  	env PODMAN=./bin/podman stdbuf -o0 -e0 ./test/apiv2/test-apiv2
   671  
   672  .PHONY: localapiv2-python
   673  localapiv2-python:
   674  	env CONTAINERS_CONF=$(CURDIR)/test/apiv2/containers.conf PODMAN=./bin/podman \
   675  		pytest --verbose --disable-warnings ./test/apiv2/python
   676  	touch test/__init__.py
   677  	env CONTAINERS_CONF=$(CURDIR)/test/apiv2/containers.conf PODMAN=./bin/podman \
   678  		pytest --verbose --disable-warnings ./test/python/docker
   679  	rm -f test/__init__.py
   680  
   681  # Order is important running python tests first causes the bash tests
   682  # to fail, see 12-imagesMore.  FIXME order of tests should not matter
   683  .PHONY: localapiv2
   684  localapiv2: localapiv2-bash localapiv2-python
   685  
   686  .PHONY: remoteapiv2
   687  remoteapiv2:
   688  	true
   689  
   690  .PHONY: system.test-binary
   691  system.test-binary: .install.ginkgo
   692  	$(GO) test -c ./test/system
   693  
   694  .PHONY: test-binaries
   695  test-binaries: test/checkseccomp/checkseccomp test/goecho/goecho install.catatonit test/version/version
   696  	@echo "Canonical source version: $(call err_if_empty,RELEASE_VERSION)"
   697  
   698  .PHONY: tests-included
   699  tests-included:
   700  	contrib/cirrus/pr-should-include-tests
   701  
   702  .PHONY: tests-expect-exit
   703  tests-expect-exit:
   704  	@if grep -E --line-number 'Expect.*ExitCode' test/e2e/*.go | grep -E -v ', ".*"\)'; then \
   705  		echo "^^^ Unhelpful use of Expect(ExitCode())"; \
   706  		echo "   Please use '.Should(Exit(...))' pattern instead."; \
   707  		echo "   If that's not possible, please add an annotation (description) to your assertion:"; \
   708  		echo "        Expect(...).To(..., \"Friendly explanation of this check\")"; \
   709  		exit 1; \
   710  	fi
   711  
   712  .PHONY: pr-removes-fixed-skips
   713  pr-removes-fixed-skips:
   714  	contrib/cirrus/pr-removes-fixed-skips
   715  
   716  ###
   717  ### Release/Packaging targets
   718  ###
   719  
   720  .PHONY: podman-release
   721  podman-release: podman-release-$(GOARCH).tar.gz  # Build all Linux binaries for $GOARCH, docs., and installation tree, into a tarball.
   722  
   723  # The following two targets are nuanced and complex:
   724  # Cross-building the podman-remote documentation requires a functional
   725  # native architecture executable.  However `make` only deals with
   726  # files/timestamps, it doesn't understand if an existing binary will
   727  # function on the system or not.  This makes building cross-platform
   728  # releases incredibly accident-prone and fragile.  The only practical
   729  # way to deal with this, is via multiple conditional (nested) `make`
   730  # calls along with careful manipulation of `$GOOS` and `$GOARCH`.
   731  
   732  podman-release-%.tar.gz: test/version/version
   733  	$(eval tmpsubdir := $(shell mktemp -d podman_tmp_XXXX))
   734  	$(eval releasedir := podman-v$(call err_if_empty,RELEASE_NUMBER))
   735  	$(eval _dstargs := "DESTDIR=$(tmpsubdir)/$(releasedir)" "PREFIX=$(RELEASE_PREFIX)")
   736  	$(eval GOARCH := $*)
   737  	mkdir -p "$(call err_if_empty,tmpsubdir)/$(releasedir)"
   738  	$(MAKE) GOOS=$(GOOS) GOARCH=$(NATIVE_GOARCH) \
   739  		clean-binaries docs podman-remote-$(GOOS)-docs
   740  	if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
   741  		$(MAKE) CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
   742  			BUILDTAGS="$(BUILDTAGS_CROSS)" clean-binaries binaries; \
   743  	else \
   744  		$(MAKE) GOOS=$(GOOS) GOARCH=$(GOARCH) binaries; \
   745  	fi
   746  	$(MAKE) $(_dstargs) install.bin install.remote install.man install.systemd
   747  	tar -czvf $@ --xattrs -C "$(tmpsubdir)" "./$(releasedir)"
   748  	if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
   749  	-rm -rf "$(tmpsubdir)"
   750  
   751  podman-remote-release-%.zip: test/version/version ## Build podman-remote for %=$GOOS_$GOARCH, and docs. into an installation zip.
   752  	$(eval tmpsubdir := $(shell mktemp -d podman_tmp_XXXX))
   753  	$(eval releasedir := podman-$(call err_if_empty,RELEASE_NUMBER))
   754  	$(eval _dstargs := "DESTDIR=$(tmpsubdir)/$(releasedir)" "PREFIX=$(RELEASE_PREFIX)")
   755  	$(eval GOOS := $(firstword $(subst _, ,$*)))
   756  	$(eval GOARCH := $(lastword $(subst _, ,$*)))
   757  	$(eval _GOPLAT := GOOS=$(call err_if_empty,GOOS) GOARCH=$(call err_if_empty,GOARCH))
   758  	mkdir -p "$(call err_if_empty,tmpsubdir)/$(releasedir)"
   759  	$(MAKE) GOOS=$(GOOS) GOARCH=$(GOARCH) \
   760  		clean-binaries podman-remote-$(GOOS)-docs
   761  	if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
   762  		$(MAKE) CGO_ENABLED=0 $(GOPLAT) BUILDTAGS="$(BUILDTAGS_CROSS)" \
   763  			clean-binaries podman-remote; \
   764  	else \
   765  		$(MAKE) $(GOPLAT) podman-remote; \
   766  	fi
   767  	if [[ "$(GOOS)" == "windows" ]]; then \
   768  		$(MAKE) $(GOPLAT) TMPDIR="" win-gvproxy; \
   769  	fi
   770  	if [[ "$(GOOS)" == "darwin" ]]; then \
   771  		$(MAKE) $(GOPLAT) podman-mac-helper;\
   772  	fi
   773  	cp -r ./docs/build/remote/$(GOOS) "$(tmpsubdir)/$(releasedir)/docs/"
   774  	cp ./contrib/remote/containers.conf "$(tmpsubdir)/$(releasedir)/"
   775  	$(MAKE) $(GOPLAT) $(_dstargs) SELINUXOPT="" install.remote
   776  	cd "$(tmpsubdir)" && \
   777  		zip --recurse-paths "$(CURDIR)/$@" "./$(releasedir)"
   778  	if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
   779  	-rm -rf "$(tmpsubdir)"
   780  
   781  # Checks out and builds win-sshproxy helper. See comment on GV_GITURL declaration
   782  .PHONY: win-gvproxy
   783  win-gvproxy: test/version/version
   784  	mkdir -p bin/windows/
   785  	curl -sSL -o bin/windows/gvproxy.exe --retry 5 https://github.com/containers/gvisor-tap-vsock/releases/download/$(GV_VERSION)/gvproxy-windowsgui.exe
   786  	curl -sSL -o bin/windows/win-sshproxy.exe --retry 5 https://github.com/containers/gvisor-tap-vsock/releases/download/$(GV_VERSION)/win-sshproxy.exe
   787  
   788  .PHONY: rpm
   789  rpm:  ## Build rpm packages
   790  	$(MAKE) -C rpm
   791  
   792  ###
   793  ### Installation targets
   794  ###
   795  
   796  # Remember that rpms install exec to /usr/bin/podman while a `make install`
   797  # installs them to /usr/local/bin/podman which is likely before. Always use
   798  # a full path to test installed podman or you risk to call another executable.
   799  .PHONY: rpm-install
   800  rpm-install: package  ## Install rpm packages
   801  	$(call err_if_empty,PKG_MANAGER) -y install rpm/RPMS/*/*.rpm
   802  	/usr/bin/podman version
   803  	/usr/bin/podman info  # will catch a broken conmon
   804  
   805  .PHONY: install
   806  install: install.bin install.remote install.man install.systemd  ## Install binaries to system locations
   807  
   808  .PHONY: install.catatonit
   809  install.catatonit:
   810  	./hack/install_catatonit.sh
   811  
   812  .PHONY: install.remote
   813  install.remote:
   814  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR)
   815  	install ${SELINUXOPT} -m 755 $(SRCBINDIR)/podman$(BINSFX) \
   816  		$(DESTDIR)$(BINDIR)/podman$(BINSFX)
   817  	test "${GOOS}" != "windows" || \
   818  		install -m 755 $(SRCBINDIR)/win-sshproxy.exe $(DESTDIR)$(BINDIR)
   819  	test "${GOOS}" != "windows" || \
   820  		install -m 755 $(SRCBINDIR)/gvproxy.exe $(DESTDIR)$(BINDIR)
   821  	test "${GOOS}" != "darwin" || \
   822  		install -m 755 $(SRCBINDIR)/podman-mac-helper $(DESTDIR)$(BINDIR)
   823  	test -z "${SELINUXOPT}" || \
   824  		chcon --verbose --reference=$(DESTDIR)$(BINDIR)/podman-remote \
   825  		bin/podman-remote
   826  
   827  .PHONY: install.bin
   828  install.bin:
   829  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR)
   830  	install ${SELINUXOPT} -m 755 bin/podman $(DESTDIR)$(BINDIR)/podman
   831  	ln -sf podman $(DESTDIR)$(BINDIR)/podmansh
   832  	test -z "${SELINUXOPT}" || chcon --verbose --reference=$(DESTDIR)$(BINDIR)/podman bin/podman
   833  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(LIBEXECPODMAN)
   834  ifneq ($(shell uname -s),FreeBSD)
   835  	install ${SELINUXOPT} -m 755 bin/rootlessport $(DESTDIR)$(LIBEXECPODMAN)/rootlessport
   836  	test -z "${SELINUXOPT}" || chcon --verbose --reference=$(DESTDIR)$(LIBEXECPODMAN)/rootlessport bin/rootlessport
   837  	install ${SELINUXOPT} -m 755 bin/quadlet $(DESTDIR)$(LIBEXECPODMAN)/quadlet
   838  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(SYSTEMDGENERATORSDIR)
   839  	ln -sfr $(DESTDIR)$(LIBEXECPODMAN)/quadlet $(DESTDIR)$(SYSTEMDGENERATORSDIR)/podman-system-generator
   840  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(USERSYSTEMDGENERATORSDIR)
   841  	ln -sfr $(DESTDIR)$(LIBEXECPODMAN)/quadlet $(DESTDIR)$(USERSYSTEMDGENERATORSDIR)/podman-user-generator
   842  	install ${SELINUXOPT} -m 755 -d ${DESTDIR}${TMPFILESDIR}
   843  	install ${SELINUXOPT} -m 644 contrib/tmpfile/podman.conf ${DESTDIR}${TMPFILESDIR}/podman.conf
   844  endif
   845  
   846  .PHONY: install.modules-load
   847  install.modules-load: # This should only be used by distros which might use iptables-legacy, this is not needed on RHEL
   848  	install ${SELINUXOPT} -m 755 -d ${DESTDIR}${MODULESLOADDIR}
   849  	install ${SELINUXOPT} -m 644 contrib/modules-load.d/podman-iptables.conf ${DESTDIR}${MODULESLOADDIR}/podman-iptables.conf
   850  
   851  .PHONY: install.man
   852  install.man:
   853  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man1
   854  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man5
   855  	install ${SELINUXOPT} -m 644 $(filter %.1,$(MANPAGES_DEST)) $(DESTDIR)$(MANDIR)/man1
   856  	install ${SELINUXOPT} -m 644 docs/source/markdown/links/*1 $(DESTDIR)$(MANDIR)/man1
   857  	install ${SELINUXOPT} -m 644 $(filter %.5,$(MANPAGES_DEST)) $(DESTDIR)$(MANDIR)/man5
   858  	install ${SELINUXOPT} -m 644 docs/source/markdown/links/*5 $(DESTDIR)$(MANDIR)/man5
   859  
   860  .PHONY: install.completions
   861  install.completions:
   862  	install ${SELINUXOPT} -d -m 755 ${DESTDIR}${BASHINSTALLDIR}
   863  	install ${SELINUXOPT} -m 644 completions/bash/podman ${DESTDIR}${BASHINSTALLDIR}
   864  	install ${SELINUXOPT} -m 644 completions/bash/podman-remote ${DESTDIR}${BASHINSTALLDIR}
   865  	install ${SELINUXOPT} -d -m 755 ${DESTDIR}${ZSHINSTALLDIR}
   866  	install ${SELINUXOPT} -m 644 completions/zsh/_podman ${DESTDIR}${ZSHINSTALLDIR}
   867  	install ${SELINUXOPT} -m 644 completions/zsh/_podman-remote ${DESTDIR}${ZSHINSTALLDIR}
   868  	install ${SELINUXOPT} -d -m 755 ${DESTDIR}${FISHINSTALLDIR}
   869  	install ${SELINUXOPT} -m 644 completions/fish/podman.fish ${DESTDIR}${FISHINSTALLDIR}
   870  	install ${SELINUXOPT} -m 644 completions/fish/podman-remote.fish ${DESTDIR}${FISHINSTALLDIR}
   871  	# There is no common location for powershell files so do not install them. Users have to source the file from their powershell profile.
   872  
   873  .PHONY: install.docker
   874  install.docker:
   875  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR)
   876  	$(eval INTERPOLATED_DOCKER_SCRIPT := $(shell mktemp))
   877  	env BINDIR=${BINDIR} ETCDIR=${ETCDIR} envsubst < docker.in > ${INTERPOLATED_DOCKER_SCRIPT}
   878  	install ${SELINUXOPT} -m 755 ${INTERPOLATED_DOCKER_SCRIPT} $(DESTDIR)$(BINDIR)/docker
   879  	rm ${INTERPOLATED_DOCKER_SCRIPT}
   880  	install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR}  ${DESTDIR}${USERSYSTEMDDIR} ${DESTDIR}${TMPFILESDIR} ${DESTDIR}${USERTMPFILESDIR}
   881  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-docker.conf -t ${DESTDIR}${TMPFILESDIR}
   882  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-docker.conf -t ${DESTDIR}${USERTMPFILESDIR}
   883  
   884  .PHONY: install.docker-docs
   885  install.docker-docs:
   886  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man1
   887  	install ${SELINUXOPT} -m 644 docs/build/man/docker*.1 -t $(DESTDIR)$(MANDIR)/man1
   888  	install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man5
   889  	install ${SELINUXOPT} -m 644 docs/build/man/docker*.5 -t $(DESTDIR)$(MANDIR)/man5
   890  
   891  .PHONY: install.docker-full
   892  install.docker-full: install.docker install.docker-docs
   893  
   894  .PHONY: install.systemd
   895  ifneq (,$(findstring systemd,$(BUILDTAGS)))
   896  PODMAN_UNIT_FILES = contrib/systemd/auto-update/podman-auto-update.service \
   897  		    contrib/systemd/system/podman.service \
   898  		    contrib/systemd/system/podman-restart.service \
   899  		    contrib/systemd/system/podman-kube@.service \
   900  		    contrib/systemd/system/podman-clean-transient.service
   901  
   902  %.service: %.service.in
   903  	sed -e 's;@@PODMAN@@;$(BINDIR)/podman;g' $< >$@.tmp.$$ \
   904  		&& mv -f $@.tmp.$$ $@
   905  
   906  install.systemd: $(PODMAN_UNIT_FILES)
   907  	install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR}  ${DESTDIR}${USERSYSTEMDDIR}
   908  	# User services
   909  	install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.service
   910  	install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.timer
   911  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
   912  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${USERSYSTEMDDIR}/podman.service
   913  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service ${DESTDIR}${USERSYSTEMDDIR}/podman-restart.service
   914  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-kube@.service ${DESTDIR}${USERSYSTEMDDIR}/podman-kube@.service
   915  	# System services
   916  	install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.service
   917  	install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.timer
   918  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${SYSTEMDDIR}/podman.socket
   919  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${SYSTEMDDIR}/podman.service
   920  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service ${DESTDIR}${SYSTEMDDIR}/podman-restart.service
   921  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-kube@.service ${DESTDIR}${SYSTEMDDIR}/podman-kube@.service
   922  	install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-clean-transient.service ${DESTDIR}${SYSTEMDDIR}/podman-clean-transient.service
   923  	rm -f $(PODMAN_UNIT_FILES)
   924  else
   925  install.systemd:
   926  endif
   927  
   928  .PHONY: install.tools
   929  install.tools: .install.golangci-lint ## Install needed tools
   930  	$(MAKE) -C test/tools
   931  
   932  .PHONY: .install.goimports
   933  .install.goimports:
   934  	$(MAKE) -C test/tools build/goimports
   935  
   936  .PHONY: .install.ginkgo
   937  .install.ginkgo:
   938  	$(MAKE) -C test/tools build/ginkgo
   939  
   940  .PHONY: .install.gitvalidation
   941  .install.gitvalidation:
   942  	$(MAKE) -C test/tools build/git-validation
   943  
   944  .PHONY: .install.golangci-lint
   945  .install.golangci-lint:
   946  	VERSION=$(GOLANGCI_LINT_VERSION) ./hack/install_golangci.sh
   947  
   948  .PHONY: .install.swagger
   949  .install.swagger:
   950  	env VERSION=0.30.3 \
   951  		BINDIR=$(BINDIR) \
   952  		GOOS=$(GOOS) \
   953  		GOARCH=$(GOARCH) \
   954  		./hack/install_swagger.sh
   955  
   956  .PHONY: .install.md2man
   957  .install.md2man:
   958  	if [ ! -x "$(GOMD2MAN)" ]; then \
   959  		$(MAKE) -C test/tools build/go-md2man GOOS=$(NATIVE_GOOS) GOARCH=$(NATIVE_GOARCH); \
   960  	fi
   961  
   962  .PHONY: .install.pre-commit
   963  .install.pre-commit:
   964  	if [ -z "$(PRE_COMMIT)" ]; then \
   965  		$(PYTHON) -m pip install --user pre-commit; \
   966  	fi
   967  
   968  .PHONY: release-artifacts
   969  release-artifacts: clean-binaries
   970  	mkdir -p release/
   971  	$(MAKE) podman-remote-release-darwin_amd64.zip
   972  	mv podman-remote-release-darwin_amd64.zip release/
   973  	$(MAKE) podman-remote-release-darwin_arm64.zip
   974  	mv podman-remote-release-darwin_arm64.zip release/
   975  	$(MAKE) podman-remote-release-windows_amd64.zip
   976  	mv podman-remote-release-windows_amd64.zip release/
   977  	$(MAKE) podman-remote-static-linux_amd64
   978  	tar -cvzf podman-remote-static-linux_amd64.tar.gz bin/podman-remote-static-linux_amd64
   979  	$(MAKE) podman-remote-static-linux_arm64
   980  	tar -cvzf podman-remote-static-linux_arm64.tar.gz bin/podman-remote-static-linux_arm64
   981  	mv podman-remote-static-linux*.tar.gz release/
   982  	cd release/; sha256sum *.zip *.tar.gz > shasums
   983  
   984  .PHONY: uninstall
   985  uninstall:
   986  	for i in $(filter %.1,$(MANPAGES_DEST)); do \
   987  		rm -f $(DESTDIR)$(MANDIR)/man1/$$(basename $${i}); \
   988  	done; \
   989  	for i in $(filter %.5,$(MANPAGES_DEST)); do \
   990  		rm -f $(DESTDIR)$(MANDIR)/man5/$$(basename $${i}); \
   991  	done
   992  	# Remove podman and remote bin
   993  	rm -f $(DESTDIR)$(BINDIR)/podman
   994  	rm -f $(DESTDIR)$(BINDIR)/podman-remote
   995  	# Remove related config files
   996  	rm -f ${DESTDIR}${ETCDIR}/cni/net.d/87-podman-bridge.conflist
   997  	rm -f ${DESTDIR}${TMPFILESDIR}/podman.conf
   998  	rm -f ${DESTDIR}${SYSTEMDDIR}/io.podman.socket
   999  	rm -f ${DESTDIR}${USERSYSTEMDDIR}/io.podman.socket
  1000  	rm -f ${DESTDIR}${SYSTEMDDIR}/io.podman.service
  1001  	rm -f ${DESTDIR}${SYSTEMDDIR}/podman.service
  1002  	rm -f ${DESTDIR}${SYSTEMDDIR}/podman.socket
  1003  	rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
  1004  	rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.service
  1005  
  1006  .PHONY: clean-binaries
  1007  clean-binaries: ## Remove platform/architecture specific binary files
  1008  	rm -rf \
  1009  		bin
  1010  
  1011  .PHONY: clean
  1012  clean: clean-binaries ## Clean all make artifacts
  1013  	rm -rf \
  1014  		_output \
  1015  		$(wildcard podman-*.msi) \
  1016  		$(wildcard podman-remote*.zip) \
  1017  		$(wildcard podman_tmp_*) \
  1018  		$(wildcard podman*.tar.gz) \
  1019  		build \
  1020  		test/checkseccomp/checkseccomp \
  1021  		test/goecho/goecho \
  1022  		test/version/version \
  1023  		test/__init__.py \
  1024  		test/testdata/redis-image \
  1025  		libpod/container_ffjson.go \
  1026  		libpod/pod_ffjson.go \
  1027  		libpod/container_easyjson.go \
  1028  		libpod/pod_easyjson.go \
  1029  		docs/build \
  1030  		.venv
  1031  	make -C docs clean