diff --git a/pkg/distillery/basic.reason/Makefile b/pkg/distillery/basic.reason/Makefile new file mode 100644 index 0000000000..f4d8fa2507 --- /dev/null +++ b/pkg/distillery/basic.reason/Makefile @@ -0,0 +1,240 @@ + +##---------------------------------------------------------------------- +## DISCLAIMER +## +## This file contains the rules to make an Eliom project. The project is +## configured through the variables in the file Makefile.options. +##---------------------------------------------------------------------- + +include Makefile.options + +##---------------------------------------------------------------------- +## Internals + +## Required binaries +ELIOMC := eliomc -reason -ppx +ELIOMOPT := eliomopt -reason -ppx +JS_OF_ELIOM := js_of_eliom -reason -ppx +ELIOMDEP := eliomdep +OCSIGENSERVER := ocsigenserver +OCSIGENSERVER.OPT := ocsigenserver.opt + +## Where to put intermediate object files. +## - ELIOM_{SERVER,CLIENT}_DIR must be distinct +## - ELIOM_CLIENT_DIR must not be the local dir. +## - ELIOM_SERVER_DIR could be ".", but you need to +## remove it from the "clean" rules... +export ELIOM_SERVER_DIR := _server +export ELIOM_CLIENT_DIR := _client +export ELIOM_TYPE_DIR := _server +DEPSDIR := _deps + +ifeq ($(DEBUG),yes) + GENERATE_DEBUG ?= -g + RUN_DEBUG ?= "-v" + DEBUG_JS ?= -jsopt -pretty -jsopt -noinline -jsopt -debuginfo +endif + +##---------------------------------------------------------------------- +## General + +.PHONY: all byte opt +all: byte opt +byte opt:: $(TEST_PREFIX)$(ELIOMSTATICDIR)/${PROJECT_NAME}.js +byte opt:: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf +byte opt:: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME)-test.conf +byte:: $(TEST_PREFIX)$(LIBDIR)/${PROJECT_NAME}.cma +opt:: $(TEST_PREFIX)$(LIBDIR)/${PROJECT_NAME}.cmxs + +DIST_DIRS = $(ETCDIR) $(DATADIR) $(LIBDIR) $(LOGDIR) $(STATICDIR) $(ELIOMSTATICDIR) $(shell dirname $(CMDPIPE)) + +##---------------------------------------------------------------------- +## Testing + +DIST_FILES = $(ELIOMSTATICDIR)/$(PROJECT_NAME).js $(LIBDIR)/$(PROJECT_NAME).cma + +.PHONY: test.byte test.opt +test.byte: $(addprefix $(TEST_PREFIX),$(ETCDIR)/$(PROJECT_NAME)-test.conf $(DIST_DIRS) $(DIST_FILES)) + $(OCSIGENSERVER) $(RUN_DEBUG) -c $< +test.opt: $(addprefix $(TEST_PREFIX),$(ETCDIR)/$(PROJECT_NAME)-test.conf $(DIST_DIRS) $(patsubst %.cma,%.cmxs, $(DIST_FILES))) + $(OCSIGENSERVER.OPT) $(RUN_DEBUG) -c $< + +$(addprefix $(TEST_PREFIX), $(DIST_DIRS)): + mkdir -p $@ + +##---------------------------------------------------------------------- +## Installing & Running + +.PHONY: install install.byte install.byte install.opt install.static install.etc install.lib install.lib.byte install.lib.opt run.byte run.opt +install: install.byte install.opt +install.byte: install.lib.byte install.etc install.static | $(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(shell dirname $(CMDPIPE))) +install.opt: install.lib.opt install.etc install.static | $(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(shell dirname $(CMDPIPE))) +install.lib: install.lib.byte install.lib.opt +install.lib.byte: $(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cma | $(PREFIX)$(LIBDIR) + install $< $(PREFIX)$(LIBDIR) +install.lib.opt: $(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cmxs | $(PREFIX)$(LIBDIR) + install $< $(PREFIX)$(LIBDIR) +install.static: $(TEST_PREFIX)$(ELIOMSTATICDIR)/$(PROJECT_NAME).js | $(PREFIX)$(STATICDIR) $(PREFIX)$(ELIOMSTATICDIR) + cp -r $(LOCAL_STATIC)/* $(PREFIX)$(STATICDIR) + [ -z $(WWWUSER) ] || chown -R $(WWWUSER) $(PREFIX)$(STATICDIR) + install $(addprefix -o ,$(WWWUSER)) $< $(PREFIX)$(ELIOMSTATICDIR) +install.etc: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf | $(PREFIX)$(ETCDIR) + install $< $(PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf + +.PHONY: +print-install-files: + @echo $(PREFIX)$(LIBDIR) + @echo $(PREFIX)$(STATICDIR) + @echo $(PREFIX)$(ELIOMSTATICDIR) + @echo $(PREFIX)$(ETCDIR) + +$(addprefix $(PREFIX),$(ETCDIR) $(LIBDIR)): + install -d $@ +$(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(STATICDIR) $(ELIOMSTATICDIR) $(shell dirname $(CMDPIPE))): + install $(addprefix -o ,$(WWWUSER)) -d $@ + +run.byte: + $(OCSIGENSERVER) $(RUN_DEBUG) -c ${PREFIX}${ETCDIR}/${PROJECT_NAME}.conf +run.opt: + $(OCSIGENSERVER.OPT) $(RUN_DEBUG) -c ${PREFIX}${ETCDIR}/${PROJECT_NAME}.conf + +##---------------------------------------------------------------------- +## Aux + +# Use `eliomdep -sort' only in OCaml>4 +ifeq ($(shell ocamlc -version|cut -c1),4) +eliomdep=$(shell $(ELIOMDEP) $(1) -reason -ppx -sort $(2) $(filter %.eliom %.ml,$(3)))) +else +eliomdep=$(3) +endif +objs=$(patsubst %.ml,$(1)/%.$(2),$(patsubst %.eliom,$(1)/%.$(2),$(filter %.eliom %.ml,$(3)))) +depsort=$(call objs,$(1),$(2),$(call eliomdep,$(3),$(4),$(5))) + +##---------------------------------------------------------------------- +## Config files + +FINDLIB_PACKAGES=$(patsubst %,\,$(SERVER_PACKAGES)) +EDIT_WARNING=DON\'T EDIT THIS FILE! It is generated from $(PROJECT_NAME).conf.in, edit that one, or the variables in Makefile.options +SED_ARGS := -e "/^ *%%%/d" +SED_ARGS += -e "s|%%PROJECT_NAME%%|$(PROJECT_NAME)|g" +SED_ARGS += -e "s|%%DATABASE_NAME%%|$(DATABASE_NAME)|g" +SED_ARGS += -e "s|%%DATABASE_USER%%|$(DATABASE_USER)|g" +SED_ARGS += -e "s|%%CMDPIPE%%|%%PREFIX%%$(CMDPIPE)|g" +SED_ARGS += -e "s|%%LOGDIR%%|%%PREFIX%%$(LOGDIR)|g" +SED_ARGS += -e "s|%%DATADIR%%|%%PREFIX%%$(DATADIR)|g" +SED_ARGS += -e "s|%%PERSISTENT_DATA_BACKEND%%|$(PERSISTENT_DATA_BACKEND)|g" +SED_ARGS += -e "s|%%LIBDIR%%|%%PREFIX%%$(LIBDIR)|g" +SED_ARGS += -e "s|%%WARNING%%|$(EDIT_WARNING)|g" +SED_ARGS += -e "s|%%PACKAGES%%|$(FINDLIB_PACKAGES)|g" +SED_ARGS += -e "s|%%ELIOMSTATICDIR%%|%%PREFIX%%$(ELIOMSTATICDIR)|g" +ifeq ($(DEBUG),yes) + SED_ARGS += -e "s|%%DEBUGMODE%%|\|g" +else + SED_ARGS += -e "s|%%DEBUGMODE%%||g" +endif + +LOCAL_SED_ARGS := -e "s|%%PORT%%|$(TEST_PORT)|g" +LOCAL_SED_ARGS += -e "s|%%STATICDIR%%|$(LOCAL_STATIC)|g" +LOCAL_SED_ARGS += -e "s|%%USERGROUP%%||g" +GLOBAL_SED_ARGS := -e "s|%%PORT%%|$(PORT)|g" +GLOBAL_SED_ARGS += -e "s|%%STATICDIR%%|%%PREFIX%%$(STATICDIR)|g" +ifeq ($(WWWUSER)$(WWWGROUP),) + GLOBAL_SED_ARGS += -e "s|%%USERGROUP%%||g" +else + GLOBAL_SED_ARGS += -e "s|%%USERGROUP%%|$(WWWUSER)$(WWWGROUP)|g" +endif + +$(TEST_PREFIX)${ETCDIR}/${PROJECT_NAME}.conf: ${PROJECT_NAME}.conf.in Makefile.options | $(TEST_PREFIX)$(ETCDIR) + sed $(SED_ARGS) $(GLOBAL_SED_ARGS) $< | sed -e "s|%%PREFIX%%|$(PREFIX)|g" > $@ +$(TEST_PREFIX)${ETCDIR}/${PROJECT_NAME}-test.conf: ${PROJECT_NAME}.conf.in Makefile.options | $(TEST_PREFIX)$(ETCDIR) + sed $(SED_ARGS) $(LOCAL_SED_ARGS) $< | sed -e "s|%%PREFIX%%|$(TEST_PREFIX)|g" > $@ + +##---------------------------------------------------------------------- +## Server side compilation + +SERVER_INC := ${addprefix -package ,${SERVER_PACKAGES}} + +${ELIOM_TYPE_DIR}/%.type_mli: %.eliom + ${ELIOMC} -infer ${SERVER_INC} $< + +$(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cma: $(call objs,$(ELIOM_SERVER_DIR),cmo,$(SERVER_FILES)) | $(TEST_PREFIX)$(LIBDIR) + ${ELIOMC} -a -o $@ $(GENERATE_DEBUG) \ + $(call depsort,$(ELIOM_SERVER_DIR),cmo,-server,$(SERVER_INC),$(SERVER_FILES)) + +$(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cmxa: $(call objs,$(ELIOM_SERVER_DIR),cmx,$(SERVER_FILES)) | $(TEST_PREFIX)$(LIBDIR) + ${ELIOMOPT} -a -o $@ $(GENERATE_DEBUG) \ + $(call depsort,$(ELIOM_SERVER_DIR),cmx,-server,$(SERVER_INC),$(SERVER_FILES)) + +%.cmxs: %.cmxa + $(ELIOMOPT) -shared -linkall -o $@ $(GENERATE_DEBUG) $< + +${ELIOM_SERVER_DIR}/%.cmi: %.mli + ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< + +${ELIOM_SERVER_DIR}/%.cmi: %.eliomi + ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< + +${ELIOM_SERVER_DIR}/%.cmo: %.ml + ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< +${ELIOM_SERVER_DIR}/%.cmo: %.eliom + ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< + +${ELIOM_SERVER_DIR}/%.cmx: %.ml + ${ELIOMOPT} -c ${SERVER_INC} $(GENERATE_DEBUG) $< +${ELIOM_SERVER_DIR}/%.cmx: %.eliom + ${ELIOMOPT} -c ${SERVER_INC} $(GENERATE_DEBUG) $< + + +##---------------------------------------------------------------------- +## Client side compilation + +CLIENT_LIBS := ${addprefix -package ,${CLIENT_PACKAGES}} +CLIENT_INC := ${addprefix -package ,${CLIENT_PACKAGES}} + +CLIENT_OBJS := $(filter %.eliom %.ml, $(CLIENT_FILES)) +CLIENT_OBJS := $(patsubst %.eliom,${ELIOM_CLIENT_DIR}/%.cmo, ${CLIENT_OBJS}) +CLIENT_OBJS := $(patsubst %.ml,${ELIOM_CLIENT_DIR}/%.cmo, ${CLIENT_OBJS}) + +$(TEST_PREFIX)$(ELIOMSTATICDIR)/$(PROJECT_NAME).js: $(call objs,$(ELIOM_CLIENT_DIR),cmo,$(CLIENT_FILES)) | $(TEST_PREFIX)$(ELIOMSTATICDIR) + ${JS_OF_ELIOM} -o $@ $(GENERATE_DEBUG) $(CLIENT_INC) $(DEBUG_JS) \ + $(call depsort,$(ELIOM_CLIENT_DIR),cmo,-client,$(CLIENT_INC),$(CLIENT_FILES)) + +${ELIOM_CLIENT_DIR}/%.cmi: %.mli + ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< + +${ELIOM_CLIENT_DIR}/%.cmo: %.eliom + ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< +${ELIOM_CLIENT_DIR}/%.cmo: %.ml + ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< + +${ELIOM_CLIENT_DIR}/%.cmi: %.eliomi + ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< + +##---------------------------------------------------------------------- +## Dependencies + +include .depend + +.depend: $(patsubst %,$(DEPSDIR)/%.server,$(SERVER_FILES)) $(patsubst %,$(DEPSDIR)/%.client,$(CLIENT_FILES)) + cat $^ > $@ + +$(DEPSDIR)/%.server: % | $(DEPSDIR) + $(ELIOMDEP) -server -reason -ppx $(SERVER_INC) $< > $@ + +$(DEPSDIR)/%.client: % | $(DEPSDIR) + $(ELIOMDEP) -client -reason -ppx $(CLIENT_INC) $< > $@ + +$(DEPSDIR): + mkdir $@ + +##---------------------------------------------------------------------- +## Clean up + +clean: + -rm -f *.cm[ioax] *.cmxa *.cmxs *.o *.a *.annot + -rm -f *.type_mli + -rm -f ${PROJECT_NAME}.js + -rm -rf ${ELIOM_CLIENT_DIR} ${ELIOM_SERVER_DIR} + +distclean: clean + -rm -rf $(TEST_PREFIX) $(DEPSDIR) .depend diff --git a/pkg/distillery/basic.reason/Makefile.options b/pkg/distillery/basic.reason/Makefile.options new file mode 100644 index 0000000000..00a1b9e176 --- /dev/null +++ b/pkg/distillery/basic.reason/Makefile.options @@ -0,0 +1,64 @@ + +#---------------------------------------------------------------------- +# SETTINGS FOR THE ELIOM PROJECT %%%PROJECT_NAME%%% +#---------------------------------------------------------------------- + +PROJECT_NAME := %%%PROJECT_NAME%%% + +# Source files for the server +SERVER_FILES := $(wildcard *.eliomi *.eliom) +# Source files for the client +CLIENT_FILES := $(wildcard *.eliomi *.eliom) + +# OCamlfind packages for the server +SERVER_PACKAGES := lwt.ppx js_of_ocaml.deriving.ppx +# OCamlfind packages for the client +CLIENT_PACKAGES := lwt.ppx js_of_ocaml.ppx js_of_ocaml.deriving.ppx + +# Directory with files to be statically served +LOCAL_STATIC = static + +# The backend for persistent data. Can be dbm or sqlite. +# Make sure you have the following packages installed +# - *dbm* if you use dbm --> opam install dbm. +# - *sqlite3* if you use sqlite --> opam install sqlite3. +PERSISTENT_DATA_BACKEND = %%%PROJECT_DB%%% + +# Debug application (yes/no): Debugging info in compilation, +# JavaScript, ocsigenserver +DEBUG := no + +# User to run server with (make run.*) +WWWUSER := www-data +WWWGROUP := www-data + +# Port for running the server (make run.*) +PORT := 80 + +# Port for testing (make test.*) +TEST_PORT := 8080 + +# Root of installation (must end with /) +PREFIX := /usr/local/ + +# Local folder for make test.* (must end with /) +# Do not add files manually in this directory. +# It is just here to test your installation before installing in / +TEST_PREFIX := local/ + +# The installation tree (relative to $(PREFIX) when +# installing/running or $(TEST_PREFIX) when testing). +# Configuration file $(PROJECT_NAME).conf +ETCDIR := etc/${PROJECT_NAME} +# Project's library $(PROJECT_NAME).cma (cmxs) +LIBDIR := lib/${PROJECT_NAME} +# Command pipe, eg. $ echo reload > $(INSTALL_PREFIX)$(CMDPIPE) +CMDPIPE := var/run/${PROJECT_NAME}-cmd +# Ocsigenserver's logging files +LOGDIR := var/log/${PROJECT_NAME} +# Ocsigenserver's persistent data files +DATADIR := var/data/${PROJECT_NAME} +# Copy of $(LOCAL_STATIC) +STATICDIR := var/www/${PROJECT_NAME}/static +# Project's JavaScript file +ELIOMSTATICDIR := var/www/${PROJECT_NAME}/eliom diff --git a/pkg/distillery/basic.reason/PROJECT_NAME.conf.in b/pkg/distillery/basic.reason/PROJECT_NAME.conf.in new file mode 100644 index 0000000000..13a8a1fdbb --- /dev/null +++ b/pkg/distillery/basic.reason/PROJECT_NAME.conf.in @@ -0,0 +1,28 @@ +%%% This is the template for your configuration file. The %%VALUES%% below are +%%% taken from the Makefile to generate the actual configuration files. +%%% This comment will disappear. + + + + %%PORT%% + %%% Only set for running, not for testing + %%USERGROUP%% + %%LOGDIR%% + %%DATADIR%% + utf-8 + %%% Only set when debugging + %%DEBUGMODE%% + %%CMDPIPE%% + + + + %%% This will include the packages defined as SERVER_PACKAGES in your Makefile: + %%PACKAGES%% + + + + + + + + diff --git a/pkg/distillery/basic.reason/PROJECT_NAME.eliom b/pkg/distillery/basic.reason/PROJECT_NAME.eliom new file mode 100644 index 0000000000..fab29c263c --- /dev/null +++ b/pkg/distillery/basic.reason/PROJECT_NAME.eliom @@ -0,0 +1,28 @@ +[%%shared + open Eliom_lib; + open Eliom_content; + open Html.D +]; + +let module %%%MODULE_NAME%%%_app = Eliom_registration.App { + let application_name = "%%%PROJECT_NAME%%%"; + let global_data_path = None; +}; + +let main_service = + Eliom_service.create + path::(Eliom_service.Path []) + meth::(Eliom_service.Get Eliom_parameter.unit) + (); + +let () = + %%%MODULE_NAME%%%_app.register + service::main_service + ( + fun () () => Lwt.return ( + Eliom_tools.F.html + title::"%%%PROJECT_NAME%%%" + css::[["css", "%%%PROJECT_NAME%%%.css"]] + Html.F.(body [h1 [pcdata "Welcome from Eliom's distillery!"]]) + ) + ); diff --git a/pkg/distillery/basic.reason/README b/pkg/distillery/basic.reason/README new file mode 100644 index 0000000000..6c48aa8af2 --- /dev/null +++ b/pkg/distillery/basic.reason/README @@ -0,0 +1,82 @@ + +Instructions +============ + +This project is (initially) generated by eliom-distillery as the basic +project "%%%PROJECT_NAME%%%". + +Generally, you can compile it and run ocsigenserver on it by + $ make test.byte (or test.opt) +See below for other useful targets for make. + +Generated files +--------------- + +The following files in this directory have been generated by +eliom-distillery: + + - %%%PROJECT_NAME%%%.eliom + This is your initial source file. +%%%ifdef OCAML4%%% + All Eliom files (*.eliom, *.eliomi) in this directory are + automatically considered. To add a .ml/.mli file to your project, + append it to the variable SERVER_FILES or CLIENT_FILES. +%%%endif%%% +%%%ifdef OCAML3%%% + To add more source files (.ml,.mli,.eliom,.eliomi) to your project, + add it to the variables SERVER_FILES and/or CLIENT_FILES. +%%%endif%%% + + - static/ + The content of this folder is statically served. Put your CSS or + additional JavaScript files here! + + - Makefile.options + Configure your project here! + + - %%%PROJECT_NAME%%%.conf.in + This file is a template for the configuration file for + ocsigenserver. You will rarely have to edit itself - it takes its + variables from the Makefile.options. This way, the installation + rules and the configuration files are synchronized with respect to + the different folders. + + - Makefile + This contains all rules necessary to build, test, and run your + Eliom application. You better don't touch it ;) See below for the + relevant targets. + + - local/ + This directory is the target of the temporary installation of + your application, to test locally before doing a system-wide + installation in /. Do not put anything manually here. + + - README + Not completely describable here. + + +Makefile targets +---------------- + +Here's some help on how to work with this basic distillery project: + + - Test your application by compiling it and running ocsigenserver locally + $ make test.byte (or test.opt) + + - Compile it only + $ make all (or byte or opt) + + - Deploy your project on your system + $ sudo make install (or install.byte or install.opt) + + - Run the server on the deployed project + $ sudo make run.byte (or run.opt) + + If WWWUSER in the Makefile.options is you, you don't need the + `sudo'. If Eliom isn't installed globally, however, you need to + re-export some environment variables to make this work: + $ sudo PATH=$PATH OCAMLPATH=$OCAMLPATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH make run.byte/run.opt + + - If you need a findlib package in your project, add it to the + variables SERVER_PACKAGES and/or CLIENT_PACKAGES. The configuration + file will be automatically updated. diff --git a/pkg/distillery/basic.reason/static!css!PROJECT_NAME.css b/pkg/distillery/basic.reason/static!css!PROJECT_NAME.css new file mode 100644 index 0000000000..b71fa50add --- /dev/null +++ b/pkg/distillery/basic.reason/static!css!PROJECT_NAME.css @@ -0,0 +1,3 @@ +* { + font-family: sans-serif; +} diff --git a/src/ppx/ppx_eliom_utils.ml b/src/ppx/ppx_eliom_utils.ml index 9105a34a63..b01229fd47 100644 --- a/src/ppx/ppx_eliom_utils.ml +++ b/src/ppx/ppx_eliom_utils.ml @@ -37,6 +37,8 @@ let pat_args = function | [p] -> p | l -> Pat.tuple l +let override_file_name = ref None + (* We use a strong hash (MD5) of the file name. We only keep the first 36 bit, which should be well enough: with 256 files, the likelihood of a collision is about one in two @@ -44,7 +46,14 @@ let pat_args = function These bits are encoded using an OCaml-compatible variant of Base 64, as the hash is used to generate OCaml identifiers. *) let file_hash loc = - let s = Digest.string loc.Location.loc_start.pos_fname in + let file_name = + match !override_file_name with + | Some file_name -> + file_name + | None -> + loc.Location.loc_start.pos_fname + in + let s = Digest.string file_name in let e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_'" in let o = Bytes.create 6 in let g p = Char.code s.[p] in @@ -287,10 +296,17 @@ module Context = struct end -let match_args = function +let rec match_args = function | [ ] -> () - | [ "-type" ; type_file ] -> Mli.type_file := Some type_file - | [ "-notype" ] -> Mli.type_file := None + | "-orig-file-name" :: file_name :: args -> + override_file_name := Some file_name; + match_args args + | "-type" :: type_file :: args -> + Mli.type_file := Some type_file; + match_args args + | "-notype" :: args -> + Mli.type_file := None; + match_args args | args -> Location.raise_errorf ~loc:Location.(in_file !input_name) "Wrong arguments:@ %s" (String.concat " " args) diff --git a/src/tools/eliomc.ml b/src/tools/eliomc.ml index 23b5c9a36f..f3ff31aeb9 100644 --- a/src/tools/eliomc.ml +++ b/src/tools/eliomc.ml @@ -235,7 +235,8 @@ let compile_server_type_eliom file = let out = Unix.openfile obj [Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC] 0o666 in let on_error _ = Unix.close out; - Sys.remove obj + Sys.remove obj; + Utils.exit_no_refmt () in create_process ~out ~on_error !compiler ( [ "-i" ] @@ -303,14 +304,17 @@ let compile_eliom ~impl_intf file = | `Server | `ServerOpt -> obj_ext () in output_prefix file ^ ext + and ppopts = get_ppopts ~impl_intf file in + let on_error _ = + Sys.remove obj; + Utils.exit_no_refmt () in - let ppopts = get_ppopts ~impl_intf file in (* if !do_dump then begin *) (* let camlp4, ppopt = get_pp_dump pkg ("-printer" :: "o" :: ppopts @ [file]) in *) (* create_process camlp4 ppopt; *) (* exit 0 *) (* end; *) - create_process !compiler ( + create_process ~on_error !compiler ( [ "-c" ; "-o" ; obj ] @ preprocess_opt ppopts @ [ "-intf-suffix"; ".eliomi" ] @@ -322,6 +326,7 @@ let compile_eliom ~impl_intf file = args := !args @ [obj] let process_eliom ~impl_intf file = + if !Utils.use_refmt then Utils.orig_file_name := Some file; match !mode with | `Infer when impl_intf = `Impl -> compile_server_type_eliom file @@ -423,6 +428,9 @@ let process_option () = if !i+1 >= Array.length Sys.argv then usage (); process_eliom ~impl_intf:`Impl Sys.argv.(!i+1); i := !i+2 + | "-reason" -> + use_refmt := true; + incr i | arg when Filename.check_suffix arg ".mli" -> process_ocaml ~impl_intf:`Intf arg; incr i diff --git a/src/tools/eliomdep.ml b/src/tools/eliomdep.ml index 59006a5713..47f3386d50 100644 --- a/src/tools/eliomdep.ml +++ b/src/tools/eliomdep.ml @@ -275,6 +275,9 @@ let process_option () = else compile_eliom ~impl_intf:`Impl arg; i := !i+2 + | "-reason" -> + use_refmt := true; + incr i | arg when Filename.check_suffix arg ".mli" -> if not (do_sort ()) then compile_intf arg; diff --git a/src/tools/eliomdoc.ml b/src/tools/eliomdoc.ml index 07b7bcd89b..83b505c89d 100644 --- a/src/tools/eliomdoc.ml +++ b/src/tools/eliomdoc.ml @@ -179,6 +179,9 @@ let process_option () = let arg = Sys.argv.(!i+1) in compile_eliom ~impl_intf:`Impl arg; i := !i+2 + | "-reason" -> + use_refmt := true; + incr i | arg when Filename.check_suffix arg ".mli" -> compile_intf arg; incr i diff --git a/src/tools/utils.ml b/src/tools/utils.ml index b1549e1c3f..de6bf6b965 100644 --- a/src/tools/utils.ml +++ b/src/tools/utils.ml @@ -71,6 +71,10 @@ let default_server_types_ext = let build_dir : string ref = ref "" let type_dir : string ref = ref default_type_dir +let use_refmt = ref false + +let orig_file_name = ref None + let get_kind k = match k with | Some k -> k @@ -362,6 +366,12 @@ let get_ppopts ~impl_intf file = type_opt impl_intf file @ !ppopt let preprocess_opt ?(ocaml = false) ?kind opts = + let refmt () = + if !use_refmt then + [ "-pp"; "refmt --parse=re --print=ml" ] + else + [] + in match !pp_mode with | `Camlp4 -> let pkg = match ocaml, simplify_kind ?kind () with @@ -372,14 +382,20 @@ let preprocess_opt ?(ocaml = false) ?kind opts = in [ "-pp"; get_pp pkg ^ " " ^ String.concat " " opts ] | `Ppx when ocaml -> - [] + refmt () | `Ppx -> let pkg = match simplify_kind ?kind () with | `Client -> "eliom.ppx.client" | `Server -> "eliom.ppx.server" | `Types -> "eliom.ppx.type" + and opts = + match !orig_file_name, !use_refmt with + | Some orig_file_name, true -> + "-orig-file-name" :: orig_file_name :: opts + | _, _ -> + opts in - [ "-ppx"; get_ppx pkg ^ " " ^ String.concat " " opts ] + refmt () @ [ "-ppx"; get_ppx pkg ^ " " ^ String.concat " " opts ] (** Process *) @@ -414,6 +430,13 @@ let create_filter name args f = let ch = Unix.in_channel_of_descr in_ in try f ch with _ -> close_in ch; wait pid +let exit_no_refmt () = + if !use_refmt then ( + Printf.eprintf + "Compiler failed. Have you installed reason and its refmt binary?\n%!"; + exit 1 + ) + let help_filter skip msg ch = for _i = 1 to skip do ignore (input_line ch) done; prerr_endline msg;