Makefile.targ 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. # -*- mode: makefile -*-
  2. #
  3. # Copyright (c) 2021, Joyent, Inc. All rights reserved.
  4. #
  5. # Makefile.targ: common targets.
  6. #
  7. # NOTE: This makefile comes from the "eng" repo. It's designed to be dropped
  8. # into other repos as-is without requiring any modifications. If you find
  9. # yourself changing this file, you should instead update the original copy in
  10. # eng.git and then update your repo to use the new version.
  11. #
  12. # This Makefile defines several useful targets and rules. You can use it by
  13. # including it from a Makefile that specifies some of the variables below.
  14. #
  15. # Targets defined in this Makefile:
  16. #
  17. # check Checks JavaScript files for lint and style
  18. # Checks bash scripts for syntax
  19. # Checks SMF manifests for validity against the SMF DTD
  20. #
  21. # clean Removes built files
  22. #
  23. # docs Builds restdown documentation in docs/
  24. #
  25. # prepush Depends on "check" and "test"
  26. #
  27. # test Does nothing (you should override this)
  28. #
  29. # xref Generates cscope (source cross-reference index)
  30. #
  31. # For details on what these targets are supposed to do, see the Joyent
  32. # Engineering Guide.
  33. #
  34. # To make use of these targets, you'll need to set some of these variables. Any
  35. # variables left unset will simply not be used.
  36. #
  37. # BASH_FILES Bash scripts to check for syntax
  38. # (paths relative to top-level Makefile)
  39. #
  40. # CLEAN_FILES Files to remove as part of the "clean" target. Note
  41. # that files generated by targets in this Makefile are
  42. # automatically included in CLEAN_FILES. These include
  43. # restdown-generated HTML and JSON files.
  44. #
  45. # DOC_FILES Restdown (documentation source) files. These are
  46. # assumed to be contained in "docs/", and must NOT
  47. # contain the "docs/" prefix.
  48. #
  49. # JSL_CONF_NODE Specify JavaScriptLint configuration files
  50. # JSL_CONF_WEB (paths relative to top-level Makefile)
  51. #
  52. # Node.js and Web configuration files are separate
  53. # because you'll usually want different global variable
  54. # configurations. If no file is specified, none is given
  55. # to jsl, which causes it to use a default configuration,
  56. # which probably isn't what you want.
  57. #
  58. # JSL_FILES_NODE JavaScript files to check with Node config file.
  59. # JSL_FILES_WEB JavaScript files to check with Web config file.
  60. #
  61. # You can also override these variables:
  62. #
  63. # BASH Path to bash (default: bash)
  64. #
  65. # CSCOPE_DIRS Directories to search for source files for the cscope
  66. # index. (default: ".")
  67. #
  68. # JSL Path to JavaScriptLint (default: "jsl")
  69. #
  70. # JSL_FLAGS_NODE Additional flags to pass through to JSL
  71. # JSL_FLAGS_WEB
  72. # JSL_FLAGS
  73. #
  74. # JSSTYLE Path to jsstyle (default: jsstyle)
  75. #
  76. # JSSTYLE_FLAGS Additional flags to pass through to jsstyle
  77. #
  78. #
  79. # Defaults for the various tools we use.
  80. #
  81. BASH ?= bash
  82. BASHSTYLE ?= tools/bashstyle
  83. CP ?= cp
  84. CSCOPE ?= cscope
  85. CSCOPE_DIRS ?= .
  86. JSL_EXEC ?= deps/javascriptlint/build/install/jsl
  87. JSL ?= $(JSL_EXEC)
  88. JSSTYLE ?= deps/jsstyle/jsstyle
  89. MKDIR ?= mkdir -p
  90. MV ?= mv
  91. RESTDOWN_FLAGS ?=
  92. RMTREE ?= rm -rf
  93. JSL_FLAGS ?= --nologo --nosummary
  94. ifeq ($(shell uname -s),SunOS)
  95. TAR ?= gtar
  96. else
  97. TAR ?= tar
  98. endif
  99. #
  100. # Defaults for other fixed values.
  101. #
  102. BUILD = build
  103. DISTCLEAN_FILES += $(BUILD)
  104. DOC_BUILD = $(BUILD)/docs/public
  105. #
  106. # Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}.
  107. #
  108. ifneq ($(origin JSL_CONF_NODE), undefined)
  109. JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE)
  110. endif
  111. ifneq ($(origin JSL_CONF_WEB), undefined)
  112. JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB)
  113. endif
  114. #
  115. # Targets. For descriptions on what these are supposed to do, see the
  116. # Joyent Engineering Guide.
  117. #
  118. #
  119. # Instruct make to keep around temporary files. We have rules below that
  120. # automatically update git submodules as needed, but they employ a deps/*/.git
  121. # temporary file. Without this directive, make tries to remove these .git
  122. # directories after the build has completed.
  123. #
  124. .SECONDARY: $($(wildcard deps/*):%=%/.git)
  125. #
  126. # This rule enables other rules that use files from a git submodule to have
  127. # those files depend on deps/module/.git and have "make" automatically check
  128. # out the submodule as needed.
  129. #
  130. deps/%/.git:
  131. git submodule update --init deps/$*
  132. #
  133. # These recipes make heavy use of dynamically-created phony targets. The parent
  134. # Makefile defines a list of input files like BASH_FILES. We then say that each
  135. # of these files depends on a fake target called filename.bashchk, and then we
  136. # define a pattern rule for those targets that runs bash in check-syntax-only
  137. # mode. This mechanism has the nice properties that if you specify zero files,
  138. # the rule becomes a noop (unlike a single rule to check all bash files, which
  139. # would invoke bash with zero files), and you can check individual files from
  140. # the command line with "make filename.bashchk".
  141. #
  142. .PHONY: check-bash
  143. check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle)
  144. %.bashchk: %
  145. $(BASH) -n $^
  146. %.bashstyle: %
  147. $(BASHSTYLE) $^
  148. $(JSL_EXEC):
  149. make -C deps/javascriptlint install
  150. .PHONY: check-jsl check-jsl-node check-jsl-web
  151. check-jsl: check-jsl-node check-jsl-web
  152. check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk)
  153. check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk)
  154. %.jslnodechk: % $(JSL_EXEC)
  155. $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $<
  156. %.jslwebchk: % $(JSL_EXEC)
  157. $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $<
  158. .PHONY: check-jsstyle
  159. check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk)
  160. %.jsstylechk: % $(JSSTYLE_EXEC)
  161. $(JSSTYLE) $(JSSTYLE_FLAGS) $<
  162. .PHONY: check
  163. check: check-jsl check-jsstyle check-bash
  164. @echo check ok
  165. .PHONY: clean
  166. clean::
  167. -$(RMTREE) $(CLEAN_FILES)
  168. .PHONY: distclean
  169. distclean:: clean
  170. -$(RMTREE) $(DISTCLEAN_FILES)
  171. CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out
  172. CLEAN_FILES += $(CSCOPE_FILES)
  173. .PHONY: xref
  174. xref: cscope.files
  175. $(CSCOPE) -bqR
  176. .PHONY: cscope.files
  177. cscope.files:
  178. find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \
  179. -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@
  180. #
  181. # The "docs" target is complicated because we do several things here:
  182. #
  183. # (1) Use restdown to build HTML and JSON files from each of DOC_FILES.
  184. #
  185. # (2) Copy these files into $(DOC_BUILD) (build/docs/public), which
  186. # functions as a complete copy of the documentation that could be
  187. # mirrored or served over HTTP.
  188. #
  189. # (3) Then copy any directories and media from docs/media into
  190. # $(DOC_BUILD)/media. This allows projects to include their own media,
  191. # including files that will override same-named files provided by
  192. # restdown.
  193. #
  194. # Step (3) is the surprisingly complex part: in order to do this, we need to
  195. # identify the subdirectories in docs/media, recreate them in
  196. # $(DOC_BUILD)/media, then do the same with the files.
  197. #
  198. DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$")
  199. DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%)
  200. DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%)
  201. DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null)
  202. DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%)
  203. DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%)
  204. #
  205. # Like the other targets, "docs" just depends on the final files we want to
  206. # create in $(DOC_BUILD), leveraging other targets and recipes to define how
  207. # to get there.
  208. #
  209. .PHONY: docs
  210. docs: \
  211. $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \
  212. $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \
  213. $(DOC_MEDIA_FILES_BUILD)
  214. #
  215. # We keep the intermediate files so that the next build can see whether the
  216. # files in DOC_BUILD are up to date.
  217. #
  218. .PRECIOUS: \
  219. $(DOC_FILES:%.restdown=docs/%.html) \
  220. $(DOC_FILES:%.restdown=docs/%json)
  221. #
  222. # We do clean those intermediate files, as well as all of DOC_BUILD.
  223. #
  224. CLEAN_FILES += \
  225. $(DOC_BUILD) \
  226. $(DOC_FILES:%.restdown=docs/%.html) \
  227. $(DOC_FILES:%.restdown=docs/%.json)
  228. #
  229. # Before installing the files, we must make sure the directories exist. The |
  230. # syntax tells make that the dependency need only exist, not be up to date.
  231. # Otherwise, it might try to rebuild spuriously because the directory itself
  232. # appears out of date.
  233. #
  234. $(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD)
  235. $(DOC_BUILD)/%: docs/% | $(DOC_BUILD)
  236. $(CP) $< $@
  237. docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC)
  238. $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $<
  239. $(DOC_BUILD):
  240. $(MKDIR) $@
  241. $(DOC_MEDIA_DIRS_BUILD):
  242. $(MKDIR) $@
  243. #
  244. # The default "test" target does nothing. This should usually be overridden by
  245. # the parent Makefile. It's included here so we can define "prepush" without
  246. # requiring the repo to define "test".
  247. #
  248. .PHONY: test
  249. test:
  250. .PHONY: prepush
  251. prepush: check test