2 * Copyright (C) 2019 Richard W.M. Jones
3 * Copyright (C) 2019 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 (* See also "let id" in [lexer.mll]. *)
26 Str.regexp "\\([a-zA-Z_][a-zA-Z0-9_]*\\)[ \t]*=[ \t]*\\(.*\\)"
30 goals: Build software.
32 goals [-f Goalfile] ['var=value' ...] ['target' ...]
34 For detailed help see goals(1).
38 let print_version () =
39 printf "%s %s\n" Config.package_name Config.package_version;
43 (* Get stdlib directory. *)
45 try Sys.getenv "GOALS_DATADIR" with Not_found -> Config.datadir in
46 let stdlibdir = datadir // "stdlib" in
47 let prelude_gl = stdlibdir // "prelude.gl" in
48 if not (is_directory stdlibdir) || not (Sys.file_exists prelude_gl) then
49 failwithf "%s: cannot find the standard library directory, expected %s. If the standard library directory is in a non-standard location then set GOALS_DATADIR. If you can trying to run goals from the build directory then use ‘./run goals ...’"
50 Sys.executable_name stdlibdir;
52 (* Command line arguments. *)
54 let directory = ref "." in
55 let filename = ref "Goalfile" in
58 "-C", Arg.Set_string directory,
59 "directory Change to directory before running";
60 "--directory", Arg.Set_string directory,
61 "directory Change to directory before running";
62 "-f", Arg.Set_string filename,
63 "filename Set name of Goalfile";
64 "--file", Arg.Set_string filename,
65 "filename Set name of Goalfile";
66 "-V", Arg.Unit print_version,
67 " Print version and exit";
68 "--version", Arg.Unit print_version,
69 " Print version and exit";
71 let argspec = Arg.align argspec in
72 let anon_fun s = args := s :: !args in
73 Arg.parse argspec anon_fun usage;
75 let args = List.rev !args in
76 let directory = !directory in
77 let filename = !filename in
79 (* Parse the input file. *)
80 let env = Parse.parse_goalfile filename in
82 (* Now we've read the input, change directory. *)
85 (* Parse the command line anon args. Each parameter has the
86 * form "name=<expr>" to assign a value to a variable, or
87 * "<expr>" to indicate a target to build.
89 let targets = ref [] in
93 if Str.string_match var_regexp arg 0 then (
95 let name = Str.matched_group 1 arg in
96 let expr = Parse.parse_cli_expr (Str.matched_group 2 arg) in
97 env := Ast.Env.add name expr !env
101 let expr = Parse.parse_cli_expr arg in
102 targets := expr :: !targets
105 let targets = List.rev !targets and env = !env in
107 (* If no target was set on the command line, use "all ()". *)
109 if targets <> [] then targets
110 else [Ast.ECallGoal (Ast.noloc, "all", [])] in
112 Ast.print_env stderr env;
114 (* Evaluate the target expressions in turn. *)
115 Eval.evaluate_targets env targets
120 Failure msg -> prerr_endline msg; exit 1