diff --git a/Makefile b/Makefile index 9a2aefc1..a13ffda7 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ test_quietly: RUN_TESTS_QUIETLY := -q run_tests: all ckati_tests ruby runtest.rb -c -n $(RUN_TESTS_QUIETLY) +ckati.1: ckati.md + pandoc $< -t man -s -o $@ clean: ckati_clean diff --git a/ckati.1 b/ckati.1 new file mode 100644 index 00000000..bf0a981a --- /dev/null +++ b/ckati.1 @@ -0,0 +1,248 @@ +.\" Automatically generated by Pandoc 2.5 +.\" +.TH "CKATI" "1" "" "ckati" "User Commands" +.hy +.SH NAME +.PP +ckati \- experimental GNU make clone +.SH SYNOPSIS +.PP +\f[B]ckati\f[R] [\f[I]OPTION\f[R]]\&... [\f[I]TARGET\f[R]]\&... +.SH DESCRIPTION +.PP +\f[I]ckati\f[R] is a C++ implementation of \f[B]kati\f[R], an +experimental \f[B]make\f[R] clone. +.PP +The motivation of \f[B]kati\f[R] was to speed up Android platform build. +The Android platform\[cq]s build system is built on \f[B]GNU make\f[R] +and allows developers to write build rules in a descriptive way. +.PP +\f[I]ckati\f[R] is a complete rewrite of \f[B]GNU make\f[R] from +scratch, focused on speeding up incremental builds. +.PP +\f[I]ckati\f[R] supports two modes of execution. +It can directly execute the commands specified in the +\f[I]Makefile\f[R], or it can generate a \f[I]ninja\f[R] file +corresponding to the \f[I]Makefile\f[R]. +.PP +The \f[I]ninja\f[R] generator mode is the main mode of operation, since +the built\-in executor of \f[I]ckati\f[R] lacks important features for a +build system like parallel builds. +.PP +The \f[I]ninja\f[R] generator mode is not fully compatible with \f[B]GNU +make\f[R] due to a feature mismatch between \f[B]make\f[R] and +\f[B]ninja\f[R]. +Since \f[B]ninja\f[R] only allows one command per a rule, when the +\f[I]Makefile\f[R] has multiple commands, \f[I]ckati\f[R] generates a +rule with the commands joined with \f[C]&&\f[R]. +When \f[C]$(shell ...)\f[R] is used, \f[I]ckati\f[R] translates it into +shell\[cq]s \f[C]$(...)\f[R]. +This works in many cases, but doesn\[cq]t when the result of +\f[C]$(shell ...)\f[R] is passed to another function: +.IP +.nf +\f[C] +all: + echo $(if $(shell echo),FAIL,PASS) +\f[R] +.fi +.PP +If \f[C]\-\[rs]\-regen\f[R] flag is specified, \f[I]ckati\f[R] checks if +anything in your environment has changed after the previous run. +If the \f[I]ninja\f[R] file doesn\[cq]t need to be regenerated, it +finishes quickly. +.PP +The following is checked when deciding whether the \f[I]ninja\f[R] file +should be regenerated or not: +.IP \[bu] 2 +The command line flags passed to \f[I]ckati\f[R] +.IP \[bu] 2 +Timestamps of the \f[I]Makefiles\f[R] used to generate the previous +\f[I]ninja\f[R] file +.IP \[bu] 2 +Environment variables used while evaluating \f[I]Makefiles\f[R] +.IP \[bu] 2 +Results of \f[C]$(wildcard ...)\f[R] +.IP \[bu] 2 +Results of \f[C]$(shell ...)\f[R] +.PP +\f[I]Ckati\f[R] doesn\[cq]t run \f[C]$(shell date ...)\f[R] and +\f[C]$(shell echo ...)\f[R] during these checks. +.PP +\f[I]Ckati\f[R] optimises \f[C]$(shell find ...)\f[R] calls, since the +Android\[cq]s build system uses a lot of them to create a list of all +\&.java/.mk files under a directory, and they are slow. +\f[I]Ckati\f[R] has a built\-in emulator of \f[B]GNU find\f[R]. +The find emulator traverse the directory tree and creates an in\-memory +directory tree. +When \f[C]$(shell find ...)\f[R] is used, the find emulator returns +results of \f[B]find\f[R] commands using the cached tree, giving a +performance boost. +.SH OPTIONS +.TP +.B \f[B]\-d\f[R] +Print debugging information. +.TP +.B \f[B]\-\-warn\f[R] +Print \f[I]ckati\f[R] warnings. +.TP +.B \f[B]\-f\f[R] \f[I]FILE\f[R] +Use \f[I]FILE\f[R] as a \f[I]Makefile\f[R]. +.TP +.B \f[B]\-c\f[R] +Do not run anything, only perform a syntax check. +.TP +.B \f[B]\-i\f[R] +Dry run mode: print the commands that would be executed, but do not +execute them. +.TP +.B \f[B]\-s\f[R] +Silent operation; do not print the commands as they are executed. +.TP +.B \f[B]\-j\f[R] \f[I]JOBS\f[R] +Specifies the number of \f[I]JOBS\f[R] (commands) to run simultaneously. +.TP +.B \f[B]\-\-no_builtin_rules\f[R] +Do not provide any built\-in rules. +.TP +.B \f[B]\-\-ninja\f[R] +Ninja generator mode: do not execute commands directly, but generate a +\f[I]ninja\f[R] file. +By default, the ninja file is saved as \f[C]build.ninja\f[R], and a +shell script to execute +\f[B]ninja\f[R] is saved as \f[C]ninja.sh\f[R]. +An optional suffix can be added to the file names +by using \f[B]\-\-ninja_suffix\f[R] option. +.TP +.B \f[B]\-\-ninja_dir\f[R] +The directory where the \f[I]ninja\f[R] file will be generated; the +default is the current directory. +.TP +.B \f[B]\-\-ninja_suffix\f[R] +The \f[I]ninja\f[R] file suffix; the default is no suffix. +.TP +.B \f[B]\-\-use_find_emulator\f[R] +Emulate \f[C]find\f[R] command calls to improve build performance. +.TP +.B \f[B]\-\-regen\f[R] +Regenerate the \f[I]ninja\f[R] file only when necessary. +.TP +.B \f[B]\-\-detect_android_echo\f[R] +Detect the use of \f[C]$(shell echo ...)\f[R] in Android build system. +.TP +.B \f[B]\-\-detect_depfiles\f[R] +Detect dependency files. +.PP +The following options can emit warnings or errors if certain +\f[I]Makefile\f[R] features are used: +.TP +.B \f[B]\-\-werror_overriding_commands\f[R] +Fail when overriding commands for a previously defined target. +.TP +.B \f[B]\-\-warn_implicit_rules\f[R], \f[B]\-\-werror_implicit_rules\f[R] +Warn or fail when implicit rules are used. +.TP +.B \f[B]\-\-warn_suffix_rules\f[R], \f[B]\-\-werror_suffix_rules\f[R] +Warn or fail when suffix rules are used. +.TP +.B \f[B]\-\-warn_real_to_phony\f[R], \f[B]\-\-werror_real_to_phony\f[R] +Warn or fail when a real target depends on a \f[C]PHONY\f[R] target. +.TP +.B \f[B]\-\-warn_phony_looks_real\f[R], \f[B]\-\-werror_phony_looks_real\f[R] +Warn or fail when a \f[C]PHONY\f[R] target contains slashes. +.TP +.B \f[B]\-\-werror_writable\f[R] +Fail when writing to a read\-only directory. +.SH SUPPORTED MAKE FUNCTIONS +.PP +Text functions: +.IP \[bu] 2 +\f[C]subst\f[R] +.IP \[bu] 2 +\f[C]patsubst\f[R] +.IP \[bu] 2 +\f[C]strip\f[R] +.IP \[bu] 2 +\f[C]findstring\f[R] +.IP \[bu] 2 +\f[C]filter\f[R] +.IP \[bu] 2 +\f[C]filter\-out\f[R] +.IP \[bu] 2 +\f[C]sort\f[R] +.IP \[bu] 2 +\f[C]word\f[R] +.IP \[bu] 2 +\f[C]wordlist\f[R] +.IP \[bu] 2 +\f[C]words\f[R] +.IP \[bu] 2 +\f[C]firstword\f[R] +.IP \[bu] 2 +\f[C]lastword\f[R] +.PP +File name functions: +.IP \[bu] 2 +\f[C]dir\f[R] +.IP \[bu] 2 +\f[C]notdir\f[R] +.IP \[bu] 2 +\f[C]suffix\f[R] +.IP \[bu] 2 +\f[C]basename\f[R] +.IP \[bu] 2 +\f[C]addsuffix\f[R] +.IP \[bu] 2 +\f[C]addprefix\f[R] +.IP \[bu] 2 +\f[C]join\f[R] +.IP \[bu] 2 +\f[C]wildcard\f[R] +.IP \[bu] 2 +\f[C]realpath\f[R] +.IP \[bu] 2 +\f[C]abspath\f[R] +.PP +Conditional functions: +.IP \[bu] 2 +\f[C]if\f[R] +.IP \[bu] 2 +\f[C]or\f[R] +.IP \[bu] 2 +\f[C]and\f[R] +.PP +Make control functions: +.IP \[bu] 2 +\f[C]info\f[R] +.IP \[bu] 2 +\f[C]warning\f[R] +.IP \[bu] 2 +\f[C]error\f[R] +.PP +Miscellaneous: +.IP \[bu] 2 +\f[C]value\f[R] +.IP \[bu] 2 +\f[C]eval\f[R] +.IP \[bu] 2 +\f[C]shell\f[R] +.IP \[bu] 2 +\f[C]call\f[R] +.IP \[bu] 2 +\f[C]foreach\f[R] +.IP \[bu] 2 +\f[C]origin\f[R] +.IP \[bu] 2 +\f[C]flavor\f[R] +.IP \[bu] 2 +\f[C]file\f[R] +.SH EXIT STATUS +.PP +\f[B]ckati\f[R] exits with a status of zero if all \f[I]Makefiles\f[R] +were successfully parsed and no targets that were built failed. +.SH SEE ALSO +.PP +\f[B]make\f[R](1), \f[B]ninja\f[R](1) +.SH AUTHOR +.PP +This manual page was contributed by Andrej Shadura. diff --git a/ckati.md b/ckati.md new file mode 100644 index 00000000..a159b5b9 --- /dev/null +++ b/ckati.md @@ -0,0 +1,232 @@ +--- +title: CKATI +section: 1 +header: User Commands +footer: ckati +--- + +NAME +==== + +ckati - experimental GNU make clone + +SYNOPSIS +======== + +**ckati** [*OPTION*]… [*TARGET*]… + +DESCRIPTION +=========== + +*ckati* is a C++ implementation of **kati**, an experimental **make** clone. + +The motivation of **kati** was to speed up Android platform build. The Android +platform's build system is built on **GNU make** and allows developers to write +build rules in a descriptive way. + +*ckati* is a complete rewrite of **GNU make** from scratch, focused on speeding +up incremental builds. + +*ckati* supports two modes of execution. It can directly execute the commands +specified in the *Makefile*, or it can generate a *ninja* file corresponding +to the *Makefile*. + +The *ninja* generator mode is the main mode of operation, since the built-in +executor of *ckati* lacks important features for a build system like parallel +builds. + +The *ninja* generator mode is not fully compatible with **GNU make** due to +a feature mismatch between **make** and **ninja**. Since **ninja** only allows +one command per a rule, when the *Makefile* has multiple commands, *ckati* +generates a rule with the commands joined with `&&`. When `$(shell ...)` +is used, *ckati* translates it into shell's `$(...)`. This works in many cases, +but doesn't when the result of `$(shell ...)` is passed to another function: + + all: + echo $(if $(shell echo),FAIL,PASS) + +If `-\-regen` flag is specified, *ckati* checks if anything in your environment +has changed after the previous run. If the *ninja* file doesn't need to be +regenerated, it finishes quickly. + +The following is checked when deciding whether the *ninja* file should be +regenerated or not: + +* The command line flags passed to *ckati* +* Timestamps of the *Makefiles* used to generate the previous *ninja* file +* Environment variables used while evaluating *Makefiles* +* Results of `$(wildcard ...)` +* Results of `$(shell ...)` + +*Ckati* doesn't run `$(shell date ...)` and `$(shell echo ...)` during these +checks. + +*Ckati* optimises `$(shell find ...)` calls, since the Android's build system +uses a lot of them to create a list of all .java/.mk files under a directory, +and they are slow. *Ckati* has a built-in emulator of **GNU find**. The find +emulator traverse the directory tree and creates an in-memory directory tree. +When `$(shell find ...)` is used, the find emulator returns results of +**find** commands using the cached tree, giving a performance boost. + +OPTIONS +======= + +**-d** + +: Print debugging information. + +**-\-warn** + +: Print *ckati* warnings. + +**-f** *FILE* + +: Use *FILE* as a *Makefile*. + +**-c** + +: Do not run anything, only perform a syntax check. + +**-i** + +: Dry run mode: print the commands that would be executed, but do not execute them. + +**-s** + +: Silent operation; do not print the commands as they are executed. + +**-j** *JOBS* + +: Specifies the number of *JOBS* (commands) to run simultaneously. + +**-\-no\_builtin\_rules** + +: Do not provide any built-in rules. + +**-\-ninja** + +: Ninja generator mode: do not execute commands directly, but generate a *ninja* file. +: By default, the ninja file is saved as `build.ninja`, and a shell script to execute +: **ninja** is saved as `ninja.sh`. An optional suffix can be added to the file names +: by using **-\-ninja\_suffix** option. + +**-\-ninja\_dir** + +: The directory where the *ninja* file will be generated; the default is the current directory. + +**-\-ninja\_suffix** + +: The *ninja* file suffix; the default is no suffix. + +**-\-use\_find\_emulator** + +: Emulate `find` command calls to improve build performance. + +**-\-regen** + +: Regenerate the *ninja* file only when necessary. + +**-\-detect\_android\_echo** + +: Detect the use of `$(shell echo ...)` in Android build system. + +**-\-detect\_depfiles** + +: Detect dependency files. + +The following options can emit warnings or errors if certain *Makefile* +features are used: + +**-\-werror\_overriding\_commands** + +: Fail when overriding commands for a previously defined target. + +**-\-warn\_implicit\_rules**, **-\-werror\_implicit\_rules** + +: Warn or fail when implicit rules are used. + +**-\-warn\_suffix\_rules**, **-\-werror\_suffix\_rules** + +: Warn or fail when suffix rules are used. + +**-\-warn\_real\_to\_phony**, **-\-werror\_real\_to\_phony** + +: Warn or fail when a real target depends on a `PHONY` target. + +**-\-warn\_phony\_looks\_real**, **-\-werror\_phony\_looks\_real** + +: Warn or fail when a `PHONY` target contains slashes. + +**-\-werror\_writable** + +: Fail when writing to a read-only directory. + +SUPPORTED MAKE FUNCTIONS +======================== + +Text functions: + +* `subst` +* `patsubst` +* `strip` +* `findstring` +* `filter` +* `filter-out` +* `sort` +* `word` +* `wordlist` +* `words` +* `firstword` +* `lastword` + +File name functions: + +* `dir` +* `notdir` +* `suffix` +* `basename` +* `addsuffix` +* `addprefix` +* `join` +* `wildcard` +* `realpath` +* `abspath` + +Conditional functions: + +* `if` +* `or` +* `and` + +Make control functions: + +* `info` +* `warning` +* `error` + +Miscellaneous: + +* `value` +* `eval` +* `shell` +* `call` +* `foreach` +* `origin` +* `flavor` +* `file` + +EXIT STATUS +=========== + +**ckati** exits with a status of zero if all *Makefiles* were successfully +parsed and no targets that were built failed. + +SEE ALSO +======== + +**make**(1), **ninja**(1) + +AUTHOR +====== + +This manual page was contributed by Andrej Shadura.