From 6d621ea5494d356f57881e99e07e44961ddf2223 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 29 Apr 2018 23:27:27 +0100 Subject: [PATCH] Simplify build for deepcopy --- build/root/Makefile.generated_files | 1276 ++++++++++++--------------- 1 file changed, 585 insertions(+), 691 deletions(-) diff --git a/build/root/Makefile.generated_files b/build/root/Makefile.generated_files index 68e45dfa573..4ce6c804a29 100644 --- a/build/root/Makefile.generated_files +++ b/build/root/Makefile.generated_files @@ -35,78 +35,58 @@ SHELL := /bin/bash # This rule collects all the generated file sets into a single rule. Other # rules should depend on this to ensure generated files are rebuilt. .PHONY: generated_files -generated_files: gen_deepcopy gen_defaulter gen_conversion gen_openapi gen_bindata +generated_files: gen_deepcopy + +##TH##FIXMEgen_defaulter gen_conversion gen_openapi gen_bindata + -# Code-generation logic. # -# This stuff can be pretty tricky, and there's probably some corner cases that -# we don't handle well. That said, here's a straightforward test to prove that -# the most common cases work. Sadly, it is manual. +# Helper logic to calculate Go's dependency DAG ourselves. # -# make clean -# find . -name .make\* | xargs rm -f -# find . -name zz_generated\* | xargs rm -f -# # verify `find . -name zz_generated.deepcopy.go | wc -l` is 0 -# # verify `find . -name .make | wc -l` is 0 + +# This is a file that will be emitted by the go2make tool, containing a +# variable for each Go package in the project (including deps) which lists all +# of the transitive deps of that package. Each variable is named the same as +# the package - for example the variable for `k8s.io/kubernetes/pkg/api` is +# $(k8s.io/kubernetes/pkg/api). This is roughly the same DAG that the Go +# compiler uses. These variables can be used to figure out if, for example, +# generated code needs to be regenerated. +GO_PKGDEPS_FILE = go-pkgdeps.mk + +# Include the Go package dependencies file. This will cause the rule of +# the same name to be considered and if it is updated, make will restart and +# reload the updated deps. +sinclude $(META_DIR)/$(GO_PKGDEPS_FILE) + +# Update the set of Go deps for our project. This will let us determine if +# we really need to do expensive codegen. We use FORCE because it is not a +# PHONY file, but we do want it to be re-evaluated every time make is run. The +# file will only be touched if it actually changes. +$(META_DIR)/$(GO_PKGDEPS_FILE): FORCE + if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ + echo "DBG: calculating Go dependencies"; \ + fi + hack/run-in-gopath.sh go install ./hack/make-rules/helpers/go2make + hack/run-in-gopath.sh go2make \ + k8s.io/kubernetes/... \ + --prune k8s.io/kubernetes/staging \ + --prune k8s.io/kubernetes/vendor \ + k8s.io/kubernetes/vendor/k8s.io/... \ + > $@.tmp + if ! cmp -s $@.tmp $@; then \ + if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ + echo "DBG: $(GO_PKGDEPS_FILE) changed"; \ + fi; \ + cat $@.tmp > $@; \ + fi + rm -f $@.tmp + +.PHONY: FORCE +FORCE: + # -# make nonexistent -# # expect "No rule to make target" -# # verify `find .make/ -type f | wc -l` has many files +# Helper logic to find which directories need codegen as quickly as possible. # -# make gen_deepcopy -# # expect deepcopy-gen is built exactly once -# # expect many files to be regenerated -# # verify `find . -name zz_generated.deepcopy.go | wc -l` has files -# make gen_deepcopy -# # expect nothing to be rebuilt, finish in O(seconds) -# touch pkg/api/types.go -# make gen_deepcopy -# # expect one file to be regenerated -# make gen_deepcopy -# # expect nothing to be rebuilt, finish in O(seconds) -# touch vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go -# make gen_deepcopy -# # expect deepcopy-gen is built exactly once -# # expect many files to be regenerated -# # verify `find . -name zz_generated.deepcopy.go | wc -l` has files -# make gen_deepcopy -# # expect nothing to be rebuilt, finish in O(seconds) -# -# make gen_conversion -# # expect conversion-gen is built exactly once -# # expect many files to be regenerated -# # verify `find . -name zz_generated.conversion.go | wc -l` has files -# make gen_conversion -# # expect nothing to be rebuilt, finish in O(seconds) -# touch pkg/api/types.go -# make gen_conversion -# # expect one file to be regenerated -# make gen_conversion -# # expect nothing to be rebuilt, finish in O(seconds) -# touch vendor/k8s.io/code-generator/cmd/conversion-gen/main.go -# make gen_conversion -# # expect conversion-gen is built exactly once -# # expect many files to be regenerated -# # verify `find . -name zz_generated.conversion.go | wc -l` has files -# make gen_conversion -# # expect nothing to be rebuilt, finish in O(seconds) -# -# make all -# # expect it to build -# -# make test -# # expect it to pass -# -# make clean -# # verify `find . -name zz_generated.deepcopy.go | wc -l` is 0 -# # verify `find . -name .make | wc -l` is 0 -# -# make all WHAT=cmd/kube-proxy -# # expect it to build -# -# make clean -# make test WHAT=cmd/kube-proxy -# # expect it to pass # This variable holds a list of every directory that contains Go files in this # project. Other rules and variables can use this as a starting point to @@ -118,63 +98,6 @@ ALL_GO_DIRS := $(shell \ hack/make-rules/helpers/cache_go_dirs.sh $(META_DIR)/all_go_dirs.mk \ ) -# The name of the metadata file which lists *.go files in each pkg. -GOFILES_META := gofiles.mk - -# Establish a dependency between the deps file and the dir. Whenever a dir -# changes (files added or removed) the deps file will be considered stale. -# -# The variable value was set in $(GOFILES_META) and included as part of the -# dependency management logic. -# -# This is looser than we really need (e.g. we don't really care about non *.go -# files or even *_test.go files), but this is much easier to represent. -# -# Because we 'sinclude' the deps file, it is considered for rebuilding, as part -# of make's normal evaluation. If it gets rebuilt, make will restart. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -$(foreach dir, $(ALL_GO_DIRS), $(eval \ - $(META_DIR)/$(dir)/$(GOFILES_META): $(dir) \ -)) - -# How to rebuild a deps file. When make determines that the deps file is stale -# (see above), it executes this rule, and then re-loads the deps file. -# -# This is looser than we really need (e.g. we don't really care about test -# files), but this is MUCH faster than calling `go list`. -# -# We regenerate the output file in order to satisfy make's "newer than" rules, -# but we only need to rebuild targets if the contents actually changed. That -# is what the .stamp file represents. -$(foreach dir, $(ALL_GO_DIRS), \ - $(META_DIR)/$(dir)/$(GOFILES_META)): - FILES=$$(ls $$@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: gofiles changed for $@"; \ - fi; \ - touch $@.stamp; \ - fi; \ - mv $@.tmp $@ - -# This is required to fill in the DAG, since some cases (e.g. 'make clean all') -# will reference the .stamp file when it doesn't exist. We don't need to -# rebuild it in that case, just keep make happy. -$(foreach dir, $(ALL_GO_DIRS), \ - $(META_DIR)/$(dir)/$(GOFILES_META).stamp): - -# Include any deps files as additional Makefile rules. This triggers make to -# consider the deps files for rebuild, which makes the whole -# dependency-management logic work. 'sinclude' is "silent include" which does -# not fail if the file does not exist. -$(foreach dir, $(ALL_GO_DIRS), $(eval \ - sinclude $(META_DIR)/$(dir)/$(GOFILES_META) \ -)) - # Generate a list of all files that have a `+k8s:` comment-tag. This will be # used to derive lists of files/dirs for generation tools. ifeq ($(DBG_MAKEFILE),1) @@ -185,7 +108,12 @@ ALL_K8S_TAG_FILES := $(shell \ | xargs grep --color=never -l '^// *+k8s:' \ ) + # +# Code generation logic. +# + + # Deep-copy generation # # Any package that wants deep-copy functions generated must include a @@ -215,10 +143,14 @@ DEEPCOPY_DIRS := $(shell \ ) DEEPCOPY_FILES := $(addsuffix /$(DEEPCOPY_FILENAME), $(DEEPCOPY_DIRS)) +# Reset the list of packages that need generation. +$(shell mkdir -p $$(dirname $(META_DIR)/$(DEEPCOPY_GEN))) +$(shell rm -f $(META_DIR)/$(DEEPCOPY_GEN).todo) + # This rule aggregates the set of files to generate and then generates them all # in a single run of the tool. .PHONY: gen_deepcopy -gen_deepcopy: $(DEEPCOPY_FILES) $(DEEPCOPY_GEN) +gen_deepcopy: $(DEEPCOPY_GEN) $(META_DIR)/$(DEEPCOPY_GEN).todo if [[ -s $(META_DIR)/$(DEEPCOPY_GEN).todo ]]; then \ pkgs=$$(cat $(META_DIR)/$(DEEPCOPY_GEN).todo | paste -sd, -); \ if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ @@ -242,590 +174,552 @@ gen_deepcopy: $(DEEPCOPY_FILES) $(DEEPCOPY_GEN) # # The '$(eval)' is needed because this has a different RHS for each LHS, and # would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(DEEPCOPY_DIRS), $(eval \ - $(dir)/$(DEEPCOPY_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ - $(gofiles__$(dir)) \ +$(foreach dir, $(DEEPCOPY_DIRS), $(eval \ + $(dir)/$(DEEPCOPY_FILENAME): $($(PRJ_SRC_PATH)/$(dir)) \ )) -# Unilaterally remove any leftovers from previous runs. -$(shell rm -f $(META_DIR)/$(DEEPCOPY_GEN)*.todo) - # How to regenerate deep-copy code. This is a little slow to run, so we batch # it up and trigger the batch from the 'generated_files' target. +$(META_DIR)/$(DEEPCOPY_GEN).todo: $(DEEPCOPY_FILES) + $(DEEPCOPY_FILES): $(DEEPCOPY_GEN) - mkdir -p $$(dirname $(META_DIR)/$(DEEPCOPY_GEN)) if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ echo "DBG: deepcopy needed $(@D): $?"; \ ls -lf --full-time $@ $? || true; \ fi echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(DEEPCOPY_GEN).todo -# This calculates the dependencies for the generator tool, so we only rebuild -# it when needed. It is PHONY so that it always runs, but it only updates the -# file if the contents have actually changed. We 'sinclude' this later. -.PHONY: $(META_DIR)/$(DEEPCOPY_GEN).mk -$(META_DIR)/$(DEEPCOPY_GEN).mk: - mkdir -p $(@D); \ - (echo -n "$(DEEPCOPY_GEN): "; \ - ./hack/run-in-gopath.sh go list \ - -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ - ./vendor/k8s.io/code-generator/cmd/deepcopy-gen \ - | grep --color=never "^$(PRJ_SRC_PATH)/" \ - | xargs ./hack/run-in-gopath.sh go list \ - -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ - | paste -sd' ' - \ - | sed 's/ / \\=,/g' \ - | tr '=,' '\n\t' \ - | sed "s|$$(pwd -P)/||"; \ - ) > $@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: $(DEEPCOPY_GEN).mk changed"; \ - fi; \ - cat $@.tmp > $@; \ - rm -f $@.tmp; \ - fi - -# Include dependency info for the generator tool. This will cause the rule of -# the same name to be considered and if it is updated, make will restart. -sinclude $(META_DIR)/$(DEEPCOPY_GEN).mk - # How to build the generator tool. The deps for this are defined in -# the $(DEEPCOPY_GEN).mk, above. +# the $(GO_PKGDEPS_FILE), above. # # A word on the need to touch: This rule might trigger if, for example, a # non-Go file was added or deleted from a directory on which this depends. # This target needs to be reconsidered, but Go realizes it doesn't actually # have to be rebuilt. In that case, make will forever see the dependency as -# newer than the binary, and try to rebuild it over and over. So we touch it, -# and make is happy. -$(DEEPCOPY_GEN): +# newer than the binary, and try to "rebuild" it over and over. So we touch +# it, and make is happy. +$(DEEPCOPY_GEN): $(k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/deepcopy-gen) hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/deepcopy-gen touch $@ -# -# Defaulter generation -# -# Any package that wants defaulter functions generated must include a -# comment-tag in column 0 of one file of the form: -# // +k8s:defaulter-gen= -# -# The depends on context: -# on types: -# true: always generate a defaulter for this type -# false: never generate a defaulter for this type -# on functions: -# covers: if the function name matches SetDefault_NAME, instructs -# the generator not to recurse -# on packages: -# FIELDNAME: any object with a field of this name is a candidate -# for having a defaulter generated -# The result file, in each pkg, of defaulter generation. -DEFAULTER_BASENAME := $(GENERATED_FILE_PREFIX)defaults -DEFAULTER_FILENAME := $(DEFAULTER_BASENAME).go - -# The tool used to generate defaulters. -DEFAULTER_GEN := $(BIN_DIR)/defaulter-gen - -# All directories that request any form of defaulter generation. -ifeq ($(DBG_MAKEFILE),1) - $(warning ***** finding all +k8s:defaulter-gen tags) -endif -DEFAULTER_DIRS := $(shell \ - grep --color=never -l '+k8s:defaulter-gen=' $(ALL_K8S_TAG_FILES) \ - | xargs -n1 dirname \ - | LC_ALL=C sort -u \ -) - -DEFAULTER_FILES := $(addsuffix /$(DEFAULTER_FILENAME), $(DEFAULTER_DIRS)) - -# This rule aggregates the set of files to generate and then generates them all -# in a single run of the tool. -.PHONY: gen_defaulter -gen_defaulter: $(DEFAULTER_FILES) $(DEFAULTER_GEN) - if [[ -s $(META_DIR)/$(DEFAULTER_GEN).todo ]]; then \ - pkgs=$$(cat $(META_DIR)/$(DEFAULTER_GEN).todo | paste -sd, -); \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: running $(DEFAULTER_GEN) for $$pkgs"; \ - fi; \ - ./hack/run-in-gopath.sh $(DEFAULTER_GEN) \ - --v $(KUBE_VERBOSE) \ - --logtostderr \ - -i "$$pkgs" \ - --extra-peer-dirs $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(DEFAULTER_DIRS)) | sed 's/ /,/g') \ - -O $(DEFAULTER_BASENAME) \ - "$$@"; \ - fi - -# For each dir in DEFAULTER_DIRS, this establishes a dependency between the -# output file and the input files that should trigger a rebuild. -# -# The variable value was set in $(GOFILES_META) and included as part of the -# dependency management logic. -# -# Note that this is a deps-only statement, not a full rule (see below). This -# has to be done in a distinct step because wildcards don't work in static -# pattern rules. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(DEFAULTER_DIRS), $(eval \ - $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ - $(gofiles__$(dir)) \ -)) - -# For each dir in DEFAULTER_DIRS, for each target in $(defaulters__$(dir)), -# this establishes a dependency between the output file and the input files -# that should trigger a rebuild. -# -# The variable value was set in $(GOFILES_META) and included as part of the -# dependency management logic. -# -# Note that this is a deps-only statement, not a full rule (see below). This -# has to be done in a distinct step because wildcards don't work in static -# pattern rules. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(DEFAULTER_DIRS), \ - $(foreach tgt, $(defaulters__$(dir)), $(eval \ - $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \ - $(gofiles__$(tgt)) \ - )) \ -) - -# Unilaterally remove any leftovers from previous runs. -$(shell rm -f $(META_DIR)/$(DEFAULTER_GEN)*.todo) - -# How to regenerate defaulter code. This is a little slow to run, so we batch -# it up and trigger the batch from the 'generated_files' target. -$(DEFAULTER_FILES): $(DEFAULTER_GEN) - mkdir -p $$(dirname $(META_DIR)/$(DEFAULTER_GEN)) - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: defaulter needed $(@D): $?"; \ - ls -lf --full-time $@ $? || true; \ - fi - echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(DEFAULTER_GEN).todo - -# This calculates the dependencies for the generator tool, so we only rebuild -# it when needed. It is PHONY so that it always runs, but it only updates the -# file if the contents have actually changed. We 'sinclude' this later. -.PHONY: $(META_DIR)/$(DEFAULTER_GEN).mk -$(META_DIR)/$(DEFAULTER_GEN).mk: - mkdir -p $(@D); \ - (echo -n "$(DEFAULTER_GEN): "; \ - ./hack/run-in-gopath.sh go list \ - -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ - ./vendor/k8s.io/code-generator/cmd/defaulter-gen \ - | grep --color=never "^$(PRJ_SRC_PATH)/" \ - | xargs ./hack/run-in-gopath.sh go list \ - -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ - | paste -sd' ' - \ - | sed 's/ / \\=,/g' \ - | tr '=,' '\n\t' \ - | sed "s|$$(pwd -P)/||"; \ - ) > $@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: $(DEFAULTER_GEN).mk changed"; \ - fi; \ - cat $@.tmp > $@; \ - rm -f $@.tmp; \ - fi - -# Include dependency info for the generator tool. This will cause the rule of -# the same name to be considered and if it is updated, make will restart. -sinclude $(META_DIR)/$(DEFAULTER_GEN).mk - -# How to build the generator tool. The deps for this are defined in -# the $(DEFAULTER_GEN).mk, above. -# -# A word on the need to touch: This rule might trigger if, for example, a -# non-Go file was added or deleted from a directory on which this depends. -# This target needs to be reconsidered, but Go realizes it doesn't actually -# have to be rebuilt. In that case, make will forever see the dependency as -# newer than the binary, and try to rebuild it over and over. So we touch it, -# and make is happy. -$(DEFAULTER_GEN): - hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/defaulter-gen - touch $@ - -# -# Conversion generation -# -# Any package that wants conversion functions generated must include one or -# more comment-tags in any .go file, in column 0, of the form: -# // +k8s:conversion-gen= -# -# The CONVERSION_TARGET_DIR is a project-local path to another directory which -# should be considered when evaluating peer types for conversions. Types which -# are found in the source package (where conversions are being generated) -# but do not have a peer in one of the target directories will not have -# conversions generated. -# -# TODO: it might be better in the long term to make peer-types explicit in the -# IDL. - -# The result file, in each pkg, of conversion generation. -CONVERSION_BASENAME := $(GENERATED_FILE_PREFIX)conversion -CONVERSION_FILENAME := $(CONVERSION_BASENAME).go - -# The tool used to generate conversions. -CONVERSION_GEN := $(BIN_DIR)/conversion-gen - -# The name of the metadata file listing conversion peers for each pkg. -CONVERSIONS_META := conversions.mk - -# All directories that request any form of conversion generation. -ifeq ($(DBG_MAKEFILE),1) - $(warning ***** finding all +k8s:conversion-gen tags) -endif -CONVERSION_DIRS := $(shell \ - grep --color=never '^// *+k8s:conversion-gen=' $(ALL_K8S_TAG_FILES) \ - | cut -f1 -d: \ - | xargs -n1 dirname \ - | LC_ALL=C sort -u \ -) - -CONVERSION_FILES := $(addsuffix /$(CONVERSION_FILENAME), $(CONVERSION_DIRS)) -CONVERSION_EXTRA_PEER_DIRS := k8s.io/kubernetes/pkg/apis/core,k8s.io/kubernetes/pkg/apis/core/v1,k8s.io/api/core/v1 - -# This rule aggregates the set of files to generate and then generates them all -# in a single run of the tool. -.PHONY: gen_conversion -gen_conversion: $(CONVERSION_FILES) $(CONVERSION_GEN) - if [[ -s $(META_DIR)/$(CONVERSION_GEN).todo ]]; then \ - pkgs=$$(cat $(META_DIR)/$(CONVERSION_GEN).todo | paste -sd, -); \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: running $(CONVERSION_GEN) for $$pkgs"; \ - fi; \ - ./hack/run-in-gopath.sh $(CONVERSION_GEN) \ - --extra-peer-dirs $(CONVERSION_EXTRA_PEER_DIRS) \ - --v $(KUBE_VERBOSE) \ - --logtostderr \ - -i "$$pkgs" \ - -O $(CONVERSION_BASENAME) \ - "$$@"; \ - fi - -# Establish a dependency between the deps file and the dir. Whenever a dir -# changes (files added or removed) the deps file will be considered stale. -# -# This is looser than we really need (e.g. we don't really care about non *.go -# files or even *_test.go files), but this is much easier to represent. -# -# Because we 'sinclude' the deps file, it is considered for rebuilding, as part -# of make's normal evaluation. If it gets rebuilt, make will restart. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -$(foreach dir, $(CONVERSION_DIRS), $(eval \ - $(META_DIR)/$(dir)/$(CONVERSIONS_META): $(dir) \ -)) - -# How to rebuild a deps file. When make determines that the deps file is stale -# (see above), it executes this rule, and then re-loads the deps file. -# -# This is looser than we really need (e.g. we don't really care about test -# files), but this is MUCH faster than calling `go list`. -# -# We regenerate the output file in order to satisfy make's "newer than" rules, -# but we only need to rebuild targets if the contents actually changed. That -# is what the .stamp file represents. -$(foreach dir, $(CONVERSION_DIRS), \ - $(META_DIR)/$(dir)/$(CONVERSIONS_META)): - TAGS=$$(grep --color=never -h '^// *+k8s:conversion-gen=' $$@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: conversions changed for $@"; \ - fi; \ - touch $@.stamp; \ - fi; \ - mv $@.tmp $@ - -# Include any deps files as additional Makefile rules. This triggers make to -# consider the deps files for rebuild, which makes the whole -# dependency-management logic work. 'sinclude' is "silent include" which does -# not fail if the file does not exist. -$(foreach dir, $(CONVERSION_DIRS), $(eval \ - sinclude $(META_DIR)/$(dir)/$(CONVERSIONS_META) \ -)) - -# For each dir in CONVERSION_DIRS, this establishes a dependency between the -# output file and the input files that should trigger a rebuild. -# -# The variable value was set in $(GOFILES_META) and included as part of the -# dependency management logic. -# -# Note that this is a deps-only statement, not a full rule (see below). This -# has to be done in a distinct step because wildcards don't work in static -# pattern rules. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(CONVERSION_DIRS), $(eval \ - $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ - $(gofiles__$(dir)) \ -)) - -# For each dir in CONVERSION_DIRS, for each target in $(conversions__$(dir)), -# this establishes a dependency between the output file and the input files -# that should trigger a rebuild. -# -# The variable value was set in $(GOFILES_META) and included as part of the -# dependency management logic. -# -# Note that this is a deps-only statement, not a full rule (see below). This -# has to be done in a distinct step because wildcards don't work in static -# pattern rules. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(CONVERSION_DIRS), \ - $(foreach tgt, $(conversions__$(dir)), $(eval \ - $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \ - $(gofiles__$(tgt)) \ - )) \ -) - -# Unilaterally remove any leftovers from previous runs. -$(shell rm -f $(META_DIR)/$(CONVERSION_GEN)*.todo) - -# How to regenerate conversion code. This is a little slow to run, so we batch -# it up and trigger the batch from the 'generated_files' target. -$(CONVERSION_FILES): $(CONVERSION_GEN) - mkdir -p $$(dirname $(META_DIR)/$(CONVERSION_GEN)) - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: conversion needed $(@D): $?"; \ - ls -lf --full-time $@ $? || true; \ - fi - echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(CONVERSION_GEN).todo - -# This calculates the dependencies for the generator tool, so we only rebuild -# it when needed. It is PHONY so that it always runs, but it only updates the -# file if the contents have actually changed. We 'sinclude' this later. -.PHONY: $(META_DIR)/$(CONVERSION_GEN).mk -$(META_DIR)/$(CONVERSION_GEN).mk: - mkdir -p $(@D); \ - (echo -n "$(CONVERSION_GEN): "; \ - ./hack/run-in-gopath.sh go list \ - -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ - ./vendor/k8s.io/code-generator/cmd/conversion-gen \ - | grep --color=never "^$(PRJ_SRC_PATH)/" \ - | xargs ./hack/run-in-gopath.sh go list \ - -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ - | paste -sd' ' - \ - | sed 's/ / \\=,/g' \ - | tr '=,' '\n\t' \ - | sed "s|$$(pwd -P)/||"; \ - ) > $@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: $(CONVERSION_GEN).mk changed"; \ - fi; \ - cat $@.tmp > $@; \ - rm -f $@.tmp; \ - fi - -# Include dependency info for the generator tool. This will cause the rule of -# the same name to be considered and if it is updated, make will restart. -sinclude $(META_DIR)/$(CONVERSION_GEN).mk - -# How to build the generator tool. The deps for this are defined in -# the $(CONVERSION_GEN).mk, above. -# -# A word on the need to touch: This rule might trigger if, for example, a -# non-Go file was added or deleted from a directory on which this depends. -# This target needs to be reconsidered, but Go realizes it doesn't actually -# have to be rebuilt. In that case, make will forever see the dependency as -# newer than the binary, and try to rebuild it over and over. So we touch it, -# and make is happy. -$(CONVERSION_GEN): - hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/conversion-gen - touch $@ - -# -# Open-api generation -# -# Any package that wants open-api functions generated must include a -# comment-tag in column 0 of one file of the form: -# // +k8s:openapi-gen=true -# -# The result file, in each pkg, of open-api generation. -OPENAPI_BASENAME := $(GENERATED_FILE_PREFIX)openapi -OPENAPI_FILENAME := $(OPENAPI_BASENAME).go -OPENAPI_OUTPUT_PKG := pkg/generated/openapi - -# The tool used to generate open apis. -OPENAPI_GEN := $(BIN_DIR)/openapi-gen - -# Find all the directories that request open-api generation. -ifeq ($(DBG_MAKEFILE),1) - $(warning ***** finding all +k8s:openapi-gen tags) -endif -OPENAPI_DIRS := $(shell \ - grep --color=never -l '+k8s:openapi-gen=' $(ALL_K8S_TAG_FILES) \ - | xargs -n1 dirname \ - | LC_ALL=C sort -u \ -) - -OPENAPI_OUTFILE := $(OPENAPI_OUTPUT_PKG)/$(OPENAPI_FILENAME) - -# This rule is the user-friendly entrypoint for openapi generation. -.PHONY: gen_openapi -gen_openapi: $(OPENAPI_OUTFILE) $(OPENAPI_GEN) - -# For each dir in OPENAPI_DIRS, this establishes a dependency between the -# output file and the input files that should trigger a rebuild. -# -# Note that this is a deps-only statement, not a full rule (see below). This -# has to be done in a distinct step because wildcards don't work in static -# pattern rules. -# -# The '$(eval)' is needed because this has a different RHS for each LHS, and -# would otherwise produce results that make can't parse. -# -# We depend on the $(GOFILES_META).stamp to detect when the set of input files -# has changed. This allows us to detect deleted input files. -$(foreach dir, $(OPENAPI_DIRS), $(eval \ - $(OPENAPI_OUTFILE): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ - $(gofiles__$(dir)) \ -)) - -# How to regenerate open-api code. This emits a single file for all results. -$(OPENAPI_OUTFILE): $(OPENAPI_GEN) $(OPENAPI_GEN) - function run_gen_openapi() { \ - ./hack/run-in-gopath.sh $(OPENAPI_GEN) \ - --v $(KUBE_VERBOSE) \ - --logtostderr \ - -i $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(OPENAPI_DIRS)) | sed 's/ /,/g') \ - -p $(PRJ_SRC_PATH)/$(OPENAPI_OUTPUT_PKG) \ - -O $(OPENAPI_BASENAME) \ - "$$@"; \ - }; \ - run_gen_openapi - -# This calculates the dependencies for the generator tool, so we only rebuild -# it when needed. It is PHONY so that it always runs, but it only updates the -# file if the contents have actually changed. We 'sinclude' this later. -.PHONY: $(META_DIR)/$(OPENAPI_GEN).mk -$(META_DIR)/$(OPENAPI_GEN).mk: - mkdir -p $(@D); \ - (echo -n "$(OPENAPI_GEN): "; \ - ./hack/run-in-gopath.sh go list \ - -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ - ./vendor/k8s.io/code-generator/cmd/openapi-gen \ - | grep --color=never "^$(PRJ_SRC_PATH)/" \ - | xargs ./hack/run-in-gopath.sh go list \ - -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ - | paste -sd' ' - \ - | sed 's/ / \\=,/g' \ - | tr '=,' '\n\t' \ - | sed "s|$$(pwd -P)/||"; \ - ) > $@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: $(OPENAPI_GEN).mk changed"; \ - fi; \ - cat $@.tmp > $@; \ - rm -f $@.tmp; \ - fi - -# Include dependency info for the generator tool. This will cause the rule of -# the same name to be considered and if it is updated, make will restart. -sinclude $(META_DIR)/$(OPENAPI_GEN).mk - -# How to build the generator tool. The deps for this are defined in -# the $(OPENAPI_GEN).mk, above. -# -# A word on the need to touch: This rule might trigger if, for example, a -# non-Go file was added or deleted from a directory on which this depends. -# This target needs to be reconsidered, but Go realizes it doesn't actually -# have to be rebuilt. In that case, make will forever see the dependency as -# newer than the binary, and try to rebuild it over and over. So we touch it, -# and make is happy. -$(OPENAPI_GEN): - hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/openapi-gen - touch $@ - -# -# bindata generation -# - -# The tool used to generate bindata files. -BINDATA_GEN := $(BIN_DIR)/go-bindata - -# A wrapper script that generates all bindata files. It is fast enough that we -# don't care. -BINDATA_SCRIPT := hack/generate-bindata.sh - -# This rule is the user-friendly entrypoint for bindata generation. -.PHONY: gen_bindata -gen_bindata: $(BINDATA_GEN) FORCE - ./hack/run-in-gopath.sh $(BINDATA_SCRIPT) - -FORCE: - -# This calculates the dependencies for the generator tool, so we only rebuild -# it when needed. It is PHONY so that it always runs, but it only updates the -# file if the contents have actually changed. We 'sinclude' this later. -.PHONY: $(META_DIR)/$(BINDATA_GEN).mk -$(META_DIR)/$(BINDATA_GEN).mk: - mkdir -p $(@D); \ - (echo -n "$(BINDATA_GEN): "; \ - ./hack/run-in-gopath.sh go list \ - -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ - ./vendor/github.com/jteeuwen/go-bindata/go-bindata \ - | grep --color=never "^$(PRJ_SRC_PATH)/" \ - | xargs ./hack/run-in-gopath.sh go list \ - -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ - | paste -sd' ' - \ - | sed 's/ / \\=,/g' \ - | tr '=,' '\n\t' \ - | sed "s|$$(pwd -P)/||"; \ - ) > $@.tmp; \ - if ! cmp -s $@.tmp $@; then \ - if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ - echo "DBG: $(BINDATA_GEN).mk changed"; \ - fi; \ - cat $@.tmp > $@; \ - rm -f $@.tmp; \ - fi - -# Include dependency info for the generator tool. This will cause the rule of -# the same name to be considered and if it is updated, make will restart. -sinclude $(META_DIR)/$(BINDATA_GEN).mk - -# How to build the generator tool. The deps for this are defined in -# the $(BINDATA_GEN).mk, above. -# -# A word on the need to touch: This rule might trigger if, for example, a -# non-Go file was added or deleted from a directory on which this depends. -# This target needs to be reconsidered, but Go realizes it doesn't actually -# have to be rebuilt. In that case, make will forever see the dependency as -# newer than the binary, and try to rebuild it over and over. So we touch it, -# and make is happy. -$(BINDATA_GEN): - hack/make-rules/build.sh ./vendor/github.com/jteeuwen/go-bindata/go-bindata - touch $@ +##TH### Defaulter generation +##TH### +##TH### Any package that wants defaulter functions generated must include a +##TH### comment-tag in column 0 of one file of the form: +##TH### // +k8s:defaulter-gen= +##TH### +##TH### The depends on context: +##TH### on types: +##TH### true: always generate a defaulter for this type +##TH### false: never generate a defaulter for this type +##TH### on functions: +##TH### covers: if the function name matches SetDefault_NAME, instructs +##TH### the generator not to recurse +##TH### on packages: +##TH### FIELDNAME: any object with a field of this name is a candidate +##TH### for having a defaulter generated +##TH## +##TH### The result file, in each pkg, of defaulter generation. +##TH##DEFAULTER_BASENAME := $(GENERATED_FILE_PREFIX)defaults +##TH##DEFAULTER_FILENAME := $(DEFAULTER_BASENAME).go +##TH## +##TH### The tool used to generate defaulters. +##TH##DEFAULTER_GEN := $(BIN_DIR)/defaulter-gen +##TH## +##TH### All directories that request any form of defaulter generation. +##TH##ifeq ($(DBG_MAKEFILE),1) +##TH## $(warning ***** finding all +k8s:defaulter-gen tags) +##TH##endif +##TH##DEFAULTER_DIRS := $(shell \ +##TH## grep --color=never -l '+k8s:defaulter-gen=' $(ALL_K8S_TAG_FILES) \ +##TH## | xargs -n1 dirname \ +##TH## | LC_ALL=C sort -u \ +##TH##) +##TH## +##TH##DEFAULTER_FILES := $(addsuffix /$(DEFAULTER_FILENAME), $(DEFAULTER_DIRS)) +##TH## +##TH### This rule aggregates the set of files to generate and then generates them all +##TH### in a single run of the tool. +##TH##.PHONY: gen_defaulter +##TH##gen_defaulter: $(DEFAULTER_FILES) $(DEFAULTER_GEN) +##TH## if [[ -s $(META_DIR)/$(DEFAULTER_GEN).todo ]]; then \ +##TH## pkgs=$$(cat $(META_DIR)/$(DEFAULTER_GEN).todo | paste -sd, -); \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: running $(DEFAULTER_GEN) for $$pkgs"; \ +##TH## fi; \ +##TH## ./hack/run-in-gopath.sh $(DEFAULTER_GEN) \ +##TH## --v $(KUBE_VERBOSE) \ +##TH## --logtostderr \ +##TH## -i "$$pkgs" \ +##TH## --extra-peer-dirs $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(DEFAULTER_DIRS)) | sed 's/ /,/g') \ +##TH## -O $(DEFAULTER_BASENAME) \ +##TH## "$$@"; \ +##TH## fi +##TH## +##TH### For each dir in DEFAULTER_DIRS, this establishes a dependency between the +##TH### output file and the input files that should trigger a rebuild. +##TH### +##TH### The variable value was set in $(GOFILES_META) and included as part of the +##TH### dependency management logic. +##TH### +##TH### Note that this is a deps-only statement, not a full rule (see below). This +##TH### has to be done in a distinct step because wildcards don't work in static +##TH### pattern rules. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH### +##TH### We depend on the $(GOFILES_META).stamp to detect when the set of input files +##TH### has changed. This allows us to detect deleted input files. +##TH##$(foreach dir, $(DEFAULTER_DIRS), $(eval \ +##TH## $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ +##TH## $(gofiles__$(dir)) \ +##TH##)) +##TH## +##TH### For each dir in DEFAULTER_DIRS, for each target in $(defaulters__$(dir)), +##TH### this establishes a dependency between the output file and the input files +##TH### that should trigger a rebuild. +##TH### +##TH### The variable value was set in $(GOFILES_META) and included as part of the +##TH### dependency management logic. +##TH### +##TH### Note that this is a deps-only statement, not a full rule (see below). This +##TH### has to be done in a distinct step because wildcards don't work in static +##TH### pattern rules. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH### +##TH### We depend on the $(GOFILES_META).stamp to detect when the set of input files +##TH### has changed. This allows us to detect deleted input files. +##TH##$(foreach dir, $(DEFAULTER_DIRS), \ +##TH## $(foreach tgt, $(defaulters__$(dir)), $(eval \ +##TH## $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \ +##TH## $(gofiles__$(tgt)) \ +##TH## )) \ +##TH##) +##TH## +##TH### Unilaterally remove any leftovers from previous runs. +##TH##$(shell rm -f $(META_DIR)/$(DEFAULTER_GEN)*.todo) +##TH## +##TH### How to regenerate defaulter code. This is a little slow to run, so we batch +##TH### it up and trigger the batch from the 'generated_files' target. +##TH##$(DEFAULTER_FILES): $(DEFAULTER_GEN) +##TH## mkdir -p $$(dirname $(META_DIR)/$(DEFAULTER_GEN)) +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: defaulter needed $(@D): $?"; \ +##TH## ls -lf --full-time $@ $? || true; \ +##TH## fi +##TH## echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(DEFAULTER_GEN).todo +##TH## +##TH### This calculates the dependencies for the generator tool, so we only rebuild +##TH### it when needed. It is PHONY so that it always runs, but it only updates the +##TH### file if the contents have actually changed. We 'sinclude' this later. +##TH##.PHONY: $(META_DIR)/$(DEFAULTER_GEN).mk +##TH##$(META_DIR)/$(DEFAULTER_GEN).mk: +##TH## mkdir -p $(@D); \ +##TH## (echo -n "$(DEFAULTER_GEN): "; \ +##TH## ./hack/run-in-gopath.sh go list \ +##TH## -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ +##TH## ./vendor/k8s.io/code-generator/cmd/defaulter-gen \ +##TH## | grep --color=never "^$(PRJ_SRC_PATH)/" \ +##TH## | xargs ./hack/run-in-gopath.sh go list \ +##TH## -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ +##TH## | paste -sd' ' - \ +##TH## | sed 's/ / \\=,/g' \ +##TH## | tr '=,' '\n\t' \ +##TH## | sed "s|$$(pwd -P)/||"; \ +##TH## ) > $@.tmp; \ +##TH## if ! cmp -s $@.tmp $@; then \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: $(DEFAULTER_GEN).mk changed"; \ +##TH## fi; \ +##TH## cat $@.tmp > $@; \ +##TH## rm -f $@.tmp; \ +##TH## fi +##TH## +##TH### Include dependency info for the generator tool. This will cause the rule of +##TH### the same name to be considered and if it is updated, make will restart. +##TH##sinclude $(META_DIR)/$(DEFAULTER_GEN).mk +##TH## +##TH### How to build the generator tool. The deps for this are defined in +##TH### the $(DEFAULTER_GEN).mk, above. +##TH### +##TH### A word on the need to touch: This rule might trigger if, for example, a +##TH### non-Go file was added or deleted from a directory on which this depends. +##TH### This target needs to be reconsidered, but Go realizes it doesn't actually +##TH### have to be rebuilt. In that case, make will forever see the dependency as +##TH### newer than the binary, and try to rebuild it over and over. So we touch it, +##TH### and make is happy. +##TH##$(DEFAULTER_GEN): +##TH## hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/defaulter-gen +##TH## touch $@ +##TH## +##TH### +##TH### Conversion generation +##TH### +##TH### Any package that wants conversion functions generated must include one or +##TH### more comment-tags in any .go file, in column 0, of the form: +##TH### // +k8s:conversion-gen= +##TH### +##TH### The CONVERSION_TARGET_DIR is a project-local path to another directory which +##TH### should be considered when evaluating peer types for conversions. Types which +##TH### are found in the source package (where conversions are being generated) +##TH### but do not have a peer in one of the target directories will not have +##TH### conversions generated. +##TH### +##TH### TODO: it might be better in the long term to make peer-types explicit in the +##TH### IDL. +##TH## +##TH### The result file, in each pkg, of conversion generation. +##TH##CONVERSION_BASENAME := $(GENERATED_FILE_PREFIX)conversion +##TH##CONVERSION_FILENAME := $(CONVERSION_BASENAME).go +##TH## +##TH### The tool used to generate conversions. +##TH##CONVERSION_GEN := $(BIN_DIR)/conversion-gen +##TH## +##TH### The name of the metadata file listing conversion peers for each pkg. +##TH##CONVERSIONS_META := conversions.mk +##TH## +##TH### All directories that request any form of conversion generation. +##TH##ifeq ($(DBG_MAKEFILE),1) +##TH## $(warning ***** finding all +k8s:conversion-gen tags) +##TH##endif +##TH##CONVERSION_DIRS := $(shell \ +##TH## grep --color=never '^// *+k8s:conversion-gen=' $(ALL_K8S_TAG_FILES) \ +##TH## | cut -f1 -d: \ +##TH## | xargs -n1 dirname \ +##TH## | LC_ALL=C sort -u \ +##TH##) +##TH## +##TH##CONVERSION_FILES := $(addsuffix /$(CONVERSION_FILENAME), $(CONVERSION_DIRS)) +##TH##CONVERSION_EXTRA_PEER_DIRS := k8s.io/kubernetes/pkg/apis/core,k8s.io/kubernetes/pkg/apis/core/v1,k8s.io/api/core/v1 +##TH## +##TH### This rule aggregates the set of files to generate and then generates them all +##TH### in a single run of the tool. +##TH##.PHONY: gen_conversion +##TH##gen_conversion: $(CONVERSION_FILES) $(CONVERSION_GEN) +##TH## if [[ -s $(META_DIR)/$(CONVERSION_GEN).todo ]]; then \ +##TH## pkgs=$$(cat $(META_DIR)/$(CONVERSION_GEN).todo | paste -sd, -); \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: running $(CONVERSION_GEN) for $$pkgs"; \ +##TH## fi; \ +##TH## ./hack/run-in-gopath.sh $(CONVERSION_GEN) \ +##TH## --extra-peer-dirs $(CONVERSION_EXTRA_PEER_DIRS) \ +##TH## --v $(KUBE_VERBOSE) \ +##TH## --logtostderr \ +##TH## -i "$$pkgs" \ +##TH## -O $(CONVERSION_BASENAME) \ +##TH## "$$@"; \ +##TH## fi +##TH## +##TH### Establish a dependency between the deps file and the dir. Whenever a dir +##TH### changes (files added or removed) the deps file will be considered stale. +##TH### +##TH### This is looser than we really need (e.g. we don't really care about non *.go +##TH### files or even *_test.go files), but this is much easier to represent. +##TH### +##TH### Because we 'sinclude' the deps file, it is considered for rebuilding, as part +##TH### of make's normal evaluation. If it gets rebuilt, make will restart. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH##$(foreach dir, $(CONVERSION_DIRS), $(eval \ +##TH## $(META_DIR)/$(dir)/$(CONVERSIONS_META): $(dir) \ +##TH##)) +##TH## +##TH### How to rebuild a deps file. When make determines that the deps file is stale +##TH### (see above), it executes this rule, and then re-loads the deps file. +##TH### +##TH### This is looser than we really need (e.g. we don't really care about test +##TH### files), but this is MUCH faster than calling `go list`. +##TH### +##TH### We regenerate the output file in order to satisfy make's "newer than" rules, +##TH### but we only need to rebuild targets if the contents actually changed. That +##TH### is what the .stamp file represents. +##TH##$(foreach dir, $(CONVERSION_DIRS), \ +##TH## $(META_DIR)/$(dir)/$(CONVERSIONS_META)): +##TH## TAGS=$$(grep --color=never -h '^// *+k8s:conversion-gen=' $$@.tmp; \ +##TH## if ! cmp -s $@.tmp $@; then \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: conversions changed for $@"; \ +##TH## fi; \ +##TH## touch $@.stamp; \ +##TH## fi; \ +##TH## mv $@.tmp $@ +##TH## +##TH### Include any deps files as additional Makefile rules. This triggers make to +##TH### consider the deps files for rebuild, which makes the whole +##TH### dependency-management logic work. 'sinclude' is "silent include" which does +##TH### not fail if the file does not exist. +##TH##$(foreach dir, $(CONVERSION_DIRS), $(eval \ +##TH## sinclude $(META_DIR)/$(dir)/$(CONVERSIONS_META) \ +##TH##)) +##TH## +##TH### For each dir in CONVERSION_DIRS, this establishes a dependency between the +##TH### output file and the input files that should trigger a rebuild. +##TH### +##TH### The variable value was set in $(GOFILES_META) and included as part of the +##TH### dependency management logic. +##TH### +##TH### Note that this is a deps-only statement, not a full rule (see below). This +##TH### has to be done in a distinct step because wildcards don't work in static +##TH### pattern rules. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH### +##TH### We depend on the $(GOFILES_META).stamp to detect when the set of input files +##TH### has changed. This allows us to detect deleted input files. +##TH##$(foreach dir, $(CONVERSION_DIRS), $(eval \ +##TH## $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ +##TH## $(gofiles__$(dir)) \ +##TH##)) +##TH## +##TH### For each dir in CONVERSION_DIRS, for each target in $(conversions__$(dir)), +##TH### this establishes a dependency between the output file and the input files +##TH### that should trigger a rebuild. +##TH### +##TH### The variable value was set in $(GOFILES_META) and included as part of the +##TH### dependency management logic. +##TH### +##TH### Note that this is a deps-only statement, not a full rule (see below). This +##TH### has to be done in a distinct step because wildcards don't work in static +##TH### pattern rules. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH### +##TH### We depend on the $(GOFILES_META).stamp to detect when the set of input files +##TH### has changed. This allows us to detect deleted input files. +##TH##$(foreach dir, $(CONVERSION_DIRS), \ +##TH## $(foreach tgt, $(conversions__$(dir)), $(eval \ +##TH## $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \ +##TH## $(gofiles__$(tgt)) \ +##TH## )) \ +##TH##) +##TH## +##TH### Unilaterally remove any leftovers from previous runs. +##TH##$(shell rm -f $(META_DIR)/$(CONVERSION_GEN)*.todo) +##TH## +##TH### How to regenerate conversion code. This is a little slow to run, so we batch +##TH### it up and trigger the batch from the 'generated_files' target. +##TH##$(CONVERSION_FILES): $(CONVERSION_GEN) +##TH## mkdir -p $$(dirname $(META_DIR)/$(CONVERSION_GEN)) +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: conversion needed $(@D): $?"; \ +##TH## ls -lf --full-time $@ $? || true; \ +##TH## fi +##TH## echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(CONVERSION_GEN).todo +##TH## +##TH### This calculates the dependencies for the generator tool, so we only rebuild +##TH### it when needed. It is PHONY so that it always runs, but it only updates the +##TH### file if the contents have actually changed. We 'sinclude' this later. +##TH##.PHONY: $(META_DIR)/$(CONVERSION_GEN).mk +##TH##$(META_DIR)/$(CONVERSION_GEN).mk: +##TH## mkdir -p $(@D); \ +##TH## (echo -n "$(CONVERSION_GEN): "; \ +##TH## ./hack/run-in-gopath.sh go list \ +##TH## -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ +##TH## ./vendor/k8s.io/code-generator/cmd/conversion-gen \ +##TH## | grep --color=never "^$(PRJ_SRC_PATH)/" \ +##TH## | xargs ./hack/run-in-gopath.sh go list \ +##TH## -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ +##TH## | paste -sd' ' - \ +##TH## | sed 's/ / \\=,/g' \ +##TH## | tr '=,' '\n\t' \ +##TH## | sed "s|$$(pwd -P)/||"; \ +##TH## ) > $@.tmp; \ +##TH## if ! cmp -s $@.tmp $@; then \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: $(CONVERSION_GEN).mk changed"; \ +##TH## fi; \ +##TH## cat $@.tmp > $@; \ +##TH## rm -f $@.tmp; \ +##TH## fi +##TH## +##TH### Include dependency info for the generator tool. This will cause the rule of +##TH### the same name to be considered and if it is updated, make will restart. +##TH##sinclude $(META_DIR)/$(CONVERSION_GEN).mk +##TH## +##TH### How to build the generator tool. The deps for this are defined in +##TH### the $(CONVERSION_GEN).mk, above. +##TH### +##TH### A word on the need to touch: This rule might trigger if, for example, a +##TH### non-Go file was added or deleted from a directory on which this depends. +##TH### This target needs to be reconsidered, but Go realizes it doesn't actually +##TH### have to be rebuilt. In that case, make will forever see the dependency as +##TH### newer than the binary, and try to rebuild it over and over. So we touch it, +##TH### and make is happy. +##TH##$(CONVERSION_GEN): +##TH## hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/conversion-gen +##TH## touch $@ +##TH## +##TH### +##TH### Open-api generation +##TH### +##TH### Any package that wants open-api functions generated must include a +##TH### comment-tag in column 0 of one file of the form: +##TH### // +k8s:openapi-gen=true +##TH### +##TH### The result file, in each pkg, of open-api generation. +##TH##OPENAPI_BASENAME := $(GENERATED_FILE_PREFIX)openapi +##TH##OPENAPI_FILENAME := $(OPENAPI_BASENAME).go +##TH##OPENAPI_OUTPUT_PKG := pkg/generated/openapi +##TH## +##TH### The tool used to generate open apis. +##TH##OPENAPI_GEN := $(BIN_DIR)/openapi-gen +##TH## +##TH### Find all the directories that request open-api generation. +##TH##ifeq ($(DBG_MAKEFILE),1) +##TH## $(warning ***** finding all +k8s:openapi-gen tags) +##TH##endif +##TH##OPENAPI_DIRS := $(shell \ +##TH## grep --color=never -l '+k8s:openapi-gen=' $(ALL_K8S_TAG_FILES) \ +##TH## | xargs -n1 dirname \ +##TH## | LC_ALL=C sort -u \ +##TH##) +##TH## +##TH##OPENAPI_OUTFILE := $(OPENAPI_OUTPUT_PKG)/$(OPENAPI_FILENAME) +##TH## +##TH### This rule is the user-friendly entrypoint for openapi generation. +##TH##.PHONY: gen_openapi +##TH##gen_openapi: $(OPENAPI_OUTFILE) $(OPENAPI_GEN) +##TH## +##TH### For each dir in OPENAPI_DIRS, this establishes a dependency between the +##TH### output file and the input files that should trigger a rebuild. +##TH### +##TH### Note that this is a deps-only statement, not a full rule (see below). This +##TH### has to be done in a distinct step because wildcards don't work in static +##TH### pattern rules. +##TH### +##TH### The '$(eval)' is needed because this has a different RHS for each LHS, and +##TH### would otherwise produce results that make can't parse. +##TH### +##TH### We depend on the $(GOFILES_META).stamp to detect when the set of input files +##TH### has changed. This allows us to detect deleted input files. +##TH##$(foreach dir, $(OPENAPI_DIRS), $(eval \ +##TH## $(OPENAPI_OUTFILE): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \ +##TH## $(gofiles__$(dir)) \ +##TH##)) +##TH## +##TH### How to regenerate open-api code. This emits a single file for all results. +##TH##$(OPENAPI_OUTFILE): $(OPENAPI_GEN) $(OPENAPI_GEN) +##TH## function run_gen_openapi() { \ +##TH## ./hack/run-in-gopath.sh $(OPENAPI_GEN) \ +##TH## --v $(KUBE_VERBOSE) \ +##TH## --logtostderr \ +##TH## -i $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(OPENAPI_DIRS)) | sed 's/ /,/g') \ +##TH## -p $(PRJ_SRC_PATH)/$(OPENAPI_OUTPUT_PKG) \ +##TH## -O $(OPENAPI_BASENAME) \ +##TH## "$$@"; \ +##TH## }; \ +##TH## run_gen_openapi +##TH## +##TH### This calculates the dependencies for the generator tool, so we only rebuild +##TH### it when needed. It is PHONY so that it always runs, but it only updates the +##TH### file if the contents have actually changed. We 'sinclude' this later. +##TH##.PHONY: $(META_DIR)/$(OPENAPI_GEN).mk +##TH##$(META_DIR)/$(OPENAPI_GEN).mk: +##TH## mkdir -p $(@D); \ +##TH## (echo -n "$(OPENAPI_GEN): "; \ +##TH## ./hack/run-in-gopath.sh go list \ +##TH## -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ +##TH## ./vendor/k8s.io/code-generator/cmd/openapi-gen \ +##TH## | grep --color=never "^$(PRJ_SRC_PATH)/" \ +##TH## | xargs ./hack/run-in-gopath.sh go list \ +##TH## -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ +##TH## | paste -sd' ' - \ +##TH## | sed 's/ / \\=,/g' \ +##TH## | tr '=,' '\n\t' \ +##TH## | sed "s|$$(pwd -P)/||"; \ +##TH## ) > $@.tmp; \ +##TH## if ! cmp -s $@.tmp $@; then \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: $(OPENAPI_GEN).mk changed"; \ +##TH## fi; \ +##TH## cat $@.tmp > $@; \ +##TH## rm -f $@.tmp; \ +##TH## fi +##TH## +##TH### Include dependency info for the generator tool. This will cause the rule of +##TH### the same name to be considered and if it is updated, make will restart. +##TH##sinclude $(META_DIR)/$(OPENAPI_GEN).mk +##TH## +##TH### How to build the generator tool. The deps for this are defined in +##TH### the $(OPENAPI_GEN).mk, above. +##TH### +##TH### A word on the need to touch: This rule might trigger if, for example, a +##TH### non-Go file was added or deleted from a directory on which this depends. +##TH### This target needs to be reconsidered, but Go realizes it doesn't actually +##TH### have to be rebuilt. In that case, make will forever see the dependency as +##TH### newer than the binary, and try to rebuild it over and over. So we touch it, +##TH### and make is happy. +##TH##$(OPENAPI_GEN): +##TH## hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/openapi-gen +##TH## touch $@ +##TH## +##TH### +##TH### bindata generation +##TH### +##TH## +##TH### The tool used to generate bindata files. +##TH##BINDATA_GEN := $(BIN_DIR)/go-bindata +##TH## +##TH### A wrapper script that generates all bindata files. It is fast enough that we +##TH### don't care. +##TH##BINDATA_SCRIPT := hack/generate-bindata.sh +##TH## +##TH### This rule is the user-friendly entrypoint for bindata generation. +##TH##.PHONY: gen_bindata +##TH##gen_bindata: $(BINDATA_GEN) FORCE +##TH## ./hack/run-in-gopath.sh $(BINDATA_SCRIPT) +##TH## +##TH### This calculates the dependencies for the generator tool, so we only rebuild +##TH### it when needed. It is PHONY so that it always runs, but it only updates the +##TH### file if the contents have actually changed. We 'sinclude' this later. +##TH##.PHONY: $(META_DIR)/$(BINDATA_GEN).mk +##TH##$(META_DIR)/$(BINDATA_GEN).mk: +##TH## mkdir -p $(@D); \ +##TH## (echo -n "$(BINDATA_GEN): "; \ +##TH## ./hack/run-in-gopath.sh go list \ +##TH## -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \ +##TH## ./vendor/github.com/jteeuwen/go-bindata/go-bindata \ +##TH## | grep --color=never "^$(PRJ_SRC_PATH)/" \ +##TH## | xargs ./hack/run-in-gopath.sh go list \ +##TH## -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \ +##TH## | paste -sd' ' - \ +##TH## | sed 's/ / \\=,/g' \ +##TH## | tr '=,' '\n\t' \ +##TH## | sed "s|$$(pwd -P)/||"; \ +##TH## ) > $@.tmp; \ +##TH## if ! cmp -s $@.tmp $@; then \ +##TH## if [[ "$(DBG_CODEGEN)" == 1 ]]; then \ +##TH## echo "DBG: $(BINDATA_GEN).mk changed"; \ +##TH## fi; \ +##TH## cat $@.tmp > $@; \ +##TH## rm -f $@.tmp; \ +##TH## fi +##TH## +##TH### Include dependency info for the generator tool. This will cause the rule of +##TH### the same name to be considered and if it is updated, make will restart. +##TH##sinclude $(META_DIR)/$(BINDATA_GEN).mk +##TH## +##TH### How to build the generator tool. The deps for this are defined in +##TH### the $(BINDATA_GEN).mk, above. +##TH### +##TH### A word on the need to touch: This rule might trigger if, for example, a +##TH### non-Go file was added or deleted from a directory on which this depends. +##TH### This target needs to be reconsidered, but Go realizes it doesn't actually +##TH### have to be rebuilt. In that case, make will forever see the dependency as +##TH### newer than the binary, and try to rebuild it over and over. So we touch it, +##TH### and make is happy. +##TH##$(BINDATA_GEN): +##TH## hack/make-rules/build.sh ./vendor/github.com/jteeuwen/go-bindata/go-bindata +##TH## touch $@