blob: 0262ba03fbb281005e5ebb67aad4653044a377ff [file] [log] [blame]
.TH jmk 5 "13 March 2021" "1" "JMK format"
.SH SYNOPSIS
The JMK format is processed by jmk(1) to generate a Makefile.
.SH DESCRIPTION
jmk(1) is a simple M4 script which provides a handful of macros.
These macros can be used to automate many tedious parts of creating
makefiles.
.SH OVERVIEW
The following macros are provided by JMK:
.B
init(project, [target])
.NB
.RS
Initialize the project named <project> to build the target <target>.
If <target> is not provided, it defaults to <project>.
.B
Example:
.NB
.EX
init(kernel, kernel.elf)
# or
init(my_lib, my_lib.a)
.EE
.RE
.B
preset(preset_name)
.NB
.RS
Apply a preset to the project.
Currently the following presets are available:
freestanding: Applies CFLAGS suitable for freestanding targets.
optimize: Applies -O2 optimization level
debug: Applies -g
32: Sets target architecture to 32 bit
warn: Enables all warnings except unused-function and unused-variable.
nasm: Forces the assembler to be nasm.
.B
Example:
.NB
.EX
preset(32)
preset(debug)
CFLAGS += -my-flag
.EE
.RE
.B
archetype(archetype_name)
.NB
.RS
Applies a given archetype to the project.
An archetype provides support to compile a certain language or type of program.
The two archetypes available by default are
.B
c
.NB
and
.B
asm,
.NB
whose meanings are self explanatory.
.B
Example:
.NB
.EX
archetype(c)
archetype(asm)
.EE
.RE
.B
depends(name, directory, [target])
.NB
.RS
Register the target called <target> located in <directory> as a dependency named <name>.
By default, <target> is set to the last segment of the directory path plus .a.
E.g.: for foo/bar <target> would be bar.a by default.
This is usually used in conjunction with lib().
Internally this will generate a target for this library that will call make on the
other project in order to build the target.
See lib() for examples.
.RE
.B
lib(dependency_name)
.NB
.RS
Lib expands to the path to the dependency called <dependency_name> as defined by depends().
This can, for example, be used in OBJECTS to specify the project's dependency on another
(sub)project, or it can be used anywhere you would need to refer to the path of the
target generated by that project.
Despite the name, lib can be used for any type of dependency, not just for libraries.
.B
Example:
.NB
.EX
depends(libc, $(ROOT)/src/libc, libc.a)
OBJECTS = main.o lib(libc)
.EE
.RE
.B
phony(target)
.NB
.RS
Adds <target> to the list of .PHONY targets.
.RE
.B
type(type)
.NB
.RS
Sets the project type and generates the actual target for the project.
If you need to build your final target in a way unsupported by default, feel free to omit
this and write the target by hand. <type> can be one of executable, static_lib or
custom_link.
The first two cases will build an executable and library respectively, using $(CC) and ar.
custom_link will invoke $(LD), passing LDFLAGS.
Note that the objects to include in the target are to be specified in OBJECTS,
and should be built either automatically by an included archetype, or manually.
.RE
.B
finish
.NB
.RS
Include this at the end of every Jmk file, this generates some targets like .PHONY
and clean, as well as setting up automatic Makefile regeneration.
.RE
.SH EXAMPLE
Here is a full example of a JMK project:
.EX
init(kernel, kernel.elf)
preset(freestanding)
preset(optimize)
preset(32)
preset(nasm)
LDFLAGS += -Tlink.ld
archetype(c)
archetype(asm)
depends(some_driver, dri/some/driver/, driver.a)
OBJECTS = boot.o main.o other.o something.o lib(some_driver)
type(custom_link)
qemu: kernel.elf
qemu-system-i386 $<
finish
.EE
.SH SEE ALSO
jmk(1), building(9)