parent
							
								
									75b68126d0
								
							
						
					
					
						commit
						3126cbbf96
					
				| @ -0,0 +1,94 @@ | |||||||
|  | DMBS - Dean's Makefile Build System | ||||||
|  | =================================== | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Writing Your Own Modules | ||||||
|  | ------------------------ | ||||||
|  | 
 | ||||||
|  | A DMBS module consists of the several boilerplate sections, explained below. | ||||||
|  | 
 | ||||||
|  | ## The DMBS module hooks | ||||||
|  | 
 | ||||||
|  | Your module needs to advertise to DMBS its name, its makefile targets, the | ||||||
|  | required and optional variables, and the variables and macros the module | ||||||
|  | provides for use elsewhere. This is achieved with the following section: | ||||||
|  | 
 | ||||||
|  |     DMBS_BUILD_MODULES         += EXAMPLE | ||||||
|  |     DMBS_BUILD_TARGETS         += example-target another-target | ||||||
|  |     DMBS_BUILD_MANDATORY_VARS  += MANDATORY_NAME ALSO_MANDATORY | ||||||
|  |     DMBS_BUILD_OPTIONAL_VARS   += OPTIONAL_NAME ALSO_OPTIONAL | ||||||
|  |     DMBS_BUILD_PROVIDED_VARS   += MEANING_OF_LIFE | ||||||
|  |     DMBS_BUILD_PROVIDED_MACROS += STRIP_WHITESPACE | ||||||
|  | 
 | ||||||
|  | The example above declares that this module is called `EXAMPLE`, and exposes the | ||||||
|  | listed targets, variable requirements and provides variables and macros. | ||||||
|  | 
 | ||||||
|  | Your module name and provided variable/macro names must be unique, however you | ||||||
|  | can (and should) re-use variable names where appropriate if they apply to | ||||||
|  | several modules (such as `ARCH` to specify the project's microcontroller | ||||||
|  | architecture). Re-using targets is not recommended, but can be used to extend | ||||||
|  | the dependencies of another module's targets. | ||||||
|  | 
 | ||||||
|  | ## Importing the CORE module | ||||||
|  | 
 | ||||||
|  | Next, your module should always import the DMBS `CORE` module, via the | ||||||
|  | following: | ||||||
|  | 
 | ||||||
|  |     # Conditionally import the CORE module of DMBS if it is not already imported | ||||||
|  |     DMBS_MODULE_PATH := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) | ||||||
|  |     ifeq ($(findstring CORE, $(DMBS_BUILD_MODULES)),) | ||||||
|  |       include $(DMBS_MODULE_PATH)/core.mk | ||||||
|  |     endif | ||||||
|  | 
 | ||||||
|  | This ensures that the `make help` target is always available. In addition, the | ||||||
|  | `CORE` module exposes some [commonly used macros and variables](core.md) to | ||||||
|  | your module. | ||||||
|  | 
 | ||||||
|  | ## Setting optional variable's defaults | ||||||
|  | 
 | ||||||
|  | If a variable is optional, you should provide a default value. Do this via the | ||||||
|  | `?=` operator of `make`, which sets a variable's value if it has not yet been | ||||||
|  | set: | ||||||
|  | 
 | ||||||
|  |     MY_OPTIONAL_VARIABLE ?= some_default_value | ||||||
|  | 
 | ||||||
|  | ## Sanity checking user input | ||||||
|  | 
 | ||||||
|  | Sanity checks are what make DMBS useful. Where possible, validate user input and | ||||||
|  | convert generated errors to human-friendly messages. This can be achieved by | ||||||
|  | enforcing that all the declared module mandatory variables have been set by the | ||||||
|  | user: | ||||||
|  | 
 | ||||||
|  |     # Sanity-check values of mandatory user-supplied variables | ||||||
|  |     $(foreach MANDATORY_VAR, $(DMBS_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) | ||||||
|  | 
 | ||||||
|  | As well as complaining if they are set, but currently empty: | ||||||
|  |     $(call ERROR_IF_EMPTY, SOME_MANDATORY_VARIABLE) | ||||||
|  |     $(call ERROR_IF_EMPTY, SOME_OPTIONAL_BUT_NON_EMPTY_VARIABLE) | ||||||
|  | 
 | ||||||
|  | Or even if they are boolean (`Y` or `N`) variables that have an invalid value: | ||||||
|  | 
 | ||||||
|  |     $(call ERROR_IF_NONBOOL, SOME_BOOL_VARIABLE) | ||||||
|  | 
 | ||||||
|  | ## Adding targets | ||||||
|  | 
 | ||||||
|  | The meat of a DMBS module is the targets, which are run when the user types | ||||||
|  | `make {target name}` from the command line. These can be as complex or simple | ||||||
|  | as you like. See the GNU make manual for information on writing make targets. | ||||||
|  | 
 | ||||||
|  |     example-target: | ||||||
|  |         echo "Your DMBS module works!" | ||||||
|  | 
 | ||||||
|  | ## And finally, list the PHONYs | ||||||
|  | 
 | ||||||
|  | Important in GNU Make is the concept of phony targets; this special directive | ||||||
|  | tells make that a given target should never be considered a valid file. Listing | ||||||
|  | phonies ensures that, for example, if your module had a target called `build`, | ||||||
|  | it would always run when the user types `make build` from the command line, even | ||||||
|  | if a file called `build` existed in the user project folder. | ||||||
|  | 
 | ||||||
|  | You can list module-internal targets here, as well as mark all public targets | ||||||
|  | via the module header's `DMBS_BUILD_TARGETS` variable. | ||||||
|  | 
 | ||||||
|  |     # Phony build targets for this module | ||||||
|  |     .PHONY: $(DMBS_BUILD_TARGETS) some-module-internal-target another-internal-target | ||||||
					Loading…
					
					
				
		Reference in new issue
	
	 Dean Camera
						Dean Camera