Makefile.generated_files 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. # Copyright 2016 The Kubernetes Authors.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # Don't allow users to call this directly. There are too many variables this
  15. # assumes to inherit from the main Makefile. This is not a user-facing file.
  16. ifeq ($(CALLED_FROM_MAIN_MAKEFILE),)
  17. $(error Please use the main Makefile, e.g. `make generated_files`)
  18. endif
  19. # Don't allow an implicit 'all' rule. This is not a user-facing file.
  20. ifeq ($(MAKECMDGOALS),)
  21. $(error This Makefile requires an explicit rule to be specified)
  22. endif
  23. ifeq ($(DBG_MAKEFILE),1)
  24. $(warning ***** starting Makefile.generated_files for goal(s) "$(MAKECMDGOALS)")
  25. $(warning ***** $(shell date))
  26. endif
  27. # It's necessary to set this because some environments don't link sh -> bash.
  28. SHELL := /bin/bash
  29. # This rule collects all the generated file sets into a single rule. Other
  30. # rules should depend on this to ensure generated files are rebuilt.
  31. .PHONY: generated_files
  32. generated_files: gen_deepcopy gen_defaulter gen_conversion gen_openapi
  33. .PHONY: verify_generated_files
  34. verify_generated_files: verify_gen_deepcopy \
  35. verify_gen_defaulter \
  36. verify_gen_conversion
  37. # Code-generation logic.
  38. #
  39. # This stuff can be pretty tricky, and there's probably some corner cases that
  40. # we don't handle well. That said, here's a straightforward test to prove that
  41. # the most common cases work. Sadly, it is manual.
  42. #
  43. # make clean
  44. # find . -name .make\* | xargs rm -f
  45. # find . -name zz_generated\* | xargs rm -f
  46. # # verify `find . -name zz_generated.deepcopy.go | wc -l` is 0
  47. # # verify `find . -name .make | wc -l` is 0
  48. #
  49. # make nonexistent
  50. # # expect "No rule to make target"
  51. # # verify `find .make/ -type f | wc -l` has many files
  52. #
  53. # make gen_deepcopy
  54. # # expect deepcopy-gen is built exactly once
  55. # # expect many files to be regenerated
  56. # # verify `find . -name zz_generated.deepcopy.go | wc -l` has files
  57. # make gen_deepcopy
  58. # # expect nothing to be rebuilt, finish in O(seconds)
  59. # touch pkg/api/types.go
  60. # make gen_deepcopy
  61. # # expect one file to be regenerated
  62. # make gen_deepcopy
  63. # # expect nothing to be rebuilt, finish in O(seconds)
  64. # touch vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go
  65. # make gen_deepcopy
  66. # # expect deepcopy-gen is built exactly once
  67. # # expect many files to be regenerated
  68. # # verify `find . -name zz_generated.deepcopy.go | wc -l` has files
  69. # make gen_deepcopy
  70. # # expect nothing to be rebuilt, finish in O(seconds)
  71. #
  72. # make gen_conversion
  73. # # expect conversion-gen is built exactly once
  74. # # expect many files to be regenerated
  75. # # verify `find . -name zz_generated.conversion.go | wc -l` has files
  76. # make gen_conversion
  77. # # expect nothing to be rebuilt, finish in O(seconds)
  78. # touch pkg/api/types.go
  79. # make gen_conversion
  80. # # expect one file to be regenerated
  81. # make gen_conversion
  82. # # expect nothing to be rebuilt, finish in O(seconds)
  83. # touch vendor/k8s.io/code-generator/cmd/conversion-gen/main.go
  84. # make gen_conversion
  85. # # expect conversion-gen is built exactly once
  86. # # expect many files to be regenerated
  87. # # verify `find . -name zz_generated.conversion.go | wc -l` has files
  88. # make gen_conversion
  89. # # expect nothing to be rebuilt, finish in O(seconds)
  90. #
  91. # make all
  92. # # expect it to build
  93. #
  94. # make test
  95. # # expect it to pass
  96. #
  97. # make clean
  98. # # verify `find . -name zz_generated.deepcopy.go | wc -l` is 0
  99. # # verify `find . -name .make | wc -l` is 0
  100. #
  101. # make all WHAT=cmd/kube-proxy
  102. # # expect it to build
  103. #
  104. # make clean
  105. # make test WHAT=cmd/kube-proxy
  106. # # expect it to pass
  107. # This variable holds a list of every directory that contains Go files in this
  108. # project. Other rules and variables can use this as a starting point to
  109. # reduce filesystem accesses.
  110. ifeq ($(DBG_MAKEFILE),1)
  111. $(warning ***** finding all *.go dirs)
  112. endif
  113. ALL_GO_DIRS := $(shell \
  114. hack/make-rules/helpers/cache_go_dirs.sh $(META_DIR)/all_go_dirs.mk \
  115. )
  116. # The name of the metadata file which lists *.go files in each pkg.
  117. GOFILES_META := gofiles.mk
  118. # Establish a dependency between the deps file and the dir. Whenever a dir
  119. # changes (files added or removed) the deps file will be considered stale.
  120. #
  121. # The variable value was set in $(GOFILES_META) and included as part of the
  122. # dependency management logic.
  123. #
  124. # This is looser than we really need (e.g. we don't really care about non *.go
  125. # files or even *_test.go files), but this is much easier to represent.
  126. #
  127. # Because we 'sinclude' the deps file, it is considered for rebuilding, as part
  128. # of make's normal evaluation. If it gets rebuilt, make will restart.
  129. #
  130. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  131. # would otherwise produce results that make can't parse.
  132. $(foreach dir, $(ALL_GO_DIRS), $(eval \
  133. $(META_DIR)/$(dir)/$(GOFILES_META): $(dir) \
  134. ))
  135. # How to rebuild a deps file. When make determines that the deps file is stale
  136. # (see above), it executes this rule, and then re-loads the deps file.
  137. #
  138. # This is looser than we really need (e.g. we don't really care about test
  139. # files), but this is MUCH faster than calling `go list`.
  140. #
  141. # We regenerate the output file in order to satisfy make's "newer than" rules,
  142. # but we only need to rebuild targets if the contents actually changed. That
  143. # is what the .stamp file represents.
  144. $(foreach dir, $(ALL_GO_DIRS), \
  145. $(META_DIR)/$(dir)/$(GOFILES_META)):
  146. FILES=$$(ls $</*.go | grep --color=never -v $(GENERATED_FILE_PREFIX)); \
  147. mkdir -p $(@D); \
  148. echo "gofiles__$< := $$(echo $${FILES})" >$@.tmp; \
  149. if ! cmp -s $@.tmp $@; then \
  150. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  151. echo "DBG: gofiles changed for $@"; \
  152. fi; \
  153. touch $@.stamp; \
  154. fi; \
  155. mv $@.tmp $@
  156. # This is required to fill in the DAG, since some cases (e.g. 'make clean all')
  157. # will reference the .stamp file when it doesn't exist. We don't need to
  158. # rebuild it in that case, just keep make happy.
  159. $(foreach dir, $(ALL_GO_DIRS), \
  160. $(META_DIR)/$(dir)/$(GOFILES_META).stamp):
  161. # Include any deps files as additional Makefile rules. This triggers make to
  162. # consider the deps files for rebuild, which makes the whole
  163. # dependency-management logic work. 'sinclude' is "silent include" which does
  164. # not fail if the file does not exist.
  165. $(foreach dir, $(ALL_GO_DIRS), $(eval \
  166. sinclude $(META_DIR)/$(dir)/$(GOFILES_META) \
  167. ))
  168. # Generate a list of all files that have a `+k8s:` comment-tag. This will be
  169. # used to derive lists of files/dirs for generation tools.
  170. ifeq ($(DBG_MAKEFILE),1)
  171. $(warning ***** finding all +k8s: tags)
  172. endif
  173. ALL_K8S_TAG_FILES := $(shell \
  174. find $(ALL_GO_DIRS) -maxdepth 1 -type f -name \*.go \
  175. | xargs grep --color=never -l '^// *+k8s:' \
  176. )
  177. #
  178. # Deep-copy generation
  179. #
  180. # Any package that wants deep-copy functions generated must include a
  181. # comment-tag in column 0 of one file of the form:
  182. # // +k8s:deepcopy-gen=<VALUE>
  183. #
  184. # The <VALUE> may be one of:
  185. # generate: generate deep-copy functions into the package
  186. # register: generate deep-copy functions and register them with a
  187. # scheme
  188. # The result file, in each pkg, of deep-copy generation.
  189. DEEPCOPY_BASENAME := $(GENERATED_FILE_PREFIX)deepcopy
  190. DEEPCOPY_FILENAME := $(DEEPCOPY_BASENAME).go
  191. # The tool used to generate deep copies.
  192. DEEPCOPY_GEN := $(BIN_DIR)/deepcopy-gen
  193. # Find all the directories that request deep-copy generation.
  194. ifeq ($(DBG_MAKEFILE),1)
  195. $(warning ***** finding all +k8s:deepcopy-gen tags)
  196. endif
  197. DEEPCOPY_DIRS := $(shell \
  198. grep --color=never -l '+k8s:deepcopy-gen=' $(ALL_K8S_TAG_FILES) \
  199. | xargs -n1 dirname \
  200. | LC_ALL=C sort -u \
  201. )
  202. DEEPCOPY_FILES := $(addsuffix /$(DEEPCOPY_FILENAME), $(DEEPCOPY_DIRS))
  203. # Shell function for reuse in rules.
  204. RUN_GEN_DEEPCOPY = \
  205. function run_gen_deepcopy() { \
  206. if [[ -f $(META_DIR)/$(DEEPCOPY_GEN).todo ]]; then \
  207. pkgs=$$(cat $(META_DIR)/$(DEEPCOPY_GEN).todo | paste -sd, -); \
  208. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  209. echo "DBG: running $(DEEPCOPY_GEN) for $$pkgs"; \
  210. fi; \
  211. ./hack/run-in-gopath.sh $(DEEPCOPY_GEN) \
  212. --v $(KUBE_VERBOSE) \
  213. --logtostderr \
  214. -i "$$pkgs" \
  215. --bounding-dirs $(PRJ_SRC_PATH),"k8s.io/api" \
  216. -O $(DEEPCOPY_BASENAME) \
  217. "$$@"; \
  218. fi \
  219. }; \
  220. run_gen_deepcopy
  221. # This rule aggregates the set of files to generate and then generates them all
  222. # in a single run of the tool.
  223. .PHONY: gen_deepcopy
  224. gen_deepcopy: $(DEEPCOPY_FILES) $(DEEPCOPY_GEN)
  225. $(RUN_GEN_DEEPCOPY)
  226. .PHONY: verify_gen_deepcopy
  227. verify_gen_deepcopy: $(DEEPCOPY_GEN)
  228. $(RUN_GEN_DEEPCOPY) --verify-only
  229. # For each dir in DEEPCOPY_DIRS, this establishes a dependency between the
  230. # output file and the input files that should trigger a rebuild.
  231. #
  232. # Note that this is a deps-only statement, not a full rule (see below). This
  233. # has to be done in a distinct step because wildcards don't work in static
  234. # pattern rules.
  235. #
  236. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  237. # would otherwise produce results that make can't parse.
  238. #
  239. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  240. # has changed. This allows us to detect deleted input files.
  241. $(foreach dir, $(DEEPCOPY_DIRS), $(eval \
  242. $(dir)/$(DEEPCOPY_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \
  243. $(gofiles__$(dir)) \
  244. ))
  245. # Unilaterally remove any leftovers from previous runs.
  246. $(shell rm -f $(META_DIR)/$(DEEPCOPY_GEN)*.todo)
  247. # How to regenerate deep-copy code. This is a little slow to run, so we batch
  248. # it up and trigger the batch from the 'generated_files' target.
  249. $(DEEPCOPY_FILES): $(DEEPCOPY_GEN)
  250. mkdir -p $$(dirname $(META_DIR)/$(DEEPCOPY_GEN))
  251. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  252. echo "DBG: deepcopy needed $(@D): $?"; \
  253. ls -lf --full-time $@ $? || true; \
  254. fi
  255. echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(DEEPCOPY_GEN).todo
  256. # This calculates the dependencies for the generator tool, so we only rebuild
  257. # it when needed. It is PHONY so that it always runs, but it only updates the
  258. # file if the contents have actually changed. We 'sinclude' this later.
  259. .PHONY: $(META_DIR)/$(DEEPCOPY_GEN).mk
  260. $(META_DIR)/$(DEEPCOPY_GEN).mk:
  261. mkdir -p $(@D); \
  262. (echo -n "$(DEEPCOPY_GEN): "; \
  263. ./hack/run-in-gopath.sh go list \
  264. -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \
  265. ./vendor/k8s.io/code-generator/cmd/deepcopy-gen \
  266. | grep --color=never "^$(PRJ_SRC_PATH)/" \
  267. | xargs ./hack/run-in-gopath.sh go list \
  268. -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \
  269. | paste -sd' ' - \
  270. | sed 's/ / \\=,/g' \
  271. | tr '=,' '\n\t' \
  272. | sed "s|$$(pwd -P)/||"; \
  273. ) > $@.tmp; \
  274. if ! cmp -s $@.tmp $@; then \
  275. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  276. echo "DBG: $(DEEPCOPY_GEN).mk changed"; \
  277. fi; \
  278. cat $@.tmp > $@; \
  279. rm -f $@.tmp; \
  280. fi
  281. # Include dependency info for the generator tool. This will cause the rule of
  282. # the same name to be considered and if it is updated, make will restart.
  283. sinclude $(META_DIR)/$(DEEPCOPY_GEN).mk
  284. # How to build the generator tool. The deps for this are defined in
  285. # the $(DEEPCOPY_GEN).mk, above.
  286. #
  287. # A word on the need to touch: This rule might trigger if, for example, a
  288. # non-Go file was added or deleted from a directory on which this depends.
  289. # This target needs to be reconsidered, but Go realizes it doesn't actually
  290. # have to be rebuilt. In that case, make will forever see the dependency as
  291. # newer than the binary, and try to rebuild it over and over. So we touch it,
  292. # and make is happy.
  293. $(DEEPCOPY_GEN):
  294. hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/deepcopy-gen
  295. touch $@
  296. #
  297. # Defaulter generation
  298. #
  299. # Any package that wants defaulter functions generated must include a
  300. # comment-tag in column 0 of one file of the form:
  301. # // +k8s:defaulter-gen=<VALUE>
  302. #
  303. # The <VALUE> depends on context:
  304. # on types:
  305. # true: always generate a defaulter for this type
  306. # false: never generate a defaulter for this type
  307. # on functions:
  308. # covers: if the function name matches SetDefault_NAME, instructs
  309. # the generator not to recurse
  310. # on packages:
  311. # FIELDNAME: any object with a field of this name is a candidate
  312. # for having a defaulter generated
  313. # The result file, in each pkg, of defaulter generation.
  314. DEFAULTER_BASENAME := $(GENERATED_FILE_PREFIX)defaults
  315. DEFAULTER_FILENAME := $(DEFAULTER_BASENAME).go
  316. # The tool used to generate defaulters.
  317. DEFAULTER_GEN := $(BIN_DIR)/defaulter-gen
  318. # All directories that request any form of defaulter generation.
  319. ifeq ($(DBG_MAKEFILE),1)
  320. $(warning ***** finding all +k8s:defaulter-gen tags)
  321. endif
  322. DEFAULTER_DIRS := $(shell \
  323. grep --color=never -l '+k8s:defaulter-gen=' $(ALL_K8S_TAG_FILES) \
  324. | xargs -n1 dirname \
  325. | LC_ALL=C sort -u \
  326. )
  327. DEFAULTER_FILES := $(addsuffix /$(DEFAULTER_FILENAME), $(DEFAULTER_DIRS))
  328. RUN_GEN_DEFAULTER := \
  329. function run_gen_defaulter() { \
  330. if [[ -f $(META_DIR)/$(DEFAULTER_GEN).todo ]]; then \
  331. pkgs=$$(cat $(META_DIR)/$(DEFAULTER_GEN).todo | paste -sd, -); \
  332. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  333. echo "DBG: running $(DEFAULTER_GEN) for $$pkgs"; \
  334. fi; \
  335. ./hack/run-in-gopath.sh $(DEFAULTER_GEN) \
  336. --v $(KUBE_VERBOSE) \
  337. --logtostderr \
  338. -i "$$pkgs" \
  339. --extra-peer-dirs $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(DEFAULTER_DIRS)) | sed 's/ /,/g') \
  340. -O $(DEFAULTER_BASENAME) \
  341. "$$@"; \
  342. fi \
  343. }; \
  344. run_gen_defaulter
  345. # This rule aggregates the set of files to generate and then generates them all
  346. # in a single run of the tool.
  347. .PHONY: gen_defaulter
  348. gen_defaulter: $(DEFAULTER_FILES) $(DEFAULTER_GEN)
  349. $(RUN_GEN_DEFAULTER)
  350. .PHONY: verify_gen_deepcopy
  351. verify_gen_defaulter: $(DEFAULTER_GEN)
  352. $(RUN_GEN_DEFAULTER) --verify-only
  353. # For each dir in DEFAULTER_DIRS, this establishes a dependency between the
  354. # output file and the input files that should trigger a rebuild.
  355. #
  356. # The variable value was set in $(GOFILES_META) and included as part of the
  357. # dependency management logic.
  358. #
  359. # Note that this is a deps-only statement, not a full rule (see below). This
  360. # has to be done in a distinct step because wildcards don't work in static
  361. # pattern rules.
  362. #
  363. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  364. # would otherwise produce results that make can't parse.
  365. #
  366. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  367. # has changed. This allows us to detect deleted input files.
  368. $(foreach dir, $(DEFAULTER_DIRS), $(eval \
  369. $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \
  370. $(gofiles__$(dir)) \
  371. ))
  372. # For each dir in DEFAULTER_DIRS, for each target in $(defaulters__$(dir)),
  373. # this establishes a dependency between the output file and the input files
  374. # that should trigger a rebuild.
  375. #
  376. # The variable value was set in $(GOFILES_META) and included as part of the
  377. # dependency management logic.
  378. #
  379. # Note that this is a deps-only statement, not a full rule (see below). This
  380. # has to be done in a distinct step because wildcards don't work in static
  381. # pattern rules.
  382. #
  383. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  384. # would otherwise produce results that make can't parse.
  385. #
  386. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  387. # has changed. This allows us to detect deleted input files.
  388. $(foreach dir, $(DEFAULTER_DIRS), \
  389. $(foreach tgt, $(defaulters__$(dir)), $(eval \
  390. $(dir)/$(DEFAULTER_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \
  391. $(gofiles__$(tgt)) \
  392. )) \
  393. )
  394. # Unilaterally remove any leftovers from previous runs.
  395. $(shell rm -f $(META_DIR)/$(DEFAULTER_GEN)*.todo)
  396. # How to regenerate defaulter code. This is a little slow to run, so we batch
  397. # it up and trigger the batch from the 'generated_files' target.
  398. $(DEFAULTER_FILES): $(DEFAULTER_GEN)
  399. mkdir -p $$(dirname $(META_DIR)/$(DEFAULTER_GEN))
  400. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  401. echo "DBG: defaulter needed $(@D): $?"; \
  402. ls -lf --full-time $@ $? || true; \
  403. fi
  404. echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(DEFAULTER_GEN).todo
  405. # This calculates the dependencies for the generator tool, so we only rebuild
  406. # it when needed. It is PHONY so that it always runs, but it only updates the
  407. # file if the contents have actually changed. We 'sinclude' this later.
  408. .PHONY: $(META_DIR)/$(DEFAULTER_GEN).mk
  409. $(META_DIR)/$(DEFAULTER_GEN).mk:
  410. mkdir -p $(@D); \
  411. (echo -n "$(DEFAULTER_GEN): "; \
  412. ./hack/run-in-gopath.sh go list \
  413. -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \
  414. ./vendor/k8s.io/code-generator/cmd/defaulter-gen \
  415. | grep --color=never "^$(PRJ_SRC_PATH)/" \
  416. | xargs ./hack/run-in-gopath.sh go list \
  417. -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \
  418. | paste -sd' ' - \
  419. | sed 's/ / \\=,/g' \
  420. | tr '=,' '\n\t' \
  421. | sed "s|$$(pwd -P)/||"; \
  422. ) > $@.tmp; \
  423. if ! cmp -s $@.tmp $@; then \
  424. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  425. echo "DBG: $(DEFAULTER_GEN).mk changed"; \
  426. fi; \
  427. cat $@.tmp > $@; \
  428. rm -f $@.tmp; \
  429. fi
  430. # Include dependency info for the generator tool. This will cause the rule of
  431. # the same name to be considered and if it is updated, make will restart.
  432. sinclude $(META_DIR)/$(DEFAULTER_GEN).mk
  433. # How to build the generator tool. The deps for this are defined in
  434. # the $(DEFAULTER_GEN).mk, above.
  435. #
  436. # A word on the need to touch: This rule might trigger if, for example, a
  437. # non-Go file was added or deleted from a directory on which this depends.
  438. # This target needs to be reconsidered, but Go realizes it doesn't actually
  439. # have to be rebuilt. In that case, make will forever see the dependency as
  440. # newer than the binary, and try to rebuild it over and over. So we touch it,
  441. # and make is happy.
  442. $(DEFAULTER_GEN):
  443. hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/defaulter-gen
  444. touch $@
  445. #
  446. # Open-api generation
  447. #
  448. # Any package that wants open-api functions generated must include a
  449. # comment-tag in column 0 of one file of the form:
  450. # // +k8s:openapi-gen=true
  451. #
  452. # The result file, in each pkg, of open-api generation.
  453. OPENAPI_BASENAME := $(GENERATED_FILE_PREFIX)openapi
  454. OPENAPI_FILENAME := $(OPENAPI_BASENAME).go
  455. OPENAPI_OUTPUT_PKG := pkg/generated/openapi
  456. # The tool used to generate open apis.
  457. OPENAPI_GEN := $(BIN_DIR)/openapi-gen
  458. # Find all the directories that request open-api generation.
  459. ifeq ($(DBG_MAKEFILE),1)
  460. $(warning ***** finding all +k8s:openapi-gen tags)
  461. endif
  462. OPENAPI_DIRS := $(shell \
  463. grep --color=never -l '+k8s:openapi-gen=' $(ALL_K8S_TAG_FILES) \
  464. | xargs -n1 dirname \
  465. | LC_ALL=C sort -u \
  466. )
  467. OPENAPI_OUTFILE := $(OPENAPI_OUTPUT_PKG)/$(OPENAPI_FILENAME)
  468. # This rule is the user-friendly entrypoint for openapi generation.
  469. .PHONY: gen_openapi
  470. gen_openapi: $(OPENAPI_OUTFILE) $(OPENAPI_GEN)
  471. # For each dir in OPENAPI_DIRS, this establishes a dependency between the
  472. # output file and the input files that should trigger a rebuild.
  473. #
  474. # Note that this is a deps-only statement, not a full rule (see below). This
  475. # has to be done in a distinct step because wildcards don't work in static
  476. # pattern rules.
  477. #
  478. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  479. # would otherwise produce results that make can't parse.
  480. #
  481. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  482. # has changed. This allows us to detect deleted input files.
  483. $(foreach dir, $(OPENAPI_DIRS), $(eval \
  484. $(OPENAPI_OUTFILE): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \
  485. $(gofiles__$(dir)) \
  486. ))
  487. # How to regenerate open-api code. This emits a single file for all results.
  488. $(OPENAPI_OUTFILE): $(OPENAPI_GEN) $(OPENAPI_GEN)
  489. function run_gen_openapi() { \
  490. ./hack/run-in-gopath.sh $(OPENAPI_GEN) \
  491. --v $(KUBE_VERBOSE) \
  492. --logtostderr \
  493. -i $$(echo $(addprefix $(PRJ_SRC_PATH)/, $(OPENAPI_DIRS)) | sed 's/ /,/g') \
  494. -p $(PRJ_SRC_PATH)/$(OPENAPI_OUTPUT_PKG) \
  495. -O $(OPENAPI_BASENAME) \
  496. "$$@"; \
  497. }; \
  498. run_gen_openapi
  499. # This calculates the dependencies for the generator tool, so we only rebuild
  500. # it when needed. It is PHONY so that it always runs, but it only updates the
  501. # file if the contents have actually changed. We 'sinclude' this later.
  502. .PHONY: $(META_DIR)/$(OPENAPI_GEN).mk
  503. $(META_DIR)/$(OPENAPI_GEN).mk:
  504. mkdir -p $(@D); \
  505. (echo -n "$(OPENAPI_GEN): "; \
  506. ./hack/run-in-gopath.sh go list \
  507. -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \
  508. ./vendor/k8s.io/code-generator/cmd/openapi-gen \
  509. | grep --color=never "^$(PRJ_SRC_PATH)/" \
  510. | xargs ./hack/run-in-gopath.sh go list \
  511. -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \
  512. | paste -sd' ' - \
  513. | sed 's/ / \\=,/g' \
  514. | tr '=,' '\n\t' \
  515. | sed "s|$$(pwd -P)/||"; \
  516. ) > $@.tmp; \
  517. if ! cmp -s $@.tmp $@; then \
  518. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  519. echo "DBG: $(OPENAPI_GEN).mk changed"; \
  520. fi; \
  521. cat $@.tmp > $@; \
  522. rm -f $@.tmp; \
  523. fi
  524. # Include dependency info for the generator tool. This will cause the rule of
  525. # the same name to be considered and if it is updated, make will restart.
  526. sinclude $(META_DIR)/$(OPENAPI_GEN).mk
  527. # How to build the generator tool. The deps for this are defined in
  528. # the $(OPENAPI_GEN).mk, above.
  529. #
  530. # A word on the need to touch: This rule might trigger if, for example, a
  531. # non-Go file was added or deleted from a directory on which this depends.
  532. # This target needs to be reconsidered, but Go realizes it doesn't actually
  533. # have to be rebuilt. In that case, make will forever see the dependency as
  534. # newer than the binary, and try to rebuild it over and over. So we touch it,
  535. # and make is happy.
  536. $(OPENAPI_GEN):
  537. hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/openapi-gen
  538. touch $@
  539. #
  540. # Conversion generation
  541. #
  542. # Any package that wants conversion functions generated must include one or
  543. # more comment-tags in any .go file, in column 0, of the form:
  544. # // +k8s:conversion-gen=<CONVERSION_TARGET_DIR>
  545. #
  546. # The CONVERSION_TARGET_DIR is a project-local path to another directory which
  547. # should be considered when evaluating peer types for conversions. Types which
  548. # are found in the source package (where conversions are being generated)
  549. # but do not have a peer in one of the target directories will not have
  550. # conversions generated.
  551. #
  552. # TODO: it might be better in the long term to make peer-types explicit in the
  553. # IDL.
  554. # The result file, in each pkg, of conversion generation.
  555. CONVERSION_BASENAME := $(GENERATED_FILE_PREFIX)conversion
  556. CONVERSION_FILENAME := $(CONVERSION_BASENAME).go
  557. # The tool used to generate conversions.
  558. CONVERSION_GEN := $(BIN_DIR)/conversion-gen
  559. # The name of the metadata file listing conversion peers for each pkg.
  560. CONVERSIONS_META := conversions.mk
  561. # All directories that request any form of conversion generation.
  562. ifeq ($(DBG_MAKEFILE),1)
  563. $(warning ***** finding all +k8s:conversion-gen tags)
  564. endif
  565. CONVERSION_DIRS := $(shell \
  566. grep --color=never '^// *+k8s:conversion-gen=' $(ALL_K8S_TAG_FILES) \
  567. | cut -f1 -d: \
  568. | xargs -n1 dirname \
  569. | LC_ALL=C sort -u \
  570. )
  571. CONVERSION_FILES := $(addsuffix /$(CONVERSION_FILENAME), $(CONVERSION_DIRS))
  572. CONVERSION_EXTRA_PEER_DIRS := k8s.io/kubernetes/pkg/apis/core,k8s.io/kubernetes/pkg/apis/core/v1,k8s.io/api/core/v1
  573. # Shell function for reuse in rules.
  574. RUN_GEN_CONVERSION = \
  575. function run_gen_conversion() { \
  576. if [[ -f $(META_DIR)/$(CONVERSION_GEN).todo ]]; then \
  577. pkgs=$$(cat $(META_DIR)/$(CONVERSION_GEN).todo | paste -sd, -); \
  578. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  579. echo "DBG: running $(CONVERSION_GEN) for $$pkgs"; \
  580. fi; \
  581. ./hack/run-in-gopath.sh $(CONVERSION_GEN) \
  582. --extra-peer-dirs $(CONVERSION_EXTRA_PEER_DIRS) \
  583. --v $(KUBE_VERBOSE) \
  584. --logtostderr \
  585. -i "$$pkgs" \
  586. -O $(CONVERSION_BASENAME) \
  587. "$$@"; \
  588. fi \
  589. }; \
  590. run_gen_conversion
  591. # This rule aggregates the set of files to generate and then generates them all
  592. # in a single run of the tool.
  593. .PHONY: gen_conversion
  594. gen_conversion: $(CONVERSION_FILES) $(CONVERSION_GEN)
  595. $(RUN_GEN_CONVERSION)
  596. .PHONY: verify_gen_conversion
  597. verify_gen_conversion: $(CONVERSION_GEN)
  598. $(RUN_GEN_CONVERSION) --verify-only
  599. # Establish a dependency between the deps file and the dir. Whenever a dir
  600. # changes (files added or removed) the deps file will be considered stale.
  601. #
  602. # This is looser than we really need (e.g. we don't really care about non *.go
  603. # files or even *_test.go files), but this is much easier to represent.
  604. #
  605. # Because we 'sinclude' the deps file, it is considered for rebuilding, as part
  606. # of make's normal evaluation. If it gets rebuilt, make will restart.
  607. #
  608. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  609. # would otherwise produce results that make can't parse.
  610. $(foreach dir, $(CONVERSION_DIRS), $(eval \
  611. $(META_DIR)/$(dir)/$(CONVERSIONS_META): $(dir) \
  612. ))
  613. # How to rebuild a deps file. When make determines that the deps file is stale
  614. # (see above), it executes this rule, and then re-loads the deps file.
  615. #
  616. # This is looser than we really need (e.g. we don't really care about test
  617. # files), but this is MUCH faster than calling `go list`.
  618. #
  619. # We regenerate the output file in order to satisfy make's "newer than" rules,
  620. # but we only need to rebuild targets if the contents actually changed. That
  621. # is what the .stamp file represents.
  622. $(foreach dir, $(CONVERSION_DIRS), \
  623. $(META_DIR)/$(dir)/$(CONVERSIONS_META)):
  624. TAGS=$$(grep --color=never -h '^// *+k8s:conversion-gen=' $</*.go \
  625. | cut -f2- -d= \
  626. | sed 's|$(PRJ_SRC_PATH)/||' \
  627. | sed 's|^k8s.io/|vendor/k8s.io/|'); \
  628. mkdir -p $(@D); \
  629. echo "conversions__$< := $$(echo $${TAGS})" >$@.tmp; \
  630. if ! cmp -s $@.tmp $@; then \
  631. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  632. echo "DBG: conversions changed for $@"; \
  633. fi; \
  634. touch $@.stamp; \
  635. fi; \
  636. mv $@.tmp $@
  637. # Include any deps files as additional Makefile rules. This triggers make to
  638. # consider the deps files for rebuild, which makes the whole
  639. # dependency-management logic work. 'sinclude' is "silent include" which does
  640. # not fail if the file does not exist.
  641. $(foreach dir, $(CONVERSION_DIRS), $(eval \
  642. sinclude $(META_DIR)/$(dir)/$(CONVERSIONS_META) \
  643. ))
  644. # For each dir in CONVERSION_DIRS, this establishes a dependency between the
  645. # output file and the input files that should trigger a rebuild.
  646. #
  647. # The variable value was set in $(GOFILES_META) and included as part of the
  648. # dependency management logic.
  649. #
  650. # Note that this is a deps-only statement, not a full rule (see below). This
  651. # has to be done in a distinct step because wildcards don't work in static
  652. # pattern rules.
  653. #
  654. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  655. # would otherwise produce results that make can't parse.
  656. #
  657. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  658. # has changed. This allows us to detect deleted input files.
  659. $(foreach dir, $(CONVERSION_DIRS), $(eval \
  660. $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(dir)/$(GOFILES_META).stamp \
  661. $(gofiles__$(dir)) \
  662. ))
  663. # For each dir in CONVERSION_DIRS, for each target in $(conversions__$(dir)),
  664. # this establishes a dependency between the output file and the input files
  665. # that should trigger a rebuild.
  666. #
  667. # The variable value was set in $(GOFILES_META) and included as part of the
  668. # dependency management logic.
  669. #
  670. # Note that this is a deps-only statement, not a full rule (see below). This
  671. # has to be done in a distinct step because wildcards don't work in static
  672. # pattern rules.
  673. #
  674. # The '$(eval)' is needed because this has a different RHS for each LHS, and
  675. # would otherwise produce results that make can't parse.
  676. #
  677. # We depend on the $(GOFILES_META).stamp to detect when the set of input files
  678. # has changed. This allows us to detect deleted input files.
  679. $(foreach dir, $(CONVERSION_DIRS), \
  680. $(foreach tgt, $(conversions__$(dir)), $(eval \
  681. $(dir)/$(CONVERSION_FILENAME): $(META_DIR)/$(tgt)/$(GOFILES_META).stamp \
  682. $(gofiles__$(tgt)) \
  683. )) \
  684. )
  685. # Unilaterally remove any leftovers from previous runs.
  686. $(shell rm -f $(META_DIR)/$(CONVERSION_GEN)*.todo)
  687. # How to regenerate conversion code. This is a little slow to run, so we batch
  688. # it up and trigger the batch from the 'generated_files' target.
  689. $(CONVERSION_FILES): $(CONVERSION_GEN)
  690. mkdir -p $$(dirname $(META_DIR)/$(CONVERSION_GEN))
  691. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  692. echo "DBG: conversion needed $(@D): $?"; \
  693. ls -lf --full-time $@ $? || true; \
  694. fi
  695. echo $(PRJ_SRC_PATH)/$(@D) >> $(META_DIR)/$(CONVERSION_GEN).todo
  696. # This calculates the dependencies for the generator tool, so we only rebuild
  697. # it when needed. It is PHONY so that it always runs, but it only updates the
  698. # file if the contents have actually changed. We 'sinclude' this later.
  699. .PHONY: $(META_DIR)/$(CONVERSION_GEN).mk
  700. $(META_DIR)/$(CONVERSION_GEN).mk:
  701. mkdir -p $(@D); \
  702. (echo -n "$(CONVERSION_GEN): "; \
  703. ./hack/run-in-gopath.sh go list \
  704. -f '{{.ImportPath}}{{"\n"}}{{range .Deps}}{{.}}{{"\n"}}{{end}}' \
  705. ./vendor/k8s.io/code-generator/cmd/conversion-gen \
  706. | grep --color=never "^$(PRJ_SRC_PATH)/" \
  707. | xargs ./hack/run-in-gopath.sh go list \
  708. -f '{{$$d := .Dir}}{{$$d}}{{"\n"}}{{range .GoFiles}}{{$$d}}/{{.}}{{"\n"}}{{end}}' \
  709. | paste -sd' ' - \
  710. | sed 's/ / \\=,/g' \
  711. | tr '=,' '\n\t' \
  712. | sed "s|$$(pwd -P)/||"; \
  713. ) > $@.tmp; \
  714. if ! cmp -s $@.tmp $@; then \
  715. if [[ "$(DBG_CODEGEN)" == 1 ]]; then \
  716. echo "DBG: $(CONVERSION_GEN).mk changed"; \
  717. fi; \
  718. cat $@.tmp > $@; \
  719. rm -f $@.tmp; \
  720. fi
  721. # Include dependency info for the generator tool. This will cause the rule of
  722. # the same name to be considered and if it is updated, make will restart.
  723. sinclude $(META_DIR)/$(CONVERSION_GEN).mk
  724. # How to build the generator tool. The deps for this are defined in
  725. # the $(CONVERSION_GEN).mk, above.
  726. #
  727. # A word on the need to touch: This rule might trigger if, for example, a
  728. # non-Go file was added or deleted from a directory on which this depends.
  729. # This target needs to be reconsidered, but Go realizes it doesn't actually
  730. # have to be rebuilt. In that case, make will forever see the dependency as
  731. # newer than the binary, and try to rebuild it over and over. So we touch it,
  732. # and make is happy.
  733. $(CONVERSION_GEN):
  734. hack/make-rules/build.sh ./vendor/k8s.io/code-generator/cmd/conversion-gen
  735. touch $@