Skip to content

Work on issues 130 (script shell generator) #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bootstrap
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/usr/bin/env bash

libs="unix.cmxa"
libs="unix.cmxa str.cmxa"
OCAMLOPT="ocamlopt -g"
# use faster ocamlopt, if available
OCAMLOPT_OPT=`which ocamlopt.opt`
if [[ $OCAMLOPT_OPT != "" ]] ; then
OCAMLOPT="ocamlopt.opt -g"
fi

extmodules="fugue filepath filesystem"
extmodules="bash fugue filepath filesystem"
libmodules="types gconf filetype dag libname pp expr utils modname taskdep helper dagutils process findlibConf scheduler prog dependencies generators hier meta target dist project analyze configure prepare buildprogs build exception"
mainmodules="sdist doc init help install path_generated main"

Expand Down
73 changes: 73 additions & 0 deletions ext/bash.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
open Printf
open Sys

let is_bash_enabled = ref false
let filename = ref ""
let lib_path = ref ""

let create_bash fn =
let oc = open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_text] 0o740 !filename in
try
fprintf oc "#!/bin/bash\n";
fprintf oc "# Automatically generated file.\n# EDIT AT YOUR OWN RISK !!\n\n";
fprintf oc "# Find library path\n";
fprintf oc "conf_path=$(ocamlfind printconf conf)\n";
fprintf oc "lib_path=$(grep path ${conf_path} | sed 's/path=//' | sed 's/\"//g')\n\n";
close_out oc
with e ->
close_out_noerr oc;
raise e

let init_bash fn cmd stdlibPath =
is_bash_enabled := true;
lib_path := stdlibPath;
match fn with
| Some name -> (match cmd with
| "configure" -> (filename := name; create_bash name)
| "build" -> (filename := name; if Sys.file_exists name then () else create_bash name)
| _ -> failwith "--bash can only be used with build and configure options")
| None -> failwith "bash field is empty !!"

let bash_write str =
if !is_bash_enabled then
begin
let oc = open_out_gen [Open_creat; Open_text; Open_append] 0o740 !filename in
try
fprintf oc "%s\n" str;
close_out oc;
with e ->
close_out_noerr oc;
raise e;
end
else ()

let bash_cmd args =
let bash_set_var str = bash_write (Str.global_replace (Str.regexp_string !lib_path) "${lib_path}" str) in
let cmd_tmp = List.hd args in
let cmd_len = String.length cmd_tmp in
try
let cmd_pos = (String.rindex cmd_tmp '/') + 1 in
let cmd = String.sub cmd_tmp cmd_pos (cmd_len - cmd_pos) in
bash_set_var (String.concat " " (cmd :: (List.tl args)))
with e -> match e with
| Not_found -> bash_set_var (String.concat " " args)
| _ -> raise e

let bash_comment str = bash_write ("\n# " ^ str)

let bash_mkdir str perm = bash_write ("mkdir -p -m " ^ (sprintf "%o" perm) ^ " " ^ str)

let bash_symlink target link_name = bash_write ("ln -s " ^ target ^ " " ^ link_name)

let bash_generateMlFile version file flags =
bash_write ("echo \"(* autogenerated file by obuild. do not modify *)\" >> " ^ file);
bash_write (sprintf "echo \"let project_version = \\\"%s\\\"\" >> %s" version file);
List.iter (fun (name, v) -> bash_write (sprintf "let project_flag_%s = %b >> %s" name v file)) flags

let bash_generateCFile version file flags =
bash_write ("echo \"/* autogenerated file by obuild. do not modify */\" >> " ^ file);
bash_write (sprintf "echo \"#define PROJECT_VERSION \\\"%s\\\"\" >> %s" version file);
List.iter (fun (name, v) -> bash_write (sprintf "#define PROJECT_FLAG_%s %d >> %s"
(String.uppercase name) (if v then 1 else 0) file)) flags


3 changes: 2 additions & 1 deletion ext/filesystem.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
open Printf
open Fugue
open Filepath
open Bash

