![]() |
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 thing
Keyword 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:
makeNote, 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 here
apply 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 2
Note: 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 = $X
The 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 = $Y
Here, 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
commands
is 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