| # -*- mode: makefile -*- |
| # |
| # Copyright (c) 2012, Joyent, Inc. All rights reserved. |
| # |
| # Makefile.targ: common targets. |
| # |
| # NOTE: This makefile comes from the "eng" repo. It's designed to be dropped |
| # into other repos as-is without requiring any modifications. If you find |
| # yourself changing this file, you should instead update the original copy in |
| # eng.git and then update your repo to use the new version. |
| # |
| # This Makefile defines several useful targets and rules. You can use it by |
| # including it from a Makefile that specifies some of the variables below. |
| # |
| # Targets defined in this Makefile: |
| # |
| # check Checks JavaScript files for lint and style |
| # Checks bash scripts for syntax |
| # Checks SMF manifests for validity against the SMF DTD |
| # |
| # clean Removes built files |
| # |
| # docs Builds restdown documentation in docs/ |
| # |
| # prepush Depends on "check" and "test" |
| # |
| # test Does nothing (you should override this) |
| # |
| # xref Generates cscope (source cross-reference index) |
| # |
| # For details on what these targets are supposed to do, see the Joyent |
| # Engineering Guide. |
| # |
| # To make use of these targets, you'll need to set some of these variables. Any |
| # variables left unset will simply not be used. |
| # |
| # BASH_FILES Bash scripts to check for syntax |
| # (paths relative to top-level Makefile) |
| # |
| # CLEAN_FILES Files to remove as part of the "clean" target. Note |
| # that files generated by targets in this Makefile are |
| # automatically included in CLEAN_FILES. These include |
| # restdown-generated HTML and JSON files. |
| # |
| # DOC_FILES Restdown (documentation source) files. These are |
| # assumed to be contained in "docs/", and must NOT |
| # contain the "docs/" prefix. |
| # |
| # JSL_CONF_NODE Specify JavaScriptLint configuration files |
| # JSL_CONF_WEB (paths relative to top-level Makefile) |
| # |
| # Node.js and Web configuration files are separate |
| # because you'll usually want different global variable |
| # configurations. If no file is specified, none is given |
| # to jsl, which causes it to use a default configuration, |
| # which probably isn't what you want. |
| # |
| # JSL_FILES_NODE JavaScript files to check with Node config file. |
| # JSL_FILES_WEB JavaScript files to check with Web config file. |
| # |
| # You can also override these variables: |
| # |
| # BASH Path to bash (default: bash) |
| # |
| # CSCOPE_DIRS Directories to search for source files for the cscope |
| # index. (default: ".") |
| # |
| # JSL Path to JavaScriptLint (default: "jsl") |
| # |
| # JSL_FLAGS_NODE Additional flags to pass through to JSL |
| # JSL_FLAGS_WEB |
| # JSL_FLAGS |
| # |
| # JSSTYLE Path to jsstyle (default: jsstyle) |
| # |
| # JSSTYLE_FLAGS Additional flags to pass through to jsstyle |
| # |
| |
| # |
| # Defaults for the various tools we use. |
| # |
| BASH ?= bash |
| BASHSTYLE ?= tools/bashstyle |
| CP ?= cp |
| CSCOPE ?= cscope |
| CSCOPE_DIRS ?= . |
| JSL ?= jsl |
| JSSTYLE ?= jsstyle |
| MKDIR ?= mkdir -p |
| MV ?= mv |
| RESTDOWN_FLAGS ?= |
| RMTREE ?= rm -rf |
| JSL_FLAGS ?= --nologo --nosummary |
| |
| ifeq ($(shell uname -s),SunOS) |
| TAR ?= gtar |
| else |
| TAR ?= tar |
| endif |
| |
| |
| # |
| # Defaults for other fixed values. |
| # |
| BUILD = build |
| DISTCLEAN_FILES += $(BUILD) |
| DOC_BUILD = $(BUILD)/docs/public |
| |
| # |
| # Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. |
| # |
| ifneq ($(origin JSL_CONF_NODE), undefined) |
| JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) |
| endif |
| |
| ifneq ($(origin JSL_CONF_WEB), undefined) |
| JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) |
| endif |
| |
| # |
| # Targets. For descriptions on what these are supposed to do, see the |
| # Joyent Engineering Guide. |
| # |
| |
| # |
| # Instruct make to keep around temporary files. We have rules below that |
| # automatically update git submodules as needed, but they employ a deps/*/.git |
| # temporary file. Without this directive, make tries to remove these .git |
| # directories after the build has completed. |
| # |
| .SECONDARY: $($(wildcard deps/*):%=%/.git) |
| |
| # |
| # This rule enables other rules that use files from a git submodule to have |
| # those files depend on deps/module/.git and have "make" automatically check |
| # out the submodule as needed. |
| # |
| deps/%/.git: |
| git submodule update --init deps/$* |
| |
| # |
| # These recipes make heavy use of dynamically-created phony targets. The parent |
| # Makefile defines a list of input files like BASH_FILES. We then say that each |
| # of these files depends on a fake target called filename.bashchk, and then we |
| # define a pattern rule for those targets that runs bash in check-syntax-only |
| # mode. This mechanism has the nice properties that if you specify zero files, |
| # the rule becomes a noop (unlike a single rule to check all bash files, which |
| # would invoke bash with zero files), and you can check individual files from |
| # the command line with "make filename.bashchk". |
| # |
| .PHONY: check-bash |
| check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) |
| |
| %.bashchk: % |
| $(BASH) -n $^ |
| |
| %.bashstyle: % |
| $(BASHSTYLE) $^ |
| |
| .PHONY: check-jsl check-jsl-node check-jsl-web |
| check-jsl: check-jsl-node check-jsl-web |
| |
| check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) |
| |
| check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) |
| |
| %.jslnodechk: % $(JSL_EXEC) |
| $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< |
| |
| %.jslwebchk: % $(JSL_EXEC) |
| $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< |
| |
| .PHONY: check-jsstyle |
| check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) |
| |
| %.jsstylechk: % $(JSSTYLE_EXEC) |
| $(JSSTYLE) $(JSSTYLE_FLAGS) $< |
| |
| .PHONY: check |
| check: check-jsl check-jsstyle check-bash |
| @echo check ok |
| |
| .PHONY: clean |
| clean:: |
| -$(RMTREE) $(CLEAN_FILES) |
| |
| .PHONY: distclean |
| distclean:: clean |
| -$(RMTREE) $(DISTCLEAN_FILES) |
| |
| CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out |
| CLEAN_FILES += $(CSCOPE_FILES) |
| |
| .PHONY: xref |
| xref: cscope.files |
| $(CSCOPE) -bqR |
| |
| .PHONY: cscope.files |
| cscope.files: |
| find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ |
| -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ |
| |
| # |
| # The "docs" target is complicated because we do several things here: |
| # |
| # (1) Use restdown to build HTML and JSON files from each of DOC_FILES. |
| # |
| # (2) Copy these files into $(DOC_BUILD) (build/docs/public), which |
| # functions as a complete copy of the documentation that could be |
| # mirrored or served over HTTP. |
| # |
| # (3) Then copy any directories and media from docs/media into |
| # $(DOC_BUILD)/media. This allows projects to include their own media, |
| # including files that will override same-named files provided by |
| # restdown. |
| # |
| # Step (3) is the surprisingly complex part: in order to do this, we need to |
| # identify the subdirectories in docs/media, recreate them in |
| # $(DOC_BUILD)/media, then do the same with the files. |
| # |
| DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") |
| DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) |
| DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) |
| |
| DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) |
| DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) |
| DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) |
| |
| # |
| # Like the other targets, "docs" just depends on the final files we want to |
| # create in $(DOC_BUILD), leveraging other targets and recipes to define how |
| # to get there. |
| # |
| .PHONY: docs |
| docs: \ |
| $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ |
| $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ |
| $(DOC_MEDIA_FILES_BUILD) |
| |
| # |
| # We keep the intermediate files so that the next build can see whether the |
| # files in DOC_BUILD are up to date. |
| # |
| .PRECIOUS: \ |
| $(DOC_FILES:%.restdown=docs/%.html) \ |
| $(DOC_FILES:%.restdown=docs/%json) |
| |
| # |
| # We do clean those intermediate files, as well as all of DOC_BUILD. |
| # |
| CLEAN_FILES += \ |
| $(DOC_BUILD) \ |
| $(DOC_FILES:%.restdown=docs/%.html) \ |
| $(DOC_FILES:%.restdown=docs/%.json) |
| |
| # |
| # Before installing the files, we must make sure the directories exist. The | |
| # syntax tells make that the dependency need only exist, not be up to date. |
| # Otherwise, it might try to rebuild spuriously because the directory itself |
| # appears out of date. |
| # |
| $(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) |
| |
| $(DOC_BUILD)/%: docs/% | $(DOC_BUILD) |
| $(CP) $< $@ |
| |
| docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) |
| $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< |
| |
| $(DOC_BUILD): |
| $(MKDIR) $@ |
| |
| $(DOC_MEDIA_DIRS_BUILD): |
| $(MKDIR) $@ |
| |
| # |
| # The default "test" target does nothing. This should usually be overridden by |
| # the parent Makefile. It's included here so we can define "prepush" without |
| # requiring the repo to define "test". |
| # |
| .PHONY: test |
| test: |
| |
| .PHONY: prepush |
| prepush: check test |