exception UnexpectedFileType of string
exception WriteFailed
Expand Down Expand Up @@ -96,7 +97,7 @@ let mkdirSafe path perm =
then (if Sys.is_directory (fp_to_string path)
then false
else failwith ("directory " ^ (fp_to_string path) ^ " cannot be created: file already exists"))
else (Unix.mkdir (fp_to_string path) perm; true)
else (Unix.mkdir (fp_to_string path) perm; Bash.bash_mkdir (fp_to_string path) perm; true)

let mkdirSafe_ path perm =
let (_: bool) = mkdirSafe path perm in
Expand Down
10 changes: 5 additions & 5 deletions obuild.obuild
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,26 @@ extra-srcs: bootstrap

library obuild
modules: obuild
build-deps: unix, obuild.ext
build-deps: unix, str, obuild.ext
library ext
modules: ext
build-deps: unix
build-deps: unix, str

# a comment
executable obuild
main-is: main.ml
src-dir: src
build-deps: unix, obuild
build-deps: unix, str, obuild

executable obuild-simple
main-is: simple.ml
src-dir: src
build-deps: unix, obuild
build-deps: unix, str, obuild

executable obuild-from-oasis
main-is: assimilate_oasis.ml
src-dir: tools
build-deps: obuild, obuild.ext
build-deps: str, obuild, obuild.ext
installable: false

test dag
Expand Down
8 changes: 8 additions & 0 deletions obuild/build.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
open Ext.Fugue
open Ext.Filepath
open Ext.Bash
open Ext
open Types
open Helper
Expand Down Expand Up @@ -129,6 +130,8 @@ let compile_c task_index task c_file bstate task_context dag =
let (nb_step,nb_step_len) = get_nb_step dag in
verbose Report "[%*d of %d] Compiling C %-30s%s\n%!" nb_step_len task_index nb_step (fn_to_string c_file)
(if reason <> "" then " ( " ^ reason ^ " )" else "");
bash_comment (sprintf "[%*d of %d] Compiling C %-30s%s%!" nb_step_len task_index nb_step (fn_to_string c_file)
(if reason <> "" then " ( " ^ reason ^ " )" else ""));
let cflags = cbits.target_cflags in
Scheduler.AddProcess (task, runCCompile bstate.bstate_config c_dir_spec cflags c_file)
)
Expand Down Expand Up @@ -176,6 +179,7 @@ let compile_directory task_index task (h : Hier.t) task_context dag =
if ops <> [] then (
let (nb_step,nb_step_len) = get_nb_step dag in
verbose Report "[%*d of %d] Packing %-30s%s\n%!" nb_step_len task_index nb_step (Hier.to_string h) reason;
bash_comment (sprintf "[%*d of %d] Packing %-30s%s%!" nb_step_len task_index nb_step (Hier.to_string h) reason);
Scheduler.AddTask (task, ops)
) else
Scheduler.FinishTask task
Expand Down Expand Up @@ -287,6 +291,8 @@ let compile_module task_index task is_intf h bstate task_context dag =
let (nb_step, nb_step_len) = get_nb_step dag in
verbose Report "[%*d of %d] %s %-30s%s\n%!" nb_step_len task_index nb_step verb (Hier.to_string h)
(if reason <> "" then " ( " ^ reason ^ " )" else "");
bash_comment (sprintf "[%*d of %d] %s %-30s%s%!" nb_step_len task_index nb_step verb (Hier.to_string h)
(if reason <> "" then " ( " ^ reason ^ " )" else ""));
Scheduler.AddTask (task, all_fun_lists)

