xmake(1)
NAME
xmake - portable make utility
SYNOPSIS
xmake [ -v ] [ -f xmakefile ] [ -d[#] ] [ -n ] [ -D sym[=data] ] label1 ... labelN -v print version and exit. If xmake doesn't know what version it is, someone forgot to re-make and re-install it with itself. -f specify different default file -d[#] turn on debugging -n dry run - do not execute commands lists -Dsym[=data] specify additional symbols to call cpp with, also sets the EXTDEFS variable
DESCRIPTION
- XMake is a make utility. It is not compatible with other
- makes, but provides extended functionality over most standard
- makes. Whereas most other makes have confusing rulesets and do
- not support many-to-many dependancy specifications, XMake has
- relatively few (basically no) rulesets and allows you to easily
- specify many:many dependancies. This gives XMake the flexibility
- to deal with complex project hierarchies very simply. Despite
- the fact that there are no built-in rulesets, an XMakefile is of
- ten no more complex then a normal Makefile. XMake incorporates
- the following major features:
- The ability to specify one-to-many, and many-to-one depen
- dancies
- The ability to apply a single command list to many one-to
- one dependancies (typically lots of object files depending on
- lots of source files can be dealt with in a single line).
- The ability to embed shell commands (e.g. find, ls, what
- ever...) in variable and other definitions.
- The ability to generate wildcard template conversions on
- the fly. For example, you can list the source files and generate
- the object files and all associated dependancies from the source
- file list.
- Runs the C preprocessor, allowing you to use
- #if/#else/#endif and, if need be, use preprocessor macros. The
- main purpose is to support the #include directive and allow oper
- ating system and compiler auto-detect.
- Maintains special 'dependancy' variables %(left) and
- %(right) which may used in command sequences.
- Allows variables to be .set inside a command sequence,
- where the .set directive is executed when/if the command sequence
- is executed... useful when dealing with side effect issues.
- Understands delayed-expansion variable specifications. A
- normal variable specification is something like $(NAME) or
- %(NAME), whereas a delayed-expansion variable specification is
- something like ${NAME}. This allows you to set up global vari
- ables whos contents are based on other variables which have not
- yet been initialized. The variable is fully resolved when used
- in a dependancy or executed as part of a command list.
- By default, XMake attempts to access the XMakefile in the
- current directory. This can be overriden with the -f option.
DIRECTIVES AND VARIABLE SPECIFICATIONS
- Directives must start in column 1. XMake understands the
- following directives:
- .set varname contents
- Set the contents of the specified variable
- .beg / .end
- Applicable only within a command sequence, allows blank
- lines to be inserted without terminating a command sequence.
- Variables may be referenced in any one of several ways:
- $(varname)
$(varname?wildmatch)
$(varname?wildmatch:wildreplace)
$(varname:wildmatch)
$(varname:wildmatch:wildreplace)
%(special)
%(special:wildmatch)
%(special:wildmatch:wildreplace) - The $() variable form references a .set variable, while
- the %() variable form references a special dependancy variable.
- Dependancy variables only work within command sequences. Cur
- rently %(left) and %(right) are defined. %(left) represents the
- left hand side of the dependancy, while %(right) represents the
- right hand side.
- The optional wildmatch and wildreplace elements allow you
- to dynamically restrict transform the elements contained within
- the variable. For example, if a variable contains a mix of .c
- and .h files, you can extract just the .c files with
- $(VARNAME:*.c) . Transformations are accomplished with a third
- element. Each '*' or '?' in the match side is represented by %1
- to %N on the replace side. You can also use '*' and '?' on the
- replace side, which sequentially represent %1 ... %N. The most
- common transformation is something like this:
.set SRCS include.c list.c main.c subs.c
.set OBJS $(SRCS:"*.c":"$(OD)/*.o")
DEPENDANCIES
- XMake allows you to specify dependancies in a manner sim
- liar to make. However, XMake extends the facility to allow many
- one-to-one dependancies to be specified on a single line, as well
- as other combinations. The format for a dependancy is:
- d1 d2 ... dn : s1 s2 ... sn [ : a1 a2 a3 ... aX ]
d1 : s1 s2 ... sn [ : a1 a2 a3 ... aX ]
d1 d2 .. dn : [ : s1 a2 a3 ... aX ] - In the first form, each dN is dependant on the associated
- sN and ALL of the a1-aX elemnts.
- In the second form, a single d1 depends on ALL of the
- s1-sN and a1-aX elements.
- In the third form, each destination dN depends on ALL of
- the a1-aX elements, and there are no 's' elements listed at all.
- Note that the a1..aX elements are optional. You may also
- specify a dependancy with no right hand side elements at all.
- This will cause the execution list for the left hand side to be
- run if the left hand side is ever depended upon from a higher
- level.
- The right hand side is not required to represent a real
- file if its label is used on the left hand side of another depen
- dancy. However, if it does represent a real file, then the 're
- turn code' will be based on a time-stamp comparison even if the
- sub-dependancies of the right hand side themselves are out of
- date and cause commands to run. The best example of this is the
- PROTOS dependancy shown below:
- $(OBJS):: $(PROTOS)
- $(OBJS):: defs.h
- $(OBJS): $(SRCS)
- cc $(CFLAGS) %(right) -o %(left) -c
- $(PROTOS): $(OD)/$(XMKPROTO) $(SRCS)
- $(OD)/$(XMKPROTO) -o %(left) %(right:"*.c")
- In this example, the object modules are dependant on the
- prototype file being up-to-date (as well as defs.h). However,
- the prototype file is updated by xmkproto if any of the source
- files change. xmkproto is smart enough to not touch the proto
- type file if it determines that none of the prototypes have
- changed. Even though the PROTOS:SRCS dependancy is run, the OB
- JS:PROTOS dependancy will not be run if the prototypes file was
- not actually modified.
INCLUDE PATHS
- XMake automatically includes the following directories
- when it runs CPP on your XMakefile:
The . directory
The .. directory
Your $HOME/.xmk directory
/usr/local/share/xmk
/usr/share/xmk - This allows you to configure XMake in a global system,
- with local overrides. Most XMakefiles will not need any of these
- directories. The most useful is the . and .. directories, which
- allow you to setup hierarchical XMakefile.inc files which are re
- cursively included.
CONCEPTS
- It is extremely easy to construct XMakefile's that use a
- single file or directory list to compile an entire project. Once
- you have learned how to use the wildcard match-and-replace capa
- bilities, you will wonder how you could have lived without it be
- fore. Amoung other things, these functions allow you to mix mul
- tiple file extensions in a single variable, such as SRCS, yet ap
- ply a different ruleset to each extension.
FILES
- XMakefile default xmake control file
$HOME/.xmk In include path for cpp
/usr/local/share/xmk In include path for cpp
/usr/share/xmk In include path for cpp