Makefile.targ (8390B)
1 # -*- mode: makefile -*- 2 # 3 # Copyright (c) 2012, 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 # 80 # Defaults for the various tools we use. 81 # 82 BASH ?= bash 83 BASHSTYLE ?= tools/bashstyle 84 CP ?= cp 85 CSCOPE ?= cscope 86 CSCOPE_DIRS ?= . 87 JSL ?= jsl 88 JSSTYLE ?= jsstyle 89 MKDIR ?= mkdir -p 90 MV ?= mv 91 RESTDOWN_FLAGS ?= 92 RMTREE ?= rm -rf 93 JSL_FLAGS ?= --nologo --nosummary 94 95 ifeq ($(shell uname -s),SunOS) 96 TAR ?= gtar 97 else 98 TAR ?= tar 99 endif 100 101 102 # 103 # Defaults for other fixed values. 104 # 105 BUILD = build 106 DISTCLEAN_FILES += $(BUILD) 107 DOC_BUILD = $(BUILD)/docs/public 108 109 # 110 # Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. 111 # 112 ifneq ($(origin JSL_CONF_NODE), undefined) 113 JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) 114 endif 115 116 ifneq ($(origin JSL_CONF_WEB), undefined) 117 JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) 118 endif 119 120 # 121 # Targets. For descriptions on what these are supposed to do, see the 122 # Joyent Engineering Guide. 123 # 124 125 # 126 # Instruct make to keep around temporary files. We have rules below that 127 # automatically update git submodules as needed, but they employ a deps/*/.git 128 # temporary file. Without this directive, make tries to remove these .git 129 # directories after the build has completed. 130 # 131 .SECONDARY: $($(wildcard deps/*):%=%/.git) 132 133 # 134 # This rule enables other rules that use files from a git submodule to have 135 # those files depend on deps/module/.git and have "make" automatically check 136 # out the submodule as needed. 137 # 138 deps/%/.git: 139 git submodule update --init deps/$* 140 141 # 142 # These recipes make heavy use of dynamically-created phony targets. The parent 143 # Makefile defines a list of input files like BASH_FILES. We then say that each 144 # of these files depends on a fake target called filename.bashchk, and then we 145 # define a pattern rule for those targets that runs bash in check-syntax-only 146 # mode. This mechanism has the nice properties that if you specify zero files, 147 # the rule becomes a noop (unlike a single rule to check all bash files, which 148 # would invoke bash with zero files), and you can check individual files from 149 # the command line with "make filename.bashchk". 150 # 151 .PHONY: check-bash 152 check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) 153 154 %.bashchk: % 155 $(BASH) -n $^ 156 157 %.bashstyle: % 158 $(BASHSTYLE) $^ 159 160 .PHONY: check-jsl check-jsl-node check-jsl-web 161 check-jsl: check-jsl-node check-jsl-web 162 163 check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) 164 165 check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) 166 167 %.jslnodechk: % $(JSL_EXEC) 168 $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< 169 170 %.jslwebchk: % $(JSL_EXEC) 171 $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< 172 173 .PHONY: check-jsstyle 174 check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) 175 176 %.jsstylechk: % $(JSSTYLE_EXEC) 177 $(JSSTYLE) $(JSSTYLE_FLAGS) $< 178 179 .PHONY: check 180 check: check-jsl check-jsstyle check-bash 181 @echo check ok 182 183 .PHONY: clean 184 clean:: 185 -$(RMTREE) $(CLEAN_FILES) 186 187 .PHONY: distclean 188 distclean:: clean 189 -$(RMTREE) $(DISTCLEAN_FILES) 190 191 CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out 192 CLEAN_FILES += $(CSCOPE_FILES) 193 194 .PHONY: xref 195 xref: cscope.files 196 $(CSCOPE) -bqR 197 198 .PHONY: cscope.files 199 cscope.files: 200 find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ 201 -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ 202 203 # 204 # The "docs" target is complicated because we do several things here: 205 # 206 # (1) Use restdown to build HTML and JSON files from each of DOC_FILES. 207 # 208 # (2) Copy these files into $(DOC_BUILD) (build/docs/public), which 209 # functions as a complete copy of the documentation that could be 210 # mirrored or served over HTTP. 211 # 212 # (3) Then copy any directories and media from docs/media into 213 # $(DOC_BUILD)/media. This allows projects to include their own media, 214 # including files that will override same-named files provided by 215 # restdown. 216 # 217 # Step (3) is the surprisingly complex part: in order to do this, we need to 218 # identify the subdirectories in docs/media, recreate them in 219 # $(DOC_BUILD)/media, then do the same with the files. 220 # 221 DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") 222 DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) 223 DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) 224 225 DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) 226 DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) 227 DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) 228 229 # 230 # Like the other targets, "docs" just depends on the final files we want to 231 # create in $(DOC_BUILD), leveraging other targets and recipes to define how 232 # to get there. 233 # 234 .PHONY: docs 235 docs: \ 236 $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ 237 $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ 238 $(DOC_MEDIA_FILES_BUILD) 239 240 # 241 # We keep the intermediate files so that the next build can see whether the 242 # files in DOC_BUILD are up to date. 243 # 244 .PRECIOUS: \ 245 $(DOC_FILES:%.restdown=docs/%.html) \ 246 $(DOC_FILES:%.restdown=docs/%json) 247 248 # 249 # We do clean those intermediate files, as well as all of DOC_BUILD. 250 # 251 CLEAN_FILES += \ 252 $(DOC_BUILD) \ 253 $(DOC_FILES:%.restdown=docs/%.html) \ 254 $(DOC_FILES:%.restdown=docs/%.json) 255 256 # 257 # Before installing the files, we must make sure the directories exist. The | 258 # syntax tells make that the dependency need only exist, not be up to date. 259 # Otherwise, it might try to rebuild spuriously because the directory itself 260 # appears out of date. 261 # 262 $(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) 263 264 $(DOC_BUILD)/%: docs/% | $(DOC_BUILD) 265 $(CP) $< $@ 266 267 docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) 268 $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< 269 270 $(DOC_BUILD): 271 $(MKDIR) $@ 272 273 $(DOC_MEDIA_DIRS_BUILD): 274 $(MKDIR) $@ 275 276 # 277 # The default "test" target does nothing. This should usually be overridden by 278 # the parent Makefile. It's included here so we can define "prepush" without 279 # requiring the repo to define "test". 280 # 281 .PHONY: test 282 test: 283 284 .PHONY: prepush 285 prepush: check test