let wait_for_files cdep_files =
Expand Down Expand Up @@ -375,6 +381,8 @@ let link_ task_index bstate cstate pkgDeps target dag compiled useThreadLib ccli
if is_lib target then LinkingLibrary else LinkingExecutable in
verbose Report "[%*d of %d] Linking %s %s\n%!" nb_step_len task_index nb_step
(if is_lib target then "library" else "executable") (fp_to_string dest);
bash_comment (sprintf "[%*d of %d] Linking %s %s%!" nb_step_len task_index nb_step
(if is_lib target then "library" else "executable") (fp_to_string dest));
[(fun () -> runOcamlLinking (linking_paths_of compileOpt) compiledType
link_type compileOpt useThreadLib systhread cclibs buildDeps compiled dest)]
) else []
Expand Down
3 changes: 2 additions & 1 deletion obuild/buildprogs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ open Types
open Ext
open Ext.Filepath
open Ext.Fugue
open Ext.Bash
open Process
open Prepare
open Gconf
Expand Down Expand Up @@ -139,7 +140,7 @@ let runOcamlLinking includeDirs buildMode linkingMode compileType useThread syst
let real = fp_to_string dest in
let basename = Filename.basename real in
if not (file_or_link_exists basename)
then Unix.symlink real basename)
then Unix.symlink real basename; bash_symlink real basename;)
in
let prog = match buildMode with
| Native -> Prog.getOcamlOpt ()
Expand Down
33 changes: 19 additions & 14 deletions obuild/configure.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
open Ext.Fugue
open Ext.Filepath
open Ext.Bash
open Ext
open Helper
open Printf
Expand All @@ -18,22 +19,26 @@ let getDigestKV () =
[ ("obuild-digest", digest) ]

let generateMlFile project file flags =
Utils.generateFile file (fun add ->
add "(* autogenerated file by obuild. do not modify *)\n";
add (sprintf "let project_version = \"%s\"\n" project.Analyze.project_file.Project.version);
(* TODO escape name properly *)
List.iter (fun (name, v) -> add (sprintf "let project_flag_%s = %b\n" name v)) flags;
)
let version = project.Analyze.project_file.Project.version in
Utils.generateFile file (fun add ->
add "(* autogenerated file by obuild. do not modify *)\n";
add (sprintf "let project_version = \"%s\"\n" version);
(* TODO escape name properly *)
List.iter (fun (name, v) -> add (sprintf "let project_flag_%s = %b\n" name v)) flags;
);
bash_generateMlFile version (fp_to_string file) flags

let generateCFile project file flags =
Utils.generateFile file (fun add ->
add "/* autogenerated file by obuild. do not modify */\n";
add (sprintf "#define PROJECT_VERSION \"%s\"\n" project.Analyze.project_file.Project.version);
(* TODO escape name properly *)
List.iter (fun (name, v) ->
add (sprintf "#define PROJECT_FLAG_%s %d\n" (String.uppercase name) (if v then 1 else 0))
) flags;
)
let version = project.Analyze.project_file.Project.version in
Utils.generateFile file (fun add ->
add "/* autogenerated file by obuild. do not modify */\n";
add (sprintf "#define PROJECT_VERSION \"%s\"\n" version);
(* TODO escape name properly *)
List.iter (fun (name, v) ->
add (sprintf "#define PROJECT_FLAG_%s %d\n" (String.uppercase name) (if v then 1 else 0))
) flags;
);
bash_generateCFile version (fp_to_string file) flags

