diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 327515b..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -name: Build -on: - push: - branches: - - master # forall push/merge in master - pull_request: - branches: - - "**" # forall submitted Pull Requests - -jobs: - build: - strategy: - fail-fast: false - matrix: - os: - - macos-latest - - ubuntu-latest - - windows-latest - ocaml-version: - - 4.08.x - - 4.09.x - - 4.10.x - - 4.11.x - - 4.12.x - - 4.13.x - - runs-on: ${{ matrix.os }} - - steps: - - name: Prepare git - run: | - git config --global core.autocrlf false - git config --global init.defaultBranch master - - - name: Checkout code - uses: actions/checkout@v2 - - - name: Use OCaml ${{ matrix.ocaml-version }} - uses: ocaml/setup-ocaml@v2 - with: - ocaml-compiler: ${{ matrix.ocaml-version }} - - - name: Install dependencies - run: opam install --deps-only . - - - name: List installed packages - run: opam list - - - name: Build locally - run: opam exec -- make - - - name: Upload Linux/macOS artifact - if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.os }}-${{ matrix.ocaml-version }}-ocamlscript - path: ocamlscript - - - name: Upload Windows artifact - if: runner.os == 'Windows' - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.os }}-${{ matrix.ocaml-version }}-ocamlscript.exe - path: ocamlscript.exe - - - name: Build, test, and install package - run: opam install -t . - - - name: Uninstall package - run: opam uninstall . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe31a3d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.exe +/_build/ +thin-ocamlscript.install diff --git a/.ocamlformat b/.ocamlformat new file mode 100644 index 0000000..8191b13 --- /dev/null +++ b/.ocamlformat @@ -0,0 +1,15 @@ +profile = conventional + +leading-nested-match-parens = false +space-around-variants = false +space-around-arrays = false +space-around-lists = false +space-around-records = false +break-infix = fit-or-vertical +break-separators = after +break-cases = fit-or-vertical +cases-exp-indent = 2 +exp-grouping = preserve +if-then-else = fit-or-vertical +let-and = sparse +type-decl = sparse diff --git a/Changes b/Changes deleted file mode 100644 index 884777c..0000000 --- a/Changes +++ /dev/null @@ -1,95 +0,0 @@ -VERSION 2 -========= - -2014-12-27: release 2.0.4 -- fixes for opam and recent installs of camlp4 - -2012-02-03: release 2.0.3 -- no user-visible behavior (new way of creating the source tar.gz) - -2008-02-05: release 2.0.2 -- supports OCaml/Camlp4 3.10.1 - -2007-04-07: release 2.0.1 -- added support for OCaml/Camlp4 3.10.0+beta - -2007-03-04: release 2.0.0 -- small change in the interface of the Pipeline module (new_cmd -> command) -- added OCaml.pp (any preprocessor) - and Ocaml.ppsrcloc (location formatter) variables - -2006-07-25: prerelease 1.99.5 -- added support for ocamlyacc - -2006-07-14: prerelease 1.99.4 -- added Ocaml.sources variable that can hold additional source files, e.g. - Ocaml.sources := ["../thing1.ml"] - -2006-06-24: pre-release 1.99.3 -- separation of examples and tests -- added some examples - -2006-06-07: pre-release 1.99.2 -- replaced Sys.command by create_process so that arguments - with special characters are not subject to shell interpretation - -2006-06-05: pre-release 1.99.1 -- important bugfix (scripts with shebang line and no "--" line) -- not dependent of micmatch_pcre not pcre anymore - -2006-06-03: pre-release 1.99.0, nothing really changed since last time - -2006-27-03 -This is an experimental extension of ocamlscript, which is -incompatible with ocamlscript 1.1. - -Current features: -- each script must have two parts, which are separated by a line starting - with "--" and followed by any number of blanks. -- the first part gives instructions for the compilation of the second part, - which is the program itself (see "fulltest" file for an example). -- the first part can be empty or can contain some OCaml code which - makes a "compile" function visible at the end of the module. -- by default, the Ocamlscript.Ocamlopt module is opened, which makes - a "compile" function available. -- the signature of this "compile" function is the following: - val compile : string -> string -> int - Its arguments are (1) the name of the source file to compile and (2) the - name of the executable which must be produced. These names are chosen by - ocamlscript, not by the script author. -- the Ocamlopt module provides several hooks which can be used to - specify which libraries to use and other compilation options. It - uses the ocamlfind (Findlib) frontend to ocamlopt. The parameters - are currently initialized as follows: - let packs = ref [] (* findlib packages *) - let use_camlp4 = ref true (* by default camlp4 is used *) - let revised = ref false (* use this to use the revised syntax *) - let ocamlflags = ref [] (* any options that you may want to pass - to ocamlopt *) - let ppopt = ref [] (* any options that you may want to pass - to camlp4o or camlp4r *) - let verbose = ref false (* that's for debugging *) - -- Any definition of a function named "compile" will override the - default one. Ocamlscript can be used to compile programs in any - language which accepts the same line directives as OCaml (it should - however be possible to make it more flexible in the future). - For now, it should be possible to define "compile" functions - for ocamllex or ocaml+twt (and include them in the Ocamlscript library). - - - -VERSION 1 -========= - -* version 1.1 (2005-10-03): - - - the temporary copy of the original script contains proper reference - to original source so line number and script name is correct in case - of error (suggestion of Mike Lin); - - - change license to a BSD-like one. Apparently Public Domain imposes - restriction of Software redistribution on a different medium. The new - license should allow to use the software for about any use. - -* version 1.0 (2005-08-23): original release. diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 91b9239..0000000 --- a/INSTALL +++ /dev/null @@ -1,37 +0,0 @@ - Ocamlscript version 1.99 - ======================== - -Disclaimer: ----------- -This is a preview release of ocamlscript 2. It is provided for curious -programmers who are interested in testing the new system. Several -incompatible changes might take place between this pre-release and -the 2.0 release line. Be ready to adapt the header of your scripts -when you upgrade! - - -Installation: ------------- - -Requirements: - * OCaml version 3.10 or higher, - * Camlp4 (including command camlp4orf), - * GNU make, - * Findlib (ocamlfind) - -This version has been developed on Linux and will probably not work on the -Win32 port of OCaml, and maybe others. Any help to make that work is -appreciated. - -Compilation: - make - -Installation: - make install - -Uninstallation: - make uninstall - -Examples are available in the "examples" subdirectory. - -For more information on ocamlscript, see the README file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c276064..0000000 --- a/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright 2005 David MENTRE -Copyright 2006 Martin Jambon - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/META.in b/META.in deleted file mode 100644 index f9bd4f5..0000000 --- a/META.in +++ /dev/null @@ -1,6 +0,0 @@ -name = "ocamlscript" -description = "Runtime library for ocamlscript" - -requires = "unix" -archive(byte) = "ocamlscript.cmo" -archive(native) = "ocamlscript.cmx" diff --git a/Makefile b/Makefile deleted file mode 100644 index 894e94d..0000000 --- a/Makefile +++ /dev/null @@ -1,142 +0,0 @@ -VERSION = 3.0.0 -RESULT = ocamlscript -SOURCES = \ - version.ml pipeline.mli pipeline.ml common.mli common.ml \ - utils.mli utils.ml ocaml.mli ocaml.ml std.ml - -CAMLP4 := $(shell ocamlfind query camlp4) - -STDBIN = $(shell dirname `which ocamlfind`) -ifndef PREFIX - PREFIX = $(shell dirname $(STDBIN)) -endif -export PREFIX - -ifndef BINDIR - BINDIR = $(PREFIX)/bin -endif -export BINDIR - -PACKS = unix str -# PP = camlp4o -I . -parser pa_opt.cmo -# export PP - -# CAMLP4_VARIANTS = pa_opt.ml -OCAMLFLAGS = -dtypes - - -.PHONY: init default common bytelib optlib optexe bytelib optlib \ - install uninstall test tests examples ocamldoc version meta archive - -default: common bytelib optlib optexe - -# GODI targets -.PHONY: all opt -all: common bytelib byteexe -opt: common optlib optexe -### - -common: version.ml - # ocamlc -pp 'camlp4orf -loc _loc' -c \ - # -I $(CAMLP4) pa_opt310.ml && \ - # cp pa_opt310.cmo pa_opt.cmo && \ - # cp pa_opt310.cmi pa_opt.cmi - # ocamlc -pp 'camlp4orf -loc _loc' -c \ - # -I $(CAMLP4) pa_tryfinally310.ml && \ - # cp pa_tryfinally310.cmo pa_tryfinally.cmo && \ - # cp pa_tryfinally310.cmi pa_tryfinally.cmi - -byteexe: bytelib - ocamlfind ocamlc -o ocamlscript.byte \ - -package '$(PACKS)' -linkpkg $(OCAMLFLAGS) \ - ocamlscript.cmo main.ml -optexe: optlib - ocamlfind ocamlopt -o ocamlscript \ - -package '$(PACKS)' -linkpkg $(OCAMLFLAGS) \ - ocamlscript.cmx main.ml -bytelib: pabc - touch bc.done -optlib: panc - touch nc.done -install: - test -f ocamlscript$(EXE) && \ - install -m 0755 ocamlscript$(EXE) $(BINDIR)/ocamlscript$(EXE) || : - test -f ocamlscript.byte$(EXE) && \ - install -m 0755 ocamlscript.byte$(EXE) \ - $(BINDIR)/ocamlscript.byte$(EXE) || : - ocamlfind install ocamlscript META \ - ocamlscript.cmi \ - `test -f bc.done && echo ocamlscript.cmo` \ - `test -f nc.done && echo ocamlscript.cmx ocamlscript.o` -uninstall: - rm -f $(BINDIR)/ocamlscript$(EXE) $(BINDIR)/ocamlscript.byte$(EXE) - ocamlfind remove ocamlscript - -test: tests -tests: - cd tests && $(MAKE) -examples: - cd examples && $(MAKE) - -ocamldoc: - ocamldoc -d ocamldoc -html pipeline.mli common.mli utils.mli ocaml.mli - -.PHONY: version -version: version.ml -version.ml: Makefile - echo 'let version = "$(VERSION)"' > version.ml - echo 'version = "$(VERSION)"' > META - cat META.in >> META - -.PHONY: help -help: - ./ocamlscript --help > ocamlscript-help.txt - - -archive: all version help - rm -rf /tmp/ocamlscript /tmp/ocamlscript-$(VERSION) && \ - cp -r . /tmp/ocamlscript && \ - cd /tmp/ocamlscript && \ - $(MAKE) clean && \ - rm -f *~ ocamlscript*.tar* && \ - cp ocamldoc/* $$WWW/ocamlscript-doc && \ - cd /tmp && cp -r ocamlscript ocamlscript-$(VERSION) && \ - tar czf ocamlscript.tar.gz ocamlscript && \ - tar cjf ocamlscript.tar.bz2 ocamlscript && \ - tar czf ocamlscript-$(VERSION).tar.gz \ - ocamlscript-$(VERSION) && \ - tar cjf ocamlscript-$(VERSION).tar.bz2 ocamlscript-$(VERSION) - mv /tmp/ocamlscript.tar.gz /tmp/ocamlscript.tar.bz2 . - mv /tmp/ocamlscript-$(VERSION).tar.gz \ - /tmp/ocamlscript-$(VERSION).tar.bz2 . - cp ocamlscript.tar.gz ocamlscript.tar.bz2 $$WWW/ - cp ocamlscript-$(VERSION).tar.gz ocamlscript-$(VERSION).tar.bz2 $$WWW/ - cp LICENSE $$WWW/ocamlscript-license.txt - echo 'let ocamlscript_version = "$(VERSION)"' \ - > $$WWW/ocamlscript-version.ml - cp Changes $$WWW/ocamlscript-changes.txt - cp ocamlscript-help.txt $$WWW/ - rm -rf $$WWW/ocamlscript-examples - cd examples && $(MAKE) clean - cp -r examples $$WWW/ocamlscript-examples - -TRASH = \ - bc.done nc.done main.cm* main.o main.annot \ - ocamlscript$(EXE) ocamlscript.byte$(EXE) \ - *~ \ - version.ml META - - -clean:: - cd tests && $(MAKE) clean - cd examples && $(MAKE) clean - rm -rf ocamldoc *.cmi *.cmo - -OCAML_VERSION = $(shell ocamlc -v | head -1 | \ - sed -e 's/.*version \([0-9]\.[0-9][0-9]\).*/\1/') - -OCAMLBCFLAGS = -for-pack Ocamlscript -OCAMLNCFLAGS = -for-pack Ocamlscript - -OCAMLMAKEFILE = OCamlMakefile -include $(OCAMLMAKEFILE) diff --git a/OCamlMakefile b/OCamlMakefile deleted file mode 100644 index 27875aa..0000000 --- a/OCamlMakefile +++ /dev/null @@ -1,1154 +0,0 @@ -########################################################################### -# OCamlMakefile -# Copyright (C) 1999-2004 Markus Mottl -# -# For updates see: -# http://www.ocaml.info/home/ocaml_sources.html -# -# $Id: OCamlMakefile,v 1.72 2005/12/09 15:30:50 mottl Exp $ -# -########################################################################### - -# Modified by damien for .glade.ml compilation - -# Set these variables to the names of the sources to be processed and -# the result variable. Order matters during linkage! - -ifndef SOURCES - SOURCES := foo.ml -endif -export SOURCES - -ifndef RES_CLIB_SUF - RES_CLIB_SUF := _stubs -endif -export RES_CLIB_SUF - -ifndef RESULT - RESULT := foo -endif -export RESULT - -export LIB_PACK_NAME - -ifndef DOC_FILES - DOC_FILES := $(filter %.mli, $(SOURCES)) -endif -export DOC_FILES - -export BCSUFFIX -export NCSUFFIX - -ifndef TOPSUFFIX - TOPSUFFIX := .top -endif -export TOPSUFFIX - -# Eventually set include- and library-paths, libraries to link, -# additional compilation-, link- and ocamlyacc-flags -# Path- and library information needs not be written with "-I" and such... -# Define THREADS if you need it, otherwise leave it unset (same for -# USE_CAMLP4)! - -export THREADS -export VMTHREADS -export ANNOTATE -export USE_CAMLP4 - -export INCDIRS -export LIBDIRS -export EXTLIBDIRS -export RESULTDEPS -export OCAML_DEFAULT_DIRS - -export LIBS -export CLIBS - -export OCAMLFLAGS -export OCAMLNCFLAGS -export OCAMLBCFLAGS - -export OCAMLLDFLAGS -export OCAMLNLDFLAGS -export OCAMLBLDFLAGS - -ifndef OCAMLCPFLAGS - OCAMLCPFLAGS := a -endif - -export OCAMLCPFLAGS - -export PPFLAGS - -export YFLAGS -export IDLFLAGS - -export OCAMLDOCFLAGS - -export OCAMLFIND_INSTFLAGS - -export DVIPSFLAGS - -export STATIC - -# Add a list of optional trash files that should be deleted by "make clean" -export TRASH - -#################### variables depending on your OCaml-installation - -ifdef MINGW - export MINGW - WIN32 := 1 - CFLAGS_WIN32 := -mno-cygwin -endif -ifdef MSVC - export MSVC - WIN32 := 1 - ifndef STATIC - CPPFLAGS_WIN32 := -DCAML_DLL - endif - CFLAGS_WIN32 += -nologo - EXT_OBJ := obj - EXT_LIB := lib - ifeq ($(CC),gcc) - # work around GNU Make default value - ifdef THREADS - CC := cl -MT - else - CC := cl - endif - endif - ifeq ($(CXX),g++) - # work around GNU Make default value - CXX := $(CC) - endif - CFLAG_O := -Fo -endif -ifdef WIN32 - EXT_CXX := cpp - EXE := .exe -endif - -ifndef EXT_OBJ - EXT_OBJ := o -endif -ifndef EXT_LIB - EXT_LIB := a -endif -ifndef EXT_CXX - EXT_CXX := cc -endif -ifndef EXE - EXE := # empty -endif -ifndef CFLAG_O - CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)! -endif - -export CC -export CXX -export CFLAGS -export CXXFLAGS -export LDFLAGS -export CPPFLAGS - -ifndef RPATH_FLAG - RPATH_FLAG := -R -endif -export RPATH_FLAG - -ifndef MSVC -ifndef PIC_CFLAGS - PIC_CFLAGS := -fPIC -endif -ifndef PIC_CPPFLAGS - PIC_CPPFLAGS := -DPIC -endif -endif - -export PIC_CFLAGS -export PIC_CPPFLAGS - -BCRESULT := $(addsuffix $(BCSUFFIX), $(RESULT)) -NCRESULT := $(addsuffix $(NCSUFFIX), $(RESULT)) -TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT)) - -ifndef OCAMLFIND - OCAMLFIND := ocamlfind -endif -export OCAMLFIND - -ifndef OCAMLC - OCAMLC := ocamlc -endif -export OCAMLC - -ifndef OCAMLOPT - OCAMLOPT := ocamlopt -endif -export OCAMLOPT - -ifndef OCAMLMKTOP - OCAMLMKTOP := ocamlmktop -endif -export OCAMLMKTOP - -ifndef OCAMLCP - OCAMLCP := ocamlcp -endif -export OCAMLCP - -ifndef OCAMLDEP - OCAMLDEP := ocamldep -endif -export OCAMLDEP - -ifndef OCAMLLEX - OCAMLLEX := ocamllex -endif -export OCAMLLEX - -ifndef OCAMLYACC - OCAMLYACC := ocamlyacc -endif -export OCAMLYACC - -ifndef OCAMLMKLIB - OCAMLMKLIB := ocamlmklib -endif -export OCAMLMKLIB - -ifndef OCAML_GLADECC - OCAML_GLADECC := lablgladecc2 -endif -export OCAML_GLADECC - -ifndef OCAML_GLADECC_FLAGS - OCAML_GLADECC_FLAGS := -endif -export OCAML_GLADECC_FLAGS - -ifndef CAMELEON_REPORT - CAMELEON_REPORT := report -endif -export CAMELEON_REPORT - -ifndef CAMELEON_REPORT_FLAGS - CAMELEON_REPORT_FLAGS := -endif -export CAMELEON_REPORT_FLAGS - -ifndef CAMELEON_ZOGGY - CAMELEON_ZOGGY := camlp4o pa_zog.cma pr_o.cmo -endif -export CAMELEON_ZOGGY - -ifndef CAMELEON_ZOGGY_FLAGS - CAMELEON_ZOGGY_FLAGS := -endif -export CAMELEON_ZOGGY_FLAGS - -ifndef OXRIDL - OXRIDL := oxridl -endif -export OXRIDL - -ifndef CAMLIDL - CAMLIDL := camlidl -endif -export CAMLIDL - -ifndef CAMLIDLDLL - CAMLIDLDLL := camlidldll -endif -export CAMLIDLDLL - -ifndef NOIDLHEADER - MAYBE_IDL_HEADER := -header -endif -export NOIDLHEADER - -export NO_CUSTOM - -ifndef CAMLP4 - CAMLP4 := camlp4 -endif -export CAMLP4 - -ifndef REAL_OCAMLFIND - ifdef PACKS - ifndef CREATE_LIB - ifdef THREADS - PACKS += threads - endif - endif - empty := - space := $(empty) $(empty) - comma := , - ifdef PREDS - PRE_OCAML_FIND_PREDICATES := $(subst $(space),$(comma),$(PREDS)) - PRE_OCAML_FIND_PACKAGES := $(subst $(space),$(comma),$(PACKS)) - OCAML_FIND_PREDICATES := -predicates $(PRE_OCAML_FIND_PREDICATES) - # OCAML_DEP_PREDICATES := -syntax $(PRE_OCAML_FIND_PREDICATES) - OCAML_FIND_PACKAGES := $(OCAML_FIND_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) - OCAML_DEP_PACKAGES := $(OCAML_DEP_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) - else - OCAML_FIND_PACKAGES := -package $(subst $(space),$(comma),$(PACKS)) - OCAML_DEP_PACKAGES := - endif - OCAML_FIND_LINKPKG := -linkpkg - REAL_OCAMLFIND := $(OCAMLFIND) - endif -endif - -export OCAML_FIND_PACKAGES -export OCAML_DEP_PACKAGES -export OCAML_FIND_LINKPKG -export REAL_OCAMLFIND - -ifndef OCAMLDOC - OCAMLDOC := ocamldoc -endif -export OCAMLDOC - -ifndef LATEX - LATEX := latex -endif -export LATEX - -ifndef DVIPS - DVIPS := dvips -endif -export DVIPS - -ifndef PS2PDF - PS2PDF := ps2pdf -endif -export PS2PDF - -ifndef OCAMLMAKEFILE - OCAMLMAKEFILE := OCamlMakefile -endif -export OCAMLMAKEFILE - -ifndef OCAMLLIBPATH - OCAMLLIBPATH := \ - $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/local/lib/ocaml) -endif -export OCAMLLIBPATH - -ifndef OCAML_LIB_INSTALL - OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib -endif -export OCAML_LIB_INSTALL - -########################################################################### - -#################### change following sections only if -#################### you know what you are doing! - -# delete target files when a build command fails -.PHONY: .DELETE_ON_ERROR -.DELETE_ON_ERROR: - -# for pedants using "--warn-undefined-variables" -export MAYBE_IDL -export REAL_RESULT -export CAMLIDLFLAGS -export THREAD_FLAG -export RES_CLIB -export MAKEDLL -export ANNOT_FLAG -export C_OXRIDL -export SUBPROJS -export CFLAGS_WIN32 -export CPPFLAGS_WIN32 - -INCFLAGS := - -SHELL := /bin/sh - -MLDEPDIR := ._d -BCDIDIR := ._bcdi -NCDIDIR := ._ncdi - -FILTER_EXTNS := %.mli %.ml %.mll %.mly %.idl %.oxridl %.c %.$(EXT_CXX) %.rep %.zog %.glade - -FILTERED := $(filter $(FILTER_EXTNS), $(SOURCES)) -SOURCE_DIRS := $(filter-out ./, $(sort $(dir $(FILTERED)))) - -FILTERED_REP := $(filter %.rep, $(FILTERED)) -DEP_REP := $(FILTERED_REP:%.rep=$(MLDEPDIR)/%.d) -AUTO_REP := $(FILTERED_REP:.rep=.ml) - -FILTERED_ZOG := $(filter %.zog, $(FILTERED)) -DEP_ZOG := $(FILTERED_ZOG:%.zog=$(MLDEPDIR)/%.d) -AUTO_ZOG := $(FILTERED_ZOG:.zog=.ml) - -FILTERED_GLADE := $(filter %.glade, $(FILTERED)) -DEP_GLADE := $(FILTERED_GLADE:%.glade=$(MLDEPDIR)/%.d) -AUTO_GLADE := $(FILTERED_GLADE:.glade=.ml) - -FILTERED_ML := $(filter %.ml, $(FILTERED)) -DEP_ML := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d) - -FILTERED_MLI := $(filter %.mli, $(FILTERED)) -DEP_MLI := $(FILTERED_MLI:.mli=.di) - -FILTERED_MLL := $(filter %.mll, $(FILTERED)) -DEP_MLL := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d) -AUTO_MLL := $(FILTERED_MLL:.mll=.ml) - -FILTERED_MLY := $(filter %.mly, $(FILTERED)) -DEP_MLY := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di) -AUTO_MLY := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml) - -FILTERED_IDL := $(filter %.idl, $(FILTERED)) -DEP_IDL := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di) -C_IDL := $(FILTERED_IDL:%.idl=%_stubs.c) -ifndef NOIDLHEADER - C_IDL += $(FILTERED_IDL:.idl=.h) -endif -OBJ_C_IDL := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ)) -AUTO_IDL := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL) - -FILTERED_OXRIDL := $(filter %.oxridl, $(FILTERED)) -DEP_OXRIDL := $(FILTERED_OXRIDL:%.oxridl=$(MLDEPDIR)/%.d) $(FILTERED_OXRIDL:.oxridl=.di) -AUTO_OXRIDL := $(FILTERED_OXRIDL:.oxridl=.mli) $(FILTERED_OXRIDL:.oxridl=.ml) $(C_OXRIDL) - -FILTERED_C_CXX := $(filter %.c %.$(EXT_CXX), $(FILTERED)) -OBJ_C_CXX := $(FILTERED_C_CXX:.c=.$(EXT_OBJ)) -OBJ_C_CXX := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ)) - -PRE_TARGETS += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) $(AUTO_OXRIDL) $(AUTO_ZOG) $(AUTO_REP) $(AUTO_GLADE) - -ALL_DEPS := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) $(DEP_OXRIDL) $(DEP_ZOG) $(DEP_REP) $(DEP_GLADE) - -MLDEPS := $(filter %.d, $(ALL_DEPS)) -MLIDEPS := $(filter %.di, $(ALL_DEPS)) -BCDEPIS := $(MLIDEPS:%.di=$(BCDIDIR)/%.di) -NCDEPIS := $(MLIDEPS:%.di=$(NCDIDIR)/%.di) - -ALLML := $(filter %.mli %.ml %.mll %.mly %.idl %.oxridl %.rep %.zog %.glade, $(FILTERED)) - -IMPLO_INTF := $(ALLML:%.mli=%.mli.__) -IMPLO_INTF := $(foreach file, $(IMPLO_INTF), \ - $(basename $(file)).cmi $(basename $(file)).cmo) -IMPLO_INTF := $(filter-out %.mli.cmo, $(IMPLO_INTF)) -IMPLO_INTF := $(IMPLO_INTF:%.mli.cmi=%.cmi) - -IMPLX_INTF := $(IMPLO_INTF:.cmo=.cmx) - -INTF := $(filter %.cmi, $(IMPLO_INTF)) -IMPL_CMO := $(filter %.cmo, $(IMPLO_INTF)) -IMPL_CMX := $(IMPL_CMO:.cmo=.cmx) -IMPL_ASM := $(IMPL_CMO:.cmo=.asm) -IMPL_S := $(IMPL_CMO:.cmo=.s) - -OBJ_LINK := $(OBJ_C_IDL) $(OBJ_C_CXX) -OBJ_FILES := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK) - -EXECS := $(addsuffix $(EXE), \ - $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT))) -ifdef WIN32 - EXECS += $(BCRESULT).dll $(NCRESULT).dll -endif - -CLIB_BASE := $(RESULT)$(RES_CLIB_SUF) -ifneq ($(strip $(OBJ_LINK)),) - RES_CLIB := lib$(CLIB_BASE).$(EXT_LIB) -endif - -ifdef WIN32 -DLLSONAME := $(CLIB_BASE).dll -else -DLLSONAME := dll$(CLIB_BASE).so -endif - -NONEXECS := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(IMPL_ASM) $(IMPL_S) \ - $(OBJ_FILES) $(PRE_TARGETS) $(BCRESULT).cma $(NCRESULT).cmxa \ - $(NCRESULT).$(EXT_LIB) $(BCRESULT).cmi $(BCRESULT).cmo \ - $(NCRESULT).cmi $(NCRESULT).cmx $(NCRESULT).o \ - $(RES_CLIB) $(IMPL_CMO:.cmo=.annot) \ - $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(LIB_PACK_NAME).cmx $(LIB_PACK_NAME).o - -ifndef STATIC - NONEXECS += $(DLLSONAME) -endif - -ifndef LIBINSTALL_FILES - LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \ - $(RESULT).cmxa $(RESULT).$(EXT_LIB) $(RES_CLIB) - ifndef STATIC - ifneq ($(strip $(OBJ_LINK)),) - LIBINSTALL_FILES += $(DLLSONAME) - endif - endif -endif - -export LIBINSTALL_FILES - -ifdef WIN32 - # some extra stuff is created while linking DLLs - NONEXECS += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp $(CLIB_BASE).exp $(CLIB_BASE).lib -endif - -TARGETS := $(EXECS) $(NONEXECS) - -# If there are IDL-files -ifneq ($(strip $(FILTERED_IDL)),) - MAYBE_IDL := -cclib -lcamlidl -endif - -ifdef USE_CAMLP4 - CAMLP4PATH := \ - $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/local/lib/camlp4) - INCFLAGS := -I $(CAMLP4PATH) - CINCFLAGS := -I$(CAMLP4PATH) -endif - -DINCFLAGS := $(INCFLAGS) $(SOURCE_DIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %) -INCFLAGS := $(DINCFLAGS) $(INCDIRS:%=-I %) -CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%) - -ifndef MSVC -CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) \ - $(EXTLIBDIRS:%=-L%) $(EXTLIBDIRS:%=-Wl,$(RPATH_FLAG)%) \ - $(OCAML_DEFAULT_DIRS:%=-L%) -endif - -ifndef PROFILING - INTF_OCAMLC := $(OCAMLC) -else - ifndef THREADS - INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS) - else - # OCaml does not support profiling byte code - # with threads (yet), therefore we force an error. - ifndef REAL_OCAMLC - $(error Profiling of multithreaded byte code not yet supported by OCaml) - endif - INTF_OCAMLC := $(OCAMLC) - endif -endif - -ifndef MSVC -COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \ - $(LIBDIRS:%=-ccopt -L%) $(EXTLIBDIRS:%=-ccopt -L%) \ - $(EXTLIBDIRS:%=-ccopt -Wl,$(RPATH_FLAG)%) \ - $(OCAML_DEFAULT_DIRS:%=-ccopt -L%) -else -COMMON_LDFLAGS := -ccopt "/link -NODEFAULTLIB:LIBC $(LDFLAGS:%=%) $(SOURCE_DIRS:%=-LIBPATH:%) \ - $(LIBDIRS:%=-LIBPATH:%) $(EXTLIBDIRS:%=-LIBPATH:%) \ - $(OCAML_DEFAULT_DIRS:%=-LIBPATH:%) " -endif - -CLIBS_OPTS := $(CLIBS:%=-cclib -l%) -ifdef MSVC - ifndef STATIC - # MSVC libraries do not have 'lib' prefix - CLIBS_OPTS := $(CLIBS:%=-cclib %.lib) - endif -endif - -ifneq ($(strip $(OBJ_LINK)),) - ifdef CREATE_LIB - OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL) - else - OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL) - endif -else - OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL) -endif - -# If we have to make byte-code -ifndef REAL_OCAMLC - BYTE_OCAML := y - - # EXTRADEPS is added dependencies we have to insert for all - # executable files we generate. Ideally it should be all of the - # libraries we use, but it's hard to find the ones that get searched on - # the path since I don't know the paths built into the compiler, so - # just include the ones with slashes in their names. - EXTRADEPS := $(addsuffix .cma,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) - SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS) - - REAL_OCAMLC := $(INTF_OCAMLC) - - REAL_IMPL := $(IMPL_CMO) - REAL_IMPL_INTF := $(IMPLO_INTF) - IMPL_SUF := .cmo - - DEPFLAGS := - MAKE_DEPS := $(MLDEPS) $(BCDEPIS) - - ifdef CREATE_LIB - override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) - override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) - ifndef STATIC - ifneq ($(strip $(OBJ_LINK)),) - MAKEDLL := $(DLLSONAME) - ALL_LDFLAGS := -dllib $(DLLSONAME) - endif - endif - endif - - ifndef NO_CUSTOM - ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS))" "" - ALL_LDFLAGS += -custom - endif - endif - - ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \ - $(COMMON_LDFLAGS) $(LIBS:%=%.cma) - CAMLIDLDLLFLAGS := - - ifdef THREADS - ifdef VMTHREADS - THREAD_FLAG := -vmthread - else - THREAD_FLAG := -thread - endif - ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) - ifndef CREATE_LIB - ifndef REAL_OCAMLFIND - ALL_LDFLAGS := unix.cma threads.cma $(ALL_LDFLAGS) - endif - endif - endif - -# we have to make native-code -else - EXTRADEPS := $(addsuffix .cmxa,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) - ifndef PROFILING - SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS) - PLDFLAGS := - else - SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS) - PLDFLAGS := -p - endif - - REAL_IMPL := $(IMPL_CMX) - REAL_IMPL_INTF := $(IMPLX_INTF) - IMPL_SUF := .cmx - - override CPPFLAGS := -DNATIVE_CODE $(CPPFLAGS) - - DEPFLAGS := -native - MAKE_DEPS := $(MLDEPS) $(NCDEPIS) - - ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \ - $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS) - CAMLIDLDLLFLAGS := -opt - - ifndef CREATE_LIB - ALL_LDFLAGS += $(LIBS:%=%.cmxa) - else - override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) - override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) - endif - - ifdef THREADS - THREAD_FLAG := -thread - ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) - ifndef CREATE_LIB - ifndef REAL_OCAMLFIND - ALL_LDFLAGS := unix.cmxa threads.cmxa $(ALL_LDFLAGS) - endif - endif - endif -endif - -export MAKE_DEPS - -ifdef ANNOTATE - ANNOT_FLAG := -dtypes -else -endif - -ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(ANNOT_FLAG) $(OCAMLFLAGS) \ - $(INCFLAGS) $(SPECIAL_OCAMLFLAGS) - -ifdef make_deps - -include $(MAKE_DEPS) - PRE_TARGETS := -endif - -########################################################################### -# USER RULES - -# Call "OCamlMakefile QUIET=" to get rid of all of the @'s. -QUIET=@ - -# generates byte-code (default) -byte-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ - REAL_RESULT="$(BCRESULT)" make_deps=yes -bc: byte-code - -byte-code-nolink: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ - REAL_RESULT="$(BCRESULT)" make_deps=yes -bcnl: byte-code-nolink - -top: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \ - REAL_RESULT="$(BCRESULT)" make_deps=yes - -# generates native-code - -native-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - make_deps=yes -nc: native-code - -native-code-nolink: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - make_deps=yes -ncnl: native-code-nolink - -# generates byte-code libraries -byte-code-library: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(BCRESULT).cma \ - REAL_RESULT="$(BCRESULT)" \ - CREATE_LIB=yes \ - make_deps=yes -bcl: byte-code-library - -# generates native-code libraries -native-code-library: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(NCRESULT).cmxa \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - CREATE_LIB=yes \ - make_deps=yes -ncl: native-code-library - -ifdef WIN32 -# generates byte-code dll -byte-code-dll: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(BCRESULT).dll \ - REAL_RESULT="$(BCRESULT)" \ - make_deps=yes -bcd: byte-code-dll - -# generates native-code dll -native-code-dll: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(NCRESULT).dll \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - make_deps=yes -ncd: native-code-dll -endif - -# generates byte-code with debugging information -debug-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ - REAL_RESULT="$(BCRESULT)" make_deps=yes \ - OCAMLFLAGS="-g $(OCAMLFLAGS)" \ - OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" -dc: debug-code - -debug-code-nolink: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ - REAL_RESULT="$(BCRESULT)" make_deps=yes \ - OCAMLFLAGS="-g $(OCAMLFLAGS)" \ - OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" -dcnl: debug-code-nolink - -# generates byte-code libraries with debugging information -debug-code-library: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(BCRESULT).cma \ - REAL_RESULT="$(BCRESULT)" make_deps=yes \ - CREATE_LIB=yes \ - OCAMLFLAGS="-g $(OCAMLFLAGS)" \ - OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" -dcl: debug-code-library - -# generates byte-code for profiling -profiling-byte-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ - REAL_RESULT="$(BCRESULT)" PROFILING="y" \ - make_deps=yes -pbc: profiling-byte-code - -# generates native-code - -profiling-native-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - PROFILING="y" \ - make_deps=yes -pnc: profiling-native-code - -# generates byte-code libraries -profiling-byte-code-library: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(BCRESULT).cma \ - REAL_RESULT="$(BCRESULT)" PROFILING="y" \ - CREATE_LIB=yes \ - make_deps=yes -pbcl: profiling-byte-code-library - -# generates native-code libraries -profiling-native-code-library: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(RES_CLIB) $(NCRESULT).cmxa \ - REAL_RESULT="$(NCRESULT)" PROFILING="y" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - CREATE_LIB=yes \ - make_deps=yes -pncl: profiling-native-code-library - -# packs byte-code objects -pack-byte-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT).cmo \ - REAL_RESULT="$(BCRESULT)" \ - PACK_LIB=yes make_deps=yes -pabc: pack-byte-code - -# packs native-code objects -pack-native-code: $(PRE_TARGETS) - $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ - $(NCRESULT).cmx $(NCRESULT).o \ - REAL_RESULT="$(NCRESULT)" \ - REAL_OCAMLC="$(OCAMLOPT)" \ - PACK_LIB=yes make_deps=yes -panc: pack-native-code - -# generates HTML-documentation -htdoc: doc/$(RESULT)/html - -# generates Latex-documentation -ladoc: doc/$(RESULT)/latex - -# generates PostScript-documentation -psdoc: doc/$(RESULT)/latex/doc.ps - -# generates PDF-documentation -pdfdoc: doc/$(RESULT)/latex/doc.pdf - -# generates all supported forms of documentation -doc: htdoc ladoc psdoc pdfdoc - -########################################################################### -# LOW LEVEL RULES - -$(REAL_RESULT): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) $(RESULTDEPS) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) \ - $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ - $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ - $(REAL_IMPL) - -nolink: $(REAL_IMPL_INTF) $(OBJ_LINK) - -ifdef WIN32 -$(REAL_RESULT).dll: $(REAL_IMPL_INTF) $(OBJ_LINK) - $(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \ - -o $@ $(REAL_IMPL) -endif - -%$(TOPSUFFIX): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) - $(REAL_OCAMLFIND) $(OCAMLMKTOP) \ - $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ - $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ - $(REAL_IMPL) - -.SUFFIXES: .mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \ - .mly .di .d .$(EXT_LIB) .idl %.oxridl .c .$(EXT_CXX) .h .so \ - .rep .zog .glade - -ifndef STATIC -ifdef MINGW -$(DLLSONAME): $(OBJ_LINK) - $(CC) $(CFLAGS) $(CFLAGS_WIN32) $(OBJ_LINK) -shared -o $@ \ - -Wl,--whole-archive $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/lib%.a))) \ - $(OCAMLLIBPATH)/ocamlrun.a \ - -Wl,--export-all-symbols \ - -Wl,--no-whole-archive -else -ifdef MSVC -$(DLLSONAME): $(OBJ_LINK) - link /NOLOGO /DLL /OUT:$@ $(OBJ_LINK) \ - $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/%.lib))) \ - $(OCAMLLIBPATH)/ocamlrun.lib - -else -$(DLLSONAME): $(OBJ_LINK) - $(OCAMLMKLIB) $(INCFLAGS) $(CLIBFLAGS) \ - -o $(CLIB_BASE) $(OBJ_LINK) $(CLIBS:%=-l%) \ - $(OCAMLMKLIB_FLAGS) -endif -endif -endif - -ifndef LIB_PACK_NAME -$(RESULT).cma: $(REAL_IMPL_INTF) $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \ - $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(REAL_IMPL) - -$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(REAL_IMPL_INTF) $(EXTRADEPS) $(RESULTDEPS) - $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \ - $(OCAMLNLDFLAGS) -o $@ $(REAL_IMPL) -else -ifdef BYTE_OCAML -$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo: $(REAL_IMPL_INTF) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmo $(REAL_IMPL) -else -$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx: $(REAL_IMPL_INTF) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmx $(REAL_IMPL) -endif - -$(RESULT).cma: $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \ - $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(LIB_PACK_NAME).cmo - -$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx $(EXTRADEPS) $(RESULTDEPS) - $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \ - $(OCAMLNLDFLAGS) -o $@ $(LIB_PACK_NAME).cmx -endif - -$(RES_CLIB): $(OBJ_LINK) -ifndef MSVC - ifneq ($(strip $(OBJ_LINK)),) - $(AR) rcs $@ $(OBJ_LINK) - endif -else - ifneq ($(strip $(OBJ_LINK)),) - lib -nologo -debugtype:cv -out:$(RES_CLIB) $(OBJ_LINK) - endif -endif - -.mli.cmi: $(EXTRADEPS) - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c $(THREAD_FLAG) $(ANNOT_FLAG) \ - $(OCAMLFLAGS) $(INCFLAGS) $<; \ - $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c $(THREAD_FLAG) $(ANNOT_FLAG) \ - $(OCAMLFLAGS) $(INCFLAGS) $<; \ - else \ - echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c -pp \"$$pp $(PPFLAGS)\" $(THREAD_FLAG) $(ANNOT_FLAG) \ - $(OCAMLFLAGS) $(INCFLAGS) $<; \ - $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c -pp "$$pp $(PPFLAGS)" $(THREAD_FLAG) $(ANNOT_FLAG) \ - $(OCAMLFLAGS) $(INCFLAGS) $<; \ - fi - -.ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: $(EXTRADEPS) - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c $(ALL_OCAMLCFLAGS) $<; \ - $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c $(ALL_OCAMLCFLAGS) $<; \ - else \ - echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c -pp \"$$pp $(PPFLAGS)\" $(ALL_OCAMLCFLAGS) $<; \ - $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ - -c -pp "$$pp $(PPFLAGS)" $(ALL_OCAMLCFLAGS) $<; \ - fi - -ifdef PACK_LIB -$(REAL_RESULT).cmo $(REAL_RESULT).cmx $(REAL_RESULT).o: $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) - $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack $(ALL_LDFLAGS) \ - $(OBJS_LIBS) -o $@ $(REAL_IMPL) -endif - -.PRECIOUS: %.ml -%.ml: %.mll - $(OCAMLLEX) $< - -.PRECIOUS: %.ml %.mli -%.ml %.mli: %.mly - $(OCAMLYACC) $(YFLAGS) $< - $(QUIET)pp=`sed -n -e 's/.*(\*pp \([^*]*\) \*).*/\1/p;q' $<`; \ - if [ ! -z "$$pp" ]; then \ - mv $*.ml $*.ml.temporary; \ - echo "(*pp $$pp $(PPFLAGS)*)" > $*.ml; \ - cat $*.ml.temporary >> $*.ml; \ - rm $*.ml.temporary; \ - mv $*.mli $*.mli.temporary; \ - echo "(*pp $$pp $(PPFLAGS)*)" > $*.mli; \ - cat $*.mli.temporary >> $*.mli; \ - rm $*.mli.temporary; \ - fi - - -.PRECIOUS: %.ml -%.ml: %.rep - $(CAMELEON_REPORT) $(CAMELEON_REPORT_FLAGS) -gen $< - -.PRECIOUS: %.ml -%.ml: %.zog - $(CAMELEON_ZOGGY) $(CAMELEON_ZOGGY_FLAGS) -impl $< > $@ - -.PRECIOUS: %.ml -%.ml: %.glade - $(OCAML_GLADECC) $(OCAML_GLADECC_FLAGS) $< > $@ - -.PRECIOUS: %.ml %.mli -%.ml %.mli: %.oxridl - $(OXRIDL) $< - -.PRECIOUS: %.ml %.mli %_stubs.c %.h -%.ml %.mli %_stubs.c %.h: %.idl - $(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \ - $(CAMLIDLFLAGS) $< - $(QUIET)if [ $(NOIDLHEADER) ]; then touch $*.h; fi - -.c.$(EXT_OBJ): - $(OCAMLC) -c -cc "$(CC)" -ccopt "$(CFLAGS) \ - $(CPPFLAGS) $(CPPFLAGS_WIN32) \ - $(CFLAGS_WIN32) $(CINCFLAGS) $(CFLAG_O)$@ " $< - -.$(EXT_CXX).$(EXT_OBJ): - $(CXX) -c $(CXXFLAGS) $(CINCFLAGS) $(CPPFLAGS) \ - -I'$(OCAMLLIBPATH)' \ - $< $(CFLAG_O)$@ - -$(MLDEPDIR)/%.d: %.ml - $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ - $(DINCFLAGS) $< \> $@; \ - $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ - $(DINCFLAGS) $< > $@; \ - else \ - echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ - -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ - $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ - -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ - fi - -$(BCDIDIR)/%.di $(NCDIDIR)/%.di: %.mli - $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< \> $@; \ - $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< > $@; \ - else \ - echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ - -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ - $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ - -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ - fi - -doc/$(RESULT)/html: $(DOC_FILES) - rm -rf $@ - mkdir -p $@ - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \ - $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \ - else \ - echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -html -d $@ $(OCAMLDOCFLAGS) \ - $(INCFLAGS) $(DOC_FILES); \ - $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -html -d $@ $(OCAMLDOCFLAGS) \ - $(INCFLAGS) $(DOC_FILES); \ - fi - -doc/$(RESULT)/latex: $(DOC_FILES) - rm -rf $@ - mkdir -p $@ - $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ - if [ -z "$$pp" ]; then \ - echo $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) \ - $(DOC_FILES) -o $@/doc.tex; \ - $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES) \ - -o $@/doc.tex; \ - else \ - echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -latex $(OCAMLDOCFLAGS) \ - $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \ - $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -latex $(OCAMLDOCFLAGS) \ - $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \ - fi - -doc/$(RESULT)/latex/doc.ps: doc/$(RESULT)/latex - cd doc/$(RESULT)/latex && \ - $(LATEX) doc.tex && \ - $(LATEX) doc.tex && \ - $(DVIPS) $(DVIPSFLAGS) doc.dvi -o $(@F) - -doc/$(RESULT)/latex/doc.pdf: doc/$(RESULT)/latex/doc.ps - cd doc/$(RESULT)/latex && $(PS2PDF) $( +with opam: +``` +opam pin add thin-ocamlscript https://github.com/jrfondren/thin-ocamlscript.git +``` + +cloning this repo and using dune: +``` +git clone https://github.com/jrfondren/thin-ocamlscript && cd thin-ocamlscript +dune install --release +``` + +using dune and manually placing the binary: +``` +dune build --release +mv _build/default/bin/main.exe ~/bin/ocamlscript +``` + +catting a single .ml together and building that with ocamlfind: +``` +cat lib/script.ml > oscript.ml +sed 1d bin/main.ml >> oscript.ml +ocamlfind ocamlopt -O3 -package unix -linkpkg -o oscript oscript.ml +``` + +# examples + +```ocaml +#! /usr/bin/env -S thin-ocamlscript -package unix -linkpkg -- +let () = Printf.printf "%.0f\n" (Unix.time ()) +``` + +```ocaml +#! /usr/bin/env -S thin-ocamlscript -package ppx_deriving.show -linkpkg -- +type args = string array [@@deriving show] +let () = Format.printf "%a\n" pp_args Sys.argv +``` + +examples/ has replications of ocamlscript's examples + +# env + +`env -S` and `--` are required for reasonable behavior. Without the latter your +script cannot itself receive a `--`. With `env` and no `-S` you can't pass any +arguments to ocamlfind, and you'll still have the `--` limitation on the +script's own arguments. + +Even if you'd rather not search through PATH to find thin-ocamlscript, you need +`env -S`, and in this case it should be an absolute path or it'll depend on the +caller's working directory: + +```ocaml +#! /usr/bin/env -S /opt/ocaml/bin/thin-ocamlscript -package unix -linkpkg -- +(* ... *) +``` + +# files + +```ocaml +let tmpname script = script ^ ".tmp.ml" +let exename script = script ^ ".exe" + +let cleanup script = + List.iter + (fun ext -> + try Unix.unlink (script ^ ext) with + | Unix.Unix_error (Unix.ENOENT, _, _) -> () + | exn -> raise exn) + [".tmp.ml"; ".tmp.o"; ".tmp.cmx"; ".tmp.cmi"] +``` + +The exename is compiled if not newer than the script. The tmpname is deleted +after compilation. There is no protection against you doing something placing a +hello.ml script next to a hello.tmp.ml that you would regret losing. + +# design + +A temporary file is required by ocamlc/ocamlopt objecting to #! lines. + +The temporary file ending in .ml is required by camlp4. + +The .ml.exe is required by shell tab completion: if it was only .exe, then +hello.ml and hello.exe in the same dir would pause completion at 'hello.'. + +To not use hidden files for the executable is advised to help differentiate it +from malware. + +I preferred to avoid /tmp for compilation for some subtle reasons, including +that sensitive scripts would not accidentally escape filesystem security on the +script, think /root/bin/ping-secret-api.ml + +# editing with Merlin + +This generated vimscript, which calls :MerlinUse on every package in +first line, improves the editing experience a great deal: + +``` +autocmd BufReadPost *.ml call SetupMerlinPackages() + +function! SetupMerlinPackages() + let first_line = getline(1) + let matches = matchlist(first_line, '-package \(\w\+\)') + let start = 0 + while 1 + let m = matchstr(first_line, '-package \zs\w\+', start) + if m == '' + break + endif + execute ':MerlinUse ' . m + let start = matchend(first_line, '-package \w\+', start) + endwhile +endfunction +``` diff --git a/TODO b/TODO deleted file mode 100644 index b11f79b..0000000 --- a/TODO +++ /dev/null @@ -1,3 +0,0 @@ -* move documentation from pbwiki to github: - http://ocaml.pbworks.com/w/page/5867969/Ocamlscript - http://ocaml.pbworks.com/w/page/5867970/OcamlscriptDoc diff --git a/bin/dune b/bin/dune new file mode 100644 index 0000000..a74158f --- /dev/null +++ b/bin/dune @@ -0,0 +1,4 @@ +(executable + (public_name thin-ocamlscript) + (name main) + (libraries unix thin_ocamlscript)) diff --git a/bin/main.ml b/bin/main.ml new file mode 100644 index 0000000..9621cd7 --- /dev/null +++ b/bin/main.ml @@ -0,0 +1,25 @@ +open Thin_ocamlscript.Script + +let split_args a = + let len = Array.length a in + match Array.find_index (( = ) "--") a with + | None -> ([||], a.(1), Array.sub a 1 (len - 1)) + | Some i -> + (Array.sub a 1 (i - 1), a.(i + 1), Array.sub a (i + 1) (len - i - 1)) + +let () = + if Array.length Sys.argv = 1 then ( + Printf.printf + "usage: #! /usr/bin/env -S %s -package unix -linkpkg --\n\ + The -- should always be present and always at the end of the line\n\ + Arguments are to ocamlfind ocamlopt\n\ + For more, https://github.com/jrfondren/thin-ocamlscript\n" + (Filename.basename Sys.argv.(0)); + exit 1); + let oargs, script, sargs = split_args Sys.argv in + let exe = exename script in + if needs_recompile script exe then + Fun.protect + ~finally:(fun () -> cleanup script) + (fun () -> recompile oargs script); + Unix.execv exe sargs diff --git a/common.ml b/common.ml deleted file mode 100644 index 1c4b646..0000000 --- a/common.ml +++ /dev/null @@ -1,6 +0,0 @@ -let extra_args = ref ([] : string list) -let trash = ref ([] : string list) -let verbose = ref false -let script_dir = ref (Sys.getcwd ()) -let compile : (string -> string -> int) ref = - ref (fun source result -> failwith "Compile.compile is unset") diff --git a/common.mli b/common.mli deleted file mode 100644 index 473970b..0000000 --- a/common.mli +++ /dev/null @@ -1,33 +0,0 @@ -(** Options that are shared by all compilation modules. *) - -(** All arguments which are not valid options for ocamlscript - but are not arguments of the script either. - Typically it would be the case of unix.cmxa in - "#!/usr/bin/ocamlscript unix.cmxa". - It is the responsibility of the "compile" function to handle these - arguments. The default "compile" command (Ocamlscript.Ocaml.compile) - simply passes these arguments to ocamlopt. -*) -val extra_args : string list ref - -(** runtime trash which may contain the name of the executable itself, - for self-removal, in case it is a temporary file (e.g. generated from - standard input). *) -val trash : string list ref - -(** If this option is true, ocamlscript prints some debugging information - to stdout. *) -val verbose : bool ref - -(** [script_dir] is meant to hold the absolute path to the directory which - contains the script, or just the current directory at the time when - ocamlscript was started if the script is not read from a file. *) -val script_dir : string ref - -(** The function which is used to compile the program. - [compile source result] reads the source code from file [source] and - writes the executable to file [result]. This function - should return 0 if it succeeds, and 1 or another code otherwise. - Its default value is [Ocamlscript.Ocaml.compile]. -*) -val compile : (string -> string -> int) ref diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..85a1027 --- /dev/null +++ b/dune-project @@ -0,0 +1,18 @@ +(lang dune 3.20) +(name thin-ocamlscript) +(generate_opam_files true) +(source + (github jrfondren/thin-ocamlscript)) + +(authors "Julian Fondren ") +(maintainers "Julian Fondren ") +(license MIT) +(documentation https://github.com/jrfondren/thin-ocamlscript) + +(package + (name thin-ocamlscript) + (synopsis "OCaml as a scripting language with ocamlfind") + (description "Similar to ocamlscript, but configuration is restricted to the shebang line.") + (depends + (ocaml (>= 5.2)) ;; or 5.1 which introduced Array.find_index + (ocamlfind (>= 1.9.8)))) ;; latest diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index 5c7a251..0000000 --- a/examples/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -.PHONY: default clean -default: - ../ocamlscript factorial.ml 100 - ../ocamlscript revised.ml - ../ocamlscript with-includes.ml - echo "1+1" | ../ocamlscript calc.ml -clean: - $(RM) *~ *.exe diff --git a/examples/README b/examples/README deleted file mode 100644 index aa3076e..0000000 --- a/examples/README +++ /dev/null @@ -1,57 +0,0 @@ -This directory contains a few examples that should work on every platform -where ocamlscript can be installed, except hello-web.ml which requires -the ocamlnet library. - -One attractive feature on Unix-like systems is auto-executable -scripts, i.e. scripts that start with a shebang (#!) line. -The interpretation of this line is OS-dependent, so we avoid using it -in most examples. - -* factorial.ml: computes the exact factorial of integers using the num library. - Run it with: ocamlscript factorial.ml - or: ocamlscript factorial.ml 123 - -* with-includes.ml: - this program shows how to use other source file(s) than the - main script. - Run it with: ocamlscript with-includes.ml - Note that the last modification date of - the other source file(s) is not checked by - ocamlscript. If you want to force a recompilation, use - the -f option. - -* calc.ml: a complete example of using multiple source files. - lexer.mll, parser.mly and calc.ml were copied from the Objective - Caml reference manual (chapter on ocamllex and ocamlyacc), - and calc.ml was adapted to work with ocamlscript. - Now it compiles and runs in one command: - ocamlscript calc.ml - instead of 4: - ocamllex lexer.mll - ocamlyacc parser.mly - ocamlopt -o calc parser.mli parser.ml lexer.ml calc.ml - ./calc - -* revised.ml: a program in Camlp4 revised syntax - -* pp.ml: shows how to use a custom preprocessor - -* hello-web.ml: a minimalistic CGI program which prints a webpage - saying only "Yes", "No", "Other" or "Undefined" - depending on whether the CGI variable "foo" has value - 1, 0, some other defined value, or is undefined. - It requires the ocamlnet library and can be tested - from the command-line. - It recommended to compile and install such programs, - although installing the script directly into your - cgi-bin works too, as long as httpd has write access - to your cgi-bin directory and has access to the OCaml tools. - - Compilation: - ocamlscript -c hello-web.ml - - Installation: - cp hello-web.ml.exe /path/to/cgi-bin/ - - Testing: - http://localhost/cgi-bin/hello-web.ml.exe?foo=1 diff --git a/examples/calc.ml b/examples/calc.ml deleted file mode 100644 index 39016d1..0000000 --- a/examples/calc.ml +++ /dev/null @@ -1,14 +0,0 @@ -Ocaml.sources := ["parser.mly"; "lexer.mll"] --- -(* Calculator example from the Objective Caml reference manual *) - -(* File calc.ml *) -let _ = - try - let lexbuf = Lexing.from_channel stdin in - while true do - let result = Parser.main Lexer.token lexbuf in - print_int result; print_newline(); flush stdout - done - with Lexer.Eof -> - exit 0 diff --git a/examples/deriving.ml b/examples/deriving.ml new file mode 100755 index 0000000..35c9269 --- /dev/null +++ b/examples/deriving.ml @@ -0,0 +1,5 @@ +#! /usr/bin/env -S thin-ocamlscript -package ppx_deriving.show -linkpkg -- + +type args = string array [@@deriving show] + +let () = Format.printf "%a\n" pp_args Sys.argv diff --git a/examples/exists b/examples/exists new file mode 100755 index 0000000..7d7a4cf --- /dev/null +++ b/examples/exists @@ -0,0 +1,12 @@ +#! /usr/bin/env -S thin-ocamlscript -package unix -linkpkg -- + +let () = + if Array.length Sys.argv <> 2 then ( + Printf.printf "usage: %s \n" Sys.argv.(0); + exit 1); + let file = Sys.argv.(1) in + try + Unix.access file [Unix.R_OK]; + print_endline ("file exists: " ^ file) + with Unix.Unix_error (Unix.ENOENT, _, _) -> + print_endline ("file doesn't exist: " ^ file) diff --git a/examples/factorial.ml b/examples/factorial.ml old mode 100644 new mode 100755 index e09d363..03d3acc --- a/examples/factorial.ml +++ b/examples/factorial.ml @@ -1,28 +1,31 @@ -Ocaml.packs := ["num"] --- +#! /usr/bin/env -S thin-ocamlscript -package num -linkpkg -- + open Printf open Big_int let rec fac n = - if le_big_int n zero_big_int then unit_big_int - else mult_big_int n (fac (pred_big_int n)) + if le_big_int n zero_big_int then + unit_big_int + else + mult_big_int n (fac (pred_big_int n)) let rec get_int attempt = - try + try printf "Please enter a number: "; read_int () with _ -> - if attempt >= 3 then - (printf "Bye.\n"; - exit 1) - else - (printf "This is not a number. Please try again.\n"; - get_int (attempt + 1)) + if attempt >= 3 then ( + printf "Bye.\n"; + exit 1) + else ( + printf "This is not a number. Please try again.\n"; + get_int (attempt + 1)) let _ = - let x = + let x = match Sys.argv with - [| _; s |] -> (try int_of_string s with _ -> get_int 2) - | _ -> get_int 1 in + | [|_; s|] -> ( try int_of_string s with _ -> get_int 2) + | _ -> get_int 1 + in let y = fac (big_int_of_int x) in printf "%i! = %s\n" x (string_of_big_int y) diff --git a/examples/hello-web.ml b/examples/hello-web.ml deleted file mode 100755 index 58b6ce7..0000000 --- a/examples/hello-web.ml +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env ocamlscript -Ocaml.packs := ["cgi"] --- -let get actobj = - try - (match (actobj#argument "foo")#value with - "0" -> "No" - | "1" -> "Yes" - | _ -> "Other") - with Not_found -> "Undefined" - -let print (actobj : Netcgi.std_activation) s = - actobj#set_header ~content_type:"text/plain" (); - actobj#output#output_string s; - actobj#output#commit_work () - -let _ = - let actobj = new Netcgi.std_activation () in - print actobj (get actobj) diff --git a/examples/hello.ml b/examples/hello.ml old mode 100644 new mode 100755 index 0aa52fc..1ecb395 --- a/examples/hello.ml +++ b/examples/hello.ml @@ -1 +1,3 @@ -let hello () = print_endline "Hello from hello.ml" +#! /usr/bin/env -S thin-ocamlscript -- + +let () = print_endline "Hello from hello.ml" diff --git a/examples/lexer.mll b/examples/lexer.mll deleted file mode 100644 index af7e068..0000000 --- a/examples/lexer.mll +++ /dev/null @@ -1,18 +0,0 @@ -(* Calculator example from the Objective Caml reference manual *) - -(* File lexer.mll *) -{ -open Parser (* The type token is defined in parser.mli *) -exception Eof -} -rule token = parse - [' ' '\t'] { token lexbuf } (* skip blanks *) - | ['\n' ] { EOL } - | ['0'-'9']+ as lxm { INT(int_of_string lxm) } - | '+' { PLUS } - | '-' { MINUS } - | '*' { TIMES } - | '/' { DIV } - | '(' { LPAREN } - | ')' { RPAREN } - | eof { raise Eof } diff --git a/examples/no-merlin-errors.ml b/examples/no-merlin-errors.ml deleted file mode 100644 index ff84a94..0000000 --- a/examples/no-merlin-errors.ml +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env ocamlscript -let open Ocamlscript.Std in (** Inclues Ocamlscript and special (--) operator *) -begin - Ocaml.packs := ["cmdliner"] -end --- -(* ^^^ opened as infix operator here, returning a unit. - * Must be on its own line! *) -() (* need to close out the -- operator *) - -let f x y = x + 1 (* can parse basic staements after the () *) - -let arg_info = Cmdliner.Arg.info (* ensure packs are present *) - -let () = print_endline "look ma, no merlin errors!" diff --git a/examples/now.ml b/examples/now.ml new file mode 100755 index 0000000..52e91d2 --- /dev/null +++ b/examples/now.ml @@ -0,0 +1,3 @@ +#! /usr/bin/env -S thin-ocamlscript -package unix -linkpkg -- + +let () = Printf.printf "%.0f\n" (Unix.time ()) diff --git a/examples/parser.mly b/examples/parser.mly deleted file mode 100644 index 3b40538..0000000 --- a/examples/parser.mly +++ /dev/null @@ -1,25 +0,0 @@ -/* Calculator example from the Objective Caml reference manual */ - -/* File parser.mly */ -%token INT -%token PLUS MINUS TIMES DIV -%token LPAREN RPAREN -%token EOL -%left PLUS MINUS /* lowest precedence */ -%left TIMES DIV /* medium precedence */ -%nonassoc UMINUS /* highest precedence */ -%start main /* the entry point */ -%type main -%% -main: - expr EOL { $1 } -; -expr: - INT { $1 } - | LPAREN expr RPAREN { $2 } - | expr PLUS expr { $1 + $3 } - | expr MINUS expr { $1 - $3 } - | expr TIMES expr { $1 * $3 } - | expr DIV expr { $1 / $3 } - | MINUS expr %prec UMINUS { - $2 } -; diff --git a/examples/pp.mll b/examples/pp.mll deleted file mode 100644 index fd714cd..0000000 --- a/examples/pp.mll +++ /dev/null @@ -1,12 +0,0 @@ -(* Using ocamllex as if it were not supported by default, - to show how to use a custom preprocessor. *) -Ocaml.pp := - Some (fun file -> - let o = if not (Filename.check_suffix file ".mll") then "main.ml" - else Filename.chop_extension file ^ ".ml" in - Pipeline.command ["ocamllex"; file; "-o"; o; "-q"], [o]) --- -rule token = parse - _ { () } -| eof { () } -{ print_endline "Hello from pp.ml using ocamllex" } diff --git a/examples/revised.ml b/examples/revised.ml old mode 100644 new mode 100755 index 29ea353..3148029 --- a/examples/revised.ml +++ b/examples/revised.ml @@ -1,18 +1,8 @@ -(* Using Camlp4 revised syntax *) - -(* Camlp4 is used by default *) -(* Ocaml.use_camlp4 := true *) - -(* this selects the revised syntax: *) -Ocaml.revised := true --- - -(* This is the program in the revised syntax: *) - -value hello () = +#! /usr/bin/env -S thin-ocamlscript -package camlp4 -syntax camlp4r -linkpkg -- +value hello () = do { print_endline "Hello!"; print_endline "Goodbye!" } ; -value _ = hello () +value __ = hello () ; diff --git a/examples/with-includes.ml b/examples/with-includes.ml deleted file mode 100644 index 1234d2f..0000000 --- a/examples/with-includes.ml +++ /dev/null @@ -1,3 +0,0 @@ -Ocaml.sources := [ "hello.ml" ] --- -Hello.hello () diff --git a/lib/dune b/lib/dune new file mode 100644 index 0000000..8c0c360 --- /dev/null +++ b/lib/dune @@ -0,0 +1,3 @@ +(library + (name thin_ocamlscript) + (libraries unix)) diff --git a/lib/script.ml b/lib/script.ml new file mode 100644 index 0000000..6662155 --- /dev/null +++ b/lib/script.ml @@ -0,0 +1,50 @@ +let tmpname script = script ^ ".tmp.ml" +let exename script = script ^ ".exe" + +let cleanup script = + List.iter + (fun ext -> + try Unix.unlink (script ^ ext) with + | Unix.Unix_error (Unix.ENOENT, _, _) -> () + | exn -> raise exn) + [".tmp.ml"; ".tmp.o"; ".tmp.cmx"; ".tmp.cmi"] + +let needs_recompile source exe = + (not (Sys.file_exists exe)) + || (Unix.stat exe).st_mtime <= (Unix.stat source).st_mtime + +let recompile flags source = + let buflen = 4096 in + let perm = (Unix.stat source).st_perm in + let oflags = Out_channel.[Open_wronly; Open_creat; Open_trunc; Open_binary] in + In_channel.with_open_bin source (fun inp -> + Out_channel.with_open_gen oflags perm (tmpname source) (fun out -> + (* drop first line only if it's #! *) + let line = In_channel.input_line inp |> Option.get in + if not @@ String.starts_with ~prefix:"#!" line then + Printf.fprintf out "%s\n" line; + + (* underlying I/O buffers; all this does is avoid line-handling *) + let buffer = Bytes.make buflen '\000' in + let rec loop () = + match In_channel.input inp buffer 0 buflen with + | 0 -> () + | n when n = buflen -> + Out_channel.output_bytes out buffer; + loop () + | n -> + Out_channel.output_bytes out (Bytes.sub buffer 0 n); + loop () + in + loop ())); + let args = + Array.append + [|"ocamlfind"; "ocamlopt"|] + (Array.append flags [|"-o"; exename source; "-impl"; tmpname source|]) + in + let pid = + Unix.create_process "ocamlfind" args Unix.stdin Unix.stdout Unix.stderr + in + match Unix.waitpid [] pid with + | p, Unix.WEXITED 0 when p = pid -> () + | _, _ -> failwith ("attempted: " ^ String.concat " " (Array.to_list args)) diff --git a/main.ml b/main.ml deleted file mode 100644 index 288526a..0000000 --- a/main.ml +++ /dev/null @@ -1,556 +0,0 @@ -(* - ocamlscript: a utility to have shell-like optimised scripts in OCaml - - Copyright 2005 David MENTRE - Copyright 2006 Martin Jambon -*) - -open Printf -open Ocamlscript - -module Opt = -struct - let set what opt s = - match !opt with - | Some _ -> failwith (sprintf "%s is already set" what) - | None -> opt := Some s - - let help = ref false (* help and exit *) - let c = ref false (* compile only *) - let f = ref false (* force recompile *) - let debug = ref false (* additional stdout output *) - let version = ref false (* show version and exit *) - let from = ref (None : [`File of string | `String of string | `Stdin] option) - let o = ref None (* choose a name for the compiled executable *) - let vm = ref None (* possible bytecode interpreter *) - let extra_args = ref [] - - let help_message = "\ -Usage: ocamlscript [ PACKED_OPTIONS [ OPTIONS ] [ -- ] [SCRIPTNAME] [ARGS] ] - -Ocamlscript normally reads the source code of a program from a file, looks -if a compiled executable exists for this program. If it exists and if it -is more recent than the source file, the executable is executed immediately, -otherwise it is updated by executing compilation instructions that can -be specified in the program file. - -A typical self-executable script looks as follows: - - #!/usr/bin/env ocamlscript - (* this is the compilation section, in OCaml *) - Ocaml.packs := [\"unix\"; \"micmatch_pcre\"] (* Findlib packages *) - -- - (* this is the program section *) - let _ = - ... - - -Structure of the command line: - -PACKED_OPTIONS: - the first argument of ocamlscript. It is either unpacked into - several arguments that are passed to ocamlscript or into a script name - if this name doesn't start with \"-\". Double-quotes can be used - to enclose arguments that contain whitespace or double-quotes. - Double-quotes must be doubled. For instance, the following - self-executable script would be compiled into an executable named - Hello \"World\": - #!/usr/bin/ocamlscript -o \"Hello \"\"World\"\"\" - print_endline \"Hello \"World\"\" - - Important note: on some Unix systems, the whole - '-o \"Hello \"\"World\"\"\"' string is passed as a single argument - to ocamlscript. This is why the first argument must be unpacked, - even if ocamlscript is called explicitely from the command line. - -OPTIONS: - any number of arguments in this section are treated like options - to ocamlscript until a either a non-option is encountered, which is - understood as the script name (SCRIPTNAME) or \"--\" which stops - the list of arguments that are passed to ocamlscript. - -Ocamlscript supports the following options: - -- marks the end of ocamlscript arguments - -help displays a help message and exit - --help same as -help - -c compile only - -o EXEC_NAME specify a name for the executable - (required if the program is not read from a file) - -e PROGRAM execute the code given here instead of reading it from a file - -f force recompilation which is otherwise based on last modification dates - -debug print messages about what ocamlscript is doing - -version prints the version identifier to stdout and exit - - read program from stdin instead of a file - -vm VIRTUAL_MACHINE run the executable using this virtual machine (e.g. - ocamlrun) - -\"--\": passed as an argument to ocamlscript in the PACKED_OPTIONS argument - or in the OPTIONS argument marks the end of the arguments that - are passed to ocamlscript. Arguments that follow will be - interpreted as arguments of the script. - Arguments that follow \"--\" in the PACKED_OPTIONS argument - will be passed as arguments to the final executable. The first - argument that follows \"--\" in the OPTIONS command line arguments - is treated as the script name, unless the program is read from - another source, as specified by options \"-e\" (a string) or \"-\" - (standard input). - - -For a full documentation on the structure of the compilation section, go to -ocamlscript's website (http://martin.jambon.free.fr/ocamlscript.html). -" -end - -(* more generic than .opt since we can compile with other commands than - ocamlopt *) -let bin_suffix = ".exe" - -let bin_name src = - match !Opt.o with - | Some s -> s - | None -> src ^ bin_suffix - -let obin_name src = - match !Opt.o with - | Some s -> s - | None -> - match src with - | `Stdin | `String _ -> failwith "please specify a name \ - for the executable with -o" - | `File s -> s ^ bin_suffix - -let source_name = function - | None -> assert false - | Some s -> s - -let ( // ) = Filename.concat - -let endline = if Sys.os_type = "Win32" then "\r\n" else "\n" -let output_line oc s = output_string oc s; output_string oc endline - -(* based on last modification date only. - Doesn't handle dependencies toward runtime things that might change - incompatibly (DLLs, bytecode version, ...). - ocamlscript -f can be used to force recompilation in these cases. *) -let needs_recompile ?log = function - | `Stdin | `String _ -> true - | `File source -> - let bin = bin_name source in - not (Sys.file_exists bin) || - (Unix.stat bin).Unix.st_mtime <= (Unix.stat source).Unix.st_mtime - -(* -RE sep = "--" blank* eos -*) -(* -RE_STR "--" blank* eos -*) -let sep = Str.regexp "--[\t ]*$" -let is_sep s = Str.string_match sep s 0 - -let rec split_list accu is_sep = function - | [] -> `One (List.rev accu) - | hd :: tl -> - if is_sep hd then `Two (List.rev accu, tl) - else split_list (hd :: accu) is_sep tl - -let read_locstyle = function - | "ocaml" -> `Ocaml - | "blank" -> `Blank - | "none" -> `None - | _ -> failwith "invalid locstyle directive" - -(* let process_directives lines = - * let style = ref `Ocaml in - * let ocaml_lines = - * List.map - * (function - * | / "#" blank* "locstyle" blank* - * (lower ['_'alnum*] as x) blank* ";;"? blank* eol / as s -> - * style := read_locstyle x; - * String.make (String.length s) ' ' - * | s -> s) - * lines in - * (ocaml_lines, !style) *) - -let process_directives = - let micmatch_1 = - Str.regexp - "#[\t ]*locstyle[\t ]*\\([a-z][0-9A-Z_a-z]*\\)[\t ]*\\(;;\\)?[\t ]*$" - in - fun lines -> - let style = ref `Ocaml in - let ocaml_lines = - List.map - (fun micmatch_any_target -> - let micmatch_match_target_1 = micmatch_any_target in - (try - match micmatch_match_target_1 with - | micmatch_1_target as s when true -> - if Str.string_match micmatch_1 micmatch_1_target 0 then - let x = Str.matched_group 1 micmatch_1_target in - fun () -> - style := read_locstyle x; - String.make (String.length s) ' ' - else raise Exit - | _ -> raise Exit - with - Exit -> - let s = micmatch_match_target_1 in fun () -> s) - ()) - lines - in - ocaml_lines, !style - -(* let split_lines lines = - * let lines1, lines2 = split_list [] is_sep lines in - * let pos1, header = - * match lines1 with - * | / "#!" / :: header -> (2, header) - * | _ -> (1, lines1) in - * let pos2 = List.length lines1 + 2 in - * (pos1, header, pos2, lines2) *) - -let split_lines lines = - let test s = String.length s >= 2 && s.[0] = '#' && s.[1] = '!' in - let lines1, lines2 = - match split_list [] is_sep lines with - | `One (s :: prog) when test s -> [s], prog - | `One prog -> [], prog - | `Two (a, b) -> (a, b) in - let (pos1, header) = - match lines1 with - | s :: header when test s -> 2, header - | _ -> 1, lines1 in - let pos2 = List.length lines1 + 2 in - (pos1, header, pos2, lines2) - -let get_dir file = - let dir = Filename.dirname file in - if Filename.is_relative dir then Filename.concat (Sys.getcwd ()) dir - else dir - -let write_header ~pos ~source ~source_option ~verbose ~prog_file lines = - let bin = obin_name source_option in - let extra_args = - match !Opt.extra_args with - | [] -> "" - | l -> - sprintf "Ocamlscript.Common.extra_args := [ %s];;\n" - (String.concat "; " (List.map (fun s -> sprintf "%S" s) l)) in - let trash, script_dir = - match source_option with - | `Stdin - | `String _ -> (sprintf "Ocamlscript.Common.trash := \ - %S :: !Ocamlscript.Common.trash;;\n" - bin, - Sys.getcwd ()) - | `File script_name -> "", get_dir script_name in - - let file, oc = Filename.open_temp_file "meta" ".ml" in - fprintf oc "\ -#%i %S;; -(* Opam installations of findlib place topfind in a different directory *) -let () = - try Topdirs.dir_directory (Sys.getenv \"OCAML_TOPLEVEL_PATH\") - with Not_found -> () -;; -#use \"topfind\";; -#require \"ocamlscript\";; -Ocamlscript.Common.verbose := %s;; -Ocamlscript.Common.script_dir := %S;; -%s%sOcamlscript.Common.compile := Ocamlscript.Ocaml.compile;; -open Ocamlscript;; -open Utils;; -#%i %S;;\n" - pos source verbose script_dir extra_args trash pos source; - - List.iter (output_line oc) lines; - - fprintf oc "\ -let _ = exit (!Ocamlscript.Common.compile %S %S);;\n" prog_file bin; - close_out oc; - file - - -let write_body ~pos ~source ~locstyle lines = - let file, oc = Filename.open_temp_file "prog" ".ml" in - (match locstyle with - | `Ocaml -> fprintf oc "#%i %S;;\n" pos source - | `Blank -> for i = 1 to pos - 1 do output_string oc endline done - | `None -> ()); - List.iter (output_line oc) lines; - close_out oc; - file - -module Text = -struct - exception Internal_exit - - let iter_lines_of_channel f ic = - try - while true do - let line = - try input_line ic - with End_of_file -> raise Internal_exit in - f line - done - with Internal_exit -> () - - let iter_lines_of_file f file = - let ic = open_in file in - try - iter_lines_of_channel f ic; - close_in ic - with exn -> - close_in_noerr ic; - raise exn - - let lines_of_channel ic = - let l = ref [] in - iter_lines_of_channel (fun line -> l := line :: !l) ic; - List.rev !l - - let lines_of_file file = - let l = ref [] in - iter_lines_of_file (fun line -> l := line :: !l) file; - List.rev !l -end - - -let split_file = - let newline = Str.regexp "\r?\n" in - fun ?log source_option -> - let source, lines = - match source_option with - | `Stdin -> "", Text.lines_of_channel stdin - | `String s -> "", (Str.split newline) s - | `File file -> file, Text.lines_of_file file in - - let pos1, unprocessed_header, pos2, body = split_lines lines in - let header, locstyle = process_directives unprocessed_header in - - let verbose = if log = None then "false" else "true" in - - let prog_file = - write_body ~pos:pos2 ~source ~locstyle body in - let meta_file = - write_header - ~pos:pos1 ~source ~source_option ~verbose ~prog_file header in - (meta_file, prog_file) - - -let compile_script ?log source_option = - let meta_name, prog_name = split_file ?log source_option in - Fun.protect (fun () -> Pipeline.run_command (Pipeline.command ["ocaml"; meta_name])) - ~finally:(fun () -> - (* comment out for debugging: *) - Pipeline.remove meta_name; - Pipeline.remove prog_name - ) - -let absolute path = - if Filename.is_relative path then - Sys.getcwd () // path - else path - -let option0 ?(refuse_input = false) x = - let result = ref `Yes in - (match x with - | "--" -> result := `Stop - | "-help" - | "--help" -> Opt.help := true - | "-c" -> Opt.c := true - | "-f" -> Opt.f := true - | "-debug" -> Opt.debug := true - | "-version" -> Opt.version := true - | "-" -> - if refuse_input then - failwith "option - is disabled in this context" - else - Opt.set "source" Opt.from `Stdin - | _ -> result := `No); - !result - -let option1 ?(refuse_input = false) x y = - let result = ref true in - (match x with - | "-o" -> Opt.set "executable name" Opt.o y - | "-vm" -> Opt.set "virtual machine" Opt.vm y - | "-e" -> - if refuse_input then - failwith "option -e is disabled in this context" - else - Opt.set "source" Opt.from (`String y) - | _ -> result := false); - !result - -let start_option1 = - function - | "-o" - | "-vm" - | "-e" -> true - | _ -> false - -let optionx = function - | "" -> false - | s when s.[0] = '-' -> failwith (sprintf "%s is not a valid option" s) - | _ -> false - -let other_arg x = - Opt.extra_args := x :: !Opt.extra_args - - -let process_ocamlscript_args ?refuse_input ?(accept_non_option = false) l = - let rec loop = function - | x :: rest as l -> - begin - match option0 x with - | `Stop -> (None, true, rest) - | `Yes -> loop rest - | `No -> - match l with - | x :: y :: rest when option1 ?refuse_input x y -> loop rest - | x :: rest -> - if start_option1 x then - (Some x, false, rest) - else if optionx x then - loop rest - else if accept_non_option then - (other_arg x; loop rest) - else (None, false, l) - | [] -> assert false - end - | [] -> (None, false, []) in - loop l - - -let unquote s = - let buf = Buffer.create (String.length s) in - let i = ref 0 in - let len = String.length s in - while !i < len do - match s.[!i] with - | '"' -> Buffer.add_char buf '"'; i := !i + 2 - | c -> Buffer.add_char buf c; i := !i + 1 - done; - Buffer.contents buf - -(* -let tokenize_args = - COLLECT '"' (([^'"']|"\"\"")* as x := unquote) '"' - | ([^space '"']+ as x) -> x -*) -(* - RE_STR '"' ([^'"']|"\"\"")* '"' | [^space '"']+ -*) -let tokenize_args = - let token = Str.regexp "\"\\([^\"]\\|\"\"\\)*\"\\|[^ \"]+" in - fun s -> - List.fold_right - (fun x accu -> - match x with - | Str.Delim s -> - (if s <> "" && s.[0] = '"' then - unquote (String.sub s 1 (String.length s - 2)) - else s) :: accu - | _ -> accu) - (Str.full_split token s) [] - - -let guess_arg1 s = - match tokenize_args s with - | [s'] when String.length s' >= 1 && s'.[0] <> '-' -> `Script_name - | l -> - `Ocamlscript_args (process_ocamlscript_args - ~refuse_input:true - ~accept_non_option:true l) - -(* name of Sys.argv.(0) in the final process (execution of the binary) - depending on where the source program comes from: - - from a file: the name of the source file - - from stdin: - sh: sh - perl: - - python: "" - ocamlscript: "" - - from a string: - sh -c: sh - perl -e: -e - python -c: -c - ocamlscript -e: -e -*) - -let main () = - let script_path_option, script_args = - match Array.to_list Sys.argv with - | ocamlscript :: (arg1 :: other_args as l) -> - (match guess_arg1 arg1 with - | `Script_name -> (`File (absolute arg1), l) - | `Ocamlscript_args (opt1, stopped, hardcoded_script_args) -> - let command_line_script_args = - let continued_args = - match opt1 with - | None -> other_args - | Some o1 -> o1 :: other_args in - if stopped then continued_args - else - let opt1', stopped', command_line_script_args = - process_ocamlscript_args continued_args in - (match opt1' with - | None -> () - | Some x -> failwith - (sprintf "%s option expects an argument" x)); - command_line_script_args in - match !Opt.from with - | Some `Stdin -> - (`Stdin, - "" :: - (hardcoded_script_args @ command_line_script_args)) - | Some (`String s) -> - (`String s, - "-e" :: - (hardcoded_script_args @ command_line_script_args)) - | Some (`File s) -> assert false - | None -> - match command_line_script_args with - | [] -> - Opt.set "source" Opt.from `Stdin; - (`Stdin, - "" :: hardcoded_script_args) - | script_name :: l -> - Opt.set "source" Opt.from (`File script_name); - (`File (absolute script_name), - script_name :: (hardcoded_script_args @ l))) - | [_] | [] -> - Opt.set "source" Opt.from `Stdin; - (`Stdin, [""]) in - - if !Opt.help then - print_string Opt.help_message - else if !Opt.version then - print_endline Version.version - else - let bin = obin_name script_path_option in - let log = if !Opt.debug then Some stdout else None in - let compilation_status = - if !Opt.f || needs_recompile script_path_option then - let status = compile_script ?log script_path_option in - Pipeline.maybe_log log "compilation exit status: %i\n%!" status; - status - else 0 in - - if compilation_status = 0 && not !Opt.c then - let real_bin, real_args = - match !Opt.vm with - | None -> bin, script_args - | Some vm -> vm, (bin :: List.tl script_args) in - Unix.execv real_bin (Array.of_list real_args) - else (* includes the case where there is non-writeable executable *) - exit compilation_status - -let _ = - try main () - with Failure s -> - eprintf "ocamlscript: %s\n%!" s; - exit 2 diff --git a/ocaml.ml b/ocaml.ml deleted file mode 100644 index a1824c6..0000000 --- a/ocaml.ml +++ /dev/null @@ -1,165 +0,0 @@ -open Printf -open Pipeline -open Utils - - -let camlp4o = ref "camlp4o" -let camlp4r = ref "camlp4r" -let ocamllex = ref "ocamllex" -let ocamlyacc = ref "ocamlyacc" -let ocamlc = ref "ocamlc" -let ocamlopt = ref "ocamlopt" -let ocamlfind = ref "ocamlfind" - -let packs = ref [] (* findlib packages *) -let sources = ref [] (* extra sources *) -let use_ocamllex = ref false (* preprocess with ocamllex before camlp4 *) -let use_camlp4 = ref true (* by default camlp4 is used *) -let use_ocamlc = ref false (* by default we want native code *) -let use_ocamlfind = ref false (* used only if necessary *) -let revised = ref false (* use this to use the revised syntax *) -let ocamlflags = Common.extra_args (* any options that you may want to pass - to ocamlopt *) -let ppopt = ref [] (* any options that you may want to pass - to camlp4o or camlp4r *) - -type pp = string -> (Pipeline.command * string list) - -let pp : pp option ref = ref None (* additional preprocessor *) -let ppsrcloc = ref None (* non-standard source location generator *) - - - -let exe s = - match Sys.os_type with - | "Win32" | "Cygwin"-> - if Filename.check_suffix s ".exe" then s - else s ^ ".exe" - | "Unix" | _ -> s - -let import path = - let src = !+ path in - let dst = Filename.basename src in - let head = - match !pp, !ppsrcloc, !revised with - | Some _, Some f, _ -> f src - | _, _, false -> sprintf "#1 %S;;\n" src - | _, _, true -> sprintf "#1 %S;\n" src in - Pipeline.copy_file ~head src dst - -(* let ocamllex_command input = - * if !use_ocamllex then - * Some ((fun () -> ()), - * new_cmd [!ocamllex; input; - * "-o"; "ocamlscript_ocamllex_out.ml"; "-q"], - * "ocamlscript_ocamllex_out.ml") - * else None *) - -let file_kind file = - if Filename.check_suffix file ".mli" then `Mli - else if Filename.check_suffix file ".ml" then `Ml - else if Filename.check_suffix file ".mll" then `Mll - else if Filename.check_suffix file ".mly" then `Mly - else - try - let prefix = Filename.chop_extension file in - let len = String.length file - String.length prefix in - `Ext (String.sub file (String.length file - len) len) - with Invalid_argument _ -> - `Unknown - -let extra_command file = - match file_kind file with - | `Mli | `Ml -> ([], [file]) - | `Mll -> - ([command [!ocamllex; file; "-q"]], - [(Filename.chop_extension file) ^ ".ml"]) - | `Mly -> - let p = Filename.chop_extension file in - ([command [!ocamlyacc; file]], - [p ^ ".mli"; p ^ ".ml"]) - | `Ext s -> - failwith (sprintf "don't know how to handle %s files: %s" s file) - | `Unknown -> - failwith (sprintf "don't know how to handle this file: %s" file) - -let pp_command file = - match !pp with - | None -> [], [file] - | Some f -> - let cmd, files = f file in - ([cmd], files) - - -let extra_commands sources = - let input_files1 = List.map Filename.basename sources in - let cmds1, input_files2 = List.split (List.map pp_command input_files1) in - let cmds2, files = - List.split (List.map extra_command (List.flatten input_files2)) in - (List.flatten (cmds1 @ cmds2), List.flatten files) - - -let ocaml_command input = - let really_use_ocamlfind = - match !use_ocamlfind, !packs with - | true, _ | _, _ :: _ -> true - | _ -> false in - let compiler = - if really_use_ocamlfind then - if !use_ocamlc then [!ocamlfind; "ocamlc"] - else [!ocamlfind; "ocamlopt"] - else if !use_ocamlc then [!ocamlc] - else [!ocamlopt] in - - let flags = !ocamlflags in - let camlp4_stuff = - if !use_camlp4 then - let syntax, camlp4 = - if !revised then "camlp4r", !camlp4r - else "camlp4o", !camlp4o in - let ppoptions = - if !ppopt = [] then [] - else - if really_use_ocamlfind then - List.flatten (List.map (fun s -> ["-ppopt"; s]) !ppopt) - else !ppopt in - if really_use_ocamlfind then - "-syntax" :: syntax :: ppoptions - else - let space = function | "" -> "" | s -> " " ^ s in - ["-pp"; sprintf "'%s%s'" camlp4 (space (String.concat " " ppoptions))] - else [] in - let packages = - if really_use_ocamlfind then - ["-linkpkg"; "-package"; - String.concat "," - (if !use_camlp4 && not (List.mem "camlp4" !packs) then - "camlp4" :: !packs - else !packs) ] - else [] in - - let extra_sources = !sources in - let init () = List.iter import extra_sources in - let all_sources = extra_sources @ [input] in - - let xcommands, all_ml_files = extra_commands all_sources in - - let args = compiler @ "-o" :: "prog" :: - flags @ camlp4_stuff @ packages @ all_ml_files in - (init, xcommands, command args, exe "prog") - - -let compile source result = - let internal_input = - if !use_ocamllex then "ocamlscript_main.mll" - else "ocamlscript_main.ml" in - - let before, xcommands, main_command, internal_output = - ocaml_command internal_input in - let input = [internal_input, source] in - let output = [internal_output, exe result] in - let log = if !Common.verbose then Some stdout else None in - run ?log ~before ~input ~output - { input = [internal_input]; - output = [internal_output]; - commands = xcommands @ [main_command] } diff --git a/ocaml.mli b/ocaml.mli deleted file mode 100644 index c907fb8..0000000 --- a/ocaml.mli +++ /dev/null @@ -1,70 +0,0 @@ -(** Default compilation module: settings for the Ocaml compilers *) - -(** the name of the camlp4o command; default: "camlp4o" *) -val camlp4o : string ref - -(** the name of the camlp4r command; default: "camlp4r" *) -val camlp4r : string ref - -(** the name of the ocamllex command; default: "ocamllex" *) -val ocamllex : string ref - -(** the name of the ocamlyacc command; default: "ocamlyacc" *) -val ocamlyacc : string ref - -(** the name of the ocamlc command; default: "ocamlc" *) -val ocamlc : string ref - -(** the name of the ocamlopt command; default: "ocamlopt" *) -val ocamlopt : string ref - -(** the name of the ocamlfind command; default: "ocamlfind" *) -val ocamlfind : string ref - -(** Specific Findlib/ocamlfind packages to use *) -val packs : string list ref - -(** Extra source files (processed with camlp4 but not ocamllex). - They can be referenced either by an absolute path or by a path relative - to the script directory. - They are compiled and linked in like regular OCaml compilation units. *) -val sources : string list ref - -(** whether to use ocamllex or not; default: false *) -val use_ocamllex : bool ref - -(** whether to use camlp4 preprocessing or not; default: true *) -val use_camlp4 : bool ref - -(** whether to use ocamlc instead of ocamlopt; default: false *) -val use_ocamlc : bool ref - -(** whether to use ocamlfind even if [!packs] is empty; default: false *) -val use_ocamlfind : bool ref - -(** whether the revised syntax of OCaml should be used; default: false *) -val revised : bool ref - -(** any other options to pass to the compiler *) -val ocamlflags : string list ref - -(** any other options to pass to the preprocessor *) -val ppopt : string list ref - -(** type of a preprocessor: takes an input file and returns a command and - the list of files to be processed further. *) -type pp = string -> (Pipeline.command * string list) - -(** optional preprocessor that comes before all other preprocessors *) -val pp : pp option ref - -(** the function which takes the source file path and generates the string - the will be inserted at the beginning of files when they are copied. - The default is set to follow OCaml's standard syntax, - like "#1 \"file.ml\";;\n" for instance. *) -val ppsrcloc : (string -> string) option ref - - -(** the compilation function which is used - to set [Ocamlscript.Common.compile] *) -val compile : string -> string -> int diff --git a/ocamlscript-help.txt b/ocamlscript-help.txt deleted file mode 100644 index 13cc46d..0000000 --- a/ocamlscript-help.txt +++ /dev/null @@ -1,72 +0,0 @@ -Usage: ocamlscript [ PACKED_OPTIONS [ OPTIONS ] [ -- ] [SCRIPTNAME] [ARGS] ] - -Ocamlscript normally reads the source code of a program from a file, looks -if a compiled executable exists for this program. If it exists and if it -is more recent than the source file, the executable is executed immediately, -otherwise it is updated by executing compilation instructions that can -be specified in the program file. - -A typical self-executable script looks as follows: - - #!/usr/bin/env ocamlscript - (* this is the compilation section, in OCaml *) - Ocaml.packs := ["unix"; "micmatch_pcre"] (* Findlib packages *) - -- - (* this is the program section *) - let _ = - ... - - -Structure of the command line: - -PACKED_OPTIONS: - the first argument of ocamlscript. It is either unpacked into - several arguments that are passed to ocamlscript or into a script name - if this name doesn't start with "-". Double-quotes can be used - to enclose arguments that contain whitespace or double-quotes. - Double-quotes must be doubled. For instance, the following - self-executable script would be compiled into an executable named - Hello "World": - #!/usr/bin/ocamlscript -o "Hello ""World""" - print_endline "Hello "World"" - - Important note: on some Unix systems, the whole - '-o "Hello ""World"""' string is passed as a single argument - to ocamlscript. This is why the first argument must be unpacked, - even if ocamlscript is called explicitely from the command line. - -OPTIONS: - any number of arguments in this section are treated like options - to ocamlscript until a either a non-option is encountered, which is - understood as the script name (SCRIPTNAME) or "--" which stops - the list of arguments that are passed to ocamlscript. - -Ocamlscript supports the following options: - -- marks the end of ocamlscript arguments - -help displays a help message and exit - --help same as -help - -c compile only - -o EXEC_NAME specify a name for the executable - (required if the program is not read from a file) - -e PROGRAM execute the code given here instead of reading it from a file - -f force recompilation which is otherwise based on last modification dates - -debug print messages about what ocamlscript is doing - -version prints the version identifier to stdout and exit - - read program from stdin instead of a file - -vm VIRTUAL_MACHINE run the executable using this virtual machine (e.g. - ocamlrun) - -"--": passed as an argument to ocamlscript in the PACKED_OPTIONS argument - or in the OPTIONS argument marks the end of the arguments that - are passed to ocamlscript. Arguments that follow will be - interpreted as arguments of the script. - Arguments that follow "--" in the PACKED_OPTIONS argument - will be passed as arguments to the final executable. The first - argument that follows "--" in the OPTIONS command line arguments - is treated as the script name, unless the program is read from - another source, as specified by options "-e" (a string) or "-" - (standard input). - - -For a full documentation on the structure of the compilation section, go to -ocamlscript's website (http://martin.jambon.free.fr/ocamlscript.html). diff --git a/opam b/opam deleted file mode 100644 index 5b2a5d8..0000000 --- a/opam +++ /dev/null @@ -1,20 +0,0 @@ -opam-version: "2.0" -synopsis: "Tool which compiles OCaml scripts into native code" -authors: "Martin Jambon" -maintainer: [ - "martin@mjambon.com" - "Francois Berenger " -] -homepage: "https://github.com/mjambon/ocamlscript" -bug-reports: "https://github.com/mjambon/ocamlscript/issues" -dev-repo: "git://github.com/mjambon/ocamlscript" -depends: [ - "ocaml" {>= "4.08"} # because of Fun.protect - "ocamlfind" -] -build: [make] -install: [make "install"] -# url { -# src: "https://github.com/mjambon/ocamlscript/archive/XXX" -# checksum: "md5=XXX" -# } diff --git a/pipeline.ml b/pipeline.ml deleted file mode 100644 index c3cdf37..0000000 --- a/pipeline.ml +++ /dev/null @@ -1,200 +0,0 @@ - -open Printf -open Unix - -(* - - input: list of files which are copied from the base directory - to a temporary directory - - output: list of files which are copied from the temporary directory - to the base directory - - the current directory is set to the temporary directory during - the execution of the pipeline -*) - -type command = { args : string list; - stdin : string option; - stdout : string option } - -type pipeline = { input : string list; - output : string list; - commands : command list } - -let ( // ) = Filename.concat -let ( @@ ) a b = if Filename.is_relative b then a // b else b - -let command ?stdin ?stdout args = { args = args; - stdin = stdin; - stdout = stdout } - -let prng = Random.State.make_self_init ();; - -let temporary_directory = - match Sys.os_type with - | "Unix" | "Cygwin" -> (try Sys.getenv "TMPDIR" with Not_found -> "/tmp") - | "Win32" -> (try Sys.getenv "TEMP" with Not_found -> ".") - | _ -> assert false - -let temp_file_name prefix suffix = - let rnd = (Random.State.bits prng) land 0xFFFFFF in - temporary_directory // (sprintf "%s%06x%s" prefix rnd suffix) - -let temp_dir prefix suffix = - let rec try_name counter = - let name = temp_file_name prefix suffix in - try - mkdir name 0o700; - name - with Unix_error _ as e -> - if counter >= 1000 then raise e else try_name (counter + 1) - in try_name 0 - -let stderr_out_chan = Unix.out_channel_of_descr stderr - -let maybe_log maybe_out fmt = - (match maybe_out with - | Some out -> fprintf out - | None -> ifprintf stderr_out_chan) fmt - -(* rm -rf *) -let rec remove ?log file = - try - let st = stat file in - match st.st_kind with - | S_DIR -> - Array.iter (fun name -> remove (file // name)) (Sys.readdir file); - maybe_log log "remove directory %S\n%!" file; - rmdir file - | S_REG - | S_CHR - | S_BLK - | S_LNK - | S_FIFO - | S_SOCK -> - maybe_log log "remove file %S\n%!" file; - Sys.remove file - with e -> () - - -(* like Sys.command, but without shell interpretation *) -let array_command ?stdin ?stdout prog args = - let real_stdin, close_stdin = - match stdin with - | None -> Unix.stdin, false - | Some file -> Unix.openfile file [Unix.O_RDONLY] 0, true in - let real_stdout, close_stdout = - match stdout with - | None -> Unix.stdout, false - | Some file -> - Unix.openfile file - [Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC] 0o600, true in - let pid = Unix.create_process prog args real_stdin real_stdout Unix.stderr in - let pid', process_status = Unix.waitpid [] pid in - assert (pid = pid'); - if close_stdin then - (try Unix.close real_stdin with _ -> ()); - if close_stdout then - (try Unix.close real_stdout with _ -> ()); - match process_status with - | Unix.WEXITED n -> n - | Unix.WSIGNALED _ -> 2 (* like OCaml's uncaught exceptions *) - | Unix.WSTOPPED _ -> - (* only possible if the call was done using WUNTRACED - or when the child is being traced *) - assert false - -let concat_cmd cmd = String.concat " " cmd.args - -let run_command ?log cmd = - match cmd.args with - | [] -> - maybe_log log "empty command\n%!"; 0 - | prog :: _ -> - maybe_log log "%s: %s\n%!" prog (concat_cmd cmd); - let status = - array_command ?stdin:cmd.stdin ?stdout:cmd.stdout - prog (Array.of_list cmd.args) in - maybe_log log "exit status %i\n%!" status; - status - -let exec ?log cmd = - maybe_log log "%s\n%!" (concat_cmd cmd); - let status = run_command cmd in - maybe_log log "exit status %i\n%!" status; - status - -let copy_file ?log ?(head = "") ?(tail = "") ?(force = false) src dst = - maybe_log log "copy %S to %S\n%!" src dst; - if not force && Sys.file_exists dst then - invalid_arg - (sprintf "Pipeline.copy_file: destination file %s already exists" dst); - let ic = open_in_bin src in - Fun.protect (fun () -> - let oc = open_out_bin dst in - Fun.protect (fun () -> - try - output_string oc head; - while true do - output_char oc (input_char ic) - done - with End_of_file -> output_string oc tail - ) - ~finally:(fun () -> - close_out_noerr oc; - let perm = (stat src).st_perm in - chmod dst perm - ) - ) - ~finally:(fun () -> close_in_noerr ic) - -let copy_files ?log ?force src dst l = - List.iter - (fun (src_name, dst_name) -> - copy_file ?log ?force (src @@ src_name) (dst @@ dst_name)) - l - -let match_files names settings = - let tbl = Hashtbl.create 10 in - List.iter (fun id -> Hashtbl.replace tbl id None) names; - List.iter (fun (id, s) -> Hashtbl.replace tbl id (Some s)) settings; - let pairs = - Hashtbl.fold (fun id opt l -> - let x = - match opt with - | None -> (id, id) - | Some s -> (id, s) in - x :: l) tbl [] in - pairs - -let flip (a, b) = (b, a) - -let run ?log - ?(before = fun () -> ()) ?(after = fun () -> ()) - ?(input = []) ?(output = []) p = - let rec loop l = - match l with - | [] -> 0 - | cmd :: rest when cmd.stdin = None && cmd.stdout = None -> - (try - let status = exec ?log cmd in - if status = 0 then loop rest - else status - with _ -> 127) - | _ -> failwith "IO redirections: not implemented" in - let dir = temp_dir "ocamlpipeline" "" in - Fun.protect - (fun () -> - let base = Sys.getcwd () in - maybe_log log "change directory %S\n%!" dir; - Sys.chdir dir; - before (); - copy_files ?log base dir (List.map flip (match_files p.input input)); - let status = loop p.commands in - maybe_log log "change directory %S\n%!" base; - after (); - Sys.chdir base; - maybe_log log "command pipeline exits with status %i\n%!" status; - if status = 0 then - copy_files ?log ~force:true dir base (match_files p.output output); - status - ) - ~finally:(fun () -> remove ?log dir) diff --git a/pipeline.mli b/pipeline.mli deleted file mode 100644 index 337b308..0000000 --- a/pipeline.mli +++ /dev/null @@ -1,45 +0,0 @@ -(** Portable command pipeline *) - -type command - -(** A given pipeline always executes the same commands from a given temporary - directory. The input files have been copied into the directory by the time - the execution starts. After execution, the output files are copied - to some specified location and then the directory is removed. *) -type pipeline = { - input : string list; (** internal names of the input files *) - output : string list; (** internal names of the result files *) - commands : command list; (** commands which operate on the - internal file names *) -} - -(** [command ?stdin ?stdout l] creates a command which redirects stdin and - stdout to the given files, if these options are used. - For example, [command ~stdout:"bigfile" ["cat"; "file1"; "file2"]] - is equivalent to the shell command [cat file1 file2 > bigfile]. *) -val command : ?stdin:string -> ?stdout:string -> string list -> command - -(** [run ~input ~output pip] executes the given pipeline [pip] by - instanciating the internal file names used in the pipeline using - input and output files. - For example, a pipeline [pip] which works on one input file named file1 - and on one output file named file2 would be executed using - [run ~input:["file1", any_input_file] - ~output:["file2", any_output_file] pip]. - The [log] option can be used to collect information for debugging. *) -val run : - ?log:out_channel -> - ?before:(unit -> unit) -> - ?after:(unit -> unit) -> - ?input:(string * string) list -> - ?output:(string * string) list -> pipeline -> int - -(**/**) - -val remove : ?log:out_channel -> string -> unit -val copy_file : - ?log:out_channel -> ?head:string -> ?tail:string -> ?force:bool -> - string -> string -> unit -val run_command : ?log:out_channel -> command -> int - -val maybe_log : out_channel option -> ('a, out_channel, unit) format -> 'a diff --git a/std.ml b/std.ml deleted file mode 100644 index 9e9839a..0000000 --- a/std.ml +++ /dev/null @@ -1,5 +0,0 @@ -module Common = Common -module Pipeline = Pipeline -module Ocaml = Ocaml -module Utils = Utils -let (--) _ _ = () diff --git a/tests/-full test b/tests/-full test deleted file mode 100755 index f218322..0000000 --- a/tests/-full test +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env ocamlscript -(*-*- tuareg -*-*) -Ocaml.use_ocamllex := true;; -Ocaml.packs := ["camlp4.macro"];; -Ocaml.ocamlflags := ["-rectypes"; "unix.cmxa"];; --- -(* ocamllex file *) -rule line f n = parse - [^'\n']* as x { newline (f n x) n lexbuf } -and newline f n = parse - '\n' { line f (n+1) lexbuf } - | eof { () } - | "" { assert false } -{ -open Printf - -(* testing -rectypes *) -type t = t array - -(* testing program arguments *) -let args = Array.to_list Sys.argv -let _ = - assert (args <> []); - printf "Running %s\n%!" - (String.concat " " (List.map (fun s -> sprintf "%S" s) args)) - -(* running ocamllex stuff *) -let prog_name = List.hd args -let _ = - let ic = open_in_bin prog_name in - let lexbuf = Lexing.from_channel ic in - let rec f n s = printf "%i " n; f in - line f 0 lexbuf; - printf "\n" - -(* testing camlp4 extension *) -let _ = printf "This should be the source file: %S\n" __FILE__ - -(* testing library *) -let _ = Unix.gettimeofday () -} diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 4ee9b08..0000000 --- a/tests/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -.PHONY: default clean -default: - @echo '*** These tests are for developers only! ***' - @echo -e '*** They might not work on your platform! ***\n\n' - cp ../ocamlscript . - ./unpack - './Hello "World"' - ./fulltest arg1 arg2 - ./ocamlscript -- '-full test' arg1 arg2 arg3 - ./ocamlscript -c -o hello -e 'print_endline "Hello"' - ./hello - echo 'Printf.printf "Goodbye %s\n" Sys.argv.(1)' \ - | ocamlscript - -o goodbye '$(USER)' - ./goodbye again -clean: - $(RM) -- ocamlscript *~ \ - "-full test.exe" fulltest.exe 'Hello "World"' hello goodbye diff --git a/tests/fulltest b/tests/fulltest deleted file mode 100755 index e85c4e5..0000000 --- a/tests/fulltest +++ /dev/null @@ -1,46 +0,0 @@ -#!./ocamlscript str.cmxa -- hello -(*-*- tuareg -*-*) -open Ocaml;; -use_ocamllex := true;; -packs := ["camlp4.macro"];; -ocamlflags := !ocamlflags @ ["-rectypes"; "unix.cmxa"];; --- - -(* ocamllex file *) -rule line f n = parse - [^'\n']* as x { newline (f n x) n lexbuf } -and newline f n = parse - '\n' { line f (n+1) lexbuf } - | eof { () } - | "" { assert false } -{ -open Printf - -(* testing shebang option *) -let _ = Str.regexp "abc" - -(* testing -rectypes *) -type t = t array - -(* testing program arguments *) -let args = Array.to_list Sys.argv -let _ = - assert (args <> []); - printf "Running %s\n%!" - (String.concat " " (List.map (fun s -> sprintf "%S" s) args)) - -(* running ocamllex stuff *) -let prog_name = List.hd args -let _ = - let ic = open_in_bin prog_name in - let lexbuf = Lexing.from_channel ic in - let rec f n s = printf "%i " n; f in - line f 0 lexbuf; - printf "\n" - -(* testing camlp4 extension *) -let _ = printf "This should be the source file: %S\n" __FILE__ - -(* testing library *) -let _ = Unix.gettimeofday () -} diff --git a/tests/unpack b/tests/unpack deleted file mode 100755 index afa2e6e..0000000 --- a/tests/unpack +++ /dev/null @@ -1,4 +0,0 @@ -#!./ocamlscript -debug -o "Hello ""World""" -(* the line above only works on Unix flavors that pass all the options as - a single argument argv[1] *) -let _ = print_endline "Hello \"World\"" diff --git a/thin-ocamlscript.opam b/thin-ocamlscript.opam new file mode 100644 index 0000000..47c7f10 --- /dev/null +++ b/thin-ocamlscript.opam @@ -0,0 +1,33 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "OCaml as a scripting language with ocamlfind" +description: + "Similar to ocamlscript, but configuration is restricted to the shebang line." +maintainer: ["Julian Fondren "] +authors: ["Julian Fondren "] +license: "MIT" +homepage: "https://github.com/jrfondren/thin-ocamlscript" +doc: "https://github.com/jrfondren/thin-ocamlscript" +bug-reports: "https://github.com/jrfondren/thin-ocamlscript/issues" +depends: [ + "dune" {>= "3.20"} + "ocaml" {>= "5.2"} + "ocamlfind" {>= "1.9.8"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/jrfondren/thin-ocamlscript.git" +x-maintenance-intent: ["(latest)"] diff --git a/utils.ml b/utils.ml deleted file mode 100644 index 63c698f..0000000 --- a/utils.ml +++ /dev/null @@ -1,4 +0,0 @@ -let ( // ) = Filename.concat -let ( !+ ) path = - if Filename.is_relative path then !Common.script_dir // path - else path diff --git a/utils.mli b/utils.mli deleted file mode 100644 index 019d63b..0000000 --- a/utils.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Handy utilities for file manipulation. - This module is automatically opened by ocamlscript. *) - -(** shortcut for portable file path concatenation *) -val ( // ) : string -> string -> string - -(** prefix operator to reference a file relatively to the script directory. *) -val ( !+ ) : string -> string