![]() |
OMake Home Documentation Download Publications Mailing lists User contributions Users and projects Bugzilla Browse sources Changelog summary, verbose |
Jump to version 0.9.8.6, 0.9.8.5, 0.9.8.4, 0.9.8.3, 0.9.8.1, 0.9.8, 0.9.6.9, 0.9.6.8, 0.9.6.7, 0.9.6.6, 0.9.6.5, 0.9.6, 0.9.4, 0.9.3, 0.9.2.
See also the brief summary change log.
The syntax of a keyword parameter/argument is "identifier = expr".
Function Application ------------------------------------------- f(a) f(1) f(~a, b) f(~a = 10, 11) Required keyword argument f(?a, b) f(~a = 10, 12) Optional keyword argument f(12) -- defaults to empty f(?a = 1, b) f(~a = 10, 11) Optional keyword argument with default value f(~a = 1, b) f(11) -- ~a is same as ?a if there is a default value f(?a = 10, 11) -- Arguments can use ?, but it means the same thingKeyword arguments and normal arguments are processed independently. Normal arguments have to appear in the same order as in the parameter list, but keyword arguments can go anywhere.
This also adds the function notation.
fun(x, y) => add($x, $y) foreach(x => ..., a b c) println($x)where the "..." essentially means "parse as if the indented block below was actually an expression in here"
Old-style foreach generate a warning.
The outer syntax is normal; the program syntax is an ast to ast translation. The translation is turned on with the command ".LANGUAGE: program", which is scoped like "export". Here is an example:
#!/usr/bin/env osh .LANGUAGE: program f(x) = return x + 1 println(f(f(1)))The normal $-style expressions are always allowed, but in program-syntax mode, identifiers stand for variables, function application is the f(e1, ..., e2) form, and there are the standard infix operators. To switch back to the default syntax, use .LANGUAGE: make
Note, shell commands and rules never use program syntax, except within function arguments.
This is not heavily tested.
f(x,y) = return $(add $x, $y) g = $(apply $f, 2) # Partial applications must use apply println($(g 3)) # 5 ff(x) = gg(y) = return $(add $x, $y) println($(apply $(ff), 3, 5)) # Prints 8, also need to use apply hereapply can also take keyword arguments.
osh> ls(R, /etc/httpd) /home/jyh/omake/etc/httpd
X = abc # 123 equal($X, abc) # this is now true
Z. = x = 1 f() = x = 2 export Z.f() echo $(Z.x) # Prints "2"This works with arbitrary levels of nesting.
section export section public.X = 1 println($X) # Prints 1
section public.X = 1 public.Y = 2 export X section X = 3 Y = 4 export Y # X is 3 # Y is 2
public.X = 1 public.f() = X = 2 export public.Y = $f # X is 2 # Y is 2Note: this is, of course, not the same as imperative programming, because functions can always choose not to export. In particular, the string "functions" do not export.
public.X = 1 export X public.f() = X = 2 Y = $"$f" # X = 1 # Y = 2
.STATIC: println(foo) X = 1 Y = $XThe variable X is exported, with a "delayed" value. The rule is only evaluated if the value for $X is needed, but it is lazy. The definition of Y does not force evaluation.
.STATIC: x.input X = $(expensive-function x.input)This is be evaluated if x.input changes and X is forced.
.STATIC: X: x.input Y = 1 X = $YHere, Y is not exported from the section.
g(x) = eprintln($"g($x)") add($x, 1) f(x) = .STATIC: :key: $x y = $(g $x) value $y println($(f 1)) println($(f 2)) println($(f 1))will call function g twice - only once for each argument, printing:
g(1) 2 g(2) 3 2
X. = Y. = Z. = x = 1 X.Y.Z.y = 2 X.Y.Z.f() = value $(add $x, $y) echo $(X.Y.Z.f) # prints "3"
X = file([...]) a b c - :: Array
clean: %: rm -f ...
Value dependencies are specified using the :value: option in rules.
a: b c :value: $(X) ...
This rule specifies that "a" should be recompiled if the value of $(X) changes (X does not have to be a filename). This is intended to allow greater control over dependencies. In addition, it can be used in place of other kinds of dependencies. For example, the following rule:
a: b :exists: c commandsis the same as
a: b :value: $(target-exists c) commands
Notes:
One other significant difference is that the rule cache now uses a digest of the rule commands text, not the text itself. This has an impact on initial omake speed (I am not sure how significant it is) but the cache is smaller. Also, "section eval" should now be handled correctly.
Externally, a .SCANNER rule has the usual rule form:
.SCANNER: target: dependencies... ...scanner commands...
However, the scanner target is now decoupled from the build target, allowing a scanner result to be used for multiple build targets. For example, ocamldep produces dependencies for .cmo and .cmx files simultaneously. They can share the scanner rule by specifying an explicit :scanner: dependency.
.SCANNER: scan-ocaml-%.ml: %.ml ocamldep $lt; %.cmo: %.ml :scanner: scan-ocaml-%.ml $(OCAMLC) ... %.cmx %.o: %.ml :scanner: scan-ocaml-%.ml $(OCAMLOPT) ...
The current convention is that scanner targets should be named scan-<language>-<source-file>.
.SCANNER: foo: echo "foo: boo" foo: :scanner: foo ...
See documentation for the Target object and the "Examining the dependency graph" Section of the OMake Documentation for more information.
.SUBDIRS: foo boo println(Current directory is $(CWD)) ...normal configuration...
vmount(-l, src, x86) .SUBDIRS: x86
Files from the src directory are now automatically linked into the x86 directory as needed. If you want to have multiple versions, you can use multiple directories (and multiple vmounts).
The keys are now "simple" values, not just strings. Simple values include integers, floats, strings, arrays of simple values, files, and directories.
Only the Map class has the map functions defined. If you want to have, say, a File that also includes a Map, create a subclass that extends both File and Map.
Literal string keys can be written in the form $|key...|. This works both for definitions and uses. The usual modifiers are allowed $,|key| and $`|key|.
X. = extends $(Map) $|key 1| = 1 $|key 2| = $|key 1| boo $|key 2| += foo