let makeSetup digestKV project flags = hashtbl_fromList (
digestKV
Expand Down
5 changes: 4 additions & 1 deletion obuild/gconf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type t = {
mutable parallel_jobs : int;
mutable dump_dot : bool;
mutable color : bool;
mutable bash : bool;
mutable bin_annot : bool;
mutable short_path : bool;
mutable ocamlmklib : bool;
Expand All @@ -18,7 +19,8 @@ exception UnknownOption of string

let env_variables = [
"ocamlopt"; "ocamlc"; "ocaml"; "ocamldep"; "ocamldoc"; "ocamlyacc"; "ocamllex"; "ocamlmklib";
"ocamlmktop"; "cc"; "ranlib"; "ar"; "ld"; "pkg-config"; "camlp4"; "findlib-path"; "atdgen"
"ocamlmktop"; "cc"; "ranlib"; "ar"; "ld"; "pkg-config"; "camlp4"; "findlib-path"; "atdgen";
"bash"
]

let env_ =
Expand Down Expand Up @@ -77,6 +79,7 @@ let defaults = {
parallel_jobs = 2;
dump_dot = false;
color = false;
bash = false;
bin_annot = true;
short_path = false;
ocamlmklib = true;
Expand Down
3 changes: 3 additions & 0 deletions obuild/process.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
open Helper
open Gconf
open Ext.Bash
open Ext

type output = {
buf : Buffer.t;
Expand Down Expand Up @@ -29,6 +31,7 @@ let make args =
let _ = String.index s ' ' in "\"" ^ s ^ "\""
with Not_found -> s in
verbose DebugPlus " [CMD]: %s\n%!" (String.concat " " (List.map escape args));
bash_cmd args;
let (r1,w1) = Unix.pipe () in
let (r2,w2) = Unix.pipe () in
let argv = Array.of_list args in
Expand Down
23 changes: 21 additions & 2 deletions src/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ open Ext
open Obuild.Types
open Obuild.Helper
open Obuild.Gconf
open Obuild.Analyze
open Obuild

let programName = "obuild"
Expand Down Expand Up @@ -88,8 +89,9 @@ let mainBuild argv =
| _ ->
let targets = List.map Target.Name.of_string !anon in
Dag.subset project.Analyze.project_targets_dag targets
in
Build.build_dag bstate proj_file dag
in (
Build.build_dag bstate proj_file dag
)

let mainClean _ =
if Filesystem.exists (Dist.get_path ())
Expand Down Expand Up @@ -226,6 +228,16 @@ let mainGet argv =
| "name" -> printf "%s\n" proj_file.Project.name;
| "version" -> printf "%s\n" proj_file.Project.version;
| "license" -> printf "%s\n" proj_file.Project.license;
| "ocaml_extra_args" -> (match proj_file.Project.ocaml_extra_args with
| Some x -> List.iter (function y -> printf "%s\n" y) x
| None -> printf "None\n");
| "configure_script" -> (match proj_file.Project.configure_script with
| Some x -> printf "%s\n" (fp_to_string (x))
| None -> printf "None\n");
| "extra_srcs" -> List.iter (function x -> printf "%s\n" (fp_to_string (x))) proj_file.Project.extra_srcs;
(*| "extra_args" -> match proj_file.Project.ocaml_extra_args with
| None -> printf "None\n";
| Some v -> List.iter (function x -> printf "%s\n" x) v;*)
| _ -> eprintf "error: unknown field %s\n" field; exit 1
)
| _ -> eprintf "usage: obuild get <field>\n"; exit 1
Expand Down Expand Up @@ -272,6 +284,7 @@ let parseGlobalArgs () =
| [] -> failwith (optName ^ " expect a parameter")
| x::xs -> f x; xs
in

let rec processGlobalArgs l =
match l with
| x::xs -> if String.length x > 0 && x.[0] = '-'
Expand All @@ -288,6 +301,7 @@ let parseGlobalArgs () =
| "-vvv"
| "--debug+"
| "--debug-with-cmd" -> gconf.verbosity <- DebugPlus; xs
| "--bash" -> expect_param1 x xs (fun p -> (gconf.bash <- true; Gconf.set_env "bash" p;))
| "-q" (* for quiet *)
| "--silent" -> gconf.verbosity <- Silent; xs
| "--strict" -> gconf.strict <- true; xs
Expand Down Expand Up @@ -333,6 +347,11 @@ let defaultMain () =
);

let cmd = List.hd args in

let ocamlCfg = Prog.getOcamlConfig () in
let stdlibPath = fp_to_string (fp (get_ocaml_config_key_hashtbl "standard_library" ocamlCfg)) in
if gconf.bash then Bash.init_bash (Gconf.get_env "bash") cmd stdlibPath else ();

try
let mainF = List.assoc cmd knownCommands in
mainF args
Expand Down