From 8582d10e7b131ffbfe1d92352e7df39230ce1124 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 21 Mar 2012 15:12:29 +0000 Subject: [PATCH] Enable native code compilation when ocamlopt is available. --- .gitignore | 3 +-- daemon/Makefile.am | 10 ++++++++++ daemon/daemon.ml | 9 +++------ daemon/daemon.mli | 3 ++- daemon/whenjobsd.ml | 5 +++-- lib/Makefile.am | 9 +++++++++ lib/whenutils.ml | 5 +++++ lib/whenutils.mli | 3 +++ tools/Makefile.am | 10 +++++++++- tools/whenjobs.ml | 37 +++++++++++++++++++++---------------- 10 files changed, 66 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 9491e0c..e15bd84 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.cma *.cmxa *.o +*.a Makefile.in Makefile /aclocal.m4 @@ -19,7 +20,6 @@ Makefile /config.status /config.sub /configure -/daemon/libdaemon.a /daemon/whenjobsd /daemon/whenjobsd.8 /daemon/whenproto.x @@ -28,7 +28,6 @@ Makefile /depcomp /install-sh /lib/config.ml -/lib/liblibrary.a /lib/whenproto_aux.ml /lib/whenproto_aux.mli /libtool diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 0599e56..ac76e28 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -41,6 +41,8 @@ OBJECTS = \ daemon.cmo \ whenjobsd.cmo +XOBJECTS = $(OBJECTS:.cmo=.cmx) + # Daemon. noinst_LIBRARIES = libdaemon.a libdaemon_a_SOURCES = exit.c syslog_c.c @@ -52,11 +54,19 @@ whenproto_srv.ml whenproto_srv.mli: whenproto.x whenproto.x: ../lib/whenproto.x ln -f $< $@ +if HAVE_OCAMLOPT +whenjobsd: ../lib/whenlib.cmxa $(XOBJECTS) libdaemon.a + $(OCAMLFIND) opt $(OCAMLOPTFLAGS) -ccopt -L../lib \ + -linkpkg whenlib.cmxa \ + libdaemon_a-exit.o libdaemon_a-syslog_c.o \ + $(XOBJECTS) -o $@ +else whenjobsd: ../lib/whenlib.cma $(OBJECTS) libdaemon.a $(OCAMLFIND) c -custom $(OCAMLCFLAGS) -ccopt -L../lib \ -linkpkg whenlib.cma \ libdaemon_a-exit.o libdaemon_a-syslog_c.o \ $(OBJECTS) -o $@ +endif # Rules for all OCaml files. %.cmi: %.mli ../lib/whenlib.cma diff --git a/daemon/daemon.ml b/daemon/daemon.ml index c04bfcb..bc4f51a 100644 --- a/daemon/daemon.ml +++ b/daemon/daemon.ml @@ -292,14 +292,11 @@ and proc_whisper_variables vars = (* Reload the jobs file(s). *) and reload_files () = - (* Get dir/*.cmo *) + (* Get dir/*.cmo (bytecode) or dir/*.cmxs (native code) *) + let suffix = if not Dynlink.is_native then ".cmo" else ".cmxs" in let dir = !jobsdir in let files = Array.to_list (Sys.readdir dir) in - let files = List.filter ( - fun file -> - let n = String.length file in - n >= 5 && String.sub file (n-4) 4 = ".cmo" - ) files in + let files = List.filter (fun file -> string_endswith file suffix) files in let files = List.map (fun file -> dir // file) files in let files = List.sort compare files in diff --git a/daemon/daemon.mli b/daemon/daemon.mli index b7f7d57..d351ac2 100644 --- a/daemon/daemon.mli +++ b/daemon/daemon.mli @@ -25,7 +25,8 @@ val init : string -> bool -> unit The parameters are [jobsdir] and [debug]. *) val reload_files : unit -> unit - (** (Re-)load the file(s) [$jobsdir/*.cmo]. + (** (Re-)load the file(s) [$jobsdir/*.cmo] (in bytecode) + or [$jobsdir/*.cmxs] (in native code). This can raise [Failure] if the operation fails. *) diff --git a/daemon/whenjobsd.ml b/daemon/whenjobsd.ml index 647c7f2..3028503 100644 --- a/daemon/whenjobsd.ml +++ b/daemon/whenjobsd.ml @@ -126,9 +126,10 @@ Options: Syslog.notice "daemon started: version=%s uid=%d home=%s" Config.package_version euid home; - (* If there is a jobs.cmo file, load it. *) + (* If there is a jobs.cmo/jobs.cmxs file, load it. *) let () = - let file = sprintf "%s/jobs.cmo" jobsdir in + let suffix = if not Dynlink.is_native then "cmo" else "cmxs" in + let file = sprintf "%s/jobs.%s" jobsdir suffix in if Sys.file_exists file then try Daemon.reload_files () with Failure _ -> () in diff --git a/lib/Makefile.am b/lib/Makefile.am index 2a42d1e..747f074 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -20,6 +20,10 @@ EXTRA_DIST = whenproto.x pa_when.ml $(SOURCES) libwhenjobsdir = $(libdir)/$(PACKAGE_NAME) libwhenjobs_SCRIPTS = whenlib.cma pa_when.cmo $(CMI_FILES) +if HAVE_OCAMLOPT +libwhenjobs_SCRIPTS += whenlib.cmxa +endif + OCAMLPACKAGES = -package unix,num,camlp4.lib,calendar,rpc OCAMLCFLAGS = -g -warn-error CDEFLMPSUVYZX $(OCAMLPACKAGES) @@ -66,6 +70,8 @@ OBJECTS = \ whentools.cmo \ whenlock.cmo +XOBJECTS = $(OBJECTS:.cmo=.cmx) + # Library. noinst_LIBRARIES = liblibrary.a liblibrary_a_SOURCES = flock.c @@ -74,6 +80,9 @@ liblibrary_a_CFLAGS = -I$(shell $(OCAMLC) -where) whenlib.cma: $(OBJECTS) liblibrary.a $(OCAMLFIND) c -a $(OCAMLCFLAGS) $(OBJECTS) -cclib -llibrary -o $@ +whenlib.cmxa: $(XOBJECTS) liblibrary.a + $(OCAMLFIND) opt -a $(OCAMLOPTFLAGS) $(XOBJECTS) -cclib -llibrary -o $@ + whenproto_aux.ml whenproto_aux.mli: whenproto.x $(OCAMLRPCGEN) -int int32 -hyper int64 -aux $< diff --git a/lib/whenutils.ml b/lib/whenutils.ml index ca26755..5f7c4ee 100644 --- a/lib/whenutils.ml +++ b/lib/whenutils.ml @@ -63,3 +63,8 @@ let string_of_time_t ?(localtime = false) t = (1900+tm.tm_year) (1+tm.tm_mon) tm.tm_mday tm.tm_hour tm.tm_min tm.tm_sec (if localtime then "" else " UTC") + +let string_endswith str suffix = + let len = String.length str in + let slen = String.length suffix in + len >= slen && String.sub str (len-slen) slen = suffix diff --git a/lib/whenutils.mli b/lib/whenutils.mli index 00b2ff1..da51c70 100644 --- a/lib/whenutils.mli +++ b/lib/whenutils.mli @@ -160,3 +160,6 @@ val filter_map : ('a -> 'b option) -> 'a list -> 'b list val string_of_time_t : ?localtime:bool -> float -> string (** Convert string to time in ISO format. If [~localtime] is true then it uses localtime, else UTC. *) + +val string_endswith : string -> string -> bool +(** [string_endswith str suffix] returns true iff [str] ends with [suffix]. *) diff --git a/tools/Makefile.am b/tools/Makefile.am index bbb5fa8..e7e4676 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -39,6 +39,8 @@ OBJECTS = \ whenproto_clnt.cmo \ whenjobs.cmo +XOBJECTS = $(OBJECTS:.cmo=.cmx) + libdir.ml: Makefile rm -f $@ $@-t echo 'let libdir = "$(libdir)/$(PACKAGE_NAME)"' > $@-t @@ -50,9 +52,15 @@ whenproto_clnt.ml whenproto_clnt.mli: whenproto.x whenproto.x: ../lib/whenproto.x ln -f $< $@ +if HAVE_OCAMLOPT +whenjobs: ../lib/whenlib.cmxa $(XOBJECTS) + $(OCAMLFIND) opt $(OCAMLCFLAGS) -ccopt -L../lib \ + -linkpkg whenlib.cmxa $(XOBJECTS) -o $@ +else whenjobs: ../lib/whenlib.cma $(OBJECTS) - $(OCAMLFIND) ocamlc -custom $(OCAMLCFLAGS) -ccopt -L../lib \ + $(OCAMLFIND) c -custom $(OCAMLCFLAGS) -ccopt -L../lib \ -linkpkg whenlib.cma $(OBJECTS) -o $@ +endif # Rules for all OCaml files. %.cmi: %.mli ../lib/whenlib.cma diff --git a/tools/whenjobs.ml b/tools/whenjobs.ml index 49a398d..a9ae7b7 100644 --- a/tools/whenjobs.ml +++ b/tools/whenjobs.ml @@ -311,8 +311,18 @@ and upload_file () = let files = get_multijobs_filenames () in List.iter ( fun file -> - let cmd = sprintf "%s c -I +camlp4 -I %s -package unix,camlp4.lib -pp 'camlp4o %s/pa_when.cmo' -c %s" - Config.ocamlfind !libdir !libdir file in + let cmd = + if not Config.have_ocamlopt then + (* bytecode *) + sprintf "%s c -I +camlp4 -I %s -package unix,camlp4.lib -pp 'camlp4o %s/pa_when.cmo' -c %s" + Config.ocamlfind !libdir !libdir file + else ( + (* native code *) + let base = Filename.chop_extension file in (* without .ml suffix *) + sprintf "%s opt -I +camlp4 -I %s -package unix,camlp4.lib -pp 'camlp4o %s/pa_when.cmo' -c %s &&\n%s opt -shared -linkall %s.cmx -o %s.cmxs" + Config.ocamlfind !libdir !libdir file + Config.ocamlfind base base + ) in if Sys.command cmd <> 0 then ( eprintf "whenjobs: %s: could not compile jobs script, see earlier errors\n" file; @@ -321,25 +331,24 @@ and upload_file () = ) ) files; - let cmo_files = List.map ( + let suffix = if not Dynlink.is_native then "cmo" else "cmxs" in + + let compiled_files = List.map ( fun file -> let n = String.length file in if n < 4 then assert false; - String.sub file 0 (n-3) ^ ".cmo" + sprintf "%s.%s" (String.sub file 0 (n-3)) suffix ) files in (* Test-load the jobs files to ensure they make sense. *) Whenfile.init Whenstate.empty; (try - List.iter Dynlink.loadfile cmo_files + List.iter Dynlink.loadfile compiled_files with Dynlink.Error err -> - eprintf "whenjobs: %s\n" (Dynlink.error_message err); - (* Since it failed, unlink the cmo files. *) - List.iter ( - fun cmo_file -> - (try unlink cmo_file with Unix_error _ -> ()) - ) cmo_files; + eprintf "whenjobs: dynlink: %s\n" (Dynlink.error_message err); + (* Since it failed, unlink the compiled files. *) + List.iter (fun f -> try unlink f with Unix_error _ -> ()) compiled_files; exit 1 ); @@ -571,11 +580,7 @@ and get_jobs_filename () = and get_multijobs_filenames () = (* Get dir/*.ml *) let files = Array.to_list (Sys.readdir jobsdir) in - let files = List.filter ( - fun file -> - let n = String.length file in - n >= 4 && String.sub file (n-3) 3 = ".ml" - ) files in + let files = List.filter (fun file -> string_endswith file ".ml") files in let files = List.map (fun file -> jobsdir // file) files in List.sort compare files -- 1.8.3.1