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