···11+The installation procedure consists of the steps:
22+33+1) configure the "findlib" library
44+2) compile "findlib" and the "ocamlfind" frontend of "findlib"
55+3) install "findlib" and the core library configuration
66+77+Optionally, you can run ./itest after step 2 to check the
88+configuration. Problems with the configuration are unlikely, however.
99+1010+At the end of this file you find notes about MacOS and Windows.
1111+1212+1313+----------------------------------------------------------------------
1414+1515+STEP 1: DEFAULT CONFIGURATION
1616+1717+The findlib module and its ocamlfind frontend come with a "configure"
1818+script that should almost always be able to figure out a good
1919+configuration.
2020+2121+Just type:
2222+2323+ ./configure
2424+2525+First the linker options for the various core libraries are figured
2626+out, then reasonable installation paths are checked.
2727+2828+If the results are not ok, you can modify them using the following
2929+options:
3030+3131+ -bindir <path>
3232+3333+ set the location where the ocamlfind command should be
3434+ installed.
3535+ Default: same location as "ocamlc"
3636+3737+ -mandir <path>
3838+3939+ set the location where the man page should be installed.
4040+ Default: a heuristics, and "/usr/local/man" as fallback.
4141+4242+ -sitelib <path>
4343+4444+ set the default "site-lib" directory.
4545+ Default: For installations in the /usr hierarchy,
4646+ "$stdlib/site-lib", where $stdlib is the location of
4747+ Ocaml's standard library.
4848+4949+ For installations in the /opt hierarchy,
5050+ "$stdlib/../site-lib", i.e. parallel to $stdlib.
5151+5252+ -config <file>
5353+5454+ set the location of the configuration file.
5555+ Default: <bindir>/../etc/findlib.conf
5656+5757+ -no-topfind
5858+5959+ the "topfind" script is not installed in the standard
6060+ library directory. (This is not a good idea in general,
6161+ because #use "topfind" will not work when this option
6262+ is enabled.)
6363+6464+ -with-toolbox
6565+ also compile and install the "toolbox". This requires
6666+ that labltk is available. The toolbox contains the
6767+ "make_wizard" to easily create findlib-enabled Makefiles.
6868+6969+ -cygpath
7070+ Cygwin environment only: If "ocamlc -where" does not
7171+ output a Unix-style path, this option can be used
7272+ to apply the "cygpath" command to it. Use this option
7373+ if you see backslashes or drive letters in Makefile.config.
7474+7575+ALTERNATIVES:
7676+7777+If the "configure" script does not work properly (very unlikely), do
7878+7979+ cp Makefile.config.pattern Makefile.config
8080+8181+and edit Makefile.config by hand.
8282+8383+If the generated META files do not work, edit them (this is very very unlikely).
8484+8585+Note: The META files are generated from the META.in files in the same
8686+directories by sed:
8787+8888+ sed -e 's/%%findlib_version%%/<version>/g' <more parameters...> site-lib/<name>/META.in
8989+ >site-lib/<name>/META
9090+9191+You may invoke sed manually to create different META files, but this
9292+is currently not documented.
9393+9494+9595+9696+----------------------------------------------------------------------
9797+9898+STEP 2: COMPILATION
9999+100100+After configuration has been done, compile with
101101+102102+ make all
103103+104104+This creates findlib.cma, findlib_mt.cma (the thread-safe version),
105105+and ocamlfind.
106106+107107+If you have ocamlopt, do also
108108+109109+ make opt
110110+111111+This creates findlib.cmxa, findlib_mt.cmxa, and ocamlfind_opt.
112112+113113+----------------------------------------------------------------------
114114+115115+STEP 3: INSTALLATION
116116+117117+Install the findlib library, the ocamlfind frontend, and the core library
118118+configurations with:
119119+120120+ make install
121121+122122+(A "make uninstall" removes them.)
123123+124124+With
125125+ make clean
126126+127127+the build directory is cleaned up.
128128+129129+130130+OPTIONAL (BUT RECOMMENDED):
131131+132132+If you want a separate directory for DLLs, create this directory
133133+now:
134134+135135+mkdir `ocamlfind printconf destdir`/stublibs
136136+137137+If you do this, you must also tell OCaml that DLLs can be found in
138138+this directory: Add the absolute path of this directory to
139139+the ld.conf file (type "ocamlfind printconf ldconf" to get the
140140+location of the ld.conf file). Every line of this text file lists
141141+one possible directory for DLLs.
142142+143143+----------------------------------------------------------------------
144144+145145+MACOS X:
146146+147147+Findlib can be installed as described. There is even a script to
148148+create a MacOS X package, use "make package-macosx" to invoke it. As I
149149+do not have access to a Mac box, I cannot test this script, but I
150150+fully trust the author that it works.
151151+152152+----------------------------------------------------------------------
153153+154154+WINDOWS:
155155+156156+Ocaml for Windows exists in three flavours:
157157+158158+(1) Ocaml as Cygwin program
159159+(2) Ocaml as Mingw program (i.e. the gcc toolchain is used but
160160+ Ocaml is a native Windows program)
161161+(3) Ocaml as VC program
162162+163163+In all three cases you need Cygwin to build and install findlib,
164164+because "configure" and the Makefile are both Cygwin scripts. The
165165+golden rule to make everything work is this:
166166+167167+PASS CYGWIN-STYLE PATHS TO CONFIGURE!
168168+169169+Even in cases (2) and (3)! That means use something like
170170+/cygdrive/c/path and not c:\path when you specify where -bindir,
171171+-config etc. are. The point is that "configure" itself is a Cygwin
172172+script, and therefore expects Cygwin input. At the right moment, the
173173+paths are back-translated to their Windows counterparts.
174174+175175+Until OCaml 3.08 you must specify whether you have (2) or (3) by
176176+the configure switches
177177+178178+- "-system mingw" for (2)
179179+- "-system win32" for (3)
180180+- nothing for (1)
181181+182182+Since OCaml 3.09 this is no longer necessary because "ocamlc -config"
183183+outputs the required information.
184184+185185+In previous versions of Findlib there was a single switch -cygpath
186186+for both (2) and (3). It is now interpreted as -system mingw (as
187187+it was meant as that).
+22
vendor/opam/ocamlfind/LICENSE
···11+Copyright 1999 by Gerd Stolpmann
22+33+The package "findlib" is copyright by Gerd Stolpmann.
44+55+Permission is hereby granted, free of charge, to any person obtaining
66+a copy of this document and the "findlib" software (the
77+"Software"), to deal in the Software without restriction, including
88+without limitation the rights to use, copy, modify, merge, publish,
99+distribute, sublicense, and/or sell copies of the Software, and to
1010+permit persons to whom the Software is furnished to do so, subject to
1111+the following conditions:
1212+1313+The above copyright notice and this permission notice shall be included
1414+in all copies or substantial portions of the Software.
1515+1616+The Software is provided ``as is'', without warranty of any kind, express
1717+or implied, including but not limited to the warranties of
1818+merchantability, fitness for a particular purpose and noninfringement.
1919+In no event shall Gerd Stolpmann be liable for any claim, damages or
2020+other liability, whether in an action of contract, tort or otherwise,
2121+arising from, out of or in connection with the Software or the use or
2222+other dealings in the software.
+169
vendor/opam/ocamlfind/Makefile
···11+# make all: compile to bytecode
22+# make opt: compile to native code
33+# make install: install bytecode and/or native code
44+#----------------------------------------------------------------------
55+66+include Makefile.config
77+-include Makefile.packages
88+99+TOP=.
1010+1111+.PHONY: all opt install uninstall clean
1212+1313+all:
1414+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) all ) || exit; done
1515+ $(MAKE) all-config
1616+1717+opt:
1818+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) opt ) || exit; done
1919+2020+install: check-installation
2121+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
2222+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)"
2323+ $(MAKE) install-config
2424+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) install ); done
2525+ $(MAKE) install-meta
2626+ test ! -f 'site-lib-src/num-top/META' || { cd src/findlib; $(MAKE) install-num-top; }
2727+ test ! -f 'site-lib-src/camlp4/META' || $(INSTALLFILE) tools/safe_camlp4 "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
2828+ $(MAKE) install-doc
2929+3030+uninstall: check-installation
3131+ $(MAKE) uninstall-doc
3232+ $(MAKE) uninstall-meta
3333+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) uninstall ); done
3434+ $(MAKE) uninstall-config
3535+3636+clean:
3737+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) clean ); done
3838+ (cd itest-aux; $(MAKE) clean)
3939+ (cd tools/extract_args; $(MAKE) clean)
4040+ rm -f findlib.conf Makefile.packages
4141+4242+.PHONY: release
4343+release: README
4444+ ./release
4545+4646+README: doc/README
4747+ ln -s doc/README .
4848+4949+5050+.PHONY: all-config
5151+all-config: findlib.conf
5252+5353+.PHONY: findlib-template
5454+findlib-template: findlib.conf.in
5555+ USE_CYGPATH="$(USE_CYGPATH)"; \
5656+ export USE_CYGPATH; \
5757+ cat findlib.conf.in | \
5858+ $(SH) tools/patch '@SITELIB@' '$(FINDLIB_OCAML_SITELIB)' | \
5959+ $(SH) tools/patch '@FINDLIB_PATH@' '$(FINDLIB_PATH)' -p >findlib.conf
6060+ if ./tools/cmd_from_same_dir ocamlc; then \
6161+ echo 'ocamlc="ocamlc.opt"' >>findlib.conf; \
6262+ fi
6363+ if ./tools/cmd_from_same_dir ocamlopt; then \
6464+ echo 'ocamlopt="ocamlopt.opt"' >>findlib.conf; \
6565+ fi
6666+ if ./tools/cmd_from_same_dir ocamldep; then \
6767+ echo 'ocamldep="ocamldep.opt"' >>findlib.conf; \
6868+ fi
6969+ if ./tools/cmd_from_same_dir ocamldoc; then \
7070+ echo 'ocamldoc="ocamldoc.opt"' >>findlib.conf; \
7171+ fi
7272+7373+.PHONY: findlib-relative
7474+findlib-relative: FINDLIB_OCAML_SITELIB=$(RELATIVE_OCAML_SITELIB)
7575+findlib-relative: findlib-template
7676+7777+.PHONY: findlib-absolute
7878+findlib-absolute: FINDLIB_OCAML_SITELIB=$(OCAML_SITELIB)
7979+findlib-absolute: findlib-template
8080+8181+findlib.conf: findlib.conf.in
8282+ if [ "$(RELATIVE_PATHS)" = "true" ]; then \
8383+ $(MAKE) findlib-relative; \
8484+ else \
8585+ $(MAKE) findlib-absolute; \
8686+ fi
8787+8888+.PHONY: install-doc
8989+install-doc:
9090+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5"
9191+ -$(CP) doc/ref-man/ocamlfind.1 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1"
9292+ -$(CP) doc/ref-man/META.5 doc/ref-man/site-lib.5 doc/ref-man/findlib.conf.5 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5"
9393+9494+.PHONY: uninstall-doc
9595+uninstall-doc:
9696+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1/ocamlfind.1"
9797+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Findlib.3"
9898+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Topfind.3"
9999+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/META.5"
100100+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/site-lib.5"
101101+102102+103103+.PHONY: check-installation
104104+check-installation:
105105+ if [ "$(CHECK_BEFORE_INSTALL)" -eq 1 ]; then \
106106+ for x in camlp4 dbm graphics labltk num ocamlbuild; do \
107107+ if [ -f "$(prefix)$(OCAML_SITELIB)/$$x/META" ]; then \
108108+ if ! grep -Fq '[distributed with Ocaml]' "$(prefix)/$(OCAML_SITELIB)/$$x/META"; then \
109109+ rm -f site-lib-src/$$x/META; \
110110+ fi; \
111111+ fi; \
112112+ done; \
113113+ test -f "site-lib-src/num/META" || rm -f "site-lib-src/num-top/META"; \
114114+ fi
115115+ echo 'SITELIB_META =' > Makefile.packages.in
116116+ for x in `ls site-lib-src`; do test ! -f "site-lib-src/$$x/META" || echo $$x >> Makefile.packages.in; done
117117+ tr '\n' ' ' < Makefile.packages.in > Makefile.packages
118118+ rm Makefile.packages.in
119119+120120+.PHONY: install-meta
121121+install-meta:
122122+ for x in $(SITELIB_META); do $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x"; $(CP) site-lib-src/$$x/META "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META.tmp" && mv "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META.tmp" "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META"; done
123123+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib"; $(CP) Makefile.packages "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib/Makefile.packages"
124124+125125+.PHONY: uninstall-meta
126126+uninstall-meta:
127127+ for x in $(SITELIB_META); do rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x"; done
128128+129129+.PHONY: install-config
130130+install-config:
131131+ $(INSTALLDIR) "`dirname \"$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)\"`"
132132+ @if [ -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" ]; then echo "!!! Keeping old $(DESTDIR)$(prefix)$(OCAMLFIND_CONF) !!!"; fi
133133+ test -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" || $(CP) findlib.conf "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)"
134134+135135+.PHONY: uninstall-config
136136+uninstall-config:
137137+ @echo Leaving "$(OCAMLFIND_CONF)" installed, consider manual removal
138138+139139+.PHONY: interface-lists
140140+interface-lists:
141141+ d=`ocamlc -where`; \
142142+ for x in `ls site-lib-src`; do \
143143+ iflist=""; \
144144+ if [ ! -f "site-lib-src/$$x/interfaces.in" ]; then continue; fi; \
145145+ cma_spec=`cat site-lib-src/$$x/interfaces.in`; \
146146+ for cma in $$d/$$cma_spec; do \
147147+ intf=`ocamlobjinfo $$cma | \
148148+ grep 'Unit name:' | \
149149+ sed -e 's/^ Unit name: //' | \
150150+ sort | \
151151+ tr '\n' ' '`; \
152152+ iflist="$$iflist $$intf"; \
153153+ done; \
154154+ echo "$$iflist" >"site-lib-src/$$x/interfaces.out"; \
155155+ done
156156+157157+######################################################################
158158+# The following is from Pietro Abata <pietro.abate@anu.edu.au>
159159+# to create MacOS X packages. I did not test it, just include it.
160160+161161+.PHONY: package-macosx
162162+163163+package-macosx: all opt
164164+ $(INSTALLDIR) package-macosx/root
165165+ export prefix=`pwd`/package-macosx/root && make install
166166+ export VERSION=1.1.2 && sh tools/make-package-macosx
167167+168168+clean-macosx:
169169+ sudo rm -rf package-macosx
+79
vendor/opam/ocamlfind/Makefile.config.pattern
···11+# You can manually set up your configuration using this
22+# pattern. The final name of the file must be "Makefile.config".
33+# Note that there are other files containing parts of the
44+# configuration, especially the site-lib/*/META files.
55+#
66+#----------------------------------------------------------------------
77+# Where the OCAML core is installed:
88+#----------------------------------------------------------------------
99+OCAML_CORE_STDLIB=/usr/local/lib/ocaml
1010+OCAML_CORE_BIN=/usr/local/bin
1111+OCAML_CORE_MAN=/usr/local/man
1212+1313+#----------------------------------------------------------------------
1414+# Type of multi-threading support: either vm or posix
1515+# (Note: Since OCaml 3.07, "posix" includes "vm", because a build
1616+# supporting posix also supports vm.)
1717+#----------------------------------------------------------------------
1818+OCAML_THREADS=vm
1919+#OCAML_THREADS=posix
2020+2121+#----------------------------------------------------------------------
2222+# Where the site-lib directory will be
2323+#----------------------------------------------------------------------
2424+OCAML_SITELIB=/usr/local/lib/ocaml/site-lib
2525+2626+#----------------------------------------------------------------------
2727+# What the path setting will be
2828+#----------------------------------------------------------------------
2929+FINDLIB_PATH=/usr/local/lib/ocaml/site-lib:/usr/local/lib/ocaml
3030+3131+#----------------------------------------------------------------------
3232+# Where binaries and manual pages will be installed
3333+#----------------------------------------------------------------------
3434+OCAMLFIND_BIN=/usr/local/bin
3535+OCAMLFIND_MAN=/usr/local/man
3636+3737+#----------------------------------------------------------------------
3838+# The absolute location of the configuration file
3939+#----------------------------------------------------------------------
4040+OCAMLFIND_CONF=/usr/local/etc/ocamlfind.conf
4141+4242+#----------------------------------------------------------------------
4343+# Autolinking is usually on
4444+#----------------------------------------------------------------------
4545+OCAML_AUTOLINK=true
4646+4747+#----------------------------------------------------------------------
4848+# Windows only: set this to .exe
4949+#----------------------------------------------------------------------
5050+EXEC_SUFFIX=
5151+5252+#----------------------------------------------------------------------
5353+# Windows MSVC port: set this to .lib
5454+#----------------------------------------------------------------------
5555+LIB_SUFFIX=.a
5656+5757+#----------------------------------------------------------------------
5858+# Which parts are to be built: findlib, findlib-toolbox (space-separated
5959+# list)
6060+#----------------------------------------------------------------------
6161+PARTS=findlib findlib-toolbox
6262+6363+#----------------------------------------------------------------------
6464+# Whether the "topfind" script is installed in $(OCAML_CORE_STDLIB):
6565+#----------------------------------------------------------------------
6666+INSTALL_TOPFIND=1
6767+6868+#----------------------------------------------------------------------
6969+# Whether the config and paths are looked up relative to the
7070+# installation
7171+#----------------------------------------------------------------------
7272+RELATIVE_PATHS=0
7373+RELATIVE_OCAML_SITELIB=$$PREFIX/lib
7474+7575+#----------------------------------------------------------------------
7676+# Whether make install should update Makefile.packages just before
7777+# running
7878+#----------------------------------------------------------------------
7979+CHECK_BEFORE_INSTALL=0
+11
vendor/opam/ocamlfind/README.md
···11+# Findlib
22+33+ - [Project page](http://projects.camlcity.org/projects/findlib.html)
44+ with links to download tarballs and documentation
55+66+ - [README.xml with changelog](doc/README.xml)
77+88+ - [Installation](INSTALL)
99+1010+ - [License](LICENSE)
1111+
+14
vendor/opam/ocamlfind/REVISIONS
···11+The following table shows which Subversion revision of the
22+repository corresponds with which released version of
33+findlib.
44+55+Released versions up to 0.9 are checked in into CVS, and
66+not Subversion.
77+88+Released version = Subversion revision
99+----------------------------------------------------------------------
1010+1.0 54
1111+1.0.1 57
1212+1.0.2 63
1313+1.0.3 69
1414+1.0.4 72
+6
vendor/opam/ocamlfind/TODO
···11+Document archive(plugin)
22+33+Suggestion (gasche): -show-command only outputs the constructed
44+command, but does not run it.
55+66+Get ready for -ppx
+849
vendor/opam/ocamlfind/configure
···11+#! /bin/sh
22+# $Id$
33+# ----------------------------------------------------------------------
44+#
55+66+# Some functions
77+88+#set -x
99+1010+version="$(sed -ne 's/^version: *"\(.*\)\.git".*/\1/p' opam)"
1111+1212+if test -z "$version"; then
1313+ echo "Internal error: failed to parse version number from opam file" 1>&2
1414+ exit 1
1515+fi
1616+1717+# Remember the old IFS value:
1818+oldifs="$IFS"
1919+2020+2121+in_path () {
2222+ # Does $1 exist in $PATH?
2323+ IFS=":"
2424+ for d in $PATH; do
2525+ if test -x "$d/$1"; then
2626+ IFS="$oldifs"
2727+ return 0
2828+ fi
2929+ done
3030+ IFS="$oldifs"
3131+ return 1
3232+#--- The following is not portable enough:
3333+# if test -x `type -p ls`; then
3434+# # type -p works!
3535+# type -p $1 >/dev/null
3636+# else
3737+# # use 'which' instead
3838+# p=`which $1`
3939+# test -x "$p"
4040+# fi
4141+}
4242+4343+4444+get_path () {
4545+ IFS=":"
4646+ for d in $PATH; do
4747+ if test -x "$d/$1"; then
4848+ IFS="$oldifs"
4949+ echo "$d/$1"
5050+ return
5151+ fi
5252+ done
5353+ IFS="$oldifs"
5454+#--- The following is not portable enough:
5555+# if test -x `type -p ls`; then
5656+# # type -p works!
5757+# type -p $1
5858+# else
5959+# # use 'which' instead
6060+# p=`which $1`
6161+# test -x "$p" && echo $p
6262+# fi
6363+}
6464+6565+6666+get_stdlib () {
6767+ # Older versions of ocamlc do not accept -where, so there is a fallback
6868+ # method:
6969+ ocamlc -where 2>/dev/null | tr -d '\r' || {
7070+ ocamlc -v | sed -n -e "/Standard library directory/s/.*: \(.*\)/\1/p"; }
7171+}
7272+7373+7474+get_lib () {
7575+ # $1: name of a library to search for
7676+ # $2...: places to test
7777+ libname="$1"
7878+ while [ "$#" != "0" ]; do
7979+ if [ -f "$1/lib${libname}.so" ] || [ -f "$1/lib${libname}.a" ]; then
8080+ echo "$1"
8181+ return 0
8282+ fi
8383+ shift
8484+ done
8585+ return 1
8686+}
8787+8888+8989+get_lib_file () {
9090+ # $1: name of library without "lib" and suffix
9191+ # $2: directory
9292+ # returns full path of library
9393+ if [ -f "$2/lib$1.so" ]; then
9494+ echo "$2/lib$1.so"
9595+ elif [ -f "$2/lib$1.a" ]; then
9696+ echo "$2/lib$1.a"
9797+ else
9898+ echo ""
9999+ fi
100100+}
101101+102102+103103+cygpath_to_unix () {
104104+ v=$1
105105+ eval "p=\"\$$v\""
106106+ p="$(cygpath -w -s "$p")"
107107+ p="$(cygpath -u "$p")"
108108+ eval "$v=\"$p\""
109109+}
110110+111111+112112+######################################################################
113113+# Here the main program begins:
114114+115115+######################################################################
116116+# Interpret the command line
117117+118118+ocamlfind_bin=""
119119+ocamlfind_man=""
120120+ocaml_sitelib=""
121121+ocamlfind_config=""
122122+with_toolbox=0
123123+with_topfind=1
124124+with_camlp4=1
125125+with_relative_paths=0
126126+custom=-custom
127127+system=""
128128+sh=""
129129+130130+while [ "$#" != "0" ]; do
131131+ case "$1" in
132132+ -bindir) ocamlfind_bin=$2
133133+ shift 2
134134+ ;;
135135+ -mandir) ocamlfind_man=$2
136136+ shift 2
137137+ ;;
138138+ -sitelib) ocaml_sitelib=$2
139139+ shift 2
140140+ ;;
141141+ -config) ocamlfind_config=$2
142142+ with_relative_paths=0
143143+ shift 2
144144+ ;;
145145+ -no-custom) custom=
146146+ shift
147147+ ;;
148148+ -cygpath) system=mingw
149149+ shift
150150+ ;;
151151+ -system) system=$2
152152+ shift 2
153153+ ;;
154154+ -with-toolbox) with_toolbox=1
155155+ shift
156156+ ;;
157157+ -with-relative-paths-at) with_relative_paths=1
158158+ ocaml_prefix=$2
159159+ shift 2
160160+ ;;
161161+ -no-topfind) with_topfind=0
162162+ shift
163163+ ;;
164164+ -no-camlp4) with_camlp4=0
165165+ shift
166166+ ;;
167167+ -version)
168168+ echo "$version"
169169+ exit 0
170170+ ;;
171171+ -h|-help|--help) echo "usage: configure [options]" 1>&2
172172+ echo " -bindir path where binaries are installed" 1>&2
173173+ echo " -mandir path where manual pages are installed" 1>&2
174174+ echo " -sitelib path set the location of the site-specific packages" 1>&2
175175+ echo " -config path set the location of the configuration file" 1>&2
176176+ echo " -no-custom don't link in custom runtime mode" 1>&2
177177+ echo " -system <systype> override system type (esp. mingw and win32)" 1>&2
178178+ echo " -with-toolbox also build the toolbox" 1>&2
179179+ echo " -with-relative-paths-at path load configuration relative to the installation path" 1>&2
180180+ echo " -no-topfind don't install topfind script into stdlib directory" 1>&2
181181+ echo " -no-camlp4 don't install the camlp4 META file" 1>&2
182182+ exit
183183+ ;;
184184+ *) echo "configure: run 'configure -h' to get help" 1>&2
185185+ exit 1
186186+ ;;
187187+ esac
188188+done
189189+190190+echo "Welcome to findlib version $version"
191191+echo "Configuring core..."
192192+193193+194194+#######################################################################
195195+# inspect the system
196196+197197+# Some standard Unix tools must be available:
198198+199199+for tool in sed ocaml ocamlc uname rm make cat dirname basename; do
200200+ if in_path $tool; then true; else
201201+ echo "configure: $tool not in PATH; this is required" 1>&2
202202+ exit 1
203203+ fi
204204+done
205205+206206+lib_suffix=$(ocamlc -config 2>/dev/null | tr -d '\r' | sed -n -e 's/^ext_lib: //p')
207207+208208+# Check for Cygwin:
209209+210210+exec_suffix=
211211+pure_mingw="no"
212212+mingw_lib=
213213+case $(uname) in
214214+ CYGWIN*)
215215+ exec_suffix=.exe
216216+ echo "Cygwin build environment found; using .exe as suffix for binaries"
217217+ ;;
218218+ MSYS_NT*)
219219+ exec_suffix=.exe
220220+ echo "MSYS_NT build environment found; using .exe as suffix for binaries"
221221+ ;;
222222+ MINGW*)
223223+ exec_suffix=.exe
224224+ pure_mingw="yes"
225225+ echo "MinGW build environment found; using .exe as suffix for binaries"
226226+ mingw_lib=$(get_path gcc)
227227+ mingw_lib=$(dirname "$mingw_lib")/../lib
228228+ ;;
229229+ *)
230230+ true ;;
231231+esac
232232+233233+######################################################################
234234+# Is the target Win32?
235235+236236+use_cygpath=0
237237+# Whether we have to translate Unix paths to/from Windows paths.
238238+239239+if [ -z "$system" ]; then
240240+ system=$(ocamlc -config 2>/dev/null | tr -d '\r' | sed -n -e 's/^system: //p')
241241+ # This may be
242242+ # - mingw or mingw64
243243+ # - win32
244244+ # - win64
245245+ # - cygwin
246246+ # - some other string means Unix
247247+ # - empty means ocamlc does not support -config
248248+fi
249249+250250+path_sep=':'
251251+case "$system" in
252252+ mingw|mingw64)
253253+ if [ "$pure_mingw" = "no" ]; then
254254+ # CYGWIN
255255+ use_cygpath=1
256256+ fi
257257+ ;;
258258+ win32) use_cygpath=1;;
259259+ win64) use_cygpath=1;;
260260+ # A quirk of history means OCAMLPATH uses ; on Cygwin
261261+ cygwin) path_sep=';';;
262262+esac
263263+264264+######################################################################
265265+# check for presence of /bin/sh
266266+267267+if [ ! -f /bin/sh ]; then
268268+ sh="sh"
269269+fi
270270+271271+######################################################################
272272+# Find out standard library location
273273+274274+ocaml_core_stdlib=$(get_stdlib)
275275+ocaml_major="$(ocamlc -vnum 2>/dev/null | cut -f1 -d.)"
276276+if [ ! -d "$ocaml_core_stdlib" ]; then
277277+ echo "configure: cannot determine ocaml's standard library directory" 1>&2
278278+ exit 1
279279+fi
280280+if [ -z "$ocaml_major" ]; then ocaml_major=3; fi
281281+282282+if [ ${use_cygpath} -gt 0 ]; then
283283+ cygpath_to_unix ocaml_core_stdlib
284284+ # This makes ocaml_core_stdlib a Unix-type path
285285+fi
286286+287287+# Set site-lib directory:
288288+289289+if [ -z "$ocaml_sitelib" ]; then
290290+ case "$ocaml_core_stdlib" in
291291+ /opt/*) ocaml_sitelib=$(dirname "${ocaml_core_stdlib}")/site-lib
292292+ ;;
293293+ *) ocaml_sitelib="${ocaml_core_stdlib}/site-lib"
294294+ ;;
295295+ esac
296296+fi
297297+298298+ocamlpath="${ocaml_sitelib}"
299299+if [ ${use_cygpath} -gt 0 ]; then
300300+ cygpath_to_unix ocamlpath
301301+fi
302302+if [ "$ocaml_major" -ge 5 ]; then
303303+ # OCaml 5.0+ installs its own META files under the stdlib directory.
304304+ # If findlib has been configured -sitelib $(ocamlc -where) then there's
305305+ # nothing to do, but otherwise we need to put OCaml's Standard Library
306306+ # into the path setting.
307307+ if [ ! -e "${ocaml_sitelib}/stdlib.cmi" ]; then
308308+ ocamlpath="${ocaml_core_stdlib}${path_sep}${ocamlpath}"
309309+ fi
310310+fi
311311+312312+# Find out the directory where ocamlc is:
313313+314314+ocamlc=$(get_path ocamlc)
315315+ocaml_core_bin=$(dirname "${ocamlc}")
316316+317317+# Set the directory of ocamlfind:
318318+319319+test -n "$ocamlfind_bin" || ocamlfind_bin="$ocaml_core_bin"
320320+321321+# Find the directory for the manual:
322322+323323+# Fallback:
324324+ocaml_core_man=/usr/local/man
325325+326326+d="$ocaml_core_bin"
327327+while [ "$d" != '/' ]; do
328328+ f=0
329329+ if [ -d "$d/man/man1" ]; then
330330+ if [ -f "$d/man/man1/ocamlc.1" ] ||
331331+ [ -f "$d/man/man1/ocamlc.1.gz" ] ||
332332+ [ -f "$d/man/man1/ocamlc.1.Z" ]; then
333333+ f=1
334334+ fi
335335+ else
336336+ if [ -d "$d/man/mann" ]; then
337337+ if [ -f "$d/man/mann/ocamlc.n" ] ||
338338+ [ -f "$d/man/mann/ocamlc.n.gz" ] ||
339339+ [ -f "$d/man/mann/ocamlc.n.Z" ]; then
340340+ f=1
341341+ fi
342342+ fi
343343+ fi
344344+ if [ "$f" = "1" ]; then
345345+ ocaml_core_man="$d/man"
346346+ d="/"
347347+ else
348348+ d=$(dirname "$d")
349349+ fi
350350+done
351351+352352+# Set the directory for ocamlfind's manuals:
353353+354354+test -n "$ocamlfind_man" || ocamlfind_man="$ocaml_core_man"
355355+356356+# Guess the right directory for the configuration file:
357357+358358+if [ -z "${ocamlfind_config}" ]; then
359359+ d="$ocaml_core_bin"
360360+ case "$d" in
361361+ */bin)
362362+ if [ -f "$(dirname "$d")/lib/findlib.conf" ]; then
363363+ ocamlfind_config="$(dirname "$d")/lib/findlib.conf"
364364+ else
365365+ ocamlfind_config="$(dirname "$d")/etc/findlib.conf"
366366+ fi
367367+ ;;
368368+ *)
369369+ ocamlfind_config=/usr/local/etc/findlib.conf
370370+ # Fallback value
371371+ ;;
372372+ esac
373373+fi
374374+375375+######################################################################
376376+# do we have #remove_directory?
377377+378378+echo "Checking for #remove_directory..."
379379+have_remdir=1
380380+ocaml itest-aux/remdir.ml >/dev/null 2>/dev/null || have_remdir=0
381381+382382+######################################################################
383383+# Test the threading model
384384+385385+echo "Testing threading model..."
386386+387387+if ocamlc -vmthread >/dev/null 2>/dev/null; then
388388+ ocaml_threads="vm"
389389+else
390390+ ocaml_threads="none"
391391+fi
392392+393393+if ocamlc -config >/dev/null 2>/dev/null; then
394394+ # Good. ocamlc tells us the threading model.
395395+ if ocamlc -config | grep 'systhread_supported: true'; then
396396+ ocaml_threads="posix"
397397+ fi
398398+else
399399+ # Old ocamlc do not have -config.
400400+ rm -f itest-aux/simple
401401+ ocamlc -w a -custom -thread -o itest-aux/simple -I +unix unix.cma threads.cma itest-aux/simple_threads.ml \
402402+ >itest-aux/err.out 2>&1
403403+ output=$(cat itest-aux/err.out)
404404+405405+ if [ -z "$output" ]; then
406406+ ocaml_threads="posix"
407407+ fi
408408+fi
409409+410410+######################################################################
411411+# Does this version of OCaml support autolinking?
412412+413413+# Works for OCaml >= 3.00 on. Because findlib can only be compiled
414414+# with these OCaml versions, we can safely assume that autolinking
415415+# is enabled.
416416+417417+ocaml_autolink="true"
418418+419419+######################################################################
420420+# Does this version of OCaml support DLLs?
421421+422422+echo "Testing DLLs..."
423423+424424+have_dlls="yes"
425425+426426+ocaml -I +unix unix.cma itest-aux/simple.ml >/dev/null || have_dlls="no"
427427+428428+######################################################################
429429+# Does this version of OCaml support extension points?
430430+431431+echo "Testing whether ppxopt can be supported..."
432432+433433+with_ppxopt=1
434434+enable_topfind_ppxopt=true
435435+436436+ocaml -I +compiler-libs itest-aux/ppx.ml >/dev/null || {
437437+ with_ppxopt=0
438438+ enable_topfind_ppxopt=false
439439+}
440440+441441+######################################################################
442442+# Check for -opaque
443443+444444+echo "Checking for ocamlc -opaque..."
445445+446446+opaque="-opaque"
447447+ocamlc -opaque -version >/dev/null 2>/dev/null || opaque=""
448448+449449+######################################################################
450450+# Check for ocamlopt -g
451451+452452+echo "Checking for ocamlopt -g..."
453453+454454+native_debugging_info="-g"
455455+ocamlopt -g -version >/dev/null 2>/dev/null || native_debugging_info=""
456456+457457+######################################################################
458458+# Configure libraries
459459+460460+check_before_install=0
461461+findlib_installed_meta=''
462462+if [ -d "${ocaml_sitelib}" ] && [ "${ocaml_major}" -lt 5 ]; then
463463+ previous_config="${ocaml_sitelib}/findlib/Makefile.packages"
464464+ if [ -f "${previous_config}" ]; then
465465+ echo "Querying installation: found list of findlib-generated META files"
466466+ eval "$(sed -ne 's/ /,/g' -e 's/^SITELIB_META,*=,*\([^,].*[^,]\),*/findlib_installed_meta="\1"/p' "$previous_config")"
467467+ echo "Installation has: $findlib_installed_meta"
468468+ else
469469+ previous_config=''
470470+ check_before_install=1
471471+ echo "Querying installation: META list not found"
472472+ echo "make install will double-check installed META files"
473473+ fi
474474+else
475475+ previous_config=''
476476+fi
477477+478478+echo "Configuring libraries..."
479479+480480+# Only succeeds if ${ocaml_sitelib}/$1/META exists and we're **certain**
481481+# it wasn't installed by a previous findlib installation.
482482+is_third_party_META () {
483483+ if [ $check_before_install -eq 0 ]; then
484484+ if [ -f "${ocaml_sitelib}/$1/META" ]; then
485485+ case ",$findlib_installed_meta," in
486486+ *,$1,*)
487487+ return 1;;
488488+ *)
489489+ return 0;;
490490+ esac
491491+ else
492492+ return 1
493493+ fi
494494+ else
495495+ return 1
496496+ fi
497497+}
498498+499499+check_library () {
500500+ if is_third_party_META "$1"; then
501501+ echo "$1: package already present"
502502+ # Library is present - exit code is 0 because the library is found
503503+ # (e.g. detection for Unix) but we don't actually add it to the
504504+ # generated_META list.
505505+ package_dir="${ocaml_sitelib}/$1"
506506+ package_subdir="$1"
507507+ package_key="$(echo "$1" | tr - _)"
508508+ eval "${package_key}_dir=\"${package_dir}\""
509509+ eval "${package_key}_subdir=\"${package_subdir}\""
510510+ return 0
511511+ fi
512512+513513+ if [ -z "$3" ]; then
514514+ check_library "$1" "$2" "$1.cmi"
515515+ return $?
516516+ fi
517517+518518+ package="$1"
519519+ if [ -z "$2" ]; then
520520+ msg=''
521521+ else
522522+ msg=" ($2)"
523523+ fi
524524+525525+ shift 2
526526+ for file; do
527527+ if [ -e "${ocaml_core_stdlib}/${file}" ]; then
528528+ package_dir="$(dirname "${file}")"
529529+ if [ "${package_dir}" = '.' ]; then
530530+ echo "${package}: found"
531531+ package_subdir='.'
532532+ package_dir='^'
533533+ else
534534+ package_subdir="${package_dir}"
535535+ package_dir="+${package_dir}"
536536+ echo "${package}: found (in ${package_dir})"
537537+ fi
538538+ package_key="$(echo "${package}" | tr - _)"
539539+ eval "${package_key}_dir=\"${package_dir}\""
540540+ eval "${package_key}_subdir=\"${package_subdir}\""
541541+ if [ "${ocaml_major}" -ge 5 ]; then
542542+ return 0
543543+ fi
544544+ if [ "$package" = 'num' ]; then
545545+ generated_META="${generated_META} num num-top"
546546+ numtop='num-top'
547547+ else
548548+ generated_META="${generated_META} ${package}"
549549+ fi
550550+ return 0
551551+ fi
552552+ done
553553+554554+ echo "$package: not present${msg}"
555555+ return 1
556556+}
557557+558558+if [ "${ocaml_major}" -ge 5 ]; then
559559+ generated_META=''
560560+else
561561+ generated_META='stdlib'
562562+fi
563563+numtop=''
564564+565565+if ! check_library unix 'possible since 4.08' unix/unix.cmi unix.cmi; then
566566+ echo "configure: ocamlfind requires OCaml's Unix library" 1>&2
567567+ exit 1
568568+fi
569569+570570+check_library dynlink '' dynlink/dynlink.cmi dynlink.cmi
571571+check_library bigarray 'possible since 4.08'
572572+check_library compiler-libs '' 'compiler-libs'
573573+check_library dbm 'normal since 4.00'
574574+check_library graphics 'normal since 4.09'
575575+check_library num 'normal since 4.06'
576576+check_library ocamlbuild 'normal since 4.03' ocamlbuild/ocamlbuildlib.cma
577577+check_library ocamldoc '' ocamldoc/odoc.cmi
578578+check_library raw_spacetime 'normal since 4.12' raw_spacetime_lib.cmxa
579579+check_library threads '' threads/thread.cmi vmthreads/thread.cmi;
580580+581581+# Need to know if str and labltk are available for the toolbox
582582+if check_library str 'possible since 4.08' str/str.cmi str.cmi; then
583583+ have_str=1
584584+else
585585+ have_str=0
586586+fi
587587+588588+if check_library labltk 'normal since 4.02' labltk/labltk.cma; then
589589+ have_labltk=1
590590+else
591591+ have_labltk=0
592592+fi
593593+594594+# Dynlink check.
595595+596596+have_natdynlink=0
597597+natdynlink=""
598598+camlp4_dynlink=""
599599+if [ -f "${ocaml_core_stdlib}/${dynlink_subdir:?}/dynlink.cmxa" ]; then
600600+ have_natdynlink=1
601601+ natdynlink="archive(native) = \"dynlink.cmxa\""
602602+ camlp4_dynlink="dynlink"
603603+ echo "native dynlink: found"
604604+else
605605+ natdynlink="archive(native) = \"\""
606606+ echo "native dynlink: not found"
607607+fi
608608+609609+# Check on camlp4:
610610+611611+if [ $with_camlp4 -eq 0 ]; then
612612+ echo "camlp4: disabled"
613613+else
614614+ if in_path camlp4; then
615615+ if is_third_party_META camlp4; then
616616+ echo "camlp4: third-party"
617617+ fi
618618+ camlp4_dir=$(camlp4 -where | tr -d '\r')
619619+ if [ ${use_cygpath} -gt 0 ]; then
620620+ camlp4_dir=$(echo x | env USE_CYGPATH=1 tools/patch x "$camlp4_dir")
621621+ # This makes camlp4_dir a windows path
622622+ elif [ "${pure_mingw}" = "yes" ]; then
623623+ # Must double the backslahes
624624+ camlp4_dir="$(echo "${camlp4_dir}" | sed -e 's;\\;\\\\;g')"
625625+ fi
626626+ camlp4_version=$(camlp4 -v 2>&1)
627627+ if [ "$have_dlls" = "yes" ]; then
628628+ camlp4_cmd="camlp4"
629629+ else
630630+ camlp4_cmd="safe_camlp4"
631631+ fi
632632+ # Check whether 3.09 or 3.10 style:
633633+ if camlp4 -loaded-modules >/dev/null 2>/dev/null; then
634634+ camlp4style=310
635635+ else
636636+ camlp4style=309
637637+ fi
638638+ generated_META="${generated_META} camlp4"
639639+ rm -rf "site-lib-src/camlp4"
640640+ mkdir "site-lib-src/camlp4"
641641+ cp "site-lib-src/camlp4.$camlp4style/META.in" "site-lib-src/camlp4/"
642642+ echo "camlp4: using $camlp4_cmd, style $camlp4style"
643643+ else
644644+ with_camlp4=0
645645+ echo "camlp4: not present (normal since OCaml-4.02)"
646646+ fi
647647+fi
648648+649649+# bytes?
650650+# (NB. This is always ours, and it doesn't go into generated_META)
651651+652652+req_bytes=""
653653+if [ -f "${ocaml_core_stdlib}/bytes.cmi" ] ||
654654+ [ -f "${ocaml_core_stdlib}/stdlib__bytes.cmi" ] ||
655655+ [ -f "${ocaml_core_stdlib}/stdlib__Bytes.cmi" ]; then
656656+ echo "bytes: found, installing fake library"
657657+ lbytes="bytes"
658658+ cbytes=0
659659+else
660660+ echo "bytes: not found, installing compat library"
661661+ lbytes=""
662662+ req_bytes="bytes"
663663+ cbytes=1
664664+fi
665665+666666+667667+if [ $with_toolbox -gt 0 ]; then
668668+ if [ $have_str -eq 0 ] || [ $have_labltk -eq 0 ]; then
669669+ echo "Sorry, toolbox requires str and labltk - omitting toolbox."
670670+ with_toolbox=0
671671+ fi
672672+fi
673673+674674+# Generate the META files now.
675675+676676+for dir in site-lib-src/*; do
677677+ # We do not really know if $dir is a directory.
678678+ rm -f "$dir"/META
679679+done
680680+681681+for lib in $generated_META $lbytes; do
682682+ if=""
683683+ if [ -f site-lib-src/"$lib"/interfaces.out ]; then
684684+ if=$(cat site-lib-src/"$lib"/interfaces.out)
685685+ fi
686686+ sed \
687687+ -e "s|%%type_of_threads%%|${ocaml_threads}|g" \
688688+ -e "s|%%camlp4_dir%%|${camlp4_dir}|g" \
689689+ -e "s|%%camlp4_version%%|${camlp4_version}|g" \
690690+ -e "s|%%camlp4_cmd%%|${camlp4_cmd}|g" \
691691+ -e "s|%%camlp4_dynlink%%|${camlp4_dynlink}|g" \
692692+ -e "s|%%interfaces%%|${if}|g" \
693693+ -e "s|%%findlib_version%%|${version}|g" \
694694+ -e "s|%%natdynlink%%|${natdynlink}|g" \
695695+ -e "s|%%dynlink_dir%%|${dynlink_dir:?}|g" \
696696+ -e "s|%%unix_dir%%|${unix_dir:?}|g" \
697697+ -e "s|%%str_dir%%|${str_dir:?}|g" \
698698+ site-lib-src/"$lib"/META.in > site-lib-src/"$lib"/META
699699+700700+ echo "Configuration for $lib written to site-lib-src/$lib/META"
701701+done
702702+703703+# create META from META.in in POSIX-compatible & safe way
704704+# see: https://www.shellcheck.net/wiki/SC2044
705705+meta_subst="sed -e 's/@VERSION@/$version/g' \
706706+ -e 's/@REQUIRES@/${req_bytes}/g' \
707707+ \"\$1\" > \"\${1%.in}\""
708708+find src -name 'META.in' -type f -exec sh -c "$meta_subst" sh {} \;
709709+710710+######################################################################
711711+712712+printf "Detecting compiler arguments: "
713713+714714+if make -C tools/extract_args >ocargs.log 2>&1; then
715715+ printf "(extractor built) "
716716+ # ocamlbrowser does not work!
717717+ if tools/extract_args/extract_args -o src/findlib/ocaml_args.ml ocamlc ocamlcp ocamloptp ocamlmklib ocamlmktop ocamlopt ocamldep ocamldoc >>ocargs.log 2>&1; then
718718+ echo "ok"
719719+ else
720720+ echo "FAILED (see the file ocargs.log for details)"
721721+ exit 1
722722+ fi
723723+else
724724+ echo "FAILED (see the file ocargs.log for details)"
725725+ exit 1
726726+fi
727727+728728+######################################################################
729729+# Write Makefile.config
730730+731731+parts="findlib"
732732+ocamlfind_ocamlflags="-I +unix -I +dynlink"
733733+ocamlfind_archives="findlib.cma unix.cma"
734734+if [ $with_toolbox -gt 0 ]; then
735735+ parts="$parts findlib-toolbox"
736736+fi
737737+if [ $cbytes -gt 0 ]; then
738738+ # bytes first, because findlib needs it
739739+ parts="bytes $parts"
740740+ ocamlfind_ocamlflags="${ocamlfind_ocamlflags} -I ../bytes"
741741+ ocamlfind_archives="bytes.cma ${ocamlfind_archives}"
742742+fi
743743+744744+relative_site_lib=$(echo "${ocaml_sitelib}" | sed -e "s#^${ocaml_prefix}#\$PREFIX#")
745745+746746+if [ $with_relative_paths -gt 0 ]; then
747747+ # if configured with relative paths we add the relative path to the search path
748748+ relative_paths="true"
749749+ ocamlpath="${relative_site_lib}${path_sep}${ocamlpath}"
750750+else
751751+ relative_paths="false"
752752+fi
753753+754754+{
755755+ echo "# Makefile.config written by configure"
756756+ echo "OCAML_CORE_STDLIB=${ocaml_core_stdlib}"
757757+ echo "OCAML_CORE_BIN=${ocaml_core_bin}"
758758+ echo "OCAML_CORE_MAN=${ocaml_core_man}"
759759+ echo "OCAML_SITELIB=${ocaml_sitelib}"
760760+ echo "FINDLIB_PATH=${ocamlpath}"
761761+ echo "OCAML_THREADS=${ocaml_threads}"
762762+ echo "OCAMLFIND_BIN=${ocamlfind_bin}"
763763+ echo "OCAMLFIND_MAN=${ocamlfind_man}"
764764+ echo "OCAMLFIND_CONF=${ocamlfind_config}"
765765+ echo "OCAMLFIND_OCAMLFLAGS=${ocamlfind_ocamlflags}"
766766+ echo "OCAMLFIND_ARCHIVES=${ocamlfind_archives}"
767767+ echo "OCAML_AUTOLINK=${ocaml_autolink}"
768768+ echo "OCAML_REMOVE_DIRECTORY=${have_remdir}"
769769+ echo "EXEC_SUFFIX=${exec_suffix}"
770770+ echo "LIB_SUFFIX=${lib_suffix}"
771771+ echo "CUSTOM=${custom}"
772772+ echo "PARTS=${parts}"
773773+ echo "INSTALL_TOPFIND=${with_topfind}"
774774+ echo "RELATIVE_PATHS=${relative_paths}"
775775+ echo "RELATIVE_OCAML_SITELIB=${relative_site_lib}" | sed -e "s/\\\$/\$\$/"
776776+ echo "USE_CYGPATH=${use_cygpath}"
777777+ echo "HAVE_NATDYNLINK=${have_natdynlink}"
778778+ echo "VERSION=${version}"
779779+ echo "ENABLE_TOPFIND_PPXOPT=${enable_topfind_ppxopt}"
780780+ echo "SYSTEM=${system}"
781781+ echo "NUMTOP=${numtop}"
782782+ echo "SH=${sh}"
783783+ if [ "$mingw_lib" != "" ]; then
784784+ echo "OCAMLC_FLAGS=-I \"${mingw_lib}\""
785785+ echo "OCAMLOPT_FLAGS=-I \"${mingw_lib}\""
786786+ fi
787787+ echo "OPAQUE=${opaque}"
788788+ echo "OCAMLOPT_G=${native_debugging_info}"
789789+ echo "CHECK_BEFORE_INSTALL=${check_before_install}"
790790+ echo "CP = cp"
791791+ echo "INSTALLDIR = install -d"
792792+ echo "# change to INSTALLDIR = mkdir -p when BSD install is unavavailable"
793793+ echo "INSTALLFILE = install -c"
794794+ echo "# change to INSTALLFILE = cp when BSD install is unavailable"
795795+} > Makefile.config
796796+797797+echo "SITELIB_META=${generated_META}" >Makefile.packages
798798+799799+# All OK
800800+801801+echo
802802+echo "About the OCAML core installation:"
803803+echo " Standard library: ${ocaml_core_stdlib}"
804804+echo " Binaries: ${ocaml_core_bin}"
805805+echo " Manual pages: ${ocaml_core_man}"
806806+echo " Multi-threading type: ${ocaml_threads}"
807807+echo "The directory of site-specific packages will be"
808808+echo " site-lib: ${ocaml_sitelib}"
809809+echo "The configuration file is written to:"
810810+echo " findlib config file: ${ocamlfind_config}"
811811+echo "Software will be installed:"
812812+echo " Libraries: in <site-lib>/findlib"
813813+echo " Binaries: ${ocamlfind_bin}"
814814+echo " Manual pages: ${ocamlfind_man}"
815815+if [ $with_topfind -gt 0 ]; then
816816+ echo " topfind script: ${ocaml_core_stdlib}"
817817+else
818818+ echo " topfind script: omitted"
819819+fi
820820+821821+if [ $with_ppxopt -gt 0 ]; then
822822+ echo "Topfind ppxopt support: yes"
823823+else
824824+ echo "Topfind ppxopt support: no"
825825+fi
826826+827827+if [ $with_toolbox -gt 0 ]; then
828828+ echo "Toolbox: yes"
829829+else
830830+ echo "Toolbox: no"
831831+fi
832832+833833+if [ -z "$custom" ]; then
834834+ echo "Link custom runtime: no"
835835+else
836836+ echo "Link custom runtime: yes"
837837+fi
838838+839839+if [ $cbytes -gt 0 ]; then
840840+ echo "Need bytes compatibility: yes"
841841+else
842842+ echo "Need bytes compatibility: no"
843843+fi
844844+845845+echo
846846+echo "Configuration has been written to Makefile.config"
847847+echo
848848+echo "You can now do 'make all', and optionally 'make opt', to build ocamlfind."
849849+
+15
vendor/opam/ocamlfind/doc/DOCINFO
···11+To build the html and manual pages from the SGML sources, you need the
22+following tools:
33+44+- The DocBook DTD
55+ (http://www.davenport.com)
66+- James Clark's SGML tools (jade, sx suffice)
77+ (http://www.jclark.com)
88+- Normal Walsh's DSSSL stylesheets to make the HTML pages
99+ (http://nwalsh.com/docbook/dsssl)
1010+- My db2man tool to make the manual pages
1111+ (http://www.ocaml-programming.de/packages)
1212+1313+The latter also requires Christian Lindig's XML parser
1414+(//http://www.cs.tu-bs.de/softech/people/lindig/software/tony.html).
1515+
···11+<?xml version="1.0" encoding="ISO-8859-1"?>
22+<!DOCTYPE readme SYSTEM "readme.dtd" [
33+44+<!ENTITY % common SYSTEM "common.xml">
55+%common;
66+77+<!-- Special HTML config: -->
88+<!ENTITY % readme:html:up '<a href="../..">up</a>'>
99+1010+<!ENTITY % config SYSTEM "config.xml">
1111+%config;
1212+1313+]>
1414+1515+<readme title="QUICKSTART - The most important ways to use findlib">
1616+ <sect1>
1717+ <title>Intro</title>
1818+ <p>See the file INSTALL for instructions how to build and install
1919+findlib.</p>
2020+ </sect1>
2121+2222+ <sect1>
2323+ <title>Findlib and the toploop</title>
2424+2525+<p>For a number of platforms, OCaml can load bytecode-compiled
2626+libraries dynamically. For these platforms, findlib is very simple to
2727+use as explained in the following. For other platforms, see the paragraph
2828+below about "custom toploops".</p>
2929+3030+ <p>After the toploop has been started, it is possible to load the special
3131+findlib support:<footnote>In previous versions, #use "findlib" loaded the
3232+library. However, this caused a name conflict for a certain type of
3333+installation. Because of this, the name of the loader script has been changed
3434+to "topfind", but "findlib", and "ocamlfind" (Debian) are also available
3535+for backwards compatibility.</footnote>
3636+3737+<code>
3838+$ ocaml
3939+ Objective Caml version 3.07
4040+4141+# #use "topfind";;
4242+Findlib has been successfully loaded. Additional directives:
4343+ #require "package";; to load a package
4444+ #list;; to list the available packages
4545+ #camlp4o;; to load camlp4 (standard syntax)
4646+ #camlp4r;; to load camlp4 (revised syntax)
4747+ #predicates "p,q,...";; to set these predicates
4848+ Topfind.reset();; to force that packages will be reloaded
4949+ #thread;; to enable threads
5050+5151+- : unit = ()
5252+</code>
5353+5454+You can now list the available packages:
5555+5656+<code>
5757+# #list;;
5858+bigarray (version: [distributed with Ocaml])
5959+camlp4 (version: Camlp4 version 3.03 ALPHA)
6060+dbm (version: [distributed with Ocaml])
6161+dynlink (version: [distributed with Ocaml])
6262+findlib (version: 0.6)
6363+graphics (version: [distributed with Ocaml])
6464+labltk (version: [distributed with Ocaml])
6565+netstring (version: 0.10)
6666+num (version: [distributed with Ocaml])
6767+stdlib (version: [distributed with Ocaml])
6868+str (version: [distributed with Ocaml])
6969+threads (version: [distributed with Ocaml])
7070+unix (version: [distributed with Ocaml])
7171+xstrp4 (version: 1.1)
7272+</code>
7373+7474+and load packages by simply typing:
7575+7676+<code>
7777+# #require "netstring";;
7878+Loading /opt/ocaml/lib/unix.cma
7979+Loading /opt/ocaml/lib/str.cma
8080+Loading /opt/ocaml/site-lib/netstring/netstring.cma
8181+Loading /opt/ocaml/site-lib/netstring/netstring_top.cmo
8282+</code>
8383+8484+Findlib takes care to load packages that are required by loaded packages
8585+first. For example, "netstring" uses "unix" and "str" internally, but you
8686+do not need to load them because findlib does it for you. In this example
8787+you can also see that findlib loads netstring_top.cmo containing printers
8888+for the toploop.</p>
8989+9090+ <p>You can also enable the Camlp4 parsers by simply typing
9191+9292+<code>
9393+# #camlp4o;;
9494+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4o.cma
9595+ Camlp4 Parsing version 3.03 ALPHA
9696+</code>
9797+9898+for the standard syntax or
9999+100100+<code>
101101+# #camlp4r;;
102102+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4r.cma
103103+ Camlp4 Parsing version 3.03 ALPHA
104104+</code>
105105+106106+for the revised syntax. (But you cannot switch between the syntaxes.)
107107+</p>
108108+ </sect1>
109109+110110+ <sect1>
111111+ <title>Custom Toploops</title>
112112+113113+ <p>For some platforms, OCaml does not implement loading external
114114+libraries (e.g. Cygwin). One has to create a so-called custom toploop
115115+that statically links with these libraries. Example:
116116+117117+<code>
118118+$ ocamlfind ocamlmktop -o mytop -package findlib,unix -linkpkg
119119+$ ./mytop
120120+ Objective Caml version 3.07
121121+122122+# #use "topfind";;
123123+Findlib has been successfully loaded. Additional directives:
124124+ #require "package";; to load a package
125125+ #list;; to list the available packages
126126+ #camlp4o;; to load camlp4 (standard syntax)
127127+ #camlp4r;; to load camlp4 (revised syntax)
128128+ #predicates "p,q,...";; to set these predicates
129129+ Topfind.reset();; to force that packages will be reloaded
130130+ #thread;; to enable threads
131131+132132+- : unit = ()
133133+</code>
134134+135135+Now "#require" works for all libraries referring to the special "unix"
136136+functions.
137137+</p>
138138+ </sect1>
139139+140140+ <sect1>
141141+ <title>Findlib and scripts</title>
142142+143143+ <p>The #require directive can also be used in scripts. Example:
144144+145145+<code>
146146+#use "topfind";;
147147+#require "netstring";;
148148+149149+open Cgi;;
150150+...
151151+</code>
152152+153153+This makes it possible to write scripts that do not contain #directory
154154+directives that are specific for certain installations.</p>
155155+156156+ <p>For Unix environments, you can start scripts directly if you
157157+apply the following trick:
158158+159159+<code>
160160+#! /bin/sh
161161+# (*
162162+exec ocaml "$0" "$@"
163163+*) use "topfind";;
164164+#require "netstring";;
165165+166166+open Cgi;;
167167+...
168168+</code>
169169+170170+This works wherever OCaml is installed.</p>
171171+ </sect1>
172172+173173+ <sect1>
174174+ <title>Compiling programs</title>
175175+176176+ <p>Assumed you want to compile a program that uses the Netstring package.
177177+Do it the following way:
178178+179179+<code>
180180+$ ocamlfind ocamlc -package netstring -c myprogram.ml
181181+</code>
182182+183183+This way you do not need to add "-I" options to locate Netstring.</p>
184184+185185+ <p>If you want to create an executable, do not forget to add the
186186+-linkpkg switch:
187187+188188+<code>
189189+$ ocamlfind ocamlc -o myprogram -package netstring -linkpkg myprogram.cmo
190190+</code>
191191+192192+This switch causes that the mentioned packages are added to the resulting
193193+executable.</p>
194194+195195+ <p>If you want to include several packages, you can either add several
196196+"-package" options, or you can enumerate the packages separated by commas:
197197+-package netstring,labltk.</p>
198198+ </sect1>
199199+200200+ <sect1>
201201+ <title>Camlp4</title>
202202+203203+ <p>If you add a -syntax option, the compiler will be told to parse the
204204+source file using camlp4:
205205+206206+<code>
207207+$ ocamlfind ocamlc -package netstring -syntax camlp4o -c myprogram.ml
208208+</code>
209209+210210+Use -syntax camlp4o for the standard syntax or -syntax camlp4r for the
211211+revised syntax.</p>
212212+213213+ <p>Additionally, you can mention packages that add new syntax features.
214214+The package xstrp4 is an example of this:
215215+216216+<code>
217217+$ ocamlfind ocamlc -package xstrp4,netstring -syntax camlp4o -c myprogram.ml
218218+</code>
219219+220220+Now you can use the $ notation that is implemented by xstrp4 in the
221221+source file myprogram.ml.</p>
222222+223223+ <p>Note that you can also invoke ocamldep from ocamlfind:
224224+225225+<code>
226226+$ ocamlfind ocamldep -package xstrp4 -syntax camlp4o *.ml *.mli >.depend
227227+</code>
228228+229229+This enables the syntax extensions, too.</p>
230230+ </sect1>
231231+232232+ <sect1>
233233+ <title>ocamlbrowser</title>
234234+ <p>Since findlib-0.7, it is also possible to start ocamlbrowser from
235235+ocamlfind. For example,
236236+237237+<code>
238238+$ ocamlfind browser -package xstrp4
239239+</code>
240240+241241+adds the correct path specification such that the modules contained in the
242242+package xstrp4 are also displayed. With
243243+244244+<code>
245245+$ ocamlfind browser -all
246246+</code>
247247+248248+all package are added to the path spec.
249249+</p>
250250+ </sect1>
251251+252252+ <sect1>
253253+ <title>The Makefile wizard</title>
254254+ <p>There is a wizard that makes it very easy to write Makefiles. Call the
255255+wizard by
256256+<code>
257257+$ ocamlfind findlib/make_wizard
258258+</code>
259259+(the wizard requires that the labltk library is available). A new window
260260+pops up, and by very few clicks you can describe your own library. Finally,
261261+a Makefile is written.
262262+</p>
263263+ </sect1>
264264+265265+ <sect1>
266266+ <title>There is no magic!</title>
267267+268268+ <p>Findlib is neither a patch of OCaml nor uses it internal features of
269269+the OCaml programming environment. It is only a convention to install
270270+software components in filesystem hierarchies, a library interpreting
271271+this convention, and some frontend applications making the library usable for
272272+you.</p>
273273+274274+ <p>One important consequence is that you can only refer to those
275275+software components that have previously been installed in a way findlib
276276+understands. This convention is beyond the scope of this QUICKSTART guide,
277277+see the reference manual for details. You can always check whether findlib
278278+accepts a component as "findlib package" by the command
279279+280280+<code>
281281+$ ocamlfind list
282282+</code>
283283+284284+(this is the same as the #list directive in the toploop). If the package
285285+occurs in the list, it is found, otherwise not.</p>
286286+ </sect1>
287287+</readme>
288288+
+714
vendor/opam/ocamlfind/doc/README.xml
···11+<?xml version="1.0" encoding="UTF-8"?>
22+<!DOCTYPE readme SYSTEM "readme.dtd" [
33+44+<!ENTITY % common SYSTEM "common.xml">
55+%common;
66+77+<!-- Special HTML config: -->
88+<!ENTITY % readme:html:up '<a href="../..">up</a>'>
99+1010+<!ENTITY % config SYSTEM "config.xml">
1111+%config;
1212+1313+]>
1414+1515+<readme title="README - The findlib library manager">
1616+ <sect1>
1717+ <title>Introduction</title>
1818+1919+<p>The "findlib" software provides a scheme to manage reusable software
2020+components in the form of libraries, and includes tools that support
2121+this scheme. A library installed as a findlib component is also called
2222+a package. The point is that the findlib scheme allows it to store
2323+metainformation about the library, especially how it can be used in
2424+programs. The packages are kept in the filesystem hierarchy, but the
2525+directory structure is defined by findlib, and there is no way to
2626+deviate from this standard. The library contains functions to look the
2727+directory up that stores a package, to query metainformation about a
2828+package, and to retrieve dependency information about multiple
2929+packages. There is also a tool that allows the user to enter queries
3030+on the command-line. In order to simplify compilation and linkage,
3131+there are new frontends of the various OCaml compilers that can
3232+directly deal with packages.
3333+ </p>
3434+3535+ <p>It is important to understand that findlib is <em>not</em> a
3636+general-purpose package manager (like rpm for Linux), and does <em>not</em>
3737+support the management of arbitrary files, but only OCaml libraries.
3838+However, there are lots of special functions for libraries. findlib
3939+is more comparable with Gnome's pkg-config and Perl's MakeMaker, but
4040+of course there are language-specific differences.</p>
4141+4242+ <p>The metainformation includes:</p>
4343+4444+ <ul>
4545+ <li><p>The necessary command-line arguments to use a library.</p>
4646+ </li>
4747+ <li><p>Dependencies on other packages.</p>
4848+ </li>
4949+ <li><p>Version strings.</p>
5050+ </li>
5151+ </ul>
5252+5353+ <p>These data can be conditional. Possible conditions are certain
5454+environmental settings, such as whether the bytecode or the native code
5555+compiler is used, or whether the application is multi-threaded. It is
5656+also possible that a package behaves differently when a certain other
5757+package is selected.</p>
5858+5959+ <p>There is special support for scripts. It is possible to load
6060+libraries into toploops, including all dependent libraries, with only
6161+one command.</p>
6262+6363+ <p>Findlib has been developed since March 1999, and has matured
6464+for more than four years until the release of version 1.0. One of the
6565+important questions during this long period of development was which
6666+features are necessary and which not. The result is a utility that
6767+follows still simple concepts, but is flexible enough to allow even
6868+the description of complex libraries and complex interdependencies.
6969+ </p>
7070+ </sect1>
7171+7272+ <sect1>
7373+ <title>Documentation</title>
7474+7575+ <p>See the file QUICKSTART for the most important findlib commands.</p>
7676+7777+ <p>There is a User's Guide introducing into the concepts of findlib,
7878+especially explaining how to create packages.</p>
7979+8080+ <p>The Reference Manual describes commands, directory structure,
8181+configuration files, and library routines in detail.</p>
8282+ </sect1>
8383+8484+ <sect1>
8585+ <title>Installation</title>
8686+8787+ <p>See the file INSTALL.</p>
8888+ </sect1>
8989+9090+ <sect1>
9191+ <title>Download</title>
9292+ <p>
9393+ The current version is announced in the
9494+ <a href="&url.linkdb;">Objective Caml Link Database</a>.
9595+ </p>
9696+ </sect1>
9797+9898+ <sect1>
9999+ <title>Copyright and License Conditions</title>
100100+ <p>
101101+ Findlib is copyright 1999-2012 by Gerd Stolpmann. See the file LICENSE
102102+ for the MIT/X11 style license conditions.
103103+104104+ Contact me at gerd@gerd-stolpmann.de in case of questions.
105105+ </p>
106106+ </sect1>
107107+108108+ <sect1>
109109+ <title>List of Changes</title>
110110+ <ul>
111111+112112+ <li>
113113+ <p><em>1.9.8:</em>: A few build-related fixes.</p>
114114+ </li>
115115+116116+ <li>
117117+ <p><em>1.9.7:</em>: Allow overriding low-level module loader
118118+ in `Fl_dynload.load_packages`. This is very useful in JSOO
119119+ where we may want to implement a `.cma` -> `.js` cache instead
120120+ of calling `Dynlink.loadfile` dynamically. (Emilio J. Gallego
121121+ Arias).</p>
122122+ <p>Fix auto-detection of -opaque (Stephen Dolan)</p>
123123+ <p>Fix linking of threads.cmxa in OCaml-5.2 (David Allsopp)</p>
124124+ <p>Improved scripts (shellcheck) (Marek Kubica)</p>
125125+ <p>Support for relocatable installations (Marek Kubica)</p>
126126+ <p>Support OCAMLOPT_SHARED (Chen Qi)</p>
127127+ <p>Avoid exception for PATH containing "." (Dmetry Bely)</p>
128128+ <p>Fixes for Windows (David Allsopp)</p>
129129+ <p>Typos in documentation (Antonin Décimo)</p>
130130+ <p>Upgrade ocamlfind for OCaml-5 (David Allsopp)</p>
131131+ </li>
132132+133133+ <li>
134134+ <p><em>1.9.6:</em>: Support for OCaml-5 (as far as foreseeable)
135135+ (David Allsopp).</p>
136136+ <p>Again buildable since OCaml-3.08 (David Allsopp).</p>
137137+ <p>Fix an install problem when building with a system-provided
138138+ OCaml compiler (Louis Gesbert).</p>
139139+ </li>
140140+141141+ <li>
142142+ <p><em>1.9.5:</em>: fixes a bug in the scripting that
143143+ slipped into 1.9.4</p>
144144+ </li>
145145+146146+ <li>
147147+ <p><em>1.9.4:</em> Also finds the libraries str.cm(x)a, unix.cm(x)a,
148148+ and dynlink.cm(x)a in subdirectories of the OCaml standard library,
149149+ as needed for OCaml-4.14 (David Allsopp).</p>
150150+ <p>Support for runtime_events (Patrick Ferris)</p>
151151+ <p>Fix spelling of "OCaml" everywhere (Marek Kubica)</p>
152152+ <p>Work around the deprecation of a POSIX shell feature
153153+ (Issam Maghni)</p>
154154+ <p>Support DESTDIR, and favor the "install" command for installation
155155+ (Gerd Stolpmann on suggestion of Thomas Klausner)</p>
156156+ </li>
157157+158158+ <li><p><em>1.9.3:</em> Fixes another build problem regarding OCaml-5.00</p></li>
159159+160160+ <li><p><em>1.9.2:</em> Fixes a build problem regarding OCaml-5.00</p></li>
161161+162162+ <li><p><em>1.9.1:</em> Fixes a few install-related issues, like missing files.</p></li>
163163+164164+ <li>
165165+ <p><em>1.9:</em> Overhaul how separately installed packages (e.g. num)
166166+ are handled (by David Allsopp).</p>
167167+ <p>Switch to opam-2.0 file format (by David Allsopp).</p>
168168+ <p>Fix an incomaptibility with ocaml-4.13 (by David Allsopp).</p>
169169+ <p>Expose the native toplevel (by Louis Gesbert).</p>
170170+ <p>Fix an incompatibility with "Jane Street Style" (by Mark Laws).</p>
171171+ <p>Switch from m4 to sed (by kit-ty-kate).</p>
172172+ </li>
173173+174174+ <li>
175175+ <p><em>1.8.1:</em> Adapted to upcoming ocaml-4.09.</p>
176176+ <p>New API Findlib.list_packages' can specify a package prefix.</p>
177177+ </li>
178178+179179+ <li>
180180+ <p><em>1.8.0:</em> Fix reinstallation of "num" for OCaml-4.06.
181181+ </p>
182182+ <p>Fix build with OCaml-4.07.</p>
183183+ <p>The installation of graphics/META is now optional.</p>
184184+ <p>Fix "ocamlfind query -d".</p>
185185+ <p>The environment variable OCAMLFIND_IGNORE_DUPS_IN is now interpreted
186186+ as a list of directories.</p>
187187+ <p>Packages for "ocamlfind query" may now be separated by commas, too.</p>
188188+ <p>New "warning" property for packages.</p>
189189+ <p>Forgetting to pass -thread/-vmthread only prints a warning now,
190190+ but doesn't stop the build.</p>
191191+ <p>For dealing with case-sensitive filesystems it is now only tried to
192192+ match ASCII characters, but not encoding-dependent characters.</p>
193193+ </li>
194194+195195+ <li>
196196+ <p><em>1.7.3:</em> Fix regarding num-top: this library is now also
197197+ optional, as num.</p>
198198+ </li>
199199+200200+ <li>
201201+ <p><em>1.7.2:</em> Trying to protect against failures when
202202+ several package installs are done in parallel.</p>
203203+204204+ <p>New subpackage "findlib.top" for the toploop (Jeremie Dimino).</p>
205205+206206+ <p>The "num" library is now optional.</p>
207207+208208+ <p>Shell scripts are started via "sh" command when there is no
209209+ /bin/sh (ygrek)</p>
210210+ </li>
211211+212212+ <li>
213213+ <p><em>1.7.1:</em> added missing file to tarball</p>
214214+ </li>
215215+216216+ <li>
217217+ <p><em>1.7.0:</em> New command "ocamlfind printppx" that outputs
218218+ how the ppx preprocessor would be called (Hendrik Tews).</p>
219219+ <p>Support for the raw_spacetime library that comes with
220220+ OCaml 4.04 (Gerd Stolpmann with help from Mark Shinwell).</p>
221221+ <p>Require that ocamlc and ocamlc.opt are installed to the
222222+ same directory for emitting the "opt" setting in the generated
223223+ config file - same for ocamlopt.opt, ocamldep.opt, ocamldoc.opt.</p>
224224+ </li>
225225+226226+ <li>
227227+ <p><em>1.6.3:</em>Fix: "ocamlfind printconf" respects the
228228+ environment variable OCAMLFIND_CONF (reported by Andre)</p>
229229+ <p>Build with -opaque (reported by hhugo)</p>
230230+ <p>Preliminary support for native toplevel so far the toplevel
231231+ is implemented symmetrically to the bytecode case (this is not
232232+ correct in vanilla ocaml)</p>
233233+ <p>New options: ocamlfind query -qe -qo</p>
234234+ </li>
235235+236236+ <li>
237237+ <p><em>1.6.2:</em>Uninstalling findlib no longer uninstalls the
238238+ocamlbuild library by accident (Gabriel Scherer, Edwin Török)</p>
239239+ <p>Adding an "ocamldoc" library, providing the cmi's for ocamldoc
240240+plugins (suggested by Armaël Guéneau)</p>
241241+ <p>Support for OCaml-4.03: recognize that the new -color option
242242+has an argument (reported by Guillaume Bury)</p>
243243+ </li>
244244+245245+ <li>
246246+ <p><em>1.6.1:</em> Just an important doc fix.</p>
247247+ </li>
248248+249249+ <li>
250250+ <p><em>1.6.0:</em> Adding support for dynamically loading
251251+ packages (François Bobot): new "plugin" variable, new
252252+ Fl_dynload module.</p>
253253+ <p>New command "ocamlfind lint" for checking META files
254254+ (François Bobot).</p>
255255+ <p>Also support MSYS_NT on Windows. Permit spaces in install
256256+ paths (Christophe Troestler).</p>
257257+ <p>Allow to query the location of the META file of a package:
258258+ "ocamlfind query -format '%m'" (Gerd Stolpmann).</p>
259259+ <p>Get the install path for the META file of packages:
260260+ "ocamlfind printconf metapath" (Gerd Stolpmann).</p>
261261+ </li>
262262+263263+ <li>
264264+ <p><em>1.5.6:</em> for MSVC build fixing bad filename suffix
265265+ (Dmitry Bely).</p>
266266+ <p>The switch -only-show did not work as described.
267267+ (Error report from Bob Atkey.)</p>
268268+ <p>Also support mingw64 as system type (Matthieu Dubuget).</p>
269269+ </li>
270270+271271+ <li>
272272+ <p><em>1.5.5:</em> fixes a build problem for BSD systems</p>
273273+ </li>
274274+275275+ <li>
276276+ <p><em>1.5.4:</em> New ppxopt META variables (Peter Zotov).</p>
277277+ <p>Support for OCAMLFIND_TOOLCHAIN environment variable (Peter Zotov).
278278+ </p>
279279+ </li>
280280+281281+ <li>
282282+ <p><em>1.5.3:</em> The installation of "bytes" respects now $prefix and
283283+ the configured destination.</p>
284284+ <p>New option -pp for "ocamlfind query", to get preprocessor packages.</p>
285285+ <p>Updated the compatibility Bytes module to support extend, init, mapi,
286286+ blit_string (Gabriel Scherer).</p>
287287+ </li>
288288+289289+ <li>
290290+ <p><em>1.5.2:</em> support for the query formats "%+a" and "%+A".</p>
291291+ <p>Fix: the "ppx" property is now also path-expanded when interpreted
292292+in a toploop.</p>
293293+ <p>Fix: implicit "ppx" is not path-expanded anymore.</p>
294294+ <p>Fix: Build bytes.cmxs only if natdynlink is enabled (Andy Ray).</p>
295295+ </li>
296296+ <li>
297297+ <p><em>1.5.1:</em> includes a file that was missing in 1.5</p>
298298+ </li>
299299+ <li>
300300+ <p><em>1.5:</em> Including the "bytes" package that is either
301301+a compat package for ocaml < 4.02 or a fake package for ocaml >= 4.02.
302302+The package aims at helping to support the transition to the new
303303+"bytes" type for mutable strings.</p>
304304+ <p>Also installing findlib.cmxs if OCaml supports it.</p>
305305+ <p>Allowing to disable camlp4 (in prep for OCaml-4.02).</p>
306306+ <p>The "ppx" package property can be specified for constructing
307307+ppx-type preprocessors (patches from Peter Zotov).</p>
308308+ </li>
309309+310310+ <li>
311311+ <p><em>1.4.1:</em>ocamldoc: The order of -ppopt arguments was
312312+changed by ocamlfind, which is not correct. (Sylvain Le Gall and
313313+Jérémie Dimino.)</p>
314314+ </li>
315315+316316+ <li>
317317+ <p><em>1.4:</em> Fixed performance bug when many arguments
318318+need to be processed (Jérôme Vouillon).</p>
319319+ <p>Auto-configuring ocamldoc.opt if it is found (Christopher
320320+Zimmermann).</p>
321321+ <p>New config switch -no-custom to prevent that "ocamlfind"
322322+is linked in custom-runtime mode (bytecode only) (Christopher
323323+Zimmermann).</p>
324324+ <p>The library dbm is no longer part of OCaml, and now
325325+optional in findlib (Ashish Argawal).</p>
326326+ <p>Support for ocamloptp.</p>
327327+ <p>New function Topfind.log for controlling the verbosity
328328+(Jeremie Dimino).</p>
329329+ <p>Rewritten Fl_metascanner without camlp4 (patch from
330330+Gabriel Scherer)</p>
331331+ </li>
332332+333333+ <li>
334334+ <p><em>1.3.3:</em> OCaml-4: using the new #remove_directory directive
335335+ if present.</p>
336336+ <p>Better compatibility with the OCaml version from Homebrew.</p>
337337+ </li>
338338+339339+ <li>
340340+ <p><em>1.3.2:</em> Handling of empty arguments (Wojciech Meyer).</p>
341341+ <p>Added entry for camlp4.fulllib.</p>
342342+ <p>New switch -add for "ocamlfind install" (Hans Ole Rafaelsen).</p>
343343+ <p>Further fixes for ocaml-4.00.</p>
344344+ <p>Fixing the recognition of double .cmi interface files.</p>
345345+ <p>Fixing -dontlink (it is now deeply interpreted).</p>
346346+ </li>
347347+348348+ <li>
349349+ <p><em>1.3.1:</em> Fixing a bug with ocamlmklib that slipped through
350350+in 1.3.0</p>
351351+ </li>
352352+353353+ <li>
354354+ <p><em>1.3.0:</em> Fixes for ocaml-4.00 (especially topfind).</p>
355355+ <p>Emitting an error if the configuration file does not exist.</p>
356356+ <p>Emitting a warning if the selected toolchain does not exist.</p>
357357+ <p>camlp4 is referenced by "+camlp4" in META.</p>
358358+ <p>Including the sources for the documentation in the tarball.</p>
359359+ <p>License change (simplification) for num_top_printers.mli.</p>
360360+ <p>Fix ocamlmklib wrapper: processing contracted args (like -L/dir) correctly.</p>
361361+ <p>Many wrappers get a new option -passrest instructing to pass all
362362+remaining options on the command-line unchanged to the invoked tool.</p>
363363+ <p>Prettified -help output.</p>
364364+ </li>
365365+366366+ <li>
367367+ <p><em>1.2.8:</em>
368368+Adding support for ocamlmklib (B. Meurer's patches)</p>
369369+ <p>Fix for win32 in the configure script.</p>
370370+ </li>
371371+ <li>
372372+ <p><em>1.2.7:</em>
373373+Fix: if a META file defines several packages, and one of the packages
374374+has a broken dependency, ocamlfind used to report all errors even if
375375+the broken packages were not used. This is now changed - broken
376376+subpackages are ignored when they are not needed, in the same way as
377377+broken top-level packages are ignored when not needed. (Thanks to
378378+Sylvain Le Gall for reporting the problem.)</p>
379379+ <p>Added -thread and -vmthread switches to "ocamlfind ocamldoc".
380380+These actually only add the right predicates. (Thanks to Vladimir
381381+Ivanov for pointing this problem out.)</p>
382382+ <p>Package warnings can be emitted by "ocamlfind ocamldoc".</p>
383383+ </li>
384384+ <li>
385385+ <p><em>1.2.6:</em> adding META for ocamlbuild.</p>
386386+ <p>Fixes for MinGW/MSYS platform.</p>
387387+ <p>Improved messages.</p>
388388+ </li>
389389+ <li>
390390+ <p><em>1.2.5:</em> Fix: Again CR deletion... Turns out some OS do not
391391+ understand '\r' but only '\015' (thanks to Isaiah Weiner).</p>
392392+ <p>Support for Win64 (untested; thanks to David Allsopp).</p>
393393+ <p>ocamlfind no longer emits auto-generated -ccopt options. These
394394+ tend to accumulate, and it is possible that for large projects
395395+ the maximum command line length is exceeded. Current versions of
396396+ the OCaml compilers do not need these extra -ccopt anyway, so
397397+ this code is completely dropped.</p>
398398+ </li>
399399+400400+ <li>
401401+ <p><em>1.2.4:</em> Fix: Bigarray needs unix (Thanks to Markus Mottl).</p>
402402+ <p>Fix: In the version of camlp4 provided by OCaml 3.11 various
403403+ libraries do not contain dynlink anymore. Because of this, dynlink
404404+ becomes a prerequisite of camlp4. (Thanks to Martin Jambon).</p>
405405+ <p>Attempt: Fixing the space issue for paths (Win32). It is unclear
406406+ whether it is solved. (Thanks to Christophe Troestler).</p>
407407+ </li>
408408+409409+ <li>
410410+ <p><em>1.2.3:</em> Solving the CR deletion differently, to
411411+ make OS X happy.</p>
412412+ </li>
413413+414414+ <li>
415415+ <p><em>1.2.2:</em> Fix: Problem with CR character (Cygwin)
416416+ (Thanks to David Allsopp).
417417+ </p>
418418+ <p>Fix: Case-insensitive filesystems (partially solved)
419419+ (Thanks to David Allsopp).
420420+ </p>
421421+ <p>Fix: File name with backslashes at the end (Win32;
422422+ thanks to Dmitry Grebeniuk).</p>
423423+ </li>
424424+425425+ <li>
426426+ <p><em>1.2.1:</em> Fix: Camlp4 rules now activate the
427427+stream parser extension</p>
428428+ </li>
429429+430430+ <li>
431431+ <p><em>1.2:</em> Fix in build scripts: Prepending $(prefix)
432432+when installing safe_camlp4 (thanks to Daniel Janus)</p>
433433+ <p>Non-existing -I directories are ignored
434434+(thanks to Nicolas Pouillard)</p>
435435+ <p>A script to create a MacOS X package (thanks to
436436+Pietro Abate)</p>
437437+ <p>Better support for Windows (with help from Robert
438438+Roessler and David Allsopp)</p>
439439+ <p>Support for camlp4 on OCaml 3.10</p>
440440+ <p>Fix: "ocamlfind install" with "-patch" option writes
441441+now correct META file for the case that subpackages occur</p>
442442+ <p>Adding environment variable OCAMLFIND_IGNORE_DUPS_IN
443443+to reduce the number of warnings ocamlfind emits</p>
444444+ </li>
445445+446446+ <li>
447447+ <p><em>1.1.2:</em> Bugfix in the META parser: Backslashes are now
448448+correctly parsed. (Thanks to Martin Jambon for finding this problem.)</p>
449449+ <p>Fixes for platforms that do not support dynamic loading of
450450+DLLs.</p>
451451+ <p>Fixed extraction of camlp4 parameters from packages.</p>
452452+ </li>
453453+454454+ <li>
455455+ <p><em>1.1.1:</em> Bugfixes only: Fixed detection of threading model
456456+for OCaml 3.09. Fixed alternate configuration files.</p>
457457+ </li>
458458+459459+ <li>
460460+ <p><em>1.1:</em> Automatic detection of standard compiler options.</p>
461461+462462+ <p>Liberated the checks whether a package is already installed.</p>
463463+464464+ <p>The .opt compilers are entered into findlib.conf if available.</p>
465465+466466+ <p>New: "install" has -optional switch for optional files.</p>
467467+468468+ <p>New: "install" has -patch-version to patch the version into
469469+the installed META file.</p>
470470+471471+ <p>New: "install" has -patch-rmpkg to remove subpackages from
472472+the installed META file.</p>
473473+474474+ <p>New: "install" has -patch-archives which removes non-existing
475475+files from "archive" variables. This is experimental.</p>
476476+477477+ <p>New: subpackages can be disabled by exists_if.</p>
478478+479479+ <p>New: Support for toolchains.</p>
480480+481481+ <p>Fix for "remove": -destdir works again.</p>
482482+483483+ <p>Fix for "call": CTRL-C works when calling interactive commands.</p>
484484+485485+ <p>Fix for preprocessor packages: Dependencies on normal packages
486486+are resolved.</p>
487487+488488+ </li>
489489+490490+ <li><p><em>1.0.4:</em> Fix: In previous versions, "ocamlmktop"
491491+set the "toploop" predicate. It turned out, however, that the toploops
492492+generated in this way did not work properly. For this reason,
493493+"ocamlmktop" does not set "toploop" any more for link time, but
494494+instead a new predicate "create_toploop". When the toploop is
495495+executed, the predicate "toploop" is again added.</p>
496496+ </li>
497497+498498+ <li><p><em>1.0.3:</em> Fix: The relative position of "-cclib -l"
499499+ options on the command line is preserved. In previous versions,
500500+these options were moved to the beginning of the argument list. This
501501+did not work for static link editing; dynamic link editing was not
502502+affected.</p>
503503+ <p>Fix: The automatic fixup of "threads" dependencies
504504+works again. In the previous version, this was broken.</p>
505505+ <p>Addition: -format '%(name)' for ocamlfind query.</p>
506506+ <p>Some minor improvements of the documentation.</p>
507507+</li>
508508+509509+ <li><p><em>1.0.2:</em> Fix: The alternate package layout did
510510+not fully work. This is repaired now, and there are some clarifications
511511+about relative directory paths in the documentation.</p>
512512+ </li>
513513+514514+ <li><p><em>1.0.1:</em> Fix: Forgot to install some .cmi
515515+files</p>
516516+ </li>
517517+518518+ <li><p><em>1.0:</em> It is now possible to divide the
519519+description of a package into subpackages (but there is still only one
520520+META file, but with enhanced syntax). This allows it to describe
521521+intra-package dependencies.</p>
522522+523523+ <p>Predicates in META files can be negated.</p>
524524+525525+ <p>The "error" variable allows you to detect conditions under which
526526+the library would not work, and to generate error messages.</p>
527527+528528+ <p>It is possible to refer to archive files installed in other
529529+packages.</p>
530530+531531+ <p>The set of predicates is extended by "package predicates"
532532+after the dependency analysis, making conditions expressible that
533533+depend on whether other packages are selected.</p>
534534+535535+ <p>The "+=" operator in META files adds words to variables rather
536536+than setting them.</p>
537537+538538+ <p>The "#thread" directive enables multi-threading in toploops and
539539+scripts, if possible.</p>
540540+541541+ <p>The "#predicates" directive simplifies the addition of predicates.
542542+ </p>
543543+544544+ <p>Queries: The format specifier %D prints the description of
545545+the package. -long-format includes the description. Short options
546546+-r, -l, -d.</p>
547547+548548+ <p>ocamlfind list -describe prints package descriptions.</p>
549549+550550+ <p>Support for "ocamlfind ocamldoc". However, the implementation is
551551+quite sloppy.</p>
552552+553553+ <p>The configuration file is called "findlib.conf" by default,
554554+not "ocamlfind.conf".</p>
555555+556556+ <p>Removal of "ocamlfind guess".</p>
557557+558558+ <p>Support for #use "findlib" and #use "ocamlfind" has been
559559+removed. The only remaining way to load findlib is by #use "topfind".</p>
560560+561561+ <p>There is no longer a thread-safe version of findlib. The user
562562+has to ensure that only one thread uses findlib (which is usually trivial
563563+to achieve).</p>
564564+565565+ <p>ocamlmktop: Directories are no longer automatically added
566566+to the search path. This did not work anyway, and this change forces
567567+scripts to always invoke "#require" to load/enable libraries, for
568568+better uniformity.</p>
569569+570570+ <p>Fixes: num-top works. "ocamlfind ocamlopt -thread" generates
571571+a better error message on non-POSIX systems. "ocamlfind query -descendants"
572572+takes predicates into account (it did not do that in previous versions of
573573+findlib).</p>
574574+ </li>
575575+576576+ <li><p><em>0.9:</em> Changes for OCaml 3.07 (-thread,
577577+ -vmthread). Includes Zack's toploop printers for bigints.</p>
578578+ </li>
579579+580580+ <li><p><em>0.8 - 0.8.1:</em> Renamed a lot of modules to avoid name
581581+ clashes with OCaml core modules. Cygwin: Additional option
582582+ -cygpath for "configure". The man pages have a NAME
583583+ section. Bugfix in Makefile wizard.</p>
584584+ </li>
585585+586586+ <li><p><em>0.7 - 0.7.2:</em> DLLs: There are now two styles of
587587+ installation: DLLs can be installed in the package
588588+ directories (like before), or in a shared directory
589589+ "stublibs". For the first style, there is now an option
590590+ "ldconf" that determines whether the ld.conf file is to be
591591+ updated, and if so, which file. The latter style is enabled
592592+ by simply creating a directory "stublibs" in the site-lib
593593+ directory. (In the first version the directory was called
594594+ "libexec". By user request, the name of the DLL directory
595595+ has been changed to "stublibs".)</p>
596596+597597+ <p>"ocamlfind install" preserves now the mtime of the files.</p>
598598+599599+ <p>"ocamlfind printconf" is more flexible, and easier to call
600600+ from scripts.</p>
601601+602602+ <p>"ocamlfind browser" calls ocamlbrowser with the right -I
603603+ options.</p>
604604+605605+ <p>"ocamlfind query": -descendants implies now -recursive.</p>
606606+607607+ <p>"ocamlfind ocamldep": -native-filter and -bytecode-filter for more
608608+ exact dependency generation.</p>
609609+610610+ <p>There may be now postinstall and postremove scripts.</p>
611611+612612+ <p>"ocamlfind pkg/cmd": This syntax can be used to call the program cmd
613613+ that is installed in the package directory for pkg. Intended to
614614+ simplify the invocation of programs that are installed in package
615615+ directories and not in XXX/bin, which may be useful for package-
616616+ related tools.</p>
617617+618618+ <p>Findlib has now a toolbox containing helpful programs besides
619619+ ocamlfind. For the beginning, there is a Makefile wizard that
620620+ can be called by "ocamlfind findlib/make_wizard".</p>
621621+622622+ <p>#use "topfind" instead of #use "findlib" to avoid name clashes
623623+ in a certain configuration. #use "findlib" and #use "ocamlfind"
624624+ are still supported for backward compatibility if the name clash
625625+ does not occur.</p>
626626+627627+ <p>Fix: bytecode threads work again. (The wrong unix library was
628628+ linked for recent OCaml versions.)</p>
629629+630630+ <p>Many smaller improvements; the docs have been updated.</p>
631631+ </li>
632632+633633+ <li><p><em>0.6 - 0.6.2:</em> Minor changes for Ocaml-3.03-alpha
634634+ (and later for 3.04). New #list directive. New: #use
635635+ "findlib" loads the findlib directives into every toploop
636636+ (Ocaml-3.03-alpha).</p>
637637+638638+ <p>The file ld.conf is automatically updated when DLLs are
639639+ installed or removed.</p>
640640+641641+ <p>Fix: /tmp/findlib_initf* no longer overflows. The thread
642642+ library is now always the first linked library.</p>
643643+ </li>
644644+645645+ <li><p><em>0.5 - 0.5.4:</em> Findlib has now a configuration
646646+ file (see documentation under findlib.conf). Much more
647647+ environment variables. The location of the standard library is
648648+ now configurable at runtime.
649649+ </p>
650650+651651+ <p>The package search path can now be selected independently
652652+ of the package installation directory.</p>
653653+654654+ <p>New commands: ocamlfind list, ocamlfind printconf, ocamlfind guess
655655+ (See documentation under ocamlfind)</p>
656656+657657+ <p>Optional alternate directory layout: All META files go into
658658+ a separate directory (see documentation under site-lib).</p>
659659+660660+ <p>Findlib works now only for OCaml 3; support for OCaml 2 has been
661661+ dropped. As a consequence, the "configure" script could be
662662+ simplified; it is no longer necessary to figure out the
663663+ linker options.</p>
664664+665665+ <p>Improved support for camlp4: New directives #camlp4o and
666666+ #camlp4r for the toploop.</p>
667667+668668+ <p>ocamlfind now detects whether two selected packages have
669669+ equally named toplevel modules, and prints a warning in this case.</p>
670670+671671+ <p>There is a downstripped version ocamlfind-mini (see directory
672672+ "mini"). This is a one-file script that can be easily
673673+ distributed with any software. ocamlfind-mini has reduced
674674+ functionality, but it is sufficient to compile and install a
675675+ library. (But it does not support using a library.)</p>
676676+677677+ <p>Support for the Cygwin port of OCaml.</p>
678678+679679+ <p>Installation of packages: The file permissions are
680680+ preserved when files are installed. However, the umask is
681681+ applied. The "install" and "remove" subcommands have better
682682+ diagnostics.</p>
683683+684684+ <p>ocamlfind ocamlmktop: Generates now initialization code for the
685685+ include path. You don't need to call your toploop with -I
686686+ options any more. Furthermore, this fixes some problems with
687687+ packages that add printers to the toploop.</p>
688688+689689+ <p>New: ocamlfind ocamldep. ocamlfind is now prepared for the new
690690+ -pp option of ocamldep (upcoming Ocaml 3.03).</p>
691691+692692+ <p>Installation of findlib: New PREFIX variable in Makefile to
693693+ install locally.</p>
694694+695695+ <p>Fixes: itest. ocamlfind query -descendants works again.</p>
696696+ </li>
697697+698698+ <li><p><em>0.4:</em> Experimental support for camlp4 (see FAQ
699699+ section in the manual). New environment variable
700700+ OCAMLFIND_COMMANDS (see ocamlfind(1)).
701701+ </p>
702702+ </li>
703703+704704+ <li><p><em>0.3 - 0.3.1:</em> Necessary updates for OCaml
705705+3. Bugfix: Findlib did not work for bytecode threads. The reason was
706706+that findlib added the directory of the stdlib to the search
707707+path. Works now.
708708+ </p>
709709+ </li>
710710+711711+ </ul>
712712+ <p>Older changes are no longer documented.</p>
713713+ </sect1>
714714+</readme>
···11+<!-- $Id -->
22+33+<!ENTITY % p.like "p|ul">
44+<!ENTITY % text "br|code|em|footnote|a">
55+66+<!ELEMENT readme (sect1+)>
77+<!ATTLIST readme
88+ title CDATA #REQUIRED>
99+1010+<!ELEMENT sect1 (title,(sect2|%p.like;)+)>
1111+1212+<!ELEMENT sect2 (title,(sect3|%p.like;)+)>
1313+1414+<!ELEMENT sect3 (title,(%p.like;)+)>
1515+1616+<!ELEMENT title (#PCDATA|br)*>
1717+1818+<!ELEMENT p (#PCDATA|%text;)*>
1919+2020+<!ELEMENT br EMPTY>
2121+2222+<!ELEMENT code (#PCDATA)>
2323+2424+<!ELEMENT em (#PCDATA|%text;)*>
2525+2626+<!ELEMENT ul (li+)>
2727+2828+<!ELEMENT li (%p.like;)*>
2929+3030+<!ELEMENT footnote (#PCDATA|%text;)*>
3131+3232+<!ELEMENT a (#PCDATA)*>
3333+<!ATTLIST a
3434+ href CDATA #IMPLIED
3535+ readmeref CDATA #IMPLIED
3636+>
3737+3838+
+24
vendor/opam/ocamlfind/doc/src/findlib.dsl
···11+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
22+<!ENTITY dbstyle SYSTEM "docbook.dsl" CDATA DSSSL>
33+]>
44+55+<style-sheet>
66+<style-specification use="docbook">
77+<style-specification-body>
88+99+(define %footnotes-at-end%
1010+ ;; Should footnotes appear at the end of HTML pages?
1111+ #t)
1212+1313+(define %html-ext%
1414+ ;; Default extension for HTML output files
1515+ ".html")
1616+1717+(define %root-filename%
1818+ ;; Name for the root HTML document
1919+ "index")
2020+2121+</style-specification-body>
2222+</style-specification>
2323+<external-specification id="docbook" document="dbstyle">
2424+</style-sheet>
+2476
vendor/opam/ocamlfind/doc/src/findlib.sgml
···11+<!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
22+ <!ENTITY findlibmeta SYSTEM "findlib_meta.mod">
33+ <!ENTITY findlibsitelib SYSTEM "findlib_sitelib.mod">
44+ <!ENTITY findlibmli SYSTEM "findlib_mli.mod">
55+ <!ENTITY findlibtopfind SYSTEM "findlib_topfind.mod">
66+ <!ENTITY findlibocamlfind SYSTEM "findlib_ocamlfind.mod">
77+ <!ENTITY findlibconf SYSTEM "findlib_conf.mod">
88+ <!ENTITY % gps.common SYSTEM "../common.xml">
99+ %gps.common;
1010+]>
1111+1212+<book>
1313+1414+<title>The findlib User's Guide</title>
1515+<bookinfo>
1616+<!-- <bookbiblio> -->
1717+<authorgroup>
1818+ <author>
1919+ <firstname>Gerd</firstname>
2020+ <surname>Stolpmann</surname>
2121+ <authorblurb>
2222+ <para>
2323+ <address>
2424+ <email>gerd@gerd-stolpmann.de</email>
2525+ </address>
2626+ </para>
2727+ </authorblurb>
2828+ </author>
2929+</authorgroup>
3030+3131+<copyright>
3232+<year>1999-2014</year><holder>Gerd Stolpmann</holder>
3333+</copyright>
3434+<!-- </bookbiblio> -->
3535+3636+<abstract>
3737+<para>
3838+The "findlib" library provides a scheme to manage reusable software
3939+components (packages), and includes tools that support this
4040+scheme. Packages are collections of OCaml modules for which
4141+metainformation can be stored. The packages are kept in the filesystem
4242+hierarchy, but with strict directory structure. The library contains
4343+functions to look the directory up that stores a package, to query
4444+metainformation about a package, and to retrieve dependency
4545+information about multiple packages. There is also a tool that allows
4646+the user to enter queries on the command-line. In order to simplify
4747+compilation and linkage, there are new frontends of the various OCaml
4848+compilers that can directly deal with packages.
4949+</para>
5050+5151+<para>
5252+Together with the packages metainformation is stored. This includes a
5353+version string, the archives the package consists of, and additional
5454+linker options. Packages can also be dependent on other
5555+packages. There is a query which finds out all predecessors of a list
5656+of packages and sorts them topologically. The new compiler frontends
5757+do this implicitly.
5858+</para>
5959+6060+<para>
6161+Metainformation can be conditional, i.e. depend on a set of
6262+predicates. This is mainly used to be able to react on certain
6363+properties of the environment, such as if the bytecode or the native
6464+compiler is invoked, if the application is multi-threaded, and a few
6565+more. If the new compiler frontends are used, most predicates are
6666+found out automatically.
6767+</para>
6868+6969+<para>
7070+There is special support for scripts. A new directive, "#require",
7171+loads packages into scripts.
7272+</para>
7373+7474+<formalpara>
7575+<title>Download findlib</title>
7676+<para>
7777+This manual describes version &release.findlib; of the software
7878+package. It can be downloaded at
7979+<ulink URL="&url.gps-ocaml-download;">
8080+&url.gps-ocaml-download;
8181+</ulink>. The user's guide and the reference manual are included.
8282+Newest releases of "findlib" will be announced in
8383+<ulink URL="&url.linkdb;">The OCaml Link
8484+Database</ulink>.
8585+</para>
8686+</formalpara>
8787+8888+<formalpara>
8989+<title>Quickstart</title>
9090+<para>
9191+See also the <ulink URL="&url.findlib-quickstart;">Quickstart page</ulink>
9292+for instructions for the most common
9393+cases.</para>
9494+</formalpara>
9595+</abstract>
9696+9797+<legalnotice>
9898+<title>License</title>
9999+<para>
100100+This document, and the described software, "findlib", are copyright by
101101+Gerd Stolpmann.
102102+</para>
103103+104104+<para>
105105+Permission is hereby granted, free of charge, to any person obtaining
106106+a copy of this document and the "findlib" software (the
107107+"Software"), to deal in the Software without restriction, including
108108+without limitation the rights to use, copy, modify, merge, publish,
109109+distribute, sublicense, and/or sell copies of the Software, and to
110110+permit persons to whom the Software is furnished to do so, subject to
111111+the following conditions:
112112+</para>
113113+114114+<para>
115115+The above copyright notice and this permission notice shall be included
116116+in all copies or substantial portions of the Software.
117117+</para>
118118+119119+<para>
120120+The Software is provided ``as is'', without warranty of any kind, express
121121+or implied, including but not limited to the warranties of
122122+merchantability, fitness for a particular purpose and noninfringement.
123123+In no event shall Gerd Stolpmann be liable for any claim, damages or
124124+other liability, whether in an action of contract, tort or otherwise,
125125+arising from, out of or in connection with the Software or the use or
126126+other dealings in the software.
127127+</para>
128128+</legalnotice>
129129+130130+</bookinfo>
131131+132132+133133+134134+<!-- ********************************************************************** -->
135135+136136+137137+138138+<part>
139139+<title>User's Guide</title>
140140+141141+<chapter>
142142+<title>Libraries and Packages</title>
143143+144144+<para> Reusability is one of the keywords in software engineering
145145+today. It simply means to have source code that can be shared by
146146+several programs. Usually, modules are combined to libraries, and the
147147+library archive files can be linked into programs. As the idea might
148148+be simple, its practical implementation is complex because sharing of
149149+source code has an impact on all steps and phases in software
150150+production. This document only addresses the following administrative
151151+problems:
152152+</para>
153153+154154+<itemizedlist mark="bullet" spacing="compact">
155155+<listitem>
156156+<para>
157157+Storing the libraries in file hierarchies
158158+</para>
159159+</listitem>
160160+161161+<listitem>
162162+<para>
163163+Compiling and linking programs using such libraries
164164+</para>
165165+</listitem>
166166+167167+<listitem>
168168+<para>
169169+Managing dependencies between libraries
170170+</para>
171171+</listitem>
172172+</itemizedlist>
173173+174174+<para>
175175+Objective Caml has a variety of language means to support
176176+reusability. Most important, polymorphic functions can be written
177177+which generalize the types of input arguments and the
178178+type of the result value. There are many examples in the core library
179179+such that I assume that the reader is familiar with this
180180+feature. Second, modules and functors must be mentioned which not only
181181+generalize types of values, but can even generalize structures,
182182+i.e. types with associated operations. Third, the class construct
183183+allows us to adopt the object-oriented techniques of abstraction such
184184+as inheritance and dynamic method lookup.
185185+</para>
186186+187187+<para>
188188+In the following, we are only analyzing the problem of making and
189189+using libraries from a purely software-technical point of view. This
190190+means, we ignore how to make functions polymorphic, and how to create
191191+functors and classes. Instead, we only look at how to invoke the
192192+OCaml compiler to create, manage, and use libraries. Especially, we
193193+are interested in the administration of systems of libraries that
194194+have dependencies.</para>
195195+196196+<para>
197197+One of the complex operations on such a system is the replacement of
198198+a library by a newer version. Because of the strict compatibility
199199+checks of OCaml, it is usually necessary to rebuild and reinstall
200200+all dependent libraries as well. With the help of findlib, one can
201201+find out which are the dependent libraries. (However, findlib does
202202+not provide a framework to rebuild them. For example, the GODI
203203+system includes such a framework.)
204204+</para>
205205+206206+<para>
207207+The library is also called a "package" when it is seen as a removable
208208+and replaceable set of files. Findlib requires that there is a
209209+certain directory structure; it is not possible to install the files
210210+at arbitrary places (findlib does not even maintain a file list).
211211+For simplicity, every library is usually stored into its own
212212+directory, i.e. the library archive files and the interface files.
213213+</para>
214214+215215+<para>From the perspective of the compiler, the library is made
216216+accessible by adding the package directory to the search path
217217+of the compiler. By doing so, the modules of the library are
218218+added to the namespace universe, and thus can be opened by
219219+modules using them. This means that the approach "one package
220220+= one directory" can be naturally translated into language
221221+operations modifying the namespace scope.</para>
222222+223223+<para>
224224+When linking a program, it must be specified which link operation is
225225+necessary to use a certain library. Often, only a single archive file
226226+needs to be linked in, but sometimes additional archives or system
227227+libraries must be linked, too. Furthermore, the link operations
228228+often depends on certain conditions, e.g. whether a single- or
229229+multi-threaded program is being created.
230230+</para>
231231+232232+<para>
233233+The <emphasis>findlib</emphasis> library is my suggestion for a
234234+package manager suitable for Objective Caml. It is a library (stored
235235+as a package itself) which can answer the following questions:
236236+</para>
237237+238238+<itemizedlist mark="bullet" spacing="compact">
239239+<listitem>
240240+<para>If I want to use a package, which is the directory containing
241241+the compiled interfaces and implementations? - The package directory
242242+may vary from system to system, and this feature makes it easier to
243243+write Makefiles that run everywhere. Furthermore, OCaml can load
244244+modules dynamically, and it is not a good practice to compile in the
245245+location of such modules. The better way is to ask findlib where the
246246+module resides today.
247247+</para>
248248+</listitem>
249249+250250+<listitem>
251251+<para>Which other packages must be linked in, too, if I want to use a
252252+certain package?
253253+</para>
254254+</listitem>
255255+256256+<listitem>
257257+<para>Which archives need to be linked in, and which compiler options
258258+are necessary?
259259+</para>
260260+</listitem>
261261+262262+<listitem>
263263+<para>If there is a version of the archive with additional properties,
264264+which file should I use? - Additional properties are at least:
265265+Thread-safety, using POSIX threads, and being gprof-enabled. It is
266266+simple to add more criterions.
267267+</para>
268268+</listitem>
269269+</itemizedlist>
270270+271271+272272+<para>
273273+Furthermore, there is a frontend for this library called
274274+<emphasis>ocamlfind</emphasis>. It is a command-line interface for the
275275+library, but has also some additional abilities:
276276+</para>
277277+278278+279279+<itemizedlist mark="bullet" spacing="compact">
280280+<listitem>
281281+<para>It can invoke ocamlc, ocamlopt, ocamlmktop, and ocamlcp such
282282+that compiler arguments necessary to use a package or link it in are
283283+automatically added.
284284+</para>
285285+</listitem>
286286+287287+<listitem>
288288+<para>It can install and uninstall packages.
289289+</para>
290290+</listitem>
291291+292292+<listitem>
293293+<para>It can find out dependent packages.
294294+</para>
295295+</listitem>
296296+</itemizedlist>
297297+298298+<para>
299299+As you'll see in the following chapters, the usage of this library is
300300+really simple. If you want only to link in packages written by other
301301+people, you must only change the command that invokes the compiler,
302302+e.g. instead of calling "ocamlc program.ml" invoke "ocamlfind ocamlc
303303+-package name_of_package_to_use -linkpkg program.ml", and you can
304304+refer to the named package within program.ml. If you want to turn your
305305+collection of modules into a package, you need only to write one
306306+administrative file (META) containing all extra information such as
307307+required other packages.
308308+</para>
309309+310310+311311+</chapter>
312312+313313+<!-- ********************************************************************** -->
314314+315315+<chapter>
316316+<title>Using packages</title>
317317+318318+<sect1>
319319+<title>Listing the installed packages</title>
320320+321321+<para>
322322+You can list which packages are installed by executing
323323+324324+<programlisting>
325325+ocamlfind list
326326+</programlisting>
327327+328328+You will get a list of names and version numbers. You can get a bit
329329+more information by passing the -describe option:
330330+331331+<programlisting>
332332+ocamlfind list -describe
333333+</programlisting>
334334+</para>
335335+</sect1>
336336+337337+338338+<sect1>
339339+<title>Looking up package directories</title>
340340+341341+<para>
342342+The package manager knows the preferred location for packages (this
343343+location is compiled in), which is usually
344344+/usr/local/lib/ocaml/site-lib. You can ask the package manager where
345345+package p is stored by simply typing
346346+</para>
347347+348348+<programlisting>
349349+ocamlfind query p
350350+</programlisting>
351351+352352+<para>
353353+and it will answer something like
354354+</para>
355355+356356+<programlisting>
357357+/usr/local/lib/ocaml/site-lib/p
358358+</programlisting>
359359+360360+<para>
361361+There is an environment variable OCAMLPATH which can specify further
362362+directories where packages are stored. (The search order is: first
363363+the directories in OCAMLPATH in turn, then the default path
364364+set in ocamlfind.conf)
365365+</para>
366366+367367+<para>
368368+Historically, this kind of query was the first and only way of using
369369+ocamlfind, and because of the similarity to the Unix find command it
370370+got its name. Finding out package locations is a basic but
371371+nethertheless important feature because it hides the details of the
372372+filesystem hierarchy. It is sufficient only to know the name of the
373373+package, and if needed, you can use the lookup mechanism implemented
374374+in ocamlfind to get the concrete directory.
375375+</para>
376376+</sect1>
377377+378378+379379+<sect1>
380380+<title>How a package directory looks like</title>
381381+382382+<para>
383383+Let us assume that the package p implements the modules M1 and M2. If
384384+you compile m1.mli and m2.mli you get the corresponding binary files
385385+m1.cmi and m2.cmi describing the interfaces of the modules. Of course,
386386+these cmi files must go into the package directory. It is recommended
387387+to put the source mli files into the directory, too, as they document
388388+the interface.
389389+</para>
390390+391391+<para>
392392+Another product of the compilation are two cmo files, m1.cmo and
393393+m2.cmo (we assume the bytecode compiler, the native compiler would
394394+create m1.cmx and m2.cmx). It is possible to put these files directly
395395+into the directory, but there is a better way. As it makes only sense
396396+to use both modules (a very common assumption), they should first be
397397+archived by doing
398398+</para>
399399+400400+<programlisting>
401401+ocamlc -a -o p.cma m1.cmo m2.cmo
402402+</programlisting>
403403+404404+<para>
405405+The archive p.cma contains both cmo files, and preserves the order of
406406+the files. Assumed that in M2 there is a reference to an entity in M1,
407407+M2 depends on M1 and when linking a program using these modules, M1
408408+must be mentioned first (e.g. ocamlc m1.cmo m2.cmo
409409+program.ml)<footnote><para>Note that C linkers usually require the reverse
410410+order, but only for archive elements, i.e. files with suffix
411411+.a.</para></footnote>. If you create the archive p.cma it contains already
412412+this dependency, and you need not to remember it when linking in the
413413+p.cma.
414414+</para>
415415+416416+<para>
417417+So far the files m1.cmi, m2.cmi, and p.cma are needed, and m1.mli and
418418+m2.mli are recommended. Usually there is another file in the
419419+directory, META, containing additional information about the package.
420420+In our example, META looks like
421421+</para>
422422+423423+<programlisting>
424424+description = "Our super-duper package"
425425+requires = ""
426426+version = "1"
427427+archive(byte) = "p.cma"
428428+</programlisting>
429429+430430+<para>The variable "requires" contains a list of packages that are
431431+required by this package (the names may be separated by commas or
432432+spaces). As our package, p, does not depend on any other package, this
433433+list is empty. I'll explain what happens with non-empty lists below.
434434+</para>
435435+436436+<para>
437437+The variable "version" is simply a version string, and "description"
438438+is a short comment on the package.
439439+</para>
440440+441441+<para>The variable "archive" denotes the files that have to be
442442+actually linked in if the package is used. This is again a list of
443443+(file) names. In contrast to the other variables, "archive" has a
444444+condition, written in parentheses. This value of "archive" will only
445445+be used if the predicate "byte" is true; this predicate is usually
446446+given if the program is compiled to bytecode. If you have a native
447447+archive, p.cmxa, of the two modules M1 and M2, you can add another
448448+line to META:
449449+</para>
450450+451451+<programlisting>
452452+archive(native) = "p.cmxa"
453453+</programlisting>
454454+455455+<para>
456456+The correct value for the "archive" variable is selected upon the
457457+given set of predicates.
458458+</para>
459459+460460+<para>Many packages can also be loaded at runtime with the
461461+<literal>Fl_dynload</literal> module. In this case, though, the
462462+variable "plugin" is used instead of "archive", e.g.</para>
463463+464464+<programlisting>
465465+plugin(byte) = "p.cma"
466466+plugin(native) = "p.cmxs"
467467+</programlisting>
468468+469469+<para>(You can create p.cmxs from p.cmxa with
470470+"ocamlopt -shared -linkall -o p.cmxs p.cmxa".) Note that "plugin" is entirely optional.
471471+</sect1>
472472+473473+474474+<sect1>
475475+<title>Querying information stored in META files</title>
476476+477477+<para>
478478+By setting some options of ocamlfind you can query the variables from
479479+the META files. For example, -long-format (or short -l) selects all
480480+interesting variables:
481481+</para>
482482+483483+<programlisting>
484484+ocamlfind query -long-format p
485485+</programlisting>
486486+487487+<para>
488488+This would answer something like:
489489+</para>
490490+491491+<programlisting>
492492+package: p
493493+description: Our super-duper package
494494+version: 1
495495+archive(s):
496496+linkopts:
497497+location: /usr/local/lib/ocaml/site-lib/p
498498+</programlisting>
499499+500500+<para>
501501+The values of the "archive" variable are missing because no predicate
502502+has been set, without further options "ocamlfind query" operates with
503503+an empty set of predicates. To get the bytecode archive, run:
504504+</para>
505505+506506+<programlisting>
507507+ocamlfind query -long-format -predicates byte p
508508+</programlisting>
509509+510510+<para>
511511+You can set more than one predicate. It usually does not make sense, but
512512+you could for example select both bytecode and native archives by:
513513+</para>
514514+515515+<programlisting>
516516+ocamlfind query -long-format -predicates byte,native p
517517+</programlisting>
518518+519519+<para>
520520+As both settings for "archive" are now equally like, the extraction
521521+mechanism chooses simply the first. The general rule is that the first
522522+most special value is selected.
523523+</para>
524524+</sect1>
525525+526526+527527+<sect1>
528528+<title>How to compile and link a program that uses a package</title>
529529+530530+<para>
531531+Now suppose you want to compile a program which calls functions of
532532+your new package p. If prog1.ml, prog2.ml, and prog3.ml are the three
533533+source files the program consists of, compile them with the commands
534534+</para>
535535+536536+<programlisting>
537537+ocamlfind ocamlc -package p -c prog1.ml
538538+ocamlfind ocamlc -package p -c prog2.ml
539539+ocamlfind ocamlc -package p -c prog3.ml
540540+</programlisting>
541541+542542+<para>
543543+The "ocamlfind ocamlc" invocation is a frontend to "ocamlc". Most
544544+arguments are directly passed to "ocamlc", but there are a few new
545545+options, and often some new options are implicitly added. Here, the
546546+new -package option is used, which adds search paths such that the
547547+modules of package p are found. Effectively, the following direct
548548+ocamlc invocations would be equivalent
549549+<footnote><para>If you specify the -verbose option, the constructed
550550+command is printed to the terminal. Actually, there are some more
551551+implicitly added options, especially -ccopt -I<dir> for every
552552+package directory <dir>. This means that you can compile C
553553+programs accessing header files stored in the package directory.
554554+</para></footnote>:
555555+</para>
556556+557557+<programlisting>
558558+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog1.ml
559559+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog2.ml
560560+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog3.ml
561561+</programlisting>
562562+563563+<para>
564564+The -I option has the effect that the named directory is also searched
565565+when looking up cmi files. Because of this you can refer directly to
566566+the modules M1 and M2 in the program sources.
567567+</para>
568568+569569+<para>
570570+In order to link the program use the following command:
571571+</para>
572572+573573+<programlisting>
574574+ocamlfind ocamlc -o program -package p -linkpkg prog1.cmo prog2.cmo prog3.cmo
575575+</programlisting>
576576+577577+<para>
578578+The -linkpkg option causes some more arguments to be added to the
579579+constructed ocamlc command. Especially, the name of the archive of p
580580+is extracted from the META file, and automatically inserted before the
581581+prog1.cmo argument. The resulting command looks like<footnote>
582582+<para>Again, the actual command contains even some more arguments...
583583+</para></footnote>:
584584+</para>
585585+586586+<programlisting>
587587+ocamlc -o program -I /usr/local/lib/ocaml/site-lib/p p.cma prog1.cmo prog2.cmo prog3.cmo
588588+</programlisting>
589589+590590+<para>
591591+Please note that the bytecode archive p.cma has been selected, and not
592592+the native archive p.cmxa. As it is known that the bytecode compiler
593593+is used, the predicate "byte" is automatically set.
594594+</para>
595595+596596+</sect1>
597597+598598+599599+<sect1>
600600+<title>Dependencies</title>
601601+602602+<para>
603603+Often packages use other packages themselves. Let q be another package
604604+consisting of the single module M3 which contains references to M1 and
605605+M2. At the first glance, we can ignore this when describing the
606606+package, as we could always add "-package p" and "-package q" options
607607+when compiling programs using q. This solution is not optimal, as the
608608+user of a package must have knowledge about details of the package that
609609+should normally be hidden. When we introduced the notion of packages,
610610+one of the most important properties was that we can replace packages
611611+by improved versions. Imagine that q is replaced by q', but q' uses
612612+not only p but also r. Every program that used q and is now forced to
613613+use q' must be changed (at least in the Makefile) in order to link r,
614614+too. This is clearly not what is intended by packages.
615615+</para>
616616+617617+<para>
618618+The far better solution is to store dependency information in the META
619619+files. The "requires" variable can list names of packages that are
620620+direct ancestors, i.e. referred directly. (Do not put indirect
621621+ancestors into this variable, for example further packages required by
622622+r when describing q - these are found out automatically.) The META
623623+file of q looks like:
624624+</para>
625625+626626+<programlisting>
627627+description = "Something that needs p"
628628+requires = "p"
629629+version = "1"
630630+archive(byte) = q.cma
631631+archive(native) = q.cmxa
632632+</programlisting>
633633+634634+<para>
635635+If you want to put several package names into "requires", separate
636636+them with commas or spaces.
637637+</para>
638638+639639+<para>
640640+The "ocamlfind query" command ignores the "requires" value by default,
641641+you must add the -recursive option. In this case, all direct or
642642+indirect ancestors of the packages given on the command line are
643643+selected, too, and printed in topological order. For example, the
644644+command
645645+</para>
646646+647647+<programlisting>
648648+ocamlfind query -recursive -long-format -predicate byte q
649649+</programlisting>
650650+651651+<para>
652652+prints two records:
653653+</para>
654654+655655+<programlisting>
656656+package: p
657657+description: Our super-duper package
658658+version: 1
659659+archive(s): p.cma
660660+linkopts:
661661+location: /usr/local/lib/ocaml/site-lib/p
662662+663663+package: q
664664+description: Something that needs p
665665+version: 1
666666+archive(s): q.cma
667667+linkopts:
668668+location: /usr/local/lib/ocaml/site-lib/p
669669+</programlisting>
670670+671671+<para>
672672+Without -recursive, only q would have been printed.
673673+</para>
674674+675675+<para>
676676+The compiler frontend provided with ocamlfind always works
677677+recursively. In order to compile and link another.ml that uses q, the
678678+following command is sufficient:
679679+</para>
680680+681681+<programlisting>
682682+ocamlfind ocamlc -o another -package q -linkpkg another.ml
683683+</programlisting>
684684+685685+<para>
686686+It is not necessary to specify -package p in this statement as the
687687+dependency relation is always used to find out the actually meant
688688+set of packages.
689689+</para>
690690+691691+</sect1>
692692+693693+694694+<sect1>
695695+<title>Linker options</title>
696696+697697+<para>
698698+<emphasis>
699699+Beginning with OCaml 3.00, the compiler itself has an interesting feature
700700+called "automatic linking" that makes the following mechanism superfluous in
701701+most cases. Automatic linking means that it is possible to store the linker
702702+options into the cma or cmxa file such that the compiler itself knows which
703703+options are necessary. Of course, the following mechanism still works, and it
704704+is still helpful when conditional linking is required.
705705+</emphasis>
706706+</para>
707707+708708+<para>
709709+OCaml has a C interface which means that C libraries can be linked in
710710+and C functions can be declared as new language primitives. Using such
711711+libraries requires special linker options. Some of the core libraries
712712+distributed with OCaml are partly implemented in C and thus additional
713713+libraries must be specified in the linking phase of the program.
714714+</para>
715715+716716+<para>
717717+For example, the "str" library providing regular expressions requires
718718+to be linked as follows:
719719+</para>
720720+721721+<programlisting>
722722+ocamlc -o prog str.cma my_file1.cmo my_file2.cmo -cclib -lstr
723723+</programlisting>
724724+725725+<para>
726726+The -cclib option passes the following argument directly to the
727727+underlying C linker which has the effect that libstr.a is linked in,
728728+too. The "-cclib -lstr" is directly associated with str.cma as the
729729+latter simply cannot be used without the former. Assume you would
730730+write a META file describing str. That "str.cma" should be linked in
731731+as archive is clear; the "-cclib -lstr" can be specified in another
732732+variable called "linkopts". The META file would look like:
733733+</para>
734734+735735+<programlisting>
736736+requires = ""
737737+version = "str from ocaml 2.02"
738738+archive(byte) = "str.cma"
739739+archive(native) = "str.cmxa"
740740+linkopts = "-cclib -lstr"
741741+</programlisting>
742742+743743+<para>
744744+This has the effect that specifying -linkpkg in one of the compiler
745745+frontends not only chooses one of the archive files, but also extracts
746746+the necessary linker options from the META file. The above example can
747747+also be compiled with:
748748+</para>
749749+750750+<programlisting>
751751+ocamlfind ocamlc -o prog -package str -linkpkg my_file1.cmo my_file2.cmo
752752+</programlisting>
753753+754754+<para>
755755+Most people will never write META files with "linkopts" settings. But
756756+this feature is very useful at least for the core libraries such as
757757+str. Because of this, the "findlib" distribution comes with META files
758758+for the core libraries in order to hide the linker options. This
759759+means that you can already use the packages "str", "dbm", "dynlink",
760760+"graphics", "num", "threads", "unix", and "camltk", and that the
761761+appropriate archives and linker options are automatically extracted.
762762+</para>
763763+764764+</sect1>
765765+766766+</chapter>
767767+768768+<!-- ********************************************************************** -->
769769+770770+<chapter>
771771+<title>Dependency analysis of packages</title>
772772+773773+<sect1>
774774+<title>Querying ancestors</title>
775775+776776+<para>
777777+Every package denotes in its META file only the list of direct
778778+ancestors. The theoretical model of the dependency relation is a
779779+directed acyclic graph (DAG), with the packages as vertices and edges
780780+from packages to their direct ancestors. The graph must be acyclic
781781+because OCaml does not allow cyclic dependencies between modules.
782782+</para>
783783+784784+<para>
785785+What happens if you query something like
786786+</para>
787787+788788+<programlisting>
789789+ocamlfind query -recursive p1 p2 ... pN
790790+</programlisting>
791791+792792+<para>
793793+is that the named packages p1 to pN are marked in the graph, and that
794794+repeatedly all direct ancestors of marked packages are marked, too,
795795+until there is not any marked package remaining with an unmarked
796796+ancestor. All marked packages are then printed in topological
797797+order. This simply means that for the printed packages p1 to pM holds
798798+that if pI is printed before pJ then pI is a (possibly indirect)
799799+ancestor of pJ.
800800+</para>
801801+802802+<para>
803803+The topological order plays a role when the link command is
804804+constructed by "ocamlfind ocamlc", as Ocaml requires that archives
805805+must be linked in topological order. For example, the link statement
806806+</para>
807807+808808+<programlisting>
809809+ocamlfind ocamlc -o another -package q -linkpkg another.ml
810810+</programlisting>
811811+812812+<para>
813813+must be turned into the effective command
814814+</para>
815815+816816+<programlisting>
817817+ocamlc -o another [...more options...] p.cma q.cma another.ml
818818+</programlisting>
819819+820820+<para>
821821+and <emphasis>not</emphasis>
822822+</para>
823823+824824+<programlisting>
825825+ocamlc -o another [...more options...] q.cma p.cma another.ml
826826+</programlisting>
827827+828828+<para>
829829+because there are references from q.cma to p.cma.
830830+</para>
831831+832832+<para>
833833+In C, there is a similar requirement when linking static archives. The
834834+linker backend ld wants the archives in <emphasis>reversed</emphasis>
835835+topological order, i.e. the deepest ancestor must come last in the
836836+list of linked archives. Because of this, the additional linker
837837+options specified in the "linkopts" variable are passed in reversed
838838+order to the underlying linker. This means that you can refer to C
839839+libraries of ancestor packages of p in C libraries provided in p.
840840+</para>
841841+842842+<para>
843843+Note that most operating systems do not require any specific order for
844844+dynamically linked C libraries (the exception is, surprise!, AIX).
845845+</para>
846846+847847+</sect1>
848848+849849+850850+<sect1>
851851+<title>Querying descendants</title>
852852+853853+<para>
854854+It is often useful to find out the descendants of a package, i.e. all
855855+direct or indirect users of the package. There is another "ocamlfind"
856856+subcommand that allows us to query descendants. For example, to get
857857+the direct and indirect users of p, type in
858858+</para>
859859+860860+<programlisting>
861861+ocamlfind query -descendants p
862862+</programlisting>
863863+864864+<para>
865865+The set of packages that are possible descendants is determined as
866866+follows:
867867+868868+<itemizedlist mark="bullet" spacing="compact">
869869+<listitem>
870870+<para>
871871+All packages located in directories mentioned in the environment
872872+variable OCAMLPATH are candidates. Note that only package directories
873873+containing META files are taken.
874874+</para>
875875+</listitem>
876876+877877+<listitem>
878878+<para>
879879+The packages in the default package directory are candidates, too.
880880+</para>
881881+</listitem>
882882+883883+<listitem>
884884+<para>
885885+If there are two packages with the same name, only the first
886886+counts, i.e. the first in OCAMLPATH, then the one in the default directory.
887887+</para>
888888+</listitem>
889889+</itemizedlist>
890890+891891+After this set has been determined, the complete dependency graph is
892892+constructed on it. As the descendants are queried, the dependencies
893893+are read in the inverse way compared with queries of the ancestors.
894894+</para>
895895+896896+</sect1>
897897+898898+899899+</chapter>
900900+901901+<!-- ********************************************************************** -->
902902+903903+<chapter>
904904+<title>A new frontend for ocamlc</title>
905905+906906+<sect1>
907907+<title>Compiling and linking</title>
908908+909909+<para>
910910+There are compiler frontends for the four compilers ocamlc, ocamlopt,
911911+ocamlmktop, and ocamlcp. They are simply called by specifying the name
912912+of the compiler as first argument to ocamlfind, i.e.
913913+</para>
914914+915915+<programlisting>
916916+ocamlfind ocamlc ...arguments...
917917+ocamlfind ocamlopt ...arguments...
918918+ocamlfind ocamlmktop ...arguments...
919919+ocamlfind ocamlcp ...arguments...
920920+</programlisting>
921921+922922+<para>
923923+In addition to the compiler options handled by the compilers
924924+themselves, the following options are available:
925925+</para>
926926+927927+<itemizedlist mark="bullet" spacing="compact">
928928+<listitem>
929929+<para>
930930+-package <name>: Causes that the package <name> is added to
931931+the package list, and that -I options are added for every package, and
932932+all direct or indirect ancestors.
933933+</para>
934934+</listitem>
935935+936936+<listitem>
937937+<para>
938938+-linkpkg: Causes that the archives of the packages in the package list
939939+and all their direct or indirect ancestors are added in topological
940940+order to the command line before the first file to compile or to
941941+link. Packages specified by -dontlink are not linked in, though.
942942+Furthermore, the linker options of these packages are added in
943943+reverse topological order at the end of the command line.
944944+</para>
945945+</listitem>
946946+947947+<listitem>
948948+<para>
949949+-predicates <predicate-list>: The named predicates are included
950950+in the list of predicates. Note that there are some predicates set by
951951+default, see below.
952952+</para>
953953+</listitem>
954954+955955+<listitem>
956956+<para>
957957+-dontlink <name>: Specifies that the package <name> and
958958+all its direct or indirect ancestors should not be linked in.
959959+</para>
960960+</listitem>
961961+962962+963963+<listitem>
964964+<para>
965965+-passopt <opt>: The option <opt> is passed directly to the
966966+underlying compiler. This is especially needed to pass undocumented
967967+options to the compiler.
968968+</para>
969969+</listitem>
970970+</itemizedlist>
971971+972972+<para>
973973+If you only want to compile, i.e. the -c option is in effect, you
974974+normally only need the -package option.
975975+</para>
976976+977977+<para>
978978+Depending on the compiler and on the given options, some predicates
979979+are set by default:
980980+</para>
981981+982982+<itemizedlist mark="bullet" spacing="compact">
983983+<listitem>
984984+<para>
985985+byte: The predicate "byte" is set when ocamlc, ocamlcp, or ocamlmktop
986986+is used to compile or link.
987987+</para>
988988+</listitem>
989989+990990+<listitem>
991991+<para>
992992+native: The predicate "native" is set when ocamlopt is used to compile
993993+or to link.
994994+</para>
995995+</listitem>
996996+997997+<listitem>
998998+<para>
999999+toploop: The predicate "toploop" is set when a toploop is being executed
10001000+</para>
10011001+</listitem>
10021002+10031003+<listitem>
10041004+<para>
10051005+create_toploop: The predicate "toploop" is set when ocamlmktop is used to
10061006+compile or to link a toploop
10071007+</para>
10081008+</listitem>
10091009+10101010+10111011+<listitem>
10121012+<para>
10131013+gprof: The predicate "gprof" is set when ocamlopt with -p option is
10141014+invoked.
10151015+</para>
10161016+</listitem>
10171017+10181018+<listitem>
10191019+<para>
10201020+mt: The predicate "mt" is set when the -thread or the -vmthread option is in effect.
10211021+</para>
10221022+</listitem>
10231023+10241024+<listitem>
10251025+<para>
10261026+mt_posix: The predicate "mt_posix" is set together with "mt" if the
10271027+POSIX thread implementation is selected.
10281028+</para>
10291029+</listitem>
10301030+10311031+<listitem>
10321032+<para>
10331033+mt_vm: The predicate "mt_vm" is set together with "mt" if the bytecode
10341034+thread implementation is selected.
10351035+</para>
10361036+</listitem>
10371037+10381038+<listitem>
10391039+<para>
10401040+autolink: The predicate "autolink" is set if the OCaml compiler can perform
10411041+automatic linking. This predicate is never set if the -noautolink option is
10421042+in effect.
10431043+</para>
10441044+</listitem>
10451045+10461046+</itemizedlist>
10471047+10481048+</sect1>
10491049+10501050+10511051+<sect1>
10521052+<title>Toploops and runtime systems</title>
10531053+10541054+<sect2>
10551055+<title>Dynamic toploops</title>
10561056+10571057+<para>
10581058+Recent versions of OCaml support dynamic loading of stub libraries
10591059+(but only for the more widely used operating systems). This means
10601060+that one can start a toploop by running
10611061+10621062+<programlisting>
10631063+$ ocaml
10641064+ Objective Caml version 3.07+2
10651065+10661066+# _
10671067+</programlisting>
10681068+10691069+and that it is now possible to load .cma archive files referring to
10701070+shared C libraries ("DLLs"). In older versions of OCaml this was
10711071+not possible and one had to create a so-called custom toploop
10721072+with the ocamlmktop command. This method is still supported and
10731073+explained below; however, nowadays it is often not necessary to
10741074+do so. For the modern way, findlib includes a small script called
10751075+"topfind" (i.e. "ocamlfind for the toploop") that can be directly
10761076+loaded into the toploop:
10771077+10781078+<programlisting>
10791079+# #use "topfind";;
10801080+- : unit = ()
10811081+Findlib has been successfully loaded. Additional directives:
10821082+ #require "package";; to load a package
10831083+ #list;; to list the available packages
10841084+ #camlp4o;; to load camlp4 (standard syntax)
10851085+ #camlp4r;; to load camlp4 (revised syntax)
10861086+ #predicates "p,q,...";; to set these predicates
10871087+ Topfind.reset();; to force that packages will be reloaded
10881088+ #thread;; to enable threads
10891089+10901090+- : unit = ()
10911091+# _
10921092+</programlisting>
10931093+</para>
10941094+10951095+<para>
10961096+A number of additional directives are now available. The "#require"
10971097+directive loads additional packages (with all dependencies):
10981098+</para>
10991099+11001100+<programlisting>
11011101+# #require "q1,q2,...,qM";;
11021102+</programlisting>
11031103+11041104+<para>
11051105+"#require" loads the listed packages and all their ancestors in the
11061106+right order, but leaves packages out that have already been loaded.
11071107+Scripts can now simply load and document which packages are used by a
11081108+"#require" directive right at the beginning of the script.
11091109+</para>
11101110+11111111+<para>
11121112+The #list directive lists the available packages as "ocamlfind list"
11131113+would do it.</para>
11141114+11151115+<para>
11161116+If you need additional predicates, you can set them with #predicates.
11171117+Note that this should be done before the first package is loaded in
11181118+order to ensure a consistent library system.</para>
11191119+11201120+<para>
11211121+The #thread directive enables multi-threading if possible. Note that
11221122+this is only supported for installations basing on the POSIX thread
11231123+library. (However, if you have only have VM threads, you can still
11241124+create a custom toploop supporting threads. See below.) Furthermore,
11251125+the #thread directive should be executed before any packages are
11261126+loaded.
11271127+</para>
11281128+11291129+<para>
11301130+The #camlp4o and #camlp4r directives load the camlp4 syntax parsers
11311131+for the standard and the revised syntax, respectively.
11321132+</para>
11331133+11341134+<para>
11351135+Especially when developing packages, it is sometimes necessary to
11361136+reload all dynamically loaded packages in the toploop. This can be
11371137+forced by
11381138+</para>
11391139+11401140+<programlisting>
11411141+Topfind.reset();;
11421142+</programlisting>
11431143+11441144+<para>
11451145+which causes the "#require" directive to load all packages again. The
11461146+Topfind module implements all the mentioned directives.
11471147+</para>
11481148+</sect2>
11491149+11501150+<sect2>
11511151+<title>Custom toploops</title>
11521152+11531153+<para>
11541154+It is very simple to create toploops. In order to make a toploop
11551155+executable that includes directly the packages p1,p2,..,pN simply
11561156+execute the command
11571157+</para>
11581158+11591159+<programlisting>
11601160+ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib -linkpkg
11611161+</programlisting>
11621162+11631163+<para>
11641164+(Maybe you have to add the -custom switch.) Note that one of the
11651165+packages should be "findlib" itself, because this adds the
11661166+additional directives mentioned above, i.e. you can directly use
11671167+these directives without #use "topfind" (but running "topfind"
11681168+is harmless).
11691169+</para>
11701170+11711171+<para>
11721172+Note that such a toploop includes the code of the packages given
11731173+on the command line, but that it does not automatically add the
11741174+package directories to the search path (in previous versions of
11751175+findlib this was tried, but it never really worked). To do so,
11761176+you still have to #require the packages.
11771177+</para>
11781178+11791179+<para>
11801180+In order to create a toploop supporting VM-style threads, use the
11811181+command
11821182+11831183+<programlisting>
11841184+ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib,threads -vmthread -linkpkg
11851185+</programlisting>
11861186+11871187+Now the #thread directive will work and enable the access to the
11881188+multi-threading modules.
11891189+</para>
11901190+</sect2>
11911191+11921192+<sect2>
11931193+<title>Runtime systems</title>
11941194+11951195+<para>
11961196+Building of runtime systems is supported, too. For example, you can run
11971197+</para>
11981198+11991199+<programlisting>
12001200+ocamlfind ocamlc -o runtime -make-runtime -package p1,p2,...,pN -linkpkg
12011201+</programlisting>
12021202+12031203+<para>
12041204+but the problem is which options to specify when a program is linked
12051205+for this runtime system. If you executed
12061206+</para>
12071207+12081208+<programlisting>
12091209+ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\
12101210+ -linkpkg m1.cmo ... mM.cmo
12111211+</programlisting>
12121212+12131213+<para>
12141214+it would be tried to link the archives from the packages again into
12151215+the bytecode binary. Because of this, it is necessary to suppress
12161216+linking in packages of the runtime system when linking binaries for a
12171217+runtime system. The -dontlink option can be used for this:
12181218+</para>
12191219+12201220+<programlisting>
12211221+ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\
12221222+ -dontlink p1,p2,...,pN -linkpkg m1.cmo ... mM.cmo
12231223+</programlisting>
12241224+12251225+<para>
12261226+Note that the -package option can enumerate more packages than
12271227+-dontlink, and in this case the additional packages are actually
12281228+linked in as they are not contained in the runtime system.
12291229+</para>
12301230+</sect2>
12311231+12321232+</sect1>
12331233+12341234+12351235+<sect1>
12361236+<title>Multi-threaded applications</title>
12371237+12381238+<para>
12391239+If an already existing package is planned to be used in a
12401240+multi-threaded environment, some language constructs must be replaced
12411241+by different ones. For example, global variables must be protected by
12421242+locks (mutexes). Because of
12431243+this it is common practice to provide two versions of such packages,
12441244+one for single-, one for multi-threaded applications (or, another
12451245+technique, there is a special add-on module that initializes a
12461246+library for multi-threaded usage).
12471247+</para>
12481248+12491249+<para>
12501250+The predicate "mt" should be used to recognize multi-threaded
12511251+applications. For example, a package could consist of two archives,
12521252+p.cma, and p_mt.cma, where the latter archive is designed for
12531253+multi-threaded execution. The META file would contain the following
12541254+lines causing that always the appropriate archive is linked:
12551255+</para>
12561256+12571257+<programlisting>
12581258+archive(byte) = "p.cma"
12591259+archive(byte,mt) = "p_mt.cma"
12601260+</programlisting>
12611261+12621262+<para>
12631263+When querying the package database the option "-predicates mt" must be
12641264+included in the commands in order to select the appropriate entries.
12651265+</para>
12661266+12671267+<para>
12681268+When compiling or linking it is necessary to specify either the
12691269+"-thread" or the "-vmthread" option anyway. The compiler frontends
12701270+detects these options, and automatically set the "mt"
12711271+predicate. The following command is an example for this; note that the
12721272+"threads" package means the standard library of Ocaml providing thread
12731273+support:
12741274+</para>
12751275+12761276+<programlisting>
12771277+ocamlfind ocamlc -thread -package threads,p,q -c x.ml
12781278+</programlisting>
12791279+12801280+<para>
12811281+For some operating systems, Ocaml supports the native multithreading
12821282+libraries conforming to the POSIX interface. As the linker options are
12831283+generally different, another predicate must be set to get these
12841284+libraries linked in. The predicate "mt_posix" indicates POSIX
12851285+threads while "mt_vm" indicates bytecode (virtual machine) threads.
12861286+</para>
12871287+12881288+</sect1>
12891289+12901290+12911291+<sect1>
12921292+<title>Support for gprof-enabled modules</title>
12931293+12941294+<para>
12951295+When a program is compiled and linked with ocamlopt, gprof-style
12961296+profiling can be enabled by selecting the -p option. This means that
12971297+the resulting archives are different, and that it would be useful if
12981298+there were another predicate in order to select such archives.
12991299+</para>
13001300+13011301+<para>
13021302+The predicate "gprof" can be used for this. It is automatically set if
13031303+the -p option turns on the gprof-mode in an ocamlopt invocation.
13041304+</para>
13051305+13061306+</sect1>
13071307+13081308+</chapter>
13091309+13101310+<!-- ********************************************************************** -->
13111311+13121312+<chapter>
13131313+<title>Complex packages</title>
13141314+13151315+<sect1>
13161316+<title>The standard predicates</title>
13171317+13181318+<para>
13191319+Settings in the META file have usually the form:
13201320+</para>
13211321+13221322+<programlisting>
13231323+varname ( predname1, predname2, ... ) = "value"
13241324+</programlisting>
13251325+13261326+<para>
13271327+The names in the parentheses are called <emphasis>formal
13281328+predicates</emphasis> and express a condition which must hold such
13291329+that the value on the right side is selected. When querying
13301330+information you can specify a set of <emphasis> actual
13311331+predicates</emphasis> that are assumed to be true. There are the
13321332+following standard predicates:
13331333+</para>
13341334+13351335+<itemizedlist mark="bullet" spacing="compact">
13361336+<listitem>
13371337+<para>
13381338+The "byte" predicate means that the bytecode compiler is used.
13391339+</para>
13401340+</listitem>
13411341+13421342+<listitem>
13431343+<para>
13441344+The "native" predicate means that the native compiler is used.
13451345+</para>
13461346+</listitem>
13471347+13481348+<listitem>
13491349+<para>
13501350+The "toploop" predicate means that the toploop is available in the
13511351+linked program.
13521352+</para>
13531353+</listitem>
13541354+13551355+<listitem>
13561356+<para>
13571357+The "mt" predicate means that the program is multi-threaded.
13581358+</para>
13591359+</listitem>
13601360+13611361+<listitem>
13621362+<para>
13631363+The "mt_posix" predicate means that in the case "mt" is set, too, the
13641364+POSIX libraries are used to implement threads.
13651365+</para>
13661366+</listitem>
13671367+13681368+<listitem>
13691369+<para>
13701370+The "mt_vm" predicate means that in the case "mt" is set, too, the
13711371+VM-based libraries are used to implement threads.
13721372+</para>
13731373+</listitem>
13741374+13751375+<listitem>
13761376+<para>
13771377+The "gprof" predicate means that in the case "native" is set, too, the
13781378+program is compiled for profiling
13791379+</para>
13801380+</listitem>
13811381+13821382+<listitem>
13831383+<para>
13841384+The "autolink" predicate indicates that ocamlc is able to perform
13851385+automatic linking.
13861386+</para>
13871387+</listitem>
13881388+13891389+13901390+</itemizedlist>
13911391+13921392+<para>
13931393+It is possible to have more predicates indicating different
13941394+environments; just use them, it is not necessary to declare them
13951395+anywhere.
13961396+</para>
13971397+13981398+<para>
13991399+The value which is selected for a variable depends on the set of
14001400+assumed predicates. In order to get selected, all formal predicates
14011401+must be included in the set of actual predicates; if still
14021402+multiple values fulfill this condition, the value with the maximum
14031403+number of formal predicates is used; and if still in doubt, the first
14041404+of these in the META file is taken.
14051405+</para>
14061406+14071407+<para>
14081408+It is possible to negate a formal predicate: Just prepend a minus
14091409+sign to it, e.g. var(p,-q). In this case, it is required that the
14101410+negated predicates are false (not contained in the set of actual predicates).
14111411+</para>
14121412+14131413+<para>
14141414+For all variables that are evaluated after the dependency analysis,
14151415+findlib adds the so-called package predicates to the set of actual
14161416+predicates. For every selected package p the predicate pkg_p
14171417+(with the fixed prefix "pkg_") is added. One application of this
14181418+are compatibility checks: The special <literal>error</literal> variable
14191419+is evaluated after dependency analysis, but before anything else
14201420+is done. For example, to state that package p is incompatible with
14211421+package q one can add to the META file of p:
14221422+14231423+<programlisting>
14241424+error(pkg_q) = "Package p is incompatible with q"
14251425+</programlisting>
14261426+14271427+The value of <literal>error</literal> is printed as message in the
14281428+case the condition is true.</para>
14291429+14301430+</sect1>
14311431+14321432+14331433+<sect1>
14341434+<title>Defining additional predicates</title>
14351435+14361436+<para>
14371437+Additional predicates can be simply used without any declaration,
14381438+i.e. you can freely invent new predicates. One application of them
14391439+is to express conditional linkage. For example, one may provide archives
14401440+for various conditions, such as a production archive, and a
14411441+development archive. A single new predicate, "development", would be
14421442+sufficient to express this:
14431443+</para>
14441444+14451445+<programlisting>
14461446+archive(byte) = "p_production.cma"
14471447+archive(byte,development) = "p_development.cma"
14481448+</programlisting>
14491449+14501450+<para>
14511451+When linking, include a "-predicates development" argument in the
14521452+compiler command to select the development archive, otherwise the
14531453+production archive is taken.
14541454+</para>
14551455+14561456+<para>
14571457+Predicates could also be used to select among several implementations
14581458+of the same module. Define simply one predicate per implementation,
14591459+e.g. "p_impl1", "p_impl2", and "p_impl3", and specify the archives for
14601460+every implementation separately:
14611461+</para>
14621462+14631463+<programlisting>
14641464+archive(byte,p_impl1) = "p_impl1.cma"
14651465+archive(byte,p_impl2) = "p_impl2.cma"
14661466+archive(byte,p_impl3) = "p_impl3.cma"
14671467+</programlisting>
14681468+14691469+<para>
14701470+In the case that the implementations have different dependencies,
14711471+simply provide multiple "requires" variables:
14721472+</para>
14731473+14741474+<programlisting>
14751475+requires(p_impl1) = "q"
14761476+requires(p_impl2) = "q,r"
14771477+requires(p_impl3) = "r,s"
14781478+</programlisting>
14791479+14801480+<para>
14811481+Sometimes, the implementations require different linker options. In
14821482+this case, define several versions of the "linkopts" variable just
14831483+like in the "requires" example.
14841484+</para>
14851485+14861486+<para>
14871487+Note that predicates are global identifiers that can be potentially
14881488+applied to every selected package. In the case that a predicate is
14891489+only meaningful for a single package, it is common practice to
14901490+choose the package name as prefix of the predicate name (e.g.
14911491+"netstring_minimum" is a predicate usually only applied to the "netstring"
14921492+package).
14931493+<para>
14941494+14951495+<para>
14961496+Predicates could be used to select which features of a library are
14971497+linked. For example,
14981498+14991499+<programlisting>
15001500+archive(byte) = "p_basic.cma"
15011501+archive(byte,p_extension) = "p_basic.cma p_ext.cma"
15021502+</programlisting>
15031503+15041504+would add the p_ext.cma archive only if the p_extension predicate
15051505+were set. <emphasis>It is considered as bad practice to select
15061506+extensions of libraries by predicates. Findlib provides the construct
15071507+of subpackages for this purpose.</emphasis>
15081508+</para>
15091509+</sect1>
15101510+15111511+15121512+<sect1>
15131513+ <title>Appending to variables</title>
15141514+15151515+<para>The syntax
15161516+15171517+<programlisting>
15181518+varname ( predname1, predname2, ... ) += "value"
15191519+</programlisting>
15201520+15211521+(note the "+=" operator) can be used to append values to variables
15221522+depending on whether predicates are true. The "+=" lines in the META
15231523+file are evaluated one after the other, and <emphasis>every</emphasis>
15241524+line is selected for which the formal predicates are satisfied,
15251525+and these lines are added to the current value of the variable. This is
15261526+different from the "=" operator where only the most specific
15271527+assignment is taken.
15281528+</para>
15291529+15301530+<para>The values are considered as space-separated words when they
15311531+are appended, i.e. the new words are added to the list of current
15321532+words.</para>
15331533+15341534+<para>For example, in the hypothetic META file
15351535+15361536+<programlisting>
15371537+var(p) += "a"
15381538+var(p,q) += "b"
15391539+</programlisting>
15401540+15411541+the value of var is "a b" if both p and q are true, and the value is
15421542+only "a" is only p is true (and the value is empty otherwise). If
15431543+the operator "=" had been used, the value would have been only "b"
15441544+when both p and q are true.</para>
15451545+15461546+<para>In the case that there both "=" and "+=" settings for
15471547+the same variable, a special algorithm is used: First the most specific
15481548+"=" setting is determined, and second all matching "+=" settings are
15491549+appended in the order they appear in the file.</para>
15501550+15511551+<para>Finally, here is a real-world example. Imagine you have an
15521552+archive p.cma and a special extension for the toploop, p_top.cma.
15531553+Furthermore, there is a special debugging version p_dev.cma that
15541554+replaces p.cma during development. You can now simply write
15551555+15561556+<programlisting>
15571557+archive(byte) = "p.cma"
15581558+archive(byte,development) = "p_dev.cma"
15591559+archive(byte,toploop) += "p_top.cma"
15601560+</programlisting>
15611561+15621562+to select <emphasis>either</emphasis> p.cma or p_dev.cma, and append
15631563+p_top.cma for toploops to whatever was selected in the first step.</para>
15641564+</sect1>
15651565+15661566+15671567+15681568+<sect1>
15691569+ <title>Subpackages</title>
15701570+15711571+<para>
15721572+Sometimes a package consists of several archive files that are closely
15731573+related. It is now possible to express dependencies between these
15741574+archives by splitting the package into several parts called subpackages.
15751575+For example, package p consists of a base archive p_base.cma, and two
15761576+extensions p_ext1.cma and p_ext2.cma that both require the base archive
15771577+but are independent of each other. This META file expresses this
15781578+dependency directly:
15791579+15801580+<programlisting>
15811581+# META file of package p:
15821582+requires = "p.base"
15831583+15841584+package "base" (
15851585+ archive(byte) = "p_base.cma"
15861586+)
15871587+15881588+package "ext1" (
15891589+ requires = "p.base"
15901590+ archive(byte) = "p_ext1.cma"
15911591+)
15921592+15931593+package "ext2" (
15941594+ requires = "p.base"
15951595+ archive(byte) = "p_ext2.cma"
15961596+)
15971597+</programlisting>
15981598+15991599+If installed as package "p", this definition actually defines four
16001600+logical packages: "p" (the main package), "p.base", "p.ext1", and
16011601+"p.ext2" (the subpackages). These four entities only share the META
16021602+file in which they are declared, and the directory where the archive
16031603+files are stored, but all other properties can be individually set
16041604+for each package. This also means that all package dependencies
16051605+must explicitly added by "requires" variables, as there are no
16061606+implied dependencies. In this example, the main package and "p.ext1"
16071607+and "p.ext2" are all dependent on "p.base".
16081608+</para>
16091609+16101610+<para>
16111611+The users of this installation can refer to all four packages. This
16121612+means that
16131613+16141614+<programlisting>
16151615+ocamlfind ocamlc -package p -linkpkg ...
16161616+</programlisting>
16171617+16181618+links only p_base.cma into the final program, while
16191619+16201620+<programlisting>
16211621+ocamlfind ocamlc -package p.ext1 -linkpkg ...
16221622+</programlisting>
16231623+16241624+selects both p_base.cma and p_ext1.cma.
16251625+</sect1>
16261626+16271627+16281628+16291629+<sect1>
16301630+ <title>Glue code</title>
16311631+16321632+<para>Imagine we have two packages p and q that are normally
16331633+independent, i.e. one can link p without q, and q without p. However,
16341634+when both p and q are used in the same program, it is expected that
16351635+they cooperate with each other. Of course, this situation can be
16361636+modeled with the help of subpackages (a real-world example of this are
16371637+p=lablgtk and q=lablgl).</para>
16381638+16391639+<para>The idea is as follows: p has a subpackage p.for_q that contains
16401640+code with special features for q, and q has a subpackage q.use_p that
16411641+depends on p, p.for_q, and q, and that contains the code using the
16421642+special features of p. Expressed in META files, p would define
16431643+16441644+<programlisting>
16451645+# META file for p:
16461646+requires = "..."
16471647+archive = "..."
16481648+16491649+package "for_q" (
16501650+ requires = "p"
16511651+ archive = "..."
16521652+)
16531653+</programlisting>
16541654+16551655+and q would define
16561656+16571657+<programlisting>
16581658+# META file for q:
16591659+requires = "..."
16601660+archive = "..."
16611661+16621662+package "use_p" (
16631663+ requires = "q,p.for_q"
16641664+ archive = "..."
16651665+)
16661666+</programlisting>
16671667+16681668+Of course, the program using both libraries must explicitly enable
16691669+the subpackages by mentioning "q.use_p" on the ocamlfind command line,
16701670+otherwise the glue code would be omitted.
16711671+</para>
16721672+16731673+<para>
16741674+Unfortunately, it is not possible to use the package predicates
16751675+pkg_p and pkg_q to add archives depending on whether the other
16761676+package is also selected. The problem is that the order cannot
16771677+be specified, i.e. whether p must be linked first or q.
16781678+</para>
16791679+</sect1>
16801680+16811681+16821682+16831683+<sect1>
16841684+<title>Plugins</title>
16851685+16861686+<para><emphasis>(Since findlib-1.6.)</emphasis></para>
16871687+16881688+<para>
16891689+Plugins are packages that can be loaded at runtime. Plugins are
16901690+intended as a mechanism for loading add-on code into
16911691+executables. Technically, there is some overlap with the concept of a
16921692+"shared library". Note, however, that there is no universal support
16931693+for plugins, as it is unimplemented on some platforms, and only
16941694+poorly on some others (including x86 in the 32 bit case). Also, there
16951695+must always be an explicit "load" statement in the loading executable.
16961696+You cannot link an executable directly against plugins.
16971697+</para>
16981698+16991699+<sect2><title>Preparing a plugin</title>
17001700+<para>
17011701+For bytecode there is no problem to load cma files at runtime.
17021702+For native-code, though, you need to convert cmxa files into cmxs
17031703+files first:</para>
17041704+17051705+<programlisting>
17061706+ocamlopt -shared -linkall -o m.cmxs m.cmxa
17071707+</programlisting>
17081708+17091709+<para>As mentioned, be prepared that this command fails on platforms where
17101710+plugins are unavailable.</para>
17111711+17121712+<para>The cmxs files can then be referenced from META. We don't use
17131713+the "archive" variable in this case but "plugin":</para>
17141714+17151715+<programlisting>
17161716+plugin(byte) = "m.cma"
17171717+plugin(native) = "m.cmxs"
17181718+</programlisting>
17191719+17201720+<para>Before findlib-1.6, there was some half-official convention using the
17211721+"plugin" predicate. This is still supported, but deprecated:</para>
17221722+17231723+<programlisting>
17241724+archive(byte) = "m.cma"
17251725+archive(native,plugin) = "m.cmxs"
17261726+</programlisting>
17271727+</sect2>
17281728+17291729+<sect2><title>Load-time dependencies</title>
17301730+<para>Plugins can be, of course, be dependent on other
17311731+plugins. You run into a problem, though, when you make a plugin dependent
17321732+on a package that doesn't qualify as plugin (i.e. lacks the "plugin"
17331733+definition). In this case, the loader simply skips the dependency,
17341734+and you cannot load the plugin.</para>
17351735+17361736+<para>Because of this dependency issue, it is recommended to add the
17371737+"plugin" variable to all packages that are installed on a system,
17381738+because this does not only allow it to load all packages at runtime, but
17391739+also to use these packages as dependency of the actual plugin code.</para>
17401740+17411741+<para>That said, you just need to add a "requires" directive, e.g.
17421742+17431743+<programlisting>
17441744+requires = "pkg1"
17451745+plugin(byte) = "m.cma"
17461746+plugin(native) = "m.cmxs"
17471747+</programlisting>
17481748+</para>
17491749+</sect2>
17501750+17511751+<sect2><title>How to load a plugin</title>
17521752+<para>Linking an executable that can load a plugin: An executable
17531753+must link the package "findlib.dynload". This does not only add
17541754+the loader, but also special initialization code to the executable:</para>
17551755+17561756+<programlisting>
17571757+ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg ...
17581758+</programlisting>
17591759+17601760+<para>In particular, this records the packages that are already included
17611761+into the executable (in-core packages). If a plugin is now dependent
17621762+on such a package, this is recognized, and the package is not loaded
17631763+(which would not work anyway).</para>
17641764+17651765+<para>Now, you can load a plugin "foo" with:</para>
17661766+17671767+<programlisting>
17681768+Fl_dynload.load_packages ["foo"]
17691769+</programlisting>
17701770+17711771+<para>This loads the cma or cmxs files, and runs the initialization code
17721772+of all top-level definitions of the included modules.</para>
17731773+17741774+<para>Of course, you can also call <literal>load_packages</literal> from
17751775+a library if "findlib.dynload" is a required package of the library
17761776+package.</para>
17771777+</sect2>
17781778+17791779+<sect2><title>Fat plugins</title>
17801780+<para>Sometimes it is handy to create plugins that already include all
17811781+the required packages. The plugin acts more like a dynamically loadable
17821782+executable that already includes whatever it needs. You can create such
17831783+a "fat" plugin with:
17841784+17851785+<programlisting>
17861786+ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 m.cmxa
17871787+</programlisting>
17881788+17891789+In this case, the "requires" line in the META file should remain empty.
17901790+</para>
17911791+17921792+<para>
17931793+Note, however, that you cannot handle packages this way that are already
17941794+linked into the main program, because it is invalid to load a module that
17951795+is already part of the main executable. Let's assume that the executable
17961796+links in q1, q2, and q3. Then, you need to exclude these packages from the
17971797+plugin. The -dont-link option comes handy in this case:
17981798+17991799+<programlisting>
18001800+ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 -dont-link q1,q2,q3 m.cmxa
18011801+</programlisting>
18021802+18031803+This excludes q1,q2,q3 even if these packages occur as dependencies of
18041804+p1,p2,p3. In this case, though, you need to put q1,q2,q3 into the "requires"
18051805+field of META.
18061806+</para>
18071807+</sect2>
18081808+</sect1>
18091809+18101810+18111811+18121812+<sect1>
18131813+<title>Lint</title>
18141814+18151815+<para><emphasis>(Since findlib-1.6.)</emphasis></para>
18161816+18171817+<para>
18181818+As it has become more and more complicated to write correct META files
18191819+there is now some support for recognizing typical problems. Just use
18201820+18211821+<programlisting>
18221822+ocamlfind lint META
18231823+</programlisting>
18241824+18251825+to check the file META in the current directory. The tool reports problematic
18261826+lines in META, e.g.
18271827+18281828+<programlisting>
18291829+archive(byte,plugin) = "oUnit.cma"
18301830+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
18311831+18321832+archive(native,plugin) = "oUnit.cmxs"
18331833+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
18341834+</programlisting>
18351835+18361836+</para>
18371837+</sect1>
18381838+</chapter>
18391839+18401840+18411841+<!-- ********************************************************************** -->
18421842+18431843+<chapter>
18441844+<title>How to create your own packages</title>
18451845+18461846+<sect1>
18471847+<title>Installing and removing packages</title>
18481848+18491849+<para>
18501850+The ocamlfind command can install and remove packages. For example,
18511851+to install a package p containing the files META, m1.cmi, m2.cmi, p.cma,
18521852+run
18531853+18541854+<programlisting>
18551855+ocamlfind install p META m1.cmi m2.cmi p.cma
18561856+</programlisting>
18571857+18581858+This installs the files into the default location for new packages
18591859+(set in ocamlfind.conf). If you have files that are not always built,
18601860+add these after the -optional switch:
18611861+18621862+<programlisting>
18631863+ocamlfind install p META m1.cmi m2.cmi p.cma -optional p.cmxa p.cmxs
18641864+</programlisting>
18651865+18661866+To remove the package, run
18671867+18681868+<programlisting>
18691869+ocamlfind remove p
18701870+</programlisting>
18711871+18721872+Note that every package must have a META file, it is not possible to
18731873+omit it.
18741874+</para>
18751875+</sect1>
18761876+18771877+18781878+<sect1>
18791879+<title>Change your Makefile</title>
18801880+18811881+<para>
18821882+Here is a commented version of a Makefile that may be used to compile
18831883+and link a package. It describes the frequent case that the package
18841884+simply consists of a bundle of modules that are dependent on other
18851885+packages.
18861886+</para>
18871887+18881888+<para>
18891889+First, some general definitions. NAME is the name of the package. The
18901890+OBJECTS variable enumerates the bytecode objects, whereas XOBJECTS
18911891+names the native objects. The same naming convention is used for
18921892+ARCHIVE and XARCHIVE, specifying the resulting bytecode, resp. native
18931893+archive file. The REQUIRES variable lists the names of the packages
18941894+that are needed for this package. If you need additional predicates,
18951895+put them into the PREDICATES variable.
18961896+</para>
18971897+18981898+<programlisting>
18991899+NAME = p
19001900+19011901+OCAMLC = ocamlfind ocamlc
19021902+OCAMLOPT = ocamlfind ocamlopt
19031903+OCAMLDEP = ocamldep
19041904+19051905+OBJECTS = p1.cmo p2.cmo
19061906+XOBJECTS = p1.cmx p2.cmx
19071907+19081908+ARCHIVE = $(NAME).cma
19091909+XARCHIVE = $(NAME).cmxa
19101910+SARCHIVE = $(NAME).cmxs
19111911+19121912+REQUIRES = unix str q r s
19131913+PREDICATES =
19141914+</programlisting>
19151915+19161916+<para>
19171917+The default goal is "all", causing the bytecode archive to be
19181918+created. In order to get a native archive, choose "opt" as second goal.
19191919+(The ".PHONY" line is a declaration meaningful for GNU-make; "all" and
19201920+"opt" are only virtual goals as there no files "all", or "opt" which
19211921+is indicated by making them dependents of ".PHONY".)
19221922+</para>
19231923+19241924+<programlisting>
19251925+.PHONY: all opt
19261926+all: $(ARCHIVE)
19271927+opt: $(XARCHIVE) $(SARCHIVE)
19281928+</programlisting>
19291929+19301930+<para>
19311931+The following two rules create the bytecode resp. native archive from
19321932+the objects.
19331933+</para>
19341934+19351935+<programlisting>
19361936+$(ARCHIVE): $(OBJECTS)
19371937+ $(OCAMLC) -a -o $(ARCHIVE) -package "$(REQUIRES)" -linkpkg \
19381938+ -predicates "$(PREDICATES)" $(OBJECTS)
19391939+$(XARCHIVE): $(XOBJECTS)
19401940+ $(OCAMLOPT) -a -o $(XARCHIVE) -package "$(REQUIRES)" -linkpkg \
19411941+ -predicates "$(PREDICATES)" $(XOBJECTS)
19421942+19431943+$(SARCHIVE): $(XARCHIVE)
19441944+ $(OCAMLOPT) -shared -o $(SARCHIVE) $(XARCHIVE) || true
19451945+</programlisting>
19461946+19471947+<para>
19481948+Note that the cmxs archive is optional: we just ignore the error
19491949+when it cannot be built.
19501950+</para>
19511951+19521952+<para>
19531953+These rules compile the modules independently. The lines similar to
19541954+".ml.cmo" must be read: "How to transform files with suffix .ml into
19551955+files with suffix .cmo". The corresponding command can refer to the
19561956+input file as "$<" and to the output file(s) as "$@".
19571957+</para>
19581958+19591959+<programlisting>
19601960+.SUFFIXES: .cmo .cmi .cmx .ml .mli
19611961+19621962+.ml.cmo:
19631963+ $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
19641964+ -c $<
19651965+.mli.cmi:
19661966+ $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
19671967+ -c $<
19681968+.ml.cmx:
19691969+ $(OCAMLOPT) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
19701970+ -c $<
19711971+</programlisting>
19721972+19731973+<para>
19741974+The "depend" goal is the file describing the dependencies within the
19751975+package; it is created by ocamldep.
19761976+</para>
19771977+19781978+<programlisting>
19791979+depend: *.ml *.mli
19801980+ $(OCAMLDEP) *.ml *.mli >depend
19811981+include depend
19821982+</programlisting>
19831983+19841984+<para>
19851985+The "install" rule is a bit tricky. First it is tested if there is a
19861986+native archive to install, and if so, the variable "extra" contains
19871987+the corresponding files. The "ocamlfind install" command creates a new
19881988+package directory and puts the given files into it.
19891989+</para>
19901990+19911991+<programlisting>
19921992+.PHONY: install uninstall
19931993+install: all
19941994+ ocamlfind install $(NAME) *.mli *.cmi $(ARCHIVE) META \
19951995+ -optional $(XARCHIVE) $(SARCHIVE)
19961996+19971997+uninstall:
19981998+ ocamlfind remove $(NAME)
19991999+</programlisting>
20002000+20012001+<para>
20022002+Last but not least a cleanup rule:
20032003+</para>
20042004+20052005+<programlisting>
20062006+.PHONY: clean
20072007+ rm -f *.cmi *.cmo *.cmx *.cma *.cmxa *.a
20082008+</programlisting>
20092009+</sect1>
20102010+20112011+20122012+<sect1>
20132013+<title>Using the Makefile wizard</title>
20142014+20152015+<para>
20162016+Especially for beginners, the findlib distribution includes a GUI to
20172017+create Makefiles. As this is an optional feature, it must have been
20182018+selected when findlib was built (option -with-toolbox). To invoke the
20192019+GUI, run the command
20202020+20212021+<programlisting>
20222022+$ ocamlfind findlib/make_wizard
20232023+</programlisting>
20242024+20252025+(Btw, this is the general syntax to run executables installed in
20262026+package directories.) The wizard starts, and allows you to describe
20272027+your project. When you save the result, not only a "Makefile" is
20282028+created, but also the file ".make-wizard" containing the state.
20292029+If you later start the wizard again, this file will be automatically
20302030+loaded, and you can modify your definition.</para>
20312031+20322032+<para>The wizard consists of seven (hopefully self-explanatory) pages
20332033+you can fill out. The basic idea is that the .ml, .mli, .mly, and .mll
20342034+files in the current directory are compiled to a .cma or .cmxa
20352035+archive, and that optionally executables are created from this archive
20362036+and from additional modules (main programs). This scheme can be both
20372037+used for libraries and application programs.</para>
20382038+20392039+<para>You can choose packages you want to use in your library or
20402040+program by clicking at them in a selection box. The camlp4 syntax
20412041+parsers can be optionally enabled. The modules to be compiled can
20422042+be picked from the current directory, they must be selected in the
20432043+right order, however.</para>
20442044+20452045+<para>The generated "Makefile" defines a number of logical targets
20462046+(like "all", "opt", etc) that are explained at the beginning of the
20472047+file. The file is fully commented, and not very difficult to understand.
20482048+Only traditional Makefile syntax is used, so it is expected that it
20492049+works for every version of the "make" utility.
20502050+</para>
20512051+20522052+<para>When you build the project, the META file is created
20532053+dynamically. If you do not like this, set the variable MAKE_META to
20542054+the empty string. (It is a good idea to put such setting into a
20552055+second file, and enter the name of this file into the box "Local
20562056+extensions in" of the wizard, so you can generate the "Makefile" again
20572057+without overwriting your own modifications. This second file can
20582058+override the setting in the generated "Makefile".)
20592059+</para>
20602060+20612061+</sect1>
20622062+20632063+</chapter>
20642064+20652065+20662066+<!-- ********************************************************************** -->
20672067+20682068+<chapter>
20692069+<title>FAQs</title>
20702070+20712071+<sect1>
20722072+<title>Does findlib support the autolink feature of OCaml 3?</title>
20732073+20742074+<para>
20752075+<emphasis>Short answer:</emphasis> Findlib is compatible with autolink
20762076+</para>
20772077+20782078+<para>
20792079+The new archive format introduced with OCaml 3 can store the linker options
20802080+that are necessary to link an archive. For example:
20812081+20822082+<programlisting>
20832083+ocamlc -a -o myarchive.cma mymodule.cmo -cclib -lmylibrary
20842084+</programlisting>
20852085+20862086+This command does not only create the new archive
20872087+<literal>myarchive.cma</literal>, but it also writes into a special section of
20882088+that file that the linker option <literal>-cclib -lmylibrary</literal> is
20892089+necessary to link this archive.
20902090+</para>
20912091+20922092+<para>
20932093+This means for findlib that most of the "linkopts" attributes in META files
20942094+have become superfluous: The compiler itself already knows the linker options,
20952095+we do not need to tell the compiler the options. We could simply leave all
20962096+"linkopts" attributes out.
20972097+</para>
20982098+20992099+<para>
21002100+Of course, the "linkopts" feature of findlib still works. This is necessary
21012101+because findlib should keep the compatibility with older software, and because
21022102+"linkopts" is more powerful (you can have conditional linker options).
21032103+</para>
21042104+21052105+<para>
21062106+If you have software that must run in both OCaml 2 and OCaml 3 environments,
21072107+you can make your "linkopts" attribute dependent on the "autolink"
21082108+predicate. For example:
21092109+21102110+<programlisting>
21112111+linkopts = "-cclib -lmylibrary"
21122112+linkopts(autolink) = ""
21132113+</programlisting>
21142114+21152115+The findlib installation for OCaml 3 will take the second line which is
21162116+reasonable because ocamlc already knows how to link; the installation for
21172117+OCaml 2 never sets the "autolink" predicate and therefore uses the first line.
21182118+</para>
21192119+ </sect1>
21202120+21212121+21222122+21232123+ <sect1>
21242124+ <title>Why does findlib not automatically include the -custom option if
21252125+linked with C code?</title>
21262126+21272127+ <para><emphasis>Short answer:</emphasis>
21282128+Because there are several ways of linking, and findlib is not the
21292129+right instance to find out the right way</para>
21302130+21312131+ <para>Recent versions of OCaml support DLLs, at least for some
21322132+platforms. Here, the option -custom is not necessary at all, because the
21332133+C libraries can be looked up and loaded at runtime. The option -custom
21342134+would have the effect of forcing static linking.</para>
21352135+21362136+ <para>But even for platforms without DLL support, there are two
21372137+alternatives. One possibility is to use -custom, and the other is to
21382138+create runtime systems with -make-runtime, and reference them with
21392139+-use-runtime. Fortunately, recent versions of OCaml select now themselves
21402140+-custom automatically if -make-runtime is omitted, so findlib needs not to
21412141+bother with it.
21422142+</para>
21432143+ </sect1>
21442144+21452145+21462146+21472147+ <sect1>
21482148+ <title>Does findlib support linking of applications as well as
21492149+packages?</title>
21502150+21512151+ <para>
21522152+<emphasis>Short answer:</emphasis> Yes, but it is not very obvious</para>
21532153+21542154+ <para>
21552155+Applications also depend on other components, they have predicates, sometimes
21562156+they need linker options; there seems to be only little difference between
21572157+applications (stand-alone programs) and packages. If you want to use the
21582158+findlib mechanisms for applications, too, the following trick helps.
21592159+</para>
21602160+21612161+ <para>
21622162+The environment variable <literal>OCAMLPATH</literal> may contain a
21632163+colon-separated path of possible sitelib locations. It is allowed to include
21642164+"." into the path (Shell commands follow):
21652165+21662166+<programlisting>
21672167+OCAMLPATH=.
21682168+export OCAMLPATH
21692169+</programlisting>
21702170+21712171+This makes ".", i.e. your current directory, another sitelib location. You may
21722172+now put the components of your applications into subdirectories together with
21732173+META files; the hierarchy might look as follows:
21742174+21752175+<programlisting>
21762176+./Makefile global Makefile
21772177+./localpkg1/META first local package directory: Contains META
21782178+./localpkg1/... ... and more
21792179+./localpkg2/META second local package dir: Contains META
21802180+./localpkg2/... ... and more
21812181+...
21822182+</programlisting>
21832183+21842184+From findlib's point of view, these directories are now package directories,
21852185+and you can refer to them on the command line:
21862186+21872187+<programlisting>
21882188+ocamlfind ocamlc -o ... -linkpkg -package localpkg1,localpkg2,...
21892189+</programlisting>
21902190+21912191+If you do not want subdirectories, you can also refer to the META file in the
21922192+same directory by the name ".", e.g.:
21932193+21942194+<programlisting>
21952195+ocamlfind ocamlc -o ... -linkpkg -package .
21962196+</programlisting>
21972197+21982198+In this case, the linking information will be taken from
21992199+<literal>./META</literal>.
22002200+</para>
22012201+ </sect1>
22022202+22032203+22042204+ <sect1>
22052205+ <title>
22062206+ Does Findlib support camlp4?
22072207+ </title>
22082208+22092209+ <para>
22102210+ <emphasis>Short answer:</emphasis> Yes, but there is only little
22112211+ documentation.</para>
22122212+22132213+ <para>
22142214+ Since Findlib-0.4, there is some experimental camlp4 support. For
22152215+example, the following compiler invocation chooses the revised syntax:
22162216+22172217+<programlisting>
22182218+ocamlfind ocamlc -syntax camlp4r -package camlp4 -c file.ml
22192219+</programlisting>
22202220+22212221+ As you can see, camlp4 must be included as package, and the
22222222+-syntax option must specify which syntax is selected (either
22232223+<literal>camlp4o</literal> or <literal>camlp4r</literal>).</para>
22242224+22252225+ <para>
22262226+ If you want to pass additional options to the preprocessor,
22272227+you can use the <literal>-ppopt</literal> option:
22282228+22292229+<programlisting>
22302230+ocamlfind ocamlc -syntax camlp4r -package camlp4 -ppopt pa_ifdef.cmo -c file.ml
22312231+</programlisting>
22322232+ </para>
22332233+22342234+ <para>
22352235+From the toploop, the following commands work:
22362236+22372237+<programlisting>
22382238+$ ocaml
22392239+ Objective Caml version 3.07+2
22402240+22412241+# #use "./topfind";;
22422242+- : unit = ()
22432243+Findlib has been successfully loaded. Additional directives:
22442244+ #require "package";; to load a package
22452245+ #list;; to list the available packages
22462246+ #camlp4o;; to load camlp4 (standard syntax)
22472247+ #camlp4r;; to load camlp4 (revised syntax)
22482248+ #predicates "p,q,...";; to set these predicates
22492249+ Topfind.reset();; to force that packages will be reloaded
22502250+ #thread;; to enable threads
22512251+22522252+- : unit = ()
22532253+# #camlp4o;; (* or camlp4r *)
22542254+/opt/godi/lib/ocaml/std-lib/camlp4: added to search path
22552255+/opt/godi/lib/ocaml/std-lib/camlp4/camlp4o.cma: loaded
22562256+ Camlp4 Parsing version 3.07+2
22572257+22582258+# _
22592259+</programlisting>
22602260+22612261+<sect2>
22622262+<title>The concept</title>
22632263+<para>
22642264+If you have a <literal>-syntax</literal> option on the command line,
22652265+ocamlfind will generate a <literal>-pp</literal> parameter and pass it to the
22662266+invoked compiler. This is performed as follows: The specified packages are
22672267+inspected under a certain set of predicates, the <emphasis>syntax
22682268+predicates</emphasis>. The syntax predicates are <literal>syntax</literal>,
22692269+<literal>preprocessor</literal>, and the predicates following
22702270+<literal>-syntax</literal>. The predicate <literal>syntax</literal> simply
22712271+means that the <literal>-syntax</literal> option has been specified.
22722272+The predicate <literal>preprocessor</literal> means that the preprocessor
22732273+command is being constructed. The predicates added by
22742274+<literal>-syntax</literal> may be used to distinguish between syntax variants
22752275+(currently <literal>camlp4o</literal> and <literal>camlp4r</literal>).
22762276+</para>
22772277+22782278+<para>The packages are searched for a variable <literal>preprocessor</literal>;
22792279+normally the <literal>camlp4</literal> package defines it as (see its META
22802280+file):
22812281+22822282+<programlisting>
22832283+preprocessor = "camlp4 -nolib"
22842284+</programlisting>
22852285+22862286+Now that the name of the preprocessor command is known, the arguments of the
22872287+command are looked up. The META files are evaluated under the syntax
22882288+predicates, and all <literal>archive</literal> variables are collected and
22892289+passed as arguments to the preprocessor. For example, the camlp4 package
22902290+defines:
22912291+22922292+<programlisting>
22932293+archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo"
22942294+archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo"
22952295+</programlisting>
22962296+22972297+Note that the predicate <literal>preprocessor</literal> prevents ocamlfind from
22982298+including these archives into the regular list of archives to link.
22992299+</para>
23002300+</sect2>
23012301+<sect2>
23022302+<title>How to write a META file for your own syntax extension</title>
23032303+<para>
23042304+Suppose you have two archives: <literal>pa_myext.cma</literal> contains the
23052305+extension code of camlp4, and <literal>run_myext.cma</literal> contains runtime
23062306+material that must be present in programs compiled with your extensions. Your
23072307+META file should look as follows:
23082308+23092309+<programlisting>
23102310+requires = "camlp4"
23112311+archive(syntax,toploop) = "pa_myext.cma run_myext.cma"
23122312+archive(syntax,preprocessor) = "pa_myext.cma"
23132313+archive(syntax,byte) = "run_myext.cma"
23142314+archive(syntax,native) = "run_myext.cmxa"
23152315+</programlisting>
23162316+23172317+You may add dependencies on <literal>camlp4o</literal> or
23182318+<literal>camlp4r</literal> if you have archives only working for one of the two
23192319+syntax variants.
23202320+</para>
23212321+23222322+<para>To compile a program using your syntax extension package, one should use:
23232323+23242324+<programlisting>
23252325+ocamlfind ocamlc -package yourname -syntax variant ...
23262326+</programlisting>
23272327+</para>
23282328+</sect2>
23292329+23302330+ <sect2>
23312331+ <title>Example</title>
23322332+23332333+<para>The package <literal>xstrp4</literal> defines a syntax extension allowing
23342334+$-substitutions in OCaml strings. Version 1.0 of this package takes advantage
23352335+from the new camlp4 support of findlib; you may have a look at it for an
23362336+example.</para>
23372337+23382338+<para>You can find <literal>xstrp4</literal>
23392339+<ulink URL="&url.xstrp4-project;">here</ulink>.</para>
23402340+ </sect2>
23412341+</sect1>
23422342+23432343+23442344+ <sect1>
23452345+ <title>
23462346+ Does Findlib support ppx-style preprocessors?
23472347+ </title>
23482348+23492349+ <para>
23502350+ <emphasis>Short answer:</emphasis> Yes, but there is only little
23512351+ documentation.</para>
23522352+23532353+ <para>Since findlib-1.5, ppx-style preprocessors are supported
23542354+to some extent. A package can now define a "ppx" property which is simply
23552355+a command to run as preprocessor (the command gets the marshalled AST
23562356+as input, and must generate the transformed AST in its output; see the
23572357+-ppx option of ocamlc/ocamlopt). A META file can simply look like:
23582358+23592359+<programlisting>
23602360+ppx = "./command"
23612361+</programlisting>
23622362+23632363+when "command" is installed in the package directory (but you can also
23642364+omit "./" to search it, and you can prefix it with "@name/" if the command
23652365+is taken from another package "name").
23662366+</para>
23672367+23682368+ <para>For more complex scenarios, additional options or
23692369+arguments for the ppx preprocessor can be specified in descendant
23702370+packages with the "ppxopt" property. Package "A" might provide a
23712371+generic ppx preprocessor with a META file containing
23722372+23732373+<programlisting>
23742374+ppx = "./generic_ppx"
23752375+</programlisting>
23762376+23772377+Package B might instantiate that preprocessor with
23782378+23792379+<programlisting>
23802380+requires = "A"
23812381+ppxopt = "A,ppx_b.cmo"
23822382+</programlisting>
23832383+23842384+In this case "ocamlfind ocamlc -package B" would
23852385+add <literal>-ppx "path_to_A/genric_ppx ppx_b.cmo"</literal> to
23862386+the ocamlc invocation. The format of the "ppxopt" property is
23872387+specified in the findlib reference manual.
23882388+</para>
23892389+23902390+23912391+ <para>This feature is still a bit experimental.</para>
23922392+23932393+ </sect1>
23942394+23952395+23962396+ <sect1>
23972397+ <title>Why do some people install the .cmx files?</title>
23982398+23992399+ <para>In principle, it is not necessary to install the .cmx
24002400+files created by the ocamlopt compiler, as the .a and .cmxa files
24012401+already contain the assembly code and all needed auxiliary information.
24022402+However, it may be sensible to install the .cmx files, too. They
24032403+contain the intermediate code of small functions that are candidates
24042404+for inlining, and installing them allows the compiler to do inlining
24052405+even across library boundaries. Note that only very small functions
24062406+can be inlined at all, and that there are language elements that
24072407+prevent inlining (e.g. raising an exception with an argument), so
24082408+it makes only sense when the library actually has such functions
24092409+and really profits from inlining.</para>
24102410+24112411+ <para>Inlining has also disadvantages: The library can no
24122412+longer be replaced by a different version even if the interface
24132413+remains exactly the same, because code using the library may have
24142414+inlined code of the old version.</para>
24152415+ </sect1>
24162416+24172417+24182418+ <sect1>
24192419+ <title>How do I express conflicts?</title>
24202420+24212421+ <para>A conflict means that a certain combination of packages
24222422+and package features will not work. A number of conflict conditions
24232423+can be expressed:</para>
24242424+24252425+ <itemizedlist>
24262426+ <listitem>
24272427+ <para>To state that a package will not work if a certain
24282428+predicate is set, use the <literal>error</literal> variable. For example,
24292429+when package p does not work for multi-threaded programs:
24302430+24312431+<programlisting>
24322432+error(mt) = "Package p is incompatible with multi-threaded programs"
24332433+</programlisting>
24342434+24352435+This works for other standard predicates, too.</para>
24362436+ </listitem>
24372437+24382438+ <listitem>
24392439+ <para>To state that a package will not work together with
24402440+another package, it is possible to make <literal>error</literal> dependent
24412441+on package predicates. For example, when package p does not work
24422442+together with q:
24432443+24442444+<programlisting>
24452445+error(pkg_q) = "Package p is incompatible with package q"
24462446+</programlisting>
24472447+24482448+This also works with subpackages (e.g. <literal>pkg_q.q_sub</literal>).
24492449+ </para>
24502450+ </listitem>
24512451+24522452+ <listitem>
24532453+ <para>If an error is too much, it might be a good idea to
24542454+ just inform the user about possible problems. In this case
24552455+ you can emit a warning instead:
24562456+ </para>
24572457+24582458+<programlisting>
24592459+warning(pkg_q) = "Using package p and q together is a really bad idea"
24602460+</programlisting>
24612461+24622462+ </itemizedlist>
24632463+24642464+<para>Note that such error conditions should only be added if there is
24652465+absolutely no chance to get the combination of packages and features running.
24662466+For example, in the case of multi-threaded programs it is often possible
24672467+to add wrappers around unsafe libraries to fix the incompatibility.
24682468+ </para>
24692469+24702470+<para>It is not possible to express incompatibilities between package
24712471+versions. Such incompatibilities should be detected when software is
24722472+installed, not when it is used.</para>
24732473+ </sect1>
24742474+ </chapter>
24752475+ </part>
24762476+</book>
+427
vendor/opam/ocamlfind/doc/src/findlib_conf.mod
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>findlib.conf</refentrytitle>
55+ <manvolnum>5</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="findlib.conf">
1010+ <refname>findlib.conf</refname>
1111+ <refpurpose>[Configuration of findlib/ocamlfind]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsect1>
1616+<title>GENERAL</title>
1717+1818+<para>
1919+There are three possibilities to configure the findlib library:
2020+2121+<variablelist>
2222+<varlistentry>
2323+ <term>Build time:</term>
2424+ <listitem><para>
2525+ Before findlib is compiled, a "configure" script is invoked to figure
2626+ out the settings that are most likely to work on the system. Most
2727+ settings are simply entered into text files and can easily be changed
2828+ after installation. The following properties cannot be changed later
2929+ because they are compiled into the resulting binaries:
3030+3131+ <itemizedlist>
3232+ <listitem>
3333+ <para>
3434+ The default location of the configuration file findlib.conf. However,
3535+ you can set a different location by the environment variable
3636+ <literal>OCAMLFIND_CONF</literal>.
3737+ </para>
3838+ </listitem>
3939+4040+ <listitem>
4141+ <para>
4242+ Whether the installed OCaml version supports autolinking or not.
4343+ </para>
4444+ </listitem>
4545+4646+ </itemizedlist>
4747+ </para>
4848+ </listitem>
4949+</varlistentry>
5050+5151+<varlistentry>
5252+ <term>Configuration file findlib.conf:</term>
5353+ <listitem><para>
5454+ An initial version of this file is generated by the configure script,
5555+ but you are free to modify it later. Most important, this file
5656+ contains the system-wide search path used to look up packages, and the
5757+ default location where to install new packages.
5858+ </para>
5959+ <para>
6060+ All files with the suffix ".conf" found in the directory
6161+ findlib.conf.d are also scanned for parameters.
6262+ </para>
6363+ </listitem>
6464+</varlistentry>
6565+6666+<varlistentry>
6767+ <term>Environment variables:</term>
6868+ <listitem><para>
6969+ The settings of findlib.conf can be overridden by environment variables.
7070+ </para>
7171+ </listitem>
7272+</varlistentry>
7373+</variablelist>
7474+7575+Last but not least, several settings can also be passed as
7676+command-line options, or by invoking the function
7777+<literal>Findlib.init</literal>.
7878+</para>
7979+</refsect1>
8080+8181+8282+<!-- ********************************************************************** -->
8383+8484+8585+<refsect1>
8686+<title>findlib.conf</title>
8787+8888+<para>
8989+The directory containing findlib.conf is determined at build time (by
9090+running the configure script), the fallback default is
9191+<literal>/usr/local/etc</literal>. You can set a different location by
9292+changing the environment variable <literal>OCAMLFIND_CONF</literal>
9393+which must contain the absolute path of findlib.conf.
9494+</para>
9595+9696+<para>
9797+The file has the same syntax as <link
9898+linkend="META"><literal>META</literal></link>, i.e. it consists of a
9999+number of lines with the format
100100+101101+<programlisting>
102102+<replaceable>variable</replaceable> = "<replaceable>value</replaceable>"
103103+</programlisting>
104104+</para>
105105+106106+<para>Here is the list of allowed variables:
107107+108108+<variablelist>
109109+<varlistentry>
110110+ <term><literal>path</literal></term>
111111+ <listitem><para>
112112+ The search path for META files/package directories. The variable
113113+ enumerates directories which are separated by colons (Windows:
114114+ semicolons), and these directories are tried in turn to find a certain
115115+ package. More exactly, if d is such a directory and p the searched
116116+ package, the search algorithm will first check whether d/p/META
117117+ exists. In this case, this META file is taken, and d/p is the package
118118+ directory. Second, the algorithm tries d/META.p, but the package
119119+ directory must be specified in this META.p file by a
120120+ <literal>directory</literal> directive.
121121+ </para>
122122+123123+ <para>
124124+ Note that the first found META file is taken, so the order of the
125125+ directories in the search path counts.
126126+ </para>
127127+128128+ <para>
129129+ This variable is required.
130130+ </para>
131131+132132+ <para>
133133+ Example:
134134+135135+ <programlisting>
136136+path = "/usr/local/lib/ocaml/site-lib:/usr/lib/ocaml/site-lib"
137137+</programlisting>
138138+ </para>
139139+ </listitem>
140140+</varlistentry>
141141+</variablelist>
142142+143143+144144+<variablelist>
145145+<varlistentry>
146146+ <term><literal>destdir</literal></term>
147147+ <listitem><para>
148148+ This variable determines the location where <literal>ocamlfind
149149+ install</literal> puts the packages by default: If d is this
150150+ directory, and p the package to install, a new subdirectory d/p will
151151+ be created containing all the files of the package.
152152+ </para>
153153+154154+ <para>Example:
155155+ <programlisting>
156156+destdir = "/usr/local/lib/ocaml/site-lib"
157157+</programlisting>
158158+ </para>
159159+160160+ <para>
161161+ This variable is required.
162162+ </para>
163163+ </listitem>
164164+</varlistentry>
165165+</variablelist>
166166+167167+168168+<variablelist>
169169+<varlistentry>
170170+ <term><literal>metadir</literal></term>
171171+ <listitem><para>
172172+ If set, the command <literal>ocamlfind install</literal> will put the
173173+ META files of packages into this directory (files are named META.p
174174+ where p=package name); otherwise the META files are put into the
175175+ package directories like any other file.
176176+ </para>
177177+178178+ <para>Example:
179179+ <programlisting>
180180+metadir = "/var/lib/findlib/metaregistry"
181181+</programlisting>
182182+ </para>
183183+184184+ <para>
185185+ This variable is optional. It is not used by default.
186186+ </para>
187187+ </listitem>
188188+</varlistentry>
189189+</variablelist>
190190+191191+192192+<variablelist>
193193+<varlistentry>
194194+ <term><literal>ocamlc</literal>,
195195+ <literal>ocamlopt</literal>,
196196+ <literal>ocamlcp</literal>,
197197+ <literal>ocamlmktop</literal>,
198198+ <literal>ocamldoc</literal>,
199199+ <literal>ocamldep</literal>,
200200+ <literal>ocamlbrowser</literal>
201201+ </term>
202202+ <listitem><para>
203203+ If you want to call other executables than "ocamlc", "ocamlopt",
204204+ "ocamlcp", "ocamlmktop", "ocamldoc", "ocamldep", and
205205+ "ocamlbrowser", you can
206206+ set the names of
207207+ the executables here. The command <literal>ocamlfind</literal> looks
208208+ into these four variables to determine the names of the compilers to
209209+ call.
210210+ </para>
211211+212212+ <para>Example:
213213+ <programlisting>
214214+ocamlc = "ocamlc.opt"
215215+ocamlopt = "ocamlopt.opt"
216216+ocamlcp = "ocamlcp.opt"
217217+ocamlmktop = "ocamlmktop.opt"
218218+</programlisting>
219219+ </para>
220220+221221+ <para>
222222+ This variable is optional. It is not used by default.
223223+ </para>
224224+ </listitem>
225225+</varlistentry>
226226+</variablelist>
227227+228228+<variablelist>
229229+<varlistentry>
230230+ <term><literal>stdlib</literal></term>
231231+ <listitem><para>
232232+ This variable determines the location of the standard library. This must
233233+ be the same directory for which the OCaml compilers are configured.
234234+ </para>
235235+236236+ <para>
237237+ This variable is optional. It is not recommend to set this variable
238238+ unless you know what you are doing!
239239+ </para>
240240+ </listitem>
241241+</varlistentry>
242242+</variablelist>
243243+244244+<variablelist>
245245+<varlistentry>
246246+ <term><literal>ldconf</literal></term>
247247+ <listitem><para>
248248+ This variable determines the location of the ld.conf file. This must
249249+ be the same file the OCaml compilers read in; it is updated by
250250+ ocamlfind when installing and removing packages. You can set this
251251+ variable to the special value "<literal>ignore</literal>" to disable
252252+ the automatic modification of the ld.conf file.
253253+ </para>
254254+255255+ <para>
256256+ If not set, the ld.conf file is assumed to reside in the OCaml
257257+ standard library directory.
258258+ </para>
259259+260260+ <para>
261261+ This variable is optional. It is not recommended to set this variable
262262+ unless you know what you are doing!
263263+ </para>
264264+ </listitem>
265265+</varlistentry>
266266+</variablelist>
267267+</para>
268268+269269+<para>
270270+Toolchains: It is possible to have variants of the original configuration.
271271+These variants are called "toolchains" because they are intended to
272272+select different compilers, e.g. patched compilers. In order to
273273+set a variable for a certain toolchain, use the syntax
274274+275275+<programlisting>
276276+<replaceable>variable</replaceable>(<replaceable>toolchain</replaceable>) = "<replaceable>value</replaceable>"
277277+</programlisting>
278278+279279+For example:
280280+281281+<programlisting>
282282+ocamlc(mypatch) = "ocamlc-mypatch"
283283+</programlisting>
284284+285285+When the toolchain "mypatch" is selected, this compiler will be used instead
286286+of the standard one.</para>
287287+288288+<para>In order to switch to a certain toolchain, use the -toolchain
289289+option of <link linkend="ocamlfind">ocamlfind</link>.</para>
290290+291291+</refsect1>
292292+293293+294294+295295+<!-- ********************************************************************** -->
296296+297297+298298+<refsect1>
299299+<title>Environment</title>
300300+301301+<para>
302302+A number of environment variables modifies the behaviour of
303303+findlib/ocamlfind:
304304+305305+<variablelist>
306306+<varlistentry>
307307+ <term><literal>OCAMLFIND_CONF</literal></term>
308308+ <listitem><para>
309309+ This variable overrides the location of the configuration file
310310+ findlib.conf. It must contain the absolute path name of this file.
311311+ </para>
312312+ </listitem>
313313+</varlistentry>
314314+</variablelist>
315315+316316+<variablelist>
317317+<varlistentry>
318318+ <term><literal>OCAMLFIND_TOOLCHAIN</literal></term>
319319+ <listitem><para>
320320+ This variable sets the currently selected toolchain when
321321+ a <literal>-toolchain</literal> option is not passed
322322+ on the command line.
323323+ </para>
324324+ </listitem>
325325+</varlistentry>
326326+</variablelist>
327327+328328+<variablelist>
329329+<varlistentry>
330330+ <term><literal>OCAMLPATH</literal></term>
331331+ <listitem><para>
332332+ This variable may contain an additional search path for package
333333+ directories. It is treated as if the directories were prepended to
334334+ the configuration variable <literal>path</literal>.
335335+ </para>
336336+ </listitem>
337337+</varlistentry>
338338+</variablelist>
339339+340340+<variablelist>
341341+<varlistentry>
342342+ <term><literal>OCAMLFIND_DESTDIR</literal></term>
343343+ <listitem><para>
344344+ This variable overrides the configuration variable
345345+ <literal>destdir</literal>.
346346+ </para>
347347+ </listitem>
348348+</varlistentry>
349349+</variablelist>
350350+351351+<variablelist>
352352+<varlistentry>
353353+ <term><literal>OCAMLFIND_METADIR</literal></term>
354354+ <listitem><para>
355355+ This variable overrides the configuration variable
356356+ <literal>metadir</literal>.
357357+ </para>
358358+ </listitem>
359359+</varlistentry>
360360+</variablelist>
361361+362362+<variablelist>
363363+<varlistentry>
364364+ <term><literal>OCAMLFIND_COMMANDS</literal></term> <listitem><para>
365365+ This variable overrides the configuration variables
366366+ <literal>ocamlc</literal>, <literal>ocamlopt</literal>,
367367+ <literal>ocamlcp</literal>, <literal>ocamlmktop</literal>,
368368+ <literal>ocamldoc</literal>, <literal>ocamldep</literal>, and/or
369369+ <literal>ocamlbrowser</literal>.
370370+ Its value must conform to the syntax
371371+372372+ <programlisting>
373373+ocamlc=<replaceable>name</replaceable> ocamlopt=<replaceable>name</replaceable> ocamlcp=<replaceable>name</replaceable> ocamlmktop=<replaceable>name</replaceable> ocamldoc=<replaceable>name</replaceable> ocamldep=<replaceable>name</replaceable> ocamlbrowser=<replaceable>name</replaceable>
374374+</programlisting>
375375+ </para>
376376+377377+ <para>Example:
378378+ <programlisting>
379379+ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00 ocamlcp=ocamlcp-3.00 ocamlmktop=ocamlmktop-3.00
380380+</programlisting>
381381+ </para>
382382+383383+ </listitem>
384384+</varlistentry>
385385+</variablelist>
386386+387387+<variablelist>
388388+<varlistentry>
389389+ <term><literal>CAMLLIB</literal> or <literal>OCAMLLIB</literal></term>
390390+ <listitem><para>
391391+ This variable overrides the configuration variable
392392+ <literal>stdlib</literal>.
393393+ </para>
394394+ </listitem>
395395+</varlistentry>
396396+</variablelist>
397397+398398+<variablelist>
399399+<varlistentry>
400400+ <term><literal>OCAMLFIND_LDCONF</literal></term>
401401+ <listitem><para>
402402+ This variable overrides the configuration variable
403403+ <literal>ldconf</literal>.
404404+ </para>
405405+ </listitem>
406406+</varlistentry>
407407+</variablelist>
408408+409409+<variablelist>
410410+<varlistentry>
411411+ <term><literal>OCAMLFIND_IGNORE_DUPS_IN</literal></term>
412412+ <listitem><para>
413413+ This variable instructs findlib not to emit warnings that packages
414414+ or module occur several times. The variable must be set to the
415415+ directory where the packages reside that are to be ignored for this
416416+ warning.
417417+ </para>
418418+ </listitem>
419419+</varlistentry>
420420+</variablelist>
421421+422422+423423+</para>
424424+</refsect1>
425425+426426+427427+</refentry>
+420
vendor/opam/ocamlfind/doc/src/findlib_meta.mod
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>META</refentrytitle>
55+ <manvolnum>5</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="META">
1010+ <refname>META</refname>
1111+ <refpurpose>[File that specifies metainformation of OCaml packages]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsynopsisdiv>
1616+<title>GRAMMAR</title>
1717+<synopsis>
1818+ metafile ::= entry*
1919+ entry ::= assignment | addition | subpackage
2020+ subpackage ::= "package" pkgname '(' metafile ')'
2121+ assignment ::= variable_name [ formal_predicates ] '=' value
2222+ addition ::= variable_name [ formal_predicates ] '+=' value
2323+formal_predicates ::= '(' formal_predicate { ',' formal_predicate } ')'
2424+ variable_name ::= name
2525+ formal_predicate ::= name | '-' name
2626+ name ::= [ 'A'-'Z' 'a'-'z' '0'-'9' '_' '.' ]+
2727+ pkgname ::= '"' (character but not '.')* '"'
2828+ value ::= '"' character* '"'
2929+</synopsis>
3030+</refsynopsisdiv>
3131+3232+<refsect1>
3333+<title>DESCRIPTION</title>
3434+<para>
3535+If a package directory contains a file with the fixed name "META" it
3636+is interpreted as described here. The file is a sequence of entries
3737+following the given grammar; every entry defines a variable under a
3838+certain condition given by the list of formal predicates, or it
3939+introduces a subpackage.
4040+</para>
4141+4242+<para>
4343+There is a list of predefined variables and a list of standard
4444+predicates. These variables define: required packages, description, version
4545+information, directories, archive files, and linker options. The
4646+predicates denote circumstances of the application of the variables:
4747+whether the bytecode or the native compiler is used, if there is a
4848+toploop compiled in, details of multi-threading execution, details of
4949+profiling.
5050+</para>
5151+</refsect1>
5252+5353+<refsect1>
5454+<title>DETAILS OF THE FILE FORMAT</title>
5555+<para>
5656+The file consists of a sequence of entries which must be formed as the
5757+grammar prescribes. The lexical tokens are names, values, and
5858+interpunctuation like '(', ',' and so on. Note that linefeeds do not
5959+play a special role, i.e. an entry definition may be given in more than
6060+one line, or several definitions may occur on a single line. There may
6161+be comments which begin with '#' and run until the end of the line.
6262+</para>
6363+6464+<para>
6565+Names are sequences of the characters A-Z, a-z, 0-9, or _. Names
6666+containing capital letters and names beginning with digits are
6767+allowed but not recommended.
6868+</para>
6969+7070+<para>
7171+Values are enclosed between double quotes. Values may contain any
7272+character. The characters " and \ must be preceded by backslashes.
7373+</para>
7474+7575+<para>
7676+Package names must not contain the '.' character because it is used
7777+as delimiter of compound names.
7878+</para>
7979+8080+</refsect1>
8181+8282+<refsect1>
8383+<title>MAIN PACKAGES AND SUBPACKAGES</title>
8484+<para>
8585+The outermost variable assignments and additions belong to the main
8686+package. The name of the main package is not defined within META;
8787+it is either the name of the directory containing META or the suffix
8888+of the META file (if the name of the META file is formed like
8989+META.name).</para>
9090+9191+<para>The keyword <literal>package</literal> starts the definition
9292+of a subpackage. There must not be two such definitions with the
9393+same name. Within the parentheses, the variable assignments and
9494+additions refer to the subpackage. It is allowed that a subpackage
9595+contains further subpackages.</para>
9696+9797+<para>The package name following <literal>package</literal>
9898+is the local name relative to the main package, i.e. the
9999+name of the main package is not mentioned. At all other places,
100100+however, the subpackage must be prefixed by the name of the
101101+containing package, separated by a '.'.</para>
102102+103103+<para>Subpackages are independent of the containing package, except
104104+that the subpackage points to the same installation directory as
105105+the containing package (i.e. the location of the installation directory
106106+is inherited from the containing package).</para>
107107+</refsect1>
108108+109109+110110+<refsect1>
111111+<title>SEMANTICS OF VARIABLE DEFINITIONS</title>
112112+113113+<para>
114114+In order to determine the value of a variable, first all assignments
115115+are inspected, and the most specific assignment is taken (if there is
116116+none, the empty string will be taken as value). In a second step,
117117+all additions are gone through one after the other in the order
118118+they occur in the file, and the values of all matching additions are
119119+appended to the current value. In the following, it is further
120120+clarified which assignment is the most specific, which additions
121121+actually match, and how the details of the value addition look like.</para>
122122+123123+<para> The most specific assignment is selected upon a set of actual
124124+predicates, i.e. the set of predicates that are assumed to be true.
125125+The predicates occurring in the definitions of assignments and
126126+additions are called formal predicates. They may be positive or
127127+negative; the latter are prepended by a '-' sign. In order to
128128+determine the value after the evaluation of the assignments, the
129129+following rules apply: </para>
130130+131131+<itemizedlist mark="bullet" spacing="compact">
132132+<listitem>
133133+<para> An assignment can only be used if all positive formal
134134+predicates are included in the set of actual predicates, and if all
135135+negative formal predicates are not included in the set of actual
136136+predicates. Such an assignment is called
137137+<emphasis>applicable</emphasis>. If there is no such assignment, the
138138+variable will have no value.
139139+</para>
140140+</listitem>
141141+142142+<listitem>
143143+<para>
144144+If there is more than one applicable assignment, the definition with
145145+the biggest number of formal predicates is selected.
146146+</para>
147147+</listitem>
148148+149149+<listitem>
150150+<para>
151151+If there is still more than one applicable assignment, both applicable
152152+and with a maximum number of formal predicates, the definition that is defined
153153+first is selected.
154154+</para>
155155+</listitem>
156156+</itemizedlist>
157157+158158+<para>An addition is matching when all positive formal predicates are
159159+included in the set of actual predicates, and all negative formal
160160+predicates are not included.</para>
161161+162162+<para>The value of an addition is appended to the current value with
163163+implicit white space as separator.</para>
164164+165165+</refsect1>
166166+167167+<refsect1>
168168+<title>VARIABLES</title>
169169+170170+<para>
171171+There is a set of variables with predefined meaning:
172172+</para>
173173+174174+<itemizedlist mark="bullet" spacing="compact"> <listitem> <para> The
175175+variable "directory" redefines the location of the package
176176+directory. Normally, the META file is the first file read in the
177177+package directory, and before any other file is read, the "directory"
178178+variable is evaluated in order to see if the package directory must be
179179+changed. The value of the "directory" variable is determined with an
180180+empty set of actual predicates. The value must be either: an absolute
181181+path name of the alternate directory, or a path name relative to the
182182+stdlib directory of OCaml (written "+path"), or a normal relative path
183183+name (without special syntax). In the latter case, the interpretation
184184+depends on whether it is contained in a main or sub package, and
185185+whether the standard repository layout or the alternate layout is in
186186+effect (see <link linkend="site-lib">site-lib</link> for these terms).
187187+For a main package in standard layout the base directory is the
188188+directory physically containing the META file, and the relative path
189189+is interpreted for this base directory. For a main package in
190190+alternate layout the base directory is the directory physically
191191+containing the META.pkg files. The base directory for subpackages is
192192+the package directory of the containing package. (In the case
193193+that a subpackage definition does not have a "directory" setting,
194194+the subpackage simply inherits the package directory of the containing
195195+package. By writing a "directory" directive one can change this
196196+location again.)
197197+</para> </listitem>
198198+199199+<listitem>
200200+<para>
201201+The variable "requires" specifies the list of required packages. The
202202+names of the packages must be separated by white space and/or commas.
203203+The names must be fully qualified (i.e. when they refer to a subpackage,
204204+the names of all containing packages must be prepended, separated by
205205+'.').
206206+</para>
207207+</listitem>
208208+209209+<listitem>
210210+<para>
211211+The variable "description" may include a short description of the
212212+package (displayed by <literal>ocamlfind list</literal>).
213213+</para>
214214+</listitem>
215215+216216+<listitem>
217217+<para>
218218+The variable "version" specifies the version string.
219219+</para>
220220+</listitem>
221221+222222+<listitem>
223223+<para>
224224+The variable "archive" specifies the list of archive files. These
225225+files should be given either as (1) plain names without any directory
226226+information; they are only searched in the package directory.
227227+(2) Or they have the form "+path" in which case the files are looked up
228228+relative to the standard library. (3) Or they have the form "@name/file"
229229+in which case the files are looked up in the package directory
230230+of another package. (4) Or they are given as absolute paths.
231231+</para>
232232+233233+<para>The
234234+names of the files must be separated by white space and/or commas.
235235+In the preprocessor stage, the archive files are passed as extensions
236236+to the preprocessor (camlp4) call. In the linker stage (-linkpkg), the archive
237237+files are linked. In the compiler stage, the archive files are ignored.
238238+</para>
239239+240240+<para>
241241+Note that "archive" should only be used for archive files that are
242242+intended to be included in executables or loaded into toploops. For
243243+modules loaded at runtime there is the separate variable "plugin".
244244+</listitem>
245245+246246+<listitem>
247247+<para>
248248+The variable "plugin" specifies the plugin archives of the package.
249249+These can be dynamically loaded with the <literal>Fl_dynload</literal>
250250+module. The plugin archives can have ".cmo", ".cma", or ".cmxs" suffix.
251251+</para>
252252+</listitem>
253253+254254+<listitem>
255255+<para>
256256+The variable "linkopts" specifies additional linker options.
257257+</para>
258258+</listitem>
259259+260260+<listitem>
261261+<para>
262262+The variable "error" can be used to signal error conditions. When
263263+this variable is applicable, the ocaml compilers are stopped, and
264264+an error message is printed. The message is the value of the variable.
265265+</para>
266266+</listitem>
267267+268268+<listitem>
269269+<para>
270270+The variable "warning" can be used to signal warnings. When
271271+this variable is applicable, the warning is printed, but the
272272+compilation continues. The message is the value of the variable.
273273+</para>
274274+</listitem>
275275+276276+<listitem>
277277+<para>
278278+The variable "exists_if" can be used to disable subpackages. The
279279+value of "exists_if" is a file; the subpackage is hidden if this
280280+file does not exist. You can also enumerate several files, and the
281281+subpackage is hidden if none of the files exist.
282282+</para>
283283+</listitem>
284284+285285+<listitem>
286286+<para>
287287+The variable "ppx" is a command that is added to the compiler invocation
288288+via the -ppx option (available since OCaml-4.01). If the command is
289289+relative to the current directory (e.g. ./cmd), the command is expected
290290+in the package directory. The special forms as defined for "archive"
291291+are also available (e.g. @otherpkg/cmd). Additional arguments can be
292292+specified on the ocamlfind command line with the -ppxopt option
293293+or the "ppxopt" variable.
294294+</para>
295295+</listitem>
296296+297297+<listitem>
298298+<para>
299299+The variable "ppxopt" is a set of options that are added to the ppx
300300+rewriter invocation. The contents of the variable consists of one or
301301+several whitespace-separated parts. Every part consists of several
302302+comma-separated subparts; the first subpart indicates the package
303303+that contains the ppx rewriter invocation, the rest contain the options
304304+to be appended. If the option is a path relative to the current directory
305305+(e.g. ./foo.cma), the path is expanded relative to the package directory.
306306+The special forms as defined for "archive" are also available
307307+(e.g. @otherpkg/foo.cma).
308308+</para>
309309+</listitem>
310310+311311+</itemizedlist>
312312+313313+<para>
314314+It is possible to define additional variables but there is currently
315315+no software interpreting them.
316316+</para>
317317+</refsect1>
318318+319319+320320+<refsect1>
321321+<title>PREDICATES</title>
322322+323323+<para>
324324+There is a list of standard predicates:
325325+</para>
326326+327327+<itemizedlist mark="bullet" spacing="compact">
328328+<listitem>
329329+<para>
330330+The "byte" predicate means that the bytecode compiler is used.
331331+</para>
332332+</listitem>
333333+334334+<listitem>
335335+<para>
336336+The "native" predicate means that the native compiler is used.
337337+</para>
338338+</listitem>
339339+340340+<listitem>
341341+<para>
342342+The "toploop" predicate means that the toploop is available in the
343343+linked program. It is only set when the toploop is running, not when
344344+the toploop is generated.
345345+</para>
346346+</listitem>
347347+348348+<listitem>
349349+<para>
350350+The "create_toploop" predicate means that a toploop is created (using
351351+ocamlmktop).
352352+</para>
353353+</listitem>
354354+355355+<listitem>
356356+<para>
357357+The "mt" predicate means that the program is multi-threaded.
358358+</para>
359359+</listitem>
360360+361361+<listitem>
362362+<para>
363363+The "mt_posix" predicate means that in the case "mt" is set, too, the
364364+POSIX libraries are used to implement threads.
365365+</para>
366366+</listitem>
367367+368368+<listitem>
369369+<para>
370370+The "mt_vm" predicate means that in the case "mt" is set, too, the
371371+VM-based libraries are used to implement threads.
372372+</para>
373373+</listitem>
374374+375375+<listitem>
376376+<para>
377377+The "gprof" predicate means that in the case "native" is set, too, the
378378+program is compiled for profiling
379379+</para>
380380+</listitem>
381381+382382+<listitem>
383383+<para>
384384+The "autolink" predicate means that ocamlc can/will perform automatic linking.
385385+</para>
386386+</listitem>
387387+388388+<listitem>
389389+<para>
390390+The "preprocessor" predicate means that the META variables are scanned for
391391+preprocessor options.</para>
392392+</listitem>
393393+394394+<listitem>
395395+<para>
396396+The "syntax" predicate means that the -syntax option is present on the
397397+command line.</para>
398398+</listitem>
399399+400400+<listitem>
401401+<para>
402402+Legacy: The "plugin" predicate could be used in some versions of findlib
403403+to select cmxs archives instead of cmxa archives. This use is still possible
404404+but discouraged.
405405+</para>
406406+</listitem>
407407+408408+</itemizedlist>
409409+410410+<para>In addition to these predicates, there are package predicates
411411+for every package that is finally selected. Of course, this kind of
412412+predicate must not be used to select "directory" and "requires"
413413+variables, but for the other variables they are perfectly valid.
414414+The package predicates have the form "pkg_" plus the name of the
415415+package (fully qualified).</para>
416416+417417+418418+</refsect1>
419419+420420+</refentry>
+181
vendor/opam/ocamlfind/doc/src/findlib_mli.mod
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>Findlib</refentrytitle>
55+ <manvolnum>3</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="Findlib">
1010+ <refname>Findlib</refname>
1111+ <refpurpose>[Module for package management]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsynopsisdiv>
1616+<title>SIGNATURE</title>
1717+<synopsis>
1818+module Findlib :
1919+ sig
2020+ <link linkend="Findlib.package-directory"
2121+ endterm="val.Findlib.package-directory"></link>
2222+ <link linkend="Findlib.package-property"
2323+ endterm="val.Findlib.package-property"></link>
2424+ <link linkend="Findlib.package-ancestors"
2525+ endterm="val.Findlib.package-ancestors"></link>
2626+ <link linkend="Findlib.package-deep-ancestors"
2727+ endterm="val.Findlib.package-deep-ancestors"></link>
2828+ <link linkend="Findlib.default-location"
2929+ endterm="val.Findlib.default-location"></link>
3030+3131+ (* Note: This signature is incomplete. See findlib.mli for the
3232+ * full signature.
3333+ *)
3434+3535+ end
3636+</synopsis>
3737+</refsynopsisdiv>
3838+3939+4040+<refsect1>
4141+<title>PACKAGING</title>
4242+4343+<para>
4444+The Findlib module is part of the "findlib" package. In order to link
4545+it in, it is sufficient to link "findlib" in, e.g.
4646+</para>
4747+4848+<programlisting>
4949+ocamlfind ocamlc <replaceable>options</replaceable> -package findlib -linkpkg <replaceable>options</replaceable>
5050+</programlisting>
5151+5252+<para>
5353+There are archives for the bytecode compiler and for the native
5454+compiler; for single-threaded and for multi-threaded applications, and
5555+there is a special addition for toploops.
5656+</para>
5757+</refsect1>
5858+5959+6060+<refsect1>
6161+<title>DESCRIPTION</title>
6262+6363+<para>
6464+The Findlib module is the primary interface of the findlib library. It
6565+contains functions to lookup packages, to interpret <xref
6666+linkend="META" endterm="META"> files, and to determine the ancestors of
6767+packages.
6868+</para>
6969+7070+7171+<refsect2>
7272+<title><anchor id="Findlib.package-directory">
7373+Findlib.package_directory <replaceable>pkg</replaceable></title>
7474+<programlisting id="val.Findlib.package-directory">
7575+val package_directory : string -> string
7676+</programlisting>
7777+<para>
7878+Gets the absolute path of the directory where the package
7979+<replaceable>pkg</replaceable> is stored. The exception Not_found is
8080+raised if the package could not be found.
8181+Other exceptions may occur as file I/O is done.
8282+</para>
8383+</refsect2>
8484+8585+8686+8787+<refsect2>
8888+<title><anchor id="Findlib.package-property">
8989+Findlib.package_property <replaceable>predicates</replaceable>
9090+<replaceable>pkg</replaceable> <replaceable>variable</replaceable>
9191+</title>
9292+<programlisting id="val.Findlib.package-property">
9393+val package_property : string list -> string -> string -> string
9494+</programlisting>
9595+<para>
9696+Determines the value of the <replaceable>variable</replaceable>
9797+defined in the <xref linkend="META" endterm="META"> file of package
9898+<replaceable>pkg</replaceable> with the given set of
9999+<replaceable>predicates</replaceable>. The exception Not_found is
100100+raised if the package or the variable could not be found. Other
101101+exceptions may occur as file I/O is done.
102102+</para>
103103+<refsect3>
104104+<title>Examples</title>
105105+<para>
106106+Get the value of the "requires" variable of package "p" with an empty
107107+set of predicates:
108108+</para>
109109+<programlisting>
110110+Findlib.package_property [] "p" "requires"
111111+</programlisting>
112112+<para>
113113+Get the value of the "archive" variable of package "p" for
114114+multi-threaded bytecode applications:
115115+</para>
116116+<programlisting>
117117+Findlib.package_property [ "mt"; "byte" ] "p" "archive"
118118+</programlisting>
119119+</refsect3>
120120+</refsect2>
121121+122122+123123+124124+<refsect2>
125125+<title><anchor id="Findlib.package-ancestors">
126126+Findlib.package_ancestors <replaceable>predicates</replaceable>
127127+ <replaceable>pkg</replaceable>
128128+</title>
129129+<programlisting id="val.Findlib.package-ancestors">
130130+val package_ancestors : string list -> string -> string list
131131+</programlisting>
132132+<para>
133133+Determines the direct ancestors of package
134134+<replaceable>pkg</replaceable> for the set of
135135+<replaceable>predicates</replaceable>. The returned list has no
136136+specific order. The exception Not_found is raised if the package could
137137+not be found. The exception Failure is raised if one of the ancestors
138138+could not be found, or if a circular dependency has been
139139+detected. Other exceptions may occur as file I/O is done.
140140+</para>
141141+</refsect2>
142142+143143+144144+145145+<refsect2>
146146+<title><anchor id="Findlib.package-deep-ancestors">
147147+Findlib.package_deep_ancestors <replaceable>predicates</replaceable>
148148+ <replaceable>pkglist</replaceable>
149149+</title>
150150+<programlisting id="val.Findlib.package-deep-ancestors">
151151+val package_deep_ancestors : string list -> string list -> string list
152152+</programlisting>
153153+<para>
154154+Determines the list of direct or indirect ancestors of the packages in
155155+<replaceable>pkglist</replaceable> for the set of
156156+<replaceable>predicates</replaceable>. The returned list is
157157+topologically sorted.
158158+The exception Not_found is raised if the package could
159159+not be found. The exception Failure is raised if one of the ancestors
160160+could not be found, or if a circular dependency has been
161161+detected. Other exceptions may occur as file I/O is done.
162162+</para>
163163+</refsect2>
164164+165165+166166+167167+<refsect2>
168168+<title><anchor id="Findlib.default-location">
169169+Findlib.default_location ()</title>
170170+<programlisting id="val.Findlib.default-location">
171171+val default_location : unit -> string
172172+</programlisting>
173173+<para>
174174+Gets the default location where new packages will be installed.
175175+</para>
176176+</refsect2>
177177+178178+</refsect1>
179179+180180+</refentry>
181181+
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>ocamlfind</refentrytitle>
55+ <manvolnum>1</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="ocamlfind">
1010+ <refname>ocamlfind</refname>
1111+ <refpurpose>[Command-line interface of the Package manager]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsynopsisdiv>
1616+<title>SYNOPSIS</title>
1717+<synopsis>
1818+ <link linkend="ocamlfind.query">ocamlfind query [-help | other options] <replaceable>package_name</replaceable> ...</link>
1919+ or: <link linkend="ocamlfind.ocamlc">ocamlfind ocamlc [-help | other options] <replaceable>file</replaceable> ...</link>
2020+ or: <link linkend="ocamlfind.ocamlcp">ocamlfind ocamlcp [-help | other options] <replaceable>file</replaceable> ...</link>
2121+ or: <link linkend="ocamlfind.ocamlmktop">ocamlfind ocamlmktop [-help | other options] <replaceable>file</replaceable> ...</link>
2222+ or: <link linkend="ocamlfind.ocamlopt">ocamlfind ocamlopt [-help | other options] <replaceable>file</replaceable> ...</link>
2323+ or: <link linkend="ocamlfind.ocamldoc">ocamlfind ocamldoc [-help | other options] <replaceable>file</replaceable> ...</link>
2424+ or: <link linkend="ocamlfind.ocamldep">ocamlfind ocamldep [-help | other options] <replaceable>file</replaceable> ...</link>
2525+ or: <link linkend="ocamlfind.ocamlmklib">ocamlfind ocamlmklib [-help | other options] <replaceable>file</replaceable> ...</link>
2626+ or: <link linkend="ocamlfind.ocamlbrowser">ocamlfind ocamlbrowser [-help | other options]</link>
2727+ or: <link linkend="ocamlfind.install">ocamlfind install [-help | other options] <replaceable>package_name</replaceable> <replaceable>file</replaceable> ...</link>
2828+ or: <link linkend="ocamlfind.remove">ocamlfind remove [-help | other options] <replaceable>package_name</replaceable></link>
2929+ or: <link linkend="ocamlfind.list">ocamlfind lint <replaceable>META</replaceable></link>
3030+ or: <link linkend="ocamlfind.list">ocamlfind list [-describe]</link>
3131+ or: <link linkend="ocamlfind.printppx">ocamlfind printppx [-help | other options] <replaceable>package_name</replaceable> ...</link>
3232+ or: <link linkend="ocamlfind.printconf">ocamlfind printconf [ variable ]</link>
3333+ or: <link linkend="ocamlfind.pkgcmd">ocamlfind <replaceable>package</replaceable>/<replaceable>command</replaceable> <replaceable>arg</replaceable> ...</link>
3434+3535+Optional toolchain selection by:
3636+ <link linkend="ocamlfind.toolchain">ocamlfind -toolchain <replaceable>name</replaceable> ...</link>
3737+</synopsis>
3838+</refsynopsisdiv>
3939+4040+4141+<!-- ********************************************************************** -->
4242+4343+<refsect1>
4444+<title><anchor id="ocamlfind.query">
4545+ THE "query" SUBCOMMAND
4646+</title>
4747+4848+<refsect2>
4949+<title>Synopsis</title>
5050+<programlisting>
5151+ocamlfind query [ -predicates <replaceable>p</replaceable> |
5252+ -format <replaceable>f</replaceable> |
5353+ -long-format | -l |
5454+ -i-format |
5555+ -l-format |
5656+ -a-format |
5757+ -o-format |
5858+ -p-format |
5959+ -prefix <replaceable>p</replaceable> |
6060+ -separator <replaceable>s</replaceable> |
6161+ -suffix <replaceable>s</replaceable> |
6262+ -pp |
6363+ -descendants | -d |
6464+ -recursive | -r
6565+ -qe | -qo] <replaceable>package</replaceable> ...
6666+</programlisting>
6767+</refsect2>
6868+6969+<refsect2> <title>Description</title>
7070+7171+<para> This command looks packages up, sorts them optionally, and
7272+prints attributes of them. If the option -recursive (short: -r) is not
7373+specified, exactly the packages given on the command line are looked
7474+up; if -recursive is present, the packages and all their ancestors, or
7575+if -descendants (short: -d) is present, too, all their descendants are printed.
7676+</para>
7777+7878+<para>
7979+Package lookup and the selection of the attributes of the packages can
8080+be modified by specifying predicates; without a -predicates option the
8181+empty set of predicates is used. Note that even the lookup is
8282+influenced by the set of actual predicates as the "requires" variables
8383+may be conditional.
8484+</para>
8585+8686+<para>
8787+What is printed about a package depends on the specified format; there
8888+are a number of options that modify the format. Some formats denote
8989+sets of values (such as -format %a), in which case multiple output
9090+records are printed for every package. (It is even possible to specify
9191+formats denoting the Cartesian product of sets, such as -format %a%o,
9292+but this does not make sense.) Before the first output record the
9393+prefix is printed, and the suffix after the last record. Between two
9494+records the separator is printed.
9595+</para>
9696+</refsect2>
9797+9898+<refsect2>
9999+<title>Options</title>
100100+101101+<variablelist>
102102+<varlistentry>
103103+<term>-predicates <replaceable>p</replaceable></term>
104104+<listitem><para>Sets the set of actual predicates. The argument
105105+ <replaceable>p</replaceable> is a list of predicate names separated
106106+ by commas and/or whitespace. If multiple -predicates options are
107107+ given, the union of all specified sets is effectively used.
108108+</para></listitem>
109109+</varlistentry>
110110+<varlistentry>
111111+<term>-format <replaceable>f</replaceable></term>
112112+<listitem><para>Sets the format to the string
113113+ <replaceable>f</replaceable>. Characters preceded by a percent sign
114114+ are interpreted as placeholders; all other characters mean
115115+ themselves. The defined placeholders are listed below.
116116+ The default format is "%d".
117117+</para></listitem>
118118+</varlistentry>
119119+<varlistentry>
120120+<term>-long-format or -l</term>
121121+<listitem><para>Sets the format such that all relevant variables are printed.
122122+</para></listitem>
123123+</varlistentry>
124124+<varlistentry>
125125+<term>-i-format</term>
126126+<listitem><para>Same as -format "-I %d", i.e. directory options for ocamlc are printed.
127127+</para></listitem>
128128+</varlistentry>
129129+<varlistentry>
130130+<term>-l-format</term>
131131+<listitem><para>Same as -format "-ccopt -L%d", i.e. directory options for the
132132+linker backend are printed.
133133+</para></listitem>
134134+</varlistentry>
135135+<varlistentry>
136136+<term>-a-format</term>
137137+<listitem><para>Same as -format "%+a", i.e. archive file names are printed.
138138+</para></listitem>
139139+</varlistentry>
140140+<varlistentry>
141141+<term>-o-format</term>
142142+<listitem><para>Same as -format "%o", i.e. linker options are printed.
143143+</para></listitem>
144144+</varlistentry>
145145+<varlistentry>
146146+<term>-p-format</term>
147147+<listitem><para>Same as -format "%p", i.e. package names are printed.
148148+</para></listitem>
149149+</varlistentry>
150150+<varlistentry>
151151+<term>-prefix <replaceable>p</replaceable></term>
152152+<listitem><para>Sets the prefix that is printed before the first output record
153153+ to the given string. The default prefix is the empty string.
154154+</para></listitem>
155155+</varlistentry>
156156+<varlistentry>
157157+<term>-suffix <replaceable>s</replaceable></term>
158158+<listitem><para>Sets the suffix that is printed after the last output record
159159+ to the given string. The default suffix is the empty string.
160160+</para></listitem>
161161+</varlistentry>
162162+<varlistentry>
163163+<term>-separator <replaceable>s</replaceable></term>
164164+<listitem><para>Sets the separator that is printed between output records to
165165+ the given string. The default separator is a linefeed character.
166166+</para></listitem>
167167+</varlistentry>
168168+<varlistentry>
169169+<term>-recursive or -r</term>
170170+<listitem><para>Not only the packages given on the command line are queried
171171+ but also all ancestors or descendants. If the option -descendants is
172172+ specified, too, the descendants are printed, otherwise the
173173+ ancestors. The packages are topologically sorted.
174174+</para></listitem>
175175+</varlistentry>
176176+<varlistentry>
177177+<term>-descendants -d</term>
178178+<listitem><para>Instead of the ancestors the descendants of the
179179+ given packages are queried. This option implies <literal>-recursive</literal>.
180180+</para></listitem>
181181+</varlistentry>
182182+<varlistentry>
183183+<term>-pp</term>
184184+<listitem><para>Query preprocessor packages (camlp4 syntax extensions). Normally
185185+it is not needed to set -predicates, except you need the archives (then add
186186+-predicates byte). This option implies <literal>-recursive</literal>.
187187+</para></listitem>
188188+</varlistentry>
189189+<varlistentry>
190190+<term>-qe</term>
191191+<listitem><para>Do not print most errors to stderr, just set the exit code
192192+</para></listitem>
193193+</varlistentry>
194194+<varlistentry>
195195+<term>-qo</term>
196196+<listitem><para>Do not print the regular output.
197197+</para></listitem>
198198+</varlistentry>
199199+200200+</variablelist>
201201+</refsect2>
202202+203203+<refsect2>
204204+<title>Placeholders meaningful in the -format option</title>
205205+206206+<variablelist>
207207+<varlistentry>
208208+<term>%%</term>
209209+ <listitem><para>Replaced by a single percent sign</para></listitem>
210210+</varlistentry>
211211+<varlistentry>
212212+<term>%p</term>
213213+ <listitem><para>Replaced by the package name</para></listitem>
214214+</varlistentry>
215215+<varlistentry>
216216+<term>%d</term>
217217+ <listitem><para>Replaced by the package directory</para></listitem>
218218+</varlistentry>
219219+<varlistentry>
220220+<term>%m</term>
221221+ <listitem><para>Replaced by the path to the META file (new since findlib-1.6)
222222+</para></listitem>
223223+</varlistentry>
224224+<varlistentry>
225225+<term>%D</term>
226226+ <listitem><para>Replaced by the package description</para></listitem>
227227+</varlistentry>
228228+<varlistentry>
229229+<term>%v</term>
230230+ <listitem><para>Replaced by the version string</para></listitem>
231231+</varlistentry>
232232+<varlistentry>
233233+<term>%a</term>
234234+ <listitem><para>Replaced by the archive filename. If there is more
235235+ than one archive, a separate output record is printed for every archive.
236236+</para></listitem>
237237+</varlistentry>
238238+<varlistentry>
239239+<term>%+a</term>
240240+ <listitem><para>Like %a, but the filenames are converted to absolute
241241+ paths ("+" and "@" notations are resolved)
242242+</para></listitem>
243243+</varlistentry>
244244+<varlistentry>
245245+<term>%A</term>
246246+ <listitem><para>Replaced by the list of archive filenames.</para></listitem>
247247+</varlistentry>
248248+<varlistentry>
249249+<term>%+A</term>
250250+ <listitem><para>Like %A, but the filenames are converted to absolute
251251+ paths ("+" and "@" notations are resolved)
252252+</para></listitem>
253253+<varlistentry>
254254+<term>%o</term>
255255+ <listitem><para>Replaced by one linker option. If there is more than
256256+ one option, a separate output record is printed for every option.
257257+</para></listitem>
258258+</varlistentry>
259259+<varlistentry>
260260+<term>%O</term>
261261+ <listitem><para>Replaced by the list of linker options.</para></listitem>
262262+</varlistentry>
263263+<varlistentry>
264264+<term>%(<replaceable>property</replaceable>)</term>
265265+ <listitem><para>Replaced by the value of the property named in parentheses,
266266+or the empty string if not defined.</para></listitem>
267267+</varlistentry>
268268+</variablelist>
269269+</refsect2>
270270+271271+</refsect1>
272272+273273+274274+<!-- ********************************************************************** -->
275275+276276+<refsect1>
277277+<title><anchor id="ocamlfind.ocamlc">
278278+ <anchor id="ocamlfind.ocamlcp">
279279+ <anchor id="ocamlfind.ocamlopt">
280280+ <anchor id="ocamlfind.ocamlmktop">
281281+ THE SUBCOMMANDS "ocamlc", "ocamlcp", "ocamlopt", and "ocamlmktop"
282282+</title>
283283+284284+<refsect2>
285285+<title>Synopsis</title>
286286+<programlisting>
287287+ocamlfind ( ocamlc | ocamlcp | ocamlopt | ocamlmktop )
288288+ [ -package <replaceable>package-name-list</replaceable> |
289289+ -linkpkg |
290290+ -predicates <replaceable>pred-name-list</replaceable> |
291291+ -dontlink <replaceable>package-name-list</replaceable> |
292292+ -syntax <replaceable>pred-name-list</replaceable> |
293293+ -ppopt <replaceable>camlp4-arg</replaceable> |
294294+ -ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable> |
295295+ -dllpath-pkg <replaceable>package-name-list</replaceable> |
296296+ -dllpath-all |
297297+ -passopt <replaceable>arg</replaceable> |
298298+ -passrest <replaceable>arg...</replaceable> |
299299+ -only-show |
300300+ <replaceable>standard-option</replaceable> ]
301301+ <replaceable>file</replaceable> ...
302302+</programlisting>
303303+</refsect2>
304304+305305+<refsect2>
306306+<title>Description</title>
307307+308308+<para>
309309+These subcommands are drivers for the compilers with the same names,
310310+i.e. "ocamlfind ocamlc" is a driver for "ocamlc", and so on. The
311311+subcommands understand all documented options of the compilers (here
312312+called <replaceable>standard-options</replaceable>), but also a few
313313+more options. If these subcommands are invoked only with standard
314314+options, they behave as if the underlying compiler had been called
315315+directly. The extra options modify this.
316316+</para>
317317+318318+<para>
319319+Internally, these subcommands transform the given list of options and
320320+file arguments into an invocation of the driven compiler. This
321321+transformation only adds options and files, and the relative order of
322322+the options and files passed directly is unchanged.
323323+</para>
324324+325325+<para>
326326+If there are -package options, additional directory search specifiers
327327+will be included ("-I", and "-ccopt -I"), such that files of all named
328328+packages and all ancestors can be found.
329329+</para>
330330+331331+<para>
332332+The -linkpkg option causes that the packages listed in the -package
333333+options and all necessary ancestors are linked in. This means that the
334334+archive files implementing the packages are inserted into the list of
335335+file arguments.
336336+</para>
337337+338338+<para>
339339+As the package database is queried a set of predicates is needed. Most
340340+predicates are set automatically, see below, but additional predicates
341341+can be given by a -predicates option.
342342+</para>
343343+344344+<para>
345345+If there is a <literal>-syntax</literal> option, the drivers assume that
346346+a preprocessor is to be used. In this case, the preprocessor command
347347+is built first in a preprocessor stage, and this command is passed to the
348348+compiler using the <literal>-pp</literal> option. The set of predicates
349349+in the preprocessor stage is different from the set in the compiler/linker
350350+stage.</para>
351351+352352+</refsect2>
353353+354354+<refsect2>
355355+<title>Options for compiling and linking</title>
356356+357357+<para>
358358+Here, only the additional options not interpreted by the compiler but
359359+by the driver itself, and options with additional effects are explained.
360360+Some options are only meaningful for the preprocessor call, and are
361361+explained below.
362362+</para>
363363+364364+<variablelist>
365365+<varlistentry>
366366+<term>-package <replaceable>package-name-list</replaceable></term>
367367+ <listitem><para>Adds the listed package names to the set of included
368368+ packages. The package names may be separated by commas and/or
369369+ whitespace. In the transformed command, for every package of the set
370370+ of included packages and for any ancestor a directory search option
371371+ is inserted after the already given options. This means that
372372+ "-I" and "-ccopt -I" options are added for every package directory.
373373+ </para></listitem>
374374+</varlistentry>
375375+<varlistentry>
376376+<term>-linkpkg</term>
377377+ <listitem><para>Causes that in the transformed command all archives
378378+ of the packages specified by -packages and all their ancestors are
379379+ added to the file arguments. More precisely, these archives are
380380+ inserted before the first given file argument. Furthermore, "-ccopt
381381+ -L" options for all package directories, and the linker options of
382382+ the selected packages are added, too. Note that the archives are
383383+ inserted in topological order while the linker options are added in
384384+ reverse toplogical order.
385385+</para></listitem>
386386+</varlistentry>
387387+<varlistentry>
388388+<term>-predicates <replaceable>pred-name-list</replaceable></term>
389389+ <listitem><para>Adds the given predicates to the set of actual
390390+ predicates. The predicates must be separated by commas and/or
391391+ whitespace.
392392+</para></listitem>
393393+</varlistentry>
394394+<varlistentry>
395395+<term>-dontlink <replaceable>package-name-list</replaceable></term>
396396+ <listitem><para>This option modifies the behaviour of
397397+ -linkpkg. Packages specified here and all ancestors are not linked
398398+ in. Again the packages are separated by commas and/or whitespace.
399399+</para></listitem>
400400+</varlistentry>
401401+<varlistentry>
402402+<term>-dllpath-pkg <replaceable>package-name-list</replaceable></term>
403403+ <listitem><para>For these packages <literal>-dllpath</literal> options
404404+ are added to the compiler command. This may be useful when the ld.conf
405405+ file is not properly configured.</para></listitem>
406406+</varlistentry>
407407+<varlistentry>
408408+<term>-dllpath-all</term>
409409+ <listitem><para>For all linked packages <literal>-dllpath</literal> options
410410+ are added to the compiler command. This may be useful when the ld.conf
411411+ file is not properly configured.</para></listitem>
412412+</varlistentry>
413413+<varlistentry>
414414+<term>-passopt <replaceable>arg</replaceable></term>
415415+ <listitem><para>The argument <replaceable>arg</replaceable> is
416416+ passed directly to the underlying compiler. This is needed to
417417+ specify undocumented compiler options.
418418+</para></listitem>
419419+</varlistentry>
420420+<varlistentry>
421421+<term>-passrest <replaceable>arg...</replaceable></term>
422422+ <listitem><para>All following arguments <replaceable>arg...</replaceable> are
423423+ passed directly to the underlying compiler. This is needed to
424424+ specify undocumented compiler options.
425425+</para></listitem>
426426+<varlistentry>
427427+<term>-only-show</term>
428428+ <listitem><para>Only prints the constructed command (ocamlc/ocamlopt) to
429429+ stdout, but does not execute the command. (This is for the unlikely event
430430+ that you need a wrapper around ocamlfind.)
431431+</para></listitem>
432432+</varlistentry>
433433+434434+<varlistentry>
435435+<term>-verbose</term>
436436+ <listitem><para>This standard option is interpreted by the driver, too.
437437+</para></listitem>
438438+</varlistentry>
439439+<varlistentry>
440440+<term>-thread</term>
441441+ <listitem><para>This standard option causes that the predicate "mt"
442442+ is added to the set of actual predicates. If POSIX threads are available,
443443+ the predicate "mt_posix" is selected, too. If only VM threads are
444444+ available, the predicate "mt_vm" is included into the set, and the
445445+ compiler switch is changed into -vmthread.
446446+</para>
447447+ <para>Note that the presence of the "mt" predicate triggers special
448448+fixup of the dependency graph (see below).</para>
449449+</listitem>
450450+</varlistentry>
451451+<varlistentry>
452452+<term>-vmthread</term>
453453+ <listitem><para>This standard option causes that the predicates "mt"
454454+ and "mt_vm" are added to the set of actual predicates.
455455+</para>
456456+ <para>Note that the presence of the "mt" predicate triggers special
457457+fixup of the dependency graph (see below).</para>
458458+</listitem>
459459+</varlistentry>
460460+<varlistentry>
461461+<term>-p</term>
462462+ <listitem><para>This standard option of "ocamlopt" causes that the
463463+ predicate "gprof" is added to the set of actual predicates.
464464+</para></listitem>
465465+</varlistentry>
466466+467467+</variablelist>
468468+469469+</refsect2>
470470+471471+<refsect2>
472472+<title>Options for preprocessing</title>
473473+474474+<para>
475475+The options relevant for the preprocessor are the following:
476476+</para>
477477+478478+<variablelist>
479479+<varlistentry>
480480+<term>-package <replaceable>package-name-list</replaceable></term>
481481+ <listitem><para>These packages are considered while looking up the
482482+ preprocessor arguments. (It does not cause problems that the same
483483+ -package option is used for this purpose, because the set of predicates
484484+ is different.) It is recommended to mention at least <literal>camlp4</literal>
485485+ here if the preprocessor is going to be used.
486486+ </para></listitem>
487487+</varlistentry>
488488+<varlistentry>
489489+<term>-syntax <replaceable>pred-name-list</replaceable></term>
490490+ <listitem><para>These predicates are assumed to be true in addition
491491+ to the standard preprocessor predicates. See below for a list.
492492+</para></listitem>
493493+</varlistentry>
494494+<varlistentry>
495495+ <term>-ppopt <replaceable>camlp4-arg</replaceable></term>
496496+ <listitem><para>This argument is passed to the camlp4 call.
497497+ </para></listitem>
498498+</varlistentry>
499499+<varlistentry>
500500+ <term>-ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable></term>
501501+ <listitem><para>Add <replaceable>arg</replaceable> to the ppx
502502+ preprocessor invocation specified via the "ppx" property in
503503+ the META file of <replaceable>package</replaceable>.
504504+ </para></listitem>
505505+</varlistentry>
506506+</variablelist>
507507+</refsect2>
508508+509509+<refsect2>
510510+<title>Predicates for compiling and linking</title>
511511+512512+<variablelist>
513513+<varlistentry>
514514+<term>byte</term>
515515+<listitem>
516516+<para>
517517+The "byte" predicate means that one of the bytecode compilers is
518518+used. It is automatically included into the predicate set if the
519519+"ocamlc", "ocamlcp", or "ocamlmktop" compiler is used.
520520+</para>
521521+</listitem>
522522+</varlistentry>
523523+524524+<varlistentry>
525525+<term>native</term>
526526+<listitem>
527527+<para>
528528+The "native" predicate means that the native compiler is used. It is
529529+automatically included into the predicate set if the "ocamlopt"
530530+compiler is used.
531531+</para>
532532+</listitem>
533533+</varlistentry>
534534+535535+<varlistentry>
536536+<term>toploop</term>
537537+<listitem>
538538+<para>
539539+The "toploop" predicate means that the toploop is available in the
540540+linked program. This predicate is only set when the toploop is actually
541541+being executed, not when the toploop is created (this changed in version
542542+1.0.4 of findlib).
543543+</para>
544544+</listitem>
545545+</varlistentry>
546546+547547+<varlistentry>
548548+<term>create_toploop</term>
549549+<listitem>
550550+<para>
551551+This predicate means that a toploop is being created (using
552552+ocamlmktop).
553553+</para>
554554+</listitem>
555555+</varlistentry>
556556+557557+<varlistentry>
558558+<term>mt</term>
559559+<listitem>
560560+<para>
561561+The "mt" predicate means that the program is multi-threaded. It is
562562+automatically included into the predicate set if the -thread option is
563563+given.
564564+</para>
565565+</listitem>
566566+</varlistentry>
567567+568568+<varlistentry>
569569+<term>mt_posix</term>
570570+<listitem>
571571+<para>
572572+The "mt_posix" predicate means that in the case "mt" is set, too, the
573573+POSIX libraries are used to implement threads. "mt_posix" is automatically
574574+included into the predicate set if the variable "type_of_threads" in the
575575+META description of the "threads" package has the value "posix". This
576576+is normally the case if "findlib" is configured for POSIX threads.
577577+</para>
578578+</listitem>
579579+</varlistentry>
580580+581581+<varlistentry>
582582+<term>mt_vm</term>
583583+<listitem>
584584+<para>
585585+The "mt_vm" predicate means that in the case "mt" is set, too, the
586586+VM thread emulation is used to implement multi-threading.
587587+</para>
588588+</listitem>
589589+</varlistentry>
590590+591591+<varlistentry>
592592+<term>gprof</term>
593593+<listitem>
594594+<para>
595595+The "gprof" predicate means that in the case "native" is set, too, the
596596+program is compiled for profiling. It is automatically included into
597597+the predicate set if "ocamlopt" is used and the -p option is in
598598+effect.
599599+</para>
600600+</listitem>
601601+</varlistentry>
602602+603603+<varlistentry>
604604+<term>autolink</term>
605605+<listitem>
606606+<para>
607607+The "autolink" predicate means that ocamlc is able to perform automatic
608608+linking. It is automatically included into the predicate set if ocamlc
609609+knows automatic linking (from version 3.00), but it is not set if the
610610+-noautolink option is set.
611611+</para>
612612+</listitem>
613613+</varlistentry>
614614+615615+<varlistentry>
616616+ <term>syntax</term>
617617+ <listitem><para>This predicate is set if there is a <literal>-syntax</literal>
618618+ option. It is set both for the preprocessor and the compiler/linker stage,
619619+ and it can be used to find out whether the preprocessor is enabled or not.
620620+ </para></listitem>
621621+</varlistentry>
622622+623623+</variablelist>
624624+625625+</refsect2>
626626+627627+<refsect2>
628628+<title>Predicates for preprocessing</title>
629629+630630+<variablelist>
631631+<varlistentry>
632632+ <term>preprocessor</term>
633633+ <listitem><para>This predicate is always set while looking up the
634634+ preprocessor arguments. It can be used to distinguish between the
635635+ preprocessor stage and the compiler/linker stage.</para></listitem>
636636+</varlistentry>
637637+<varlistentry>
638638+ <term>syntax</term>
639639+ <listitem><para>This predicate is set if there is a <literal>-syntax</literal>
640640+ option. It is set both for the preprocessor and the compiler/linker stage,
641641+ and it can be used to find out whether the preprocessor is enabled or not.
642642+ </para></listitem>
643643+</varlistentry>
644644+<varlistentry>
645645+ <term>camlp4o</term>
646646+ <listitem><para>This is the reserved predicate for the standard OCaml syntax.
647647+ It can be used in the <literal>-syntax</literal> predicate list.
648648+ </para></listitem>
649649+</varlistentry>
650650+<varlistentry>
651651+ <term>camlp4r</term>
652652+ <listitem><para>This is the reserved predicate for the revised OCaml syntax.
653653+ It can be used in the <literal>-syntax</literal> predicate list.
654654+ </para></listitem>
655655+</varlistentry>
656656+</variablelist>
657657+</refsect2>
658658+659659+660660+<refsect2>
661661+<title>Special behaviour of "ocamlmktop"</title>
662662+663663+<para> As there is a special module <literal>Topfind</literal> that
664664+supports loading of packages in scripts, the "ocamlmktop" subcommand
665665+can add initialization code for this module. This extra code is
666666+linked into the executable if "findlib" is in the set of effectively
667667+linked packages.
668668+</para>
669669+670670+</refsect2>
671671+672672+673673+<refsect2>
674674+<title>Fixup of the dependency graph for multi-threading</title>
675675+<para>For a number of reasons the presence of the "mt" predicate triggers
676676+that (1) the package "threads" is added to the list of required packages
677677+and (2) the package "threads" becomes prerequisite of all other packages
678678+(except of itself and a few hardcoded exceptions). The effect is that
679679+the options -thread and -vmthread automatically select the "threads"
680680+package, and that "threads" is inserted at the right position in the
681681+package list.</para>
682682+</refsect2>
683683+684684+685685+<refsect2>
686686+<title>Extended file naming</title>
687687+<para>At a number of places one can not only refer to files by absolute
688688+or relative path names, but also by extended names. These have two
689689+major forms: "+<replaceable>name</replaceable>"
690690+refers to the subdirectory <replaceable>name</replaceable> of the
691691+standard library directory, and "@<replaceable>name</replaceable>"
692692+refers to the package directory of the package <replaceable>name</replaceable>.
693693+Both forms can be continued by a path, e.g. "@netstring/netstring_top.cma".
694694+</para>
695695+696696+<para>
697697+You can use extended names: (1) With <literal>-I</literal> options,
698698+(2) as normal file arguments of the compiler, (3) in the
699699+"archive" property of packages.
700700+</para>
701701+</refsect2>
702702+703703+704704+<refsect2>
705705+<title>How to set the names of the compiler executables</title>
706706+707707+<para> Normally, the OCaml bytecode compiler can be called under the name
708708+<literal>ocamlc</literal>. However, this is not always true; sometimes a
709709+different name is chosen.</para>
710710+711711+<para> You can instruct ocamlfind to call executables with other names than
712712+<literal>ocamlc</literal>, <literal>ocamlopt</literal>,
713713+<literal>ocamlmktop</literal>, and <literal>ocamlcp</literal>. If present,
714714+the environment variable <literal>OCAMLFIND_COMMANDS</literal> is interpreted
715715+as a mapping from the standard names to the actual names of the executables. It
716716+must have the following format:
717717+718718+<programlisting>
719719+<replaceable>standardname1</replaceable>=<replaceable>actualname1</replaceable> <replaceable>standardname2</replaceable>=<replaceable>actualname2</replaceable> ...
720720+</programlisting>
721721+</para>
722722+723723+<para>Example: You may set <literal>OCAMLFIND_COMMANDS</literal> as follows:
724724+725725+<programlisting>
726726+OCAMLFIND_COMMANDS='ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00'
727727+export OCAMLFIND_COMMANDS
728728+</programlisting>
729729+</para>
730730+731731+<para>Alternatively, you can change the configuration file
732732+<link linkend="findlib.conf">findlib.conf</link>.</para>
733733+</refsect2>
734734+735735+</refsect1>
736736+737737+<!-- ********************************************************************** -->
738738+739739+<refsect1>
740740+<title><anchor id="ocamlfind.ocamlmklib">
741741+ THE SUBCOMMAND "ocamlmklib"
742742+</title>
743743+744744+<refsect2>
745745+<title>Synopsis</title>
746746+<programlisting>
747747+ocamlfind ocamlmklib
748748+ [ -package <replaceable>package-name-list</replaceable> |
749749+ -predicates <replaceable>pred-name-list</replaceable> |
750750+ -dllpath-pkg <replaceable>package-name-list</replaceable> |
751751+ -dllpath-all |
752752+ -passopt <replaceable>arg</replaceable> |
753753+ -passrest <replaceable>arg...</replaceable> |
754754+ <replaceable>standard-option</replaceable> ]
755755+ <replaceable>file</replaceable> ...
756756+</programlisting>
757757+</refsect2>
758758+759759+<refsect2>
760760+<title>Description</title>
761761+762762+<para>
763763+This is a wrapper around ocamlmklib, and creates library archives and
764764+DLLs. In addition to the standard options, one can use -package to
765765+add the search path of packages. Note that no predicates are set by default -
766766+the wrapper does not know whether this is about byte or native code linking.
767767+</para>
768768+769769+<para>
770770+This wrapper is mostly provided for completeness.
771771+</para>
772772+</refsect2>
773773+774774+</refsect1>
775775+776776+777777+778778+<!-- ********************************************************************** -->
779779+780780+<refsect1>
781781+<title><anchor id="ocamlfind.ocamldep">
782782+ THE "ocamldep" SUBCOMMAND
783783+</title>
784784+785785+<refsect2>
786786+<title>Synopsis</title>
787787+<programlisting>
788788+ocamlfind ocamldep [-package <replaceable>package-name-list</replaceable> |
789789+ -syntax <replaceable>pred-name-list</replaceable> |
790790+ -ppopt <replaceable>camlp4-arg</replaceable> |
791791+ -passopt <replaceable>arg</replaceable> |
792792+ -passrest <replaceable>arg...</replaceable> |
793793+ -verbose |
794794+ <replaceable>standard-option</replaceable>] <replaceable>file</replaceable> ...
795795+</programlisting>
796796+</refsect2>
797797+798798+<refsect2><title>Description</title>
799799+<para>
800800+This command is a driver for the tool <literal>ocamldep</literal> of the
801801+OCaml distribution. This driver is only useful in conjunction with
802802+the preprocessor camlp4; otherwise it does not provide more functions
803803+than <literal>ocamldep</literal> itself.
804804+</para>
805805+</refsect2>
806806+807807+<refsect2>
808808+<title>Options</title>
809809+810810+<para>
811811+Here, only the additional options not interpreted by <literal>ocamldep</literal>
812812+but
813813+by the driver itself, and options with additional effects are explained.
814814+</para>
815815+816816+<variablelist>
817817+<varlistentry>
818818+ <term>-package <replaceable>package-name-list</replaceable></term>
819819+ <listitem><para>The packages named here are only used to look up the
820820+preprocessor options. The package <literal>camlp4</literal> should be
821821+specified anyway, but further packages that add capabilities to the
822822+preprocessor can also be passed.</para></listitem>
823823+</varlistentry>
824824+825825+<varlistentry>
826826+ <term>-syntax <replaceable>pred-name-list</replaceable></term>
827827+ <listitem><para>The predicates that are in effect during the look-up
828828+of the preprocessor options. At least, either <literal>camlp4o</literal>
829829+(selecting the normal syntax), or <literal>camlp4r</literal> (selecting
830830+the revised syntax) should be specified.</para></listitem>
831831+</varlistentry>
832832+833833+<varlistentry>
834834+ <term>-ppopt <replaceable>camlp4-arg</replaceable></term>
835835+ <listitem><para>An option that is passed through to the camlp4 call.</para>
836836+</listitem>
837837+</varlistentry>
838838+839839+<varlistentry>
840840+ <term>-passopt <replaceable>arg</replaceable></term>
841841+ <listitem><para>An option that is passed through to the ocamldep call.</para>
842842+</listitem>
843843+</varlistentry>
844844+845845+<varlistentry>
846846+ <term>-passrest <replaceable>arg...</replaceable></term>
847847+ <listitem><para>All further arguments are passed down to ocamldep
848848+ unprocessed</para>
849849+</listitem>
850850+</varlistentry>
851851+852852+<varlistentry>
853853+ <term>-verbose</term>
854854+ <listitem><para>Displays the resulting ocamldep command (for debugging)
855855+</para></listitem>
856856+</varlistentry>
857857+</variablelist>
858858+859859+</refsect2>
860860+861861+<refsect2>
862862+<title>Example</title>
863863+864864+<para>A typical way of using this driver:
865865+866866+<programlisting>
867867+ocamlfind ocamldep -package camlp4,xstrp4 -syntax camlp4r file1.ml file2.ml
868868+</programlisting>
869869+870870+This command outputs the dependencies of <literal>file1.ml</literal> and
871871+<literal>file2.ml</literal>, although these modules make use of the
872872+syntax extensions provided by <literal>xstrp4</literal> and are written
873873+in revised syntax.
874874+</para>
875875+</refsect2>
876876+877877+</refsect1>
878878+879879+880880+<!-- ********************************************************************** -->
881881+882882+<refsect1>
883883+<title><anchor id="ocamlfind.ocamlbrowser">
884884+ THE "ocamlbrowser" SUBCOMMAND
885885+</title>
886886+887887+<refsect2>
888888+<title>Synopsis</title>
889889+<programlisting>
890890+ocamlfind ocamlbrowser [-package <replaceable>package-name-list</replaceable> |
891891+ -all |
892892+ -passopt <replaceable>arg</replaceable>
893893+ -passrest ]
894894+</programlisting>
895895+</refsect2>
896896+897897+<refsect2><title>Description</title>
898898+<para>
899899+This driver calls the <literal>ocamlbrowser</literal> with package options.
900900+With <literal>-package</literal>, the specified packages are included into
901901+the search path of the browser, and the modules of these packages become
902902+visible (in addition to the standard library). The option <literal>-all</literal> causes that all packages are selected that are managed by findlib.</para>
903903+904904+<para>
905905+As for other drivers, the options <literal>-passopt</literal> and
906906+<literal>-passrest</literal> can be used
907907+to pass arguments directly to the <literal>ocamlbrowser</literal> program.
908908+</para>
909909+</refsect2>
910910+</refsect1>
911911+912912+<!-- ********************************************************************** -->
913913+914914+<refsect1>
915915+<title><anchor id="ocamlfind.ocamldoc">
916916+ THE SUBCOMMAND "ocamldoc"
917917+</title>
918918+919919+<refsect2>
920920+<title>Synopsis</title>
921921+<programlisting>
922922+ocamlfind ocamldoc
923923+ [ -package <replaceable>package-name-list</replaceable> |
924924+ -predicates <replaceable>pred-name-list</replaceable> |
925925+ -syntax <replaceable>pred-name-list</replaceable> |
926926+ -ppopt <replaceable>camlp4-arg</replaceable> |
927927+ <replaceable>standard-option</replaceable> ]
928928+ <replaceable>file</replaceable> ...
929929+</programlisting>
930930+</refsect2>
931931+932932+<refsect2>
933933+<title>Description</title>
934934+935935+<para>
936936+This subcommand is a driver for ocamldoc. It undestands all options
937937+ocamldoc supports plus the mentioned findlib options. Basically,
938938+the -package options are translated into -I options, and the selected
939939+syntax options are translated into camlp4 options.
940940+</para>
941941+</refsect2>
942942+943943+<refsect2>
944944+<title>Options</title>
945945+946946+<para>
947947+Here, only the additional options not interpreted by <literal>ocamldep</literal>
948948+but
949949+by the driver itself, and options with additional effects are explained.
950950+</para>
951951+952952+<variablelist>
953953+<varlistentry>
954954+<term>-package <replaceable>package-name-list</replaceable></term>
955955+ <listitem><para>Adds the listed package names to the set of included
956956+ packages. The package names may be separated by commas and/or
957957+ whitespace. In the transformed command, for every package of the set
958958+ of included packages and for any ancestor a directory search option
959959+ is inserted after the already given options. This means that
960960+ "-I" options are added for every package directory.
961961+ </para></listitem>
962962+</varlistentry>
963963+964964+<varlistentry>
965965+<term>-predicates <replaceable>pred-name-list</replaceable></term>
966966+ <listitem><para>Adds the given predicates to the set of actual
967967+ predicates. The predicates must be separated by commas and/or
968968+ whitespace.
969969+</para></listitem>
970970+</varlistentry>
971971+972972+<varlistentry>
973973+ <term>-syntax <replaceable>pred-name-list</replaceable></term>
974974+ <listitem><para>The predicates that are in effect during the look-up
975975+of the preprocessor options. At least, either <literal>camlp4o</literal>
976976+(selecting the normal syntax), or <literal>camlp4r</literal> (selecting
977977+the revised syntax) should be specified.</para></listitem>
978978+</varlistentry>
979979+980980+<varlistentry>
981981+ <term>-ppopt <replaceable>camlp4-arg</replaceable></term>
982982+ <listitem><para>An option that is passed through to the camlp4 call.</para>
983983+</listitem>
984984+</varlistentry>
985985+</variablelist>
986986+</refsect2>
987987+</refsect1>
988988+989989+990990+<!-- ********************************************************************** -->
991991+992992+<!--
993993+994994+<refsect1>
995995+<title><anchor id="ocamlfind.use">
996996+ THE "use" SUBCOMMAND
997997+</title>
998998+999999+<refsect2>
10001000+<title>Synopsis</title>
10011001+<programlisting>
10021002+ocamlfind use [-p <replaceable>prefix</replaceable>] <replaceable>package_name</replaceable> ...
10031003+</programlisting>
10041004+</refsect2>
10051005+10061006+<refsect2>
10071007+<title>Description</title>
10081008+10091009+<para>
10101010+This subcommand should not be used any longer. It is equivalent to the
10111011+"query" subcommand with -i-format and -separator " ".
10121012+</para>
10131013+</refsect2>
10141014+</refsect1>
10151015+10161016+-->
10171017+10181018+<!-- ********************************************************************** -->
10191019+10201020+<refsect1>
10211021+<title><anchor id="ocamlfind.install">
10221022+ THE "install" SUBCOMMAND
10231023+</title>
10241024+10251025+<refsect2>
10261026+<title>Synopsis</title>
10271027+<programlisting>
10281028+ocamlfind install [ -destdir <replaceable>directory</replaceable> ]
10291029+ [ -metadir <replaceable>directory</replaceable> ]
10301030+ [ -ldconf <replaceable>path</replaceable> ]
10311031+ [ -dont-add-directory-directive ]
10321032+ [ -patch-version <replaceable>string</replaceable> ]
10331033+ [ -patch-rmpkg <replaceable>name</replaceable> ]
10341034+ [ -patch-archives ]
10351035+ [ -dll ] [ -nodll ] [ -optional ] [ -add ]
10361036+ <replaceable>package_name</replaceable> <replaceable>file</replaceable> ...
10371037+</programlisting>
10381038+</refsect2>
10391039+10401040+<refsect2>
10411041+<title>Description</title>
10421042+<para>
10431043+This subcommand installs a new package either at the default location
10441044+(see the variable <literal>destdir</literal> of
10451045+<link linkend="findlib.conf">findlib.conf</link>), or in the directory
10461046+specified by the -destdir option. This
10471047+means that a new package directory is created and that the files on
10481048+the command line are copied to this directory. It is required that a
10491049+<literal>META</literal> file is one of the files copied to the target
10501050+directory.
10511051+</para>
10521052+10531053+<para>
10541054+Note that package directories should be flat (no
10551055+subdirectories). Existing packages are never overwritten.
10561056+</para>
10571057+10581058+<para>
10591059+It is possible to have a separate directory for all the META files. If
10601060+you want that, you have either to set the variable
10611061+<literal>metadir</literal> of
10621062+<link linkend="findlib.conf">findlib.conf</link>, or to specify the
10631063+-metadir option. In this case, the file called META is copied to the
10641064+specified directory and renamed to META.p (where p is the package
10651065+name), while all the other files are copied to the package
10661066+directory as usual. Furthermore, the META file is modified such that the
10671067+<literal>directory</literal> variable contains the path of the package
10681068+directory.
10691069+</para>
10701070+10711071+<para>
10721072+The option -dont-add-directory-directive prevents the installer from
10731073+adding a <literal>directory</literal> variable.
10741074+</para>
10751075+10761076+<para>
10771077+If there are files ending in the suffixes <literal>.so</literal> or
10781078+<literal>.dll</literal>, the package directory will be added to the
10791079+DLL configuration file <literal>ld.conf</literal>, such that the dynamic
10801080+loader can find the DLL. The location of this file can be overridden by
10811081+the -ldconf option. To turn this feature off, use "-ldconf ignore";
10821082+this causes that the ld.conf file is not modified.
10831083+</para>
10841084+10851085+<para>
10861086+However, if there is a stublibs directory in site-lib, the DLLs are not
10871087+installed in the package directory, but in this directory that is
10881088+shared by all packages that are installed at the same location.
10891089+In this case, the configuration file <literal>ld.conf</literal> is
10901090+not modified, so you do not need to say "-ldconf ignore" if you
10911091+prefer this style of installation.
10921092+</para>
10931093+10941094+<para>
10951095+The options -dll and -nodll can be used to control exactly which files
10961096+are considered as DLLs and which not. By default, the mentioned
10971097+suffix rule is in effect: files ending in ".so" (Unix) or ".dll"
10981098+(Windows) are DLLs. The switch -dll changes this, and all following
10991099+files are considered as DLLs, regardless of their suffix. The switch
11001100+-nodll expresses that the following files are not DLLs, even if they
11011101+have a DLL-like suffix. For example, in the following call the files
11021102+f1 and f2 are handled by the suffix rule; f3 and f4 are DLLs anyway;
11031103+and f5 and f6 are not DLLs:
11041104+11051105+<programlisting>
11061106+ocamlfind install p f1 f2 -dll f3 f4 -nodll f5 f6
11071107+</programlisting>
11081108+</para>
11091109+11101110+<para>
11111111+The switch -optional declares that all following files are optional,
11121112+i.e. the command will not fail if files do not exist.
11131113+</para>
11141114+11151115+<para>
11161116+The -patch options may be used to change the contents of the META files
11171117+while it is being installed. The option -patch-version changes the
11181118+contents of the top-level "version" variable. The option -patch-rmpkg
11191119+removes the given subpackage. The option -patch-archives is experimental,
11201120+in particular it removes all non-existing files from "archive" variables,
11211121+and even whole subpackages if the archives are missing.
11221122+</para>
11231123+11241124+<para>
11251125+The effect of -add is to add further files to an already installed
11261126+packages.
11271127+</para>
11281128+11291129+</refsect2>
11301130+11311131+</refsect1>
11321132+11331133+11341134+<!-- ********************************************************************** -->
11351135+11361136+<refsect1>
11371137+<title><anchor id="ocamlfind.remove">
11381138+ THE "remove" SUBCOMMAND
11391139+</title>
11401140+11411141+<refsect2>
11421142+<title>Synopsis</title>
11431143+<programlisting>
11441144+ocamlfind remove [ -destdir <replaceable>directory</replaceable> ]
11451145+ [ -metadir <replaceable>directory</replaceable> ]
11461146+ [ -ldconf <replaceable>path</replaceable> ]
11471147+ <replaceable>package_name</replaceable>
11481148+</programlisting>
11491149+</refsect2>
11501150+11511151+<refsect2>
11521152+<title>Description</title>
11531153+<para>
11541154+The package will removed if it is installed at the default location
11551155+(see the variable <literal>destdir</literal> of
11561156+<link linkend="findlib.conf">findlib.conf</link>). If the package
11571157+resides at a different location, it will not be removed by default;
11581158+however, you can pass an alternate directory for packages by the
11591159+-destdir option. (This must be the same directory as specified at
11601160+installation time.)
11611161+</para>
11621162+11631163+<para>
11641164+Note that package directories should be flat (no subdirectories); this
11651165+subcommand cannot remove deep package directories.
11661166+</para>
11671167+11681168+<para>
11691169+If you have a separate directory for META files, you must either
11701170+configure this directory by the <literal>metadir</literal> variable
11711171+of <link linkend="findlib.conf">findlib.conf</link>, or by specifying
11721172+the -metadir option.
11731173+</para>
11741174+11751175+<para>
11761176+The command does not fail if the package and/or the META
11771177+file cannot be located. You will get a warning only in this case.
11781178+</para>
11791179+11801180+<para>
11811181+If the package directory is mentioned in the <literal>ld.conf</literal>
11821182+configuration file for DLLs, it will be tried to remove this entry
11831183+from the file. The location of this file can be overridden by
11841184+the -ldconf option. To turn this feature off, use "-ldconf ignore";
11851185+this causes that the ld.conf file is not modified.
11861186+</para>
11871187+11881188+<para>
11891189+If there is a stublibs directory, it is checked whether the package
11901190+owns any of the files in this directory, and the owned files will
11911191+be deleted.
11921192+</para>
11931193+11941194+</refsect2>
11951195+</refsect1>
11961196+11971197+11981198+<!-- ********************************************************************** -->
11991199+12001200+<refsect1>
12011201+<title><anchor id="ocamlfind.list">
12021202+ THE "list" SUBCOMMAND
12031203+</title>
12041204+12051205+<refsect2>
12061206+<title>Synopsis</title>
12071207+<programlisting>
12081208+ocamlfind list [-describe]
12091209+</programlisting>
12101210+</refsect2>
12111211+12121212+<refsect2>
12131213+<title>Description</title>
12141214+<para>
12151215+This command lists all packages in the search path. The option -describe
12161216+outputs the package descriptions, too.
12171217+</para>
12181218+</refsect2>
12191219+</refsect1>
12201220+12211221+<!-- ********************************************************************** -->
12221222+12231223+<refsect1>
12241224+<title><anchor id="ocamlfind.printppx">
12251225+ THE "printppx" SUBCOMMAND
12261226+</title>
12271227+12281228+<refsect2>
12291229+<title>Synopsis</title>
12301230+<programlisting>
12311231+ocamlfind printppx
12321232+ [ -predicates <replaceable>pred-name-list</replaceable> ]
12331233+ [ -ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable> ]
12341234+ <replaceable>package</replaceable> ...
12351235+</programlisting>
12361236+</refsect2>
12371237+12381238+<refsect2>
12391239+<title>Description</title>
12401240+<para>
12411241+This command prints the ppx preprocessor options as they would
12421242+occur in an OCaml compiler invocation for the packages listed in
12431243+the command. The output includes one "-ppx" option for each
12441244+preprocessor. The possible options have the same meaning as for
12451245+"ocamlfind ocamlc". The option "-predicates" adds assumed
12461246+predicates and
12471247+"-ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable>"
12481248+adds "<replaceable>arg</replaceable>" to the ppx invocation of
12491249+package <replaceable>package</replaceable>.
12501250+</para>
12511251+12521252+<para>
12531253+The output of "ocamlfind printppx" will contain quotes
12541254+"<literal>"</literal>" for ppx commands that contain
12551255+space-separated arguments. In this case <literal>$(ocamlfind
12561256+printppx ...)</literal> won't work as naively expected, because
12571257+many shells (including bash and dash) perform field splitting on
12581258+the result of command substitutions without honoring quotes.
12591259+</para>
12601260+</refsect2>
12611261+</refsect1>
12621262+12631263+<!-- ********************************************************************** -->
12641264+12651265+<refsect1>
12661266+<title><anchor id="ocamlfind.lint">
12671267+ THE "lint" SUBCOMMAND
12681268+</title>
12691269+12701270+<refsect2>
12711271+<title>Synopsis</title>
12721272+<programlisting>
12731273+ocamlfind lint <replaceable>file</replaceable>
12741274+</programlisting>
12751275+</refsect2>
12761276+12771277+<refsect2>
12781278+<title>Description</title>
12791279+<para>
12801280+Checks the META file, and reports possible problems.
12811281+</para>
12821282+</refsect2>
12831283+</refsect1>
12841284+12851285+<!-- ********************************************************************** -->
12861286+12871287+<refsect1>
12881288+<title><anchor id="ocamlfind.printconf">
12891289+ THE "printconf" SUBCOMMAND
12901290+</title>
12911291+12921292+<refsect2>
12931293+<title>Synopsis</title>
12941294+<programlisting>
12951295+ocamlfind printconf [ conf | path | destdir | metadir | metapath | stdlib | ldconf ]
12961296+</programlisting>
12971297+</refsect2>
12981298+12991299+<refsect2>
13001300+<title>Description</title>
13011301+<para>
13021302+This command prints the effective configuration after reading the
13031303+configuration file, and after applying the various environment
13041304+variables overriding settings. When called without arguments, the command
13051305+prints all configuration options in a human-readable form. When called
13061306+with an argument, only the value of the requested option is printed without
13071307+explaining texts:
13081308+</para>
13091309+13101310+<variablelist>
13111311+<varlistentry>
13121312+ <term><literal>conf</literal></term>
13131313+ <listitem><para>Prints the location of the configuration file findlib.conf
13141314+ </para></listitem>
13151315+</varlistentry>
13161316+<varlistentry>
13171317+ <term><literal>path</literal></term>
13181318+ <listitem><para>Prints the search path for packages. The members of the
13191319+ path are separated by linefeeds.</para></listitem>
13201320+</varlistentry>
13211321+<varlistentry>
13221322+ <term><literal>destdir</literal></term>
13231323+ <listitem><para>Prints the location where package are installed and
13241324+ removed by default.</para></listitem>
13251325+</varlistentry>
13261326+<varlistentry>
13271327+ <term><literal>metadir</literal></term>
13281328+ <listitem><para>Prints the location where META files are installed and
13291329+ removed (if the alternative layout is used).</para></listitem>
13301330+</varlistentry>
13311331+<varlistentry>
13321332+ <term><literal>metapath</literal></term>
13331333+ <listitem><para>Prints the path where the META file is installed for
13341334+a fictive package. The name of the package is marked with '%s' in the
13351335+path. For instance, this command could output "/some/path/%s/META" or
13361336+"/some/path/META.%s", depending on the layout.</para></listitem>
13371337+</varlistentry>
13381338+<varlistentry>
13391339+ <term><literal>stdlib</literal></term>
13401340+ <listitem><para>Prints the location of the standard library.
13411341+</para></listitem>
13421342+</varlistentry>
13431343+<varlistentry>
13441344+ <term><literal>ldconf</literal></term>
13451345+ <listitem><para>Prints the location of the ld.conf file
13461346+</para></listitem>
13471347+</varlistentry>
13481348+</variablelist>
13491349+13501350+</refsect2>
13511351+</refsect1>
13521352+13531353+13541354+<!-- ********************************************************************** -->
13551355+13561356+<refsect1>
13571357+<title><anchor id="ocamlfind.pkgcmd">
13581358+ THE SUBCOMMAND CALLING PACKAGE PROGRAMS
13591359+</title>
13601360+13611361+<refsect2>
13621362+<title>Synopsis</title>
13631363+<programlisting>
13641364+ocamlfind <replaceable>pkg</replaceable>/<replaceable>cmd</replaceable> <replaceable>argument</replaceable> ...
13651365+</programlisting>
13661366+</refsect2>
13671367+13681368+<refsect2>
13691369+<title>Description</title>
13701370+<para>This subcommand is useful to call programs that are installed in
13711371+package directories. It looks up the directory for
13721372+<replaceable>pkg</replaceable> and calls the command named
13731373+<replaceable>cmd</replaceable> in this directory. The remaining arguments
13741374+are passed to this command.</para>
13751375+13761376+<para>argv(0) contains the absolute path to the command, and argv(1) and
13771377+the following argv entries contain the arguments. The working directory
13781378+is not changed.</para>
13791379+13801380+<para>Example: To call the program "x" that is installed in package "p",
13811381+with arguments "y" and "z", run:</para>
13821382+13831383+<programlisting>
13841384+ocamlfind p/x y z
13851385+</programlisting>
13861386+13871387+</refsect2>
13881388+</refsect1>
13891389+13901390+13911391+<refsect1>
13921392+<title>
13931393+ CONFIGURATION FILE, ENVIRONMENT VARIABLES
13941394+</title>
13951395+13961396+<para> The configuration file and environment variables are documented
13971397+in the manual page for
13981398+ <link linkend="findlib.conf">findlib.conf</link>.
13991399+</para>
14001400+</refsect1>
14011401+14021402+<!-- ********************************************************************** -->
14031403+14041404+<refsect1>
14051405+<title><anchor id="ocamlfind.toolchain">
14061406+ HOW TO SET THE TOOLCHAIN
14071407+</title>
14081408+14091409+<refsect2>
14101410+<title>Synopsis</title>
14111411+<programlisting>
14121412+ocamlfind -toolchain <replaceable>name</replaceable> ...
14131413+</programlisting>
14141414+</refsect2>
14151415+14161416+<refsect2>
14171417+<title>Description</title>
14181418+<para>The -toolchain option can be given before any other command,
14191419+e.g.
14201420+<programlisting>
14211421+ocamlfind -toolchain foo ocamlc -c file.ml
14221422+</programlisting>
14231423+compiles file.ml with toolchain "foo". By selecting toolchains one
14241424+can switch to different command sets. For instance, the toolchain
14251425+"foo" may consist of a patched ocamlc compiler.
14261426+See <link linkend="findlib.conf">findlib.conf</link> how to
14271427+configure toolchains.
14281428+</para>
14291429+</refsect2>
14301430+</refsect1>
14311431+14321432+</refentry>
14331433+14341434+14351435+14361436+
+24
vendor/opam/ocamlfind/doc/src/findlib_ref.dsl
···11+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
22+<!ENTITY dbstyle SYSTEM "docbook.dsl" CDATA DSSSL>
33+]>
44+55+<style-sheet>
66+<style-specification use="docbook">
77+<style-specification-body>
88+99+(define %footnotes-at-end%
1010+ ;; Should footnotes appear at the end of HTML pages?
1111+ #t)
1212+1313+(define %html-ext%
1414+ ;; Default extension for HTML output files
1515+ ".html")
1616+1717+(define %root-filename%
1818+ ;; Name for the root HTML document
1919+ "index")
2020+2121+</style-specification-body>
2222+</style-specification>
2323+<external-specification id="docbook" document="dbstyle">
2424+</style-sheet>
···11+<!DOCTYPE reference PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
22+ <!ENTITY findlibmeta SYSTEM "findlib_meta.mod">
33+ <!ENTITY findlibsitelib SYSTEM "findlib_sitelib.mod">
44+ <!ENTITY findlibmli SYSTEM "findlib_mli.mod">
55+ <!ENTITY findlibtopfind SYSTEM "findlib_topfind.mod">
66+ <!ENTITY findlibocamlfind SYSTEM "findlib_ocamlfind.mod">
77+ <!ENTITY findlibconf SYSTEM "findlib_conf.mod">
88+]>
99+1010+<reference>
1111+<title>Reference</title>
1212+&findlibocamlfind;
1313+&findlibmeta;
1414+&findlibconf;
1515+&findlibsitelib;
1616+</reference>
1717+
+165
vendor/opam/ocamlfind/doc/src/findlib_sitelib.mod
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>site-lib</refentrytitle>
55+ <manvolnum>5</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="site-lib">
1010+ <refname>site-lib</refname>
1111+ <refpurpose>[Location of package directories]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsynopsisdiv>
1616+<title>STANDARD LAYOUT</title>
1717+<synopsis>
1818+...somewhere in the filesystem hierarchy...
1919+ |
2020+ \
2121+ site-lib
2222+ |
2323+ +- (optional) stublibs
2424+ +- (optional) postinstall
2525+ +- (optional) postremove
2626+ |
2727+ +- <replaceable>package1</replaceable>
2828+ | |
2929+ | +- META
3030+ | +- <replaceable>archive files</replaceable>
3131+ | +- <replaceable>interface definitions</replaceable>
3232+ |
3333+ +- <replaceable>package2</replaceable>
3434+ +
3535+ :
3636+ :
3737+ \
3838+ <replaceable>packageN</replaceable>
3939+</synopsis>
4040+</refsynopsisdiv>
4141+4242+<refsect1>
4343+<title>DESCRIPTION</title>
4444+<para>
4545+Every installation of "findlib" has a default location for package
4646+directories, which is normally a directory called "site-lib". The
4747+location can be set by the configuration variables
4848+<literal>path</literal> (used to look up packages), and
4949+<literal>destdir</literal> (used to install new packages);
5050+see <link linkend="findlib.conf">findlib.conf</link>.
5151+</para>
5252+5353+<para>
5454+The name of a package is the name of the package directory. For
5555+example, if <literal>destdir=/usr/local/lib/ocaml/site-lib</literal>, the
5656+package p will be installed in the subdirectory
5757+<literal>/usr/local/lib/ocaml/site-lib/p</literal>. This subdirectory
5858+must contain the META file and all other files belonging to the package.
5959+Package names must not contain the '.' character.
6060+</para>
6161+6262+<para>
6363+The variable <literal>destdir</literal> specifies the directory for
6464+new packages. You can only have one such directory at a time; but of
6565+course you can change this directory in findlib.conf. The command
6666+<literal>ocamlfind install</literal> puts new packages into this
6767+directory; it is recommended to use this command for installation
6868+because it ensures that the directory layout is right.
6969+</para>
7070+7171+<para>
7272+For searching packages, findlib uses (only) the variable
7373+<literal>path</literal> which may name several locations to look at.
7474+</para>
7575+7676+<para>
7777+For systems with DLL support another directory may exist: stublibs.
7878+If present, findlib will install DLLs into this directory that is
7979+shared by all packages at the same site-lib location. Findlib remembers
8080+which DLL belongs to which package by special files with the suffix
8181+".owner"; e.g. for the DLL "dllpcre.so" there is another file
8282+"dllpcre.so.owner" containing the string "pcre", so findlib knows
8383+that the package "pcre" owns this DLL. It is not possible that a DLL
8484+is owned by several packages.
8585+</para>
8686+8787+<para>
8888+If the stublibs directory does not exist, DLLs are installed regularly
8989+in the package directories like any other file.
9090+</para>
9191+9292+<para>
9393+For special needs, a postinstall and/or a postremove script may be
9494+installed in the site-lib directory. These scripts are invoked after
9595+installation or removal of a package, respectively.
9696+</para>
9797+9898+</refsect1>
9999+100100+101101+<refsect1>
102102+<title>ALTERNATE LAYOUT</title>
103103+<para>
104104+105105+<programlisting>
106106+...somewhere in the filesystem hierarchy...
107107+ |
108108+ \
109109+ site-lib
110110+ |
111111+ +- (optional) stublibs
112112+ +- (optional) postinstall
113113+ +- (optional) postremove
114114+ |
115115+ +- <replaceable>package1</replaceable>
116116+ | |
117117+ | +- <replaceable>archive files</replaceable>
118118+ | +- <replaceable>interface definitions</replaceable>
119119+ |
120120+ +- <replaceable>package2</replaceable>
121121+ +
122122+ :
123123+ :
124124+ \
125125+ : <replaceable>packageN</replaceable>
126126+ |
127127+ \
128128+ metaregistry
129129+ |
130130+ +- META.package1
131131+ +- META.package2
132132+ +
133133+ :
134134+ \
135135+ META.packageN
136136+</programlisting>
137137+</para>
138138+139139+<para>
140140+This is an alternate directory layout collecting all META files in one
141141+directory. You can configure this layout by setting
142142+<literal>path</literal> to the absolute location of
143143+<literal>metaregistry</literal>. Findlib recognizes that there are
144144+META files in this directory and uses them; it is not necessary to
145145+include <literal>site-lib</literal> into the <literal>path</literal>.
146146+</para>
147147+148148+<para>
149149+In order to work, the META files must contain a
150150+<literal>directory</literal> directive pointing to the corresponding
151151+package directory that resides below <literal>site-lib</literal>.
152152+</para>
153153+154154+<para>
155155+The command <literal>ocamlfind install</literal> copes with this
156156+layout, too. The variable <literal>destdir</literal> must contain the
157157+absolute location of <literal>site-lib</literal>, and the variable
158158+<literal>metadir</literal> must contain the absolute location of
159159+<literal>metaregistry</literal>. Note that <literal>ocamlfind
160160+install</literal> automatically adds a <literal>directory</literal>
161161+directive to the META file, so you need not do it manually.
162162+</para>
163163+</refsect1>
164164+165165+</refentry>
+333
vendor/opam/ocamlfind/doc/src/findlib_topfind.mod
···11+<refentry>
22+33+<refmeta>
44+ <refentrytitle>Topfind</refentrytitle>
55+ <manvolnum>3</manvolnum>
66+ <refmiscinfo>The findlib package manager for OCaml</refmiscinfo>
77+</refmeta>
88+99+<refnamediv id="Topfind">
1010+ <refname>Topfind</refname>
1111+ <refpurpose>[Module to load packages into toploops]</refpurpose>
1212+</refnamediv>
1313+1414+1515+<refsynopsisdiv>
1616+<title>SIGNATURE</title>
1717+<synopsis>
1818+module Topfind :
1919+ sig
2020+ <link linkend="Topfind.predicates"
2121+ endterm="val.Topfind.predicates"></link>
2222+ <link linkend="Topfind.add-predicates"
2323+ endterm="val.Topfind.add-predicates"></link>
2424+ <link linkend="Topfind.syntax"
2525+ endterm="val.Topfind.syntax"></link>
2626+ <link linkend="Topfind.standard-syntax"
2727+ endterm="val.Topfind.standard-syntax"></link>
2828+ <link linkend="Topfind.revised-syntax"
2929+ endterm="val.Topfind.revised-syntax"></link>
3030+ <link linkend="Topfind.dont-load"
3131+ endterm="val.Topfind.dont-load"></link>
3232+ <link linkend="Topfind.dont-load-deeply"
3333+ endterm="val.Topfind.dont-load-deeply"></link>
3434+ <link linkend="Topfind.load"
3535+ endterm="val.Topfind.load"></link>
3636+ <link linkend="Topfind.load-deeply"
3737+ endterm="val.Topfind.load-deeply"></link>
3838+ <link linkend="Topfind.reset"
3939+ endterm="val.Topfind.reset"></link>
4040+ end
4141+</synopsis>
4242+</refsynopsisdiv>
4343+4444+4545+<refsect1>
4646+<title>DIRECTIVES</title>
4747+<programlisting>
4848+<link linkend="Topfind.require"
4949+ endterm="val.Topfind.require"></link>
5050+<link linkend="Topfind.camlp4o"
5151+ endterm="val.Topfind.camlp4o"></link>
5252+<link linkend="Topfind.camlp4r"
5353+ endterm="val.Topfind.camlp4r"></link>
5454+<link linkend="Topfind.list"
5555+ endterm="val.Topfind.list"></link>
5656+</programlisting>
5757+</refsect1>
5858+5959+6060+<refsect1>
6161+<title>PACKAGING</title>
6262+6363+<para>
6464+The Topfind module is part of the "findlib" package. The module
6565+depends on the presence of a toploop. When building a toploop, it is
6666+automatically linked in if "findlib" is linked in, e.g.
6767+</para>
6868+6969+<programlisting>
7070+ocamlfind ocamlmktop <replaceable>options</replaceable> -package findlib -linkpkg <replaceable>options</replaceable>
7171+</programlisting>
7272+7373+<para>
7474+When the platform supports DLLs, another possibility to get a toploop
7575+with findlib directives is to load the file "topfind" (normally installed
7676+in the standard library directory):
7777+</para>
7878+7979+<programlisting>
8080+~ > ocaml
8181+ Objective Caml version 3.04
8282+8383+# #use "topfind";;
8484+Findlib has been successfully loaded. Additional directives:
8585+ #require "package";; to load a package
8686+ #list;; to list the available packages
8787+ #camlp4o;; to load camlp4 (standard syntax)
8888+ #camlp4r;; to load camlp4 (revised syntax)
8989+ Topfind.reset();; to force that packages will be reloaded
9090+9191+- : unit = ()
9292+# _
9393+</programlisting>
9494+9595+<para>
9696+This works even in scripts (but the startup message is suppressed in this
9797+case).
9898+</para>
9999+100100+<para>
101101+The module is not thread-safe; if used in a multi-threaded script, all
102102+packgage loading must have happened before the first thread forks.
103103+</para>
104104+</refsect1>
105105+106106+107107+<refsect1>
108108+<title>DESCRIPTION</title>
109109+110110+<para>
111111+The Topfind module contains some functions simplifying package loading
112112+in scripts. Most important, there is a new directive "#require" for
113113+the same purpose.
114114+</para>
115115+116116+<para>
117117+The Topfind module needs some initialization, in particular the <link
118118+linkend="Topfind.predicates">predicates</link> variable needs to be
119119+set, and the packages already compiled into the toploop needs to be
120120+declared by the <link linkend="Topfind.dont-load">don't_load</link>
121121+function. If the toploop has been built by <xref
122122+linkend="ocamlfind" endterm="ocamlfind">, the necessary initialization is
123123+automatically compiled in.
124124+</para>
125125+126126+127127+<refsect2>
128128+<title><anchor id="Topfind.predicates">
129129+The variable Topfind.predicates
130130+</title>
131131+<programlisting id="val.Topfind.predicates">
132132+val predicates : string list ref
133133+</programlisting>
134134+<para>
135135+The variable contains the set of predicates that is assumed when
136136+packages are loaded.
137137+</para>
138138+</refsect2>
139139+140140+141141+<refsect2>
142142+<title><anchor id="Topfind.add-predicates">
143143+Topfind.add_predicates <replaceable>predlist</replaceable>
144144+</title>
145145+<programlisting id="val.Topfind.add-predicates">
146146+val add_predicates : string list -> unit
147147+</programlisting>
148148+<para>
149149+This function adds the passed predicates <replaceable>predlist</replaceable>
150150+to the variable
151151+<literal>predicates</literal>.
152152+</para>
153153+</refsect2>
154154+155155+156156+<refsect2>
157157+<title><anchor id="Topfind.syntax">
158158+Topfind.syntax <replaceable>variant</replaceable>
159159+</title>
160160+<programlisting id="val.Topfind.syntax">
161161+val syntax : string -> unit
162162+</programlisting>
163163+<para>
164164+This function emulates the <literal>-syntax</literal> command line
165165+switch of ocamlfind.
166166+</para>
167167+</refsect2>
168168+169169+170170+<refsect2>
171171+<title><anchor id="Topfind.standard-syntax">
172172+Topfind.standard_syntax ()
173173+</title>
174174+<programlisting id="val.Topfind.standard-syntax">
175175+val standard_syntax : unit -> unit
176176+</programlisting>
177177+<para>
178178+The same as <literal>syntax "camlp4o"</literal>.
179179+</para>
180180+</refsect2>
181181+182182+183183+<refsect2>
184184+<title><anchor id="Topfind.revised-syntax">
185185+Topfind.revised_syntax ()
186186+</title>
187187+<programlisting id="val.Topfind.revised-syntax">
188188+val revised_syntax : unit -> unit
189189+</programlisting>
190190+<para>
191191+The same as <literal>syntax "camlp4r"</literal>.
192192+</para>
193193+</refsect2>
194194+195195+196196+<refsect2>
197197+<title><anchor id="Topfind.dont-load">
198198+Topfind.don't_load <replaceable>pkglist</replaceable>
199199+</title>
200200+<programlisting id="val.Topfind.dont-load">
201201+val don't_load : string list -> unit
202202+</programlisting>
203203+<para>
204204+Declares the packages enumerated in <replaceable>pkglist</replaceable>
205205+as being linked into the toploop.
206206+</para>
207207+</refsect2>
208208+209209+210210+<refsect2>
211211+<title><anchor id="Topfind.dont-load-deeply">
212212+Topfind.don't_load_deeply <replaceable>pkglist</replaceable>
213213+</title>
214214+<programlisting id="val.Topfind.dont-load-deeply">
215215+val don't_load_deeply : string list -> unit
216216+</programlisting>
217217+<para>
218218+Declares the packages enumerated in <replaceable>pkglist</replaceable>
219219+and all direct and indirect ancestors as being linked into the toploop.
220220+</para>
221221+</refsect2>
222222+223223+224224+<refsect2>
225225+<title><anchor id="Topfind.load">
226226+Topfind.load <replaceable>pkglist</replaceable>
227227+</title>
228228+<programlisting id="val.Topfind.load">
229229+val load : string list -> unit
230230+</programlisting>
231231+<para>
232232+The packages enumerated in <replaceable>pkglist</replaceable> are
233233+loaded in turn; packages that have already been loaded or that have
234234+been declared as linked in are skipped.
235235+</para>
236236+</refsect2>
237237+238238+239239+<refsect2>
240240+<title><anchor id="Topfind.load-deeply">
241241+Topfind.load_deeply <replaceable>pkglist</replaceable>
242242+</title>
243243+<programlisting id="val.Topfind.load-deeply">
244244+val load_deeply : string list -> unit
245245+</programlisting>
246246+<para>
247247+The packages enumerated in <replaceable>pkglist</replaceable> and all
248248+direct or indirect ancestors are loaded in topological order;
249249+packages that have already been loaded or that have
250250+been declared as linked in are skipped.
251251+</para>
252252+</refsect2>
253253+254254+255255+<refsect2>
256256+<title><anchor id="Topfind.reset">
257257+Topfind.reset ()
258258+</title>
259259+<programlisting id="val.Topfind.reset">
260260+val reset : unit -> unit
261261+</programlisting>
262262+<para>
263263+This function causes that Topfind forgets that any package has already
264264+been loaded. Information about packages linked into the toploop remain
265265+intact. The effect of this function is that all dynamically loaded
266266+packages will be loaded again when <link
267267+linkend="Topfind.load">load</link>, <link
268268+linkend="Topfind.load-deeply">load_deeply</link> functions, or the
269269+<link linkend="Topfind.require">#require</link> directive are executed.
270270+</para>
271271+</refsect2>
272272+273273+274274+275275+<refsect2>
276276+<title><anchor id="Topfind.require">
277277+#require "<replaceable>package-name-list</replaceable>";;
278278+</title>
279279+<programlisting id="val.Topfind.require">
280280+#require "<replaceable>package-name-list</replaceable>";;
281281+</programlisting>
282282+<para>
283283+The argument of the directive is a list of package names, separated by
284284+commas and/or whitespace. The directive has the same effect as <link
285285+linkend="Topfind.load-deeply">load_deeply</link>, i.e. the listed
286286+packages and all
287287+direct or indirect ancestors are loaded in topological order;
288288+packages that have already been loaded or that have
289289+been declared as linked in are skipped.
290290+</para>
291291+</refsect2>
292292+293293+294294+<refsect2>
295295+<title><anchor id="Topfind.camlp4o">
296296+#camlp4o ;;
297297+</title>
298298+<programlisting id="val.Topfind.camlp4o">
299299+#camlp4o ;;
300300+</programlisting>
301301+<para>
302302+Selects the standard syntax and loads the camlp4 preprocessor.
303303+</para>
304304+</refsect2>
305305+306306+307307+<refsect2>
308308+<title><anchor id="Topfind.camlp4r">
309309+#camlp4r ;;
310310+</title>
311311+<programlisting id="val.Topfind.camlp4r">
312312+#camlp4r ;;
313313+</programlisting>
314314+<para>
315315+Selects the revised syntax and loads the camlp4 preprocessor.
316316+</para>
317317+</refsect2>
318318+319319+<refsect2>
320320+<title><anchor id="Topfind.list">
321321+#list ;;
322322+</title>
323323+<programlisting id="val.Topfind.list">
324324+#list ;;
325325+</programlisting>
326326+<para>
327327+Lists the packages that are in the search path.
328328+</para>
329329+</refsect2>
330330+331331+</refsect1>
332332+333333+</refentry>
+182
vendor/opam/ocamlfind/findlib-ppc.patch
···11+diff -ur --unidirectional-new-file findlib-1.1.2pl1/Makefile findlib-1.1.2pl1.modify/Makefile
22+--- findlib-1.1.2pl1/Makefile 2006-01-17 10:04:50.000000000 +1100
33++++ findlib-1.1.2pl1.modify/Makefile 2006-10-23 11:50:38.000000000 +1000
44+@@ -17,12 +17,15 @@
55+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) opt ); done
66+77+ install:
88++ mkdir -p $(prefix)$(OCAMLFIND_BIN)
99++ mkdir -p $(prefix)$(OCAMLFIND_LIB)
1010++ mkdir -p $(prefix)$(OCAMLFIND_MAN)
1111+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) install ); done
1212+ $(MAKE) install-doc
1313+ $(MAKE) install-meta
1414+ cd src/findlib; $(MAKE) install-num-top
1515+ $(MAKE) install-config
1616+- cp tools/safe_camlp4 $(OCAMLFIND_BIN)
1717++ cp tools/safe_camlp4 $(prefix)$(OCAMLFIND_BIN)
1818+1919+ uninstall:
2020+ $(MAKE) uninstall-doc
2121+@@ -30,12 +33,26 @@
2222+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) uninstall ); done
2323+ $(MAKE) uninstall-config
2424+2525+-clean:
2626++clean: clean-macosx
2727+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) clean ); done
2828+ (cd itest-aux; $(MAKE) clean)
2929+ (cd tools/extract_args; $(MAKE) clean)
3030+ rm -f findlib.conf
3131+3232++# Make MacOS X package
3333++
3434++.PHONY: package-macosx
3535++
3636++package-macosx: all opt
3737++ mkdir -p package-macosx/root
3838++ export prefix=`pwd`/package-macosx/root && make install
3939++ export VERSION=1.1.2 && tools/make-package-macosx
4040++ #rm -rf package-macosx/root
4141++
4242++clean-macosx:
4343++ sudo rm -rf package-macosx
4444++ #rm -rf package-macosx/*.pkg package-macosx/*.dmg
4545++
4646+ .PHONY: release
4747+ release: README
4848+ ./release
4949+diff -ur --unidirectional-new-file findlib-1.1.2pl1/configure findlib-1.1.2pl1.modify/configure
5050+--- findlib-1.1.2pl1/configure 2006-01-17 10:04:49.000000000 +1100
5151++++ findlib-1.1.2pl1.modify/configure 2006-10-23 11:50:43.000000000 +1000
5252+@@ -427,6 +427,7 @@
5353+ echo "EXEC_SUFFIX=${exec_suffix}" >>Makefile.config
5454+ echo "PARTS=${parts}" >>Makefile.config
5555+ echo "INSTALL_TOPFIND=${with_topfind}" >>Makefile.config
5656++echo "VERSION=${version}" >> Makefile.config
5757+5858+ # All OK
5959+6060+diff -ur --unidirectional-new-file findlib-1.1.2pl1/tools/make-package-macosx findlib-1.1.2pl1.modify/tools/make-package-macosx
6161+--- findlib-1.1.2pl1/tools/make-package-macosx 1970-01-01 10:00:00.000000000 +1000
6262++++ findlib-1.1.2pl1.modify/tools/make-package-macosx 2006-10-23 11:50:52.000000000 +1000
6363+@@ -0,0 +1,119 @@
6464++#!/bin/sh
6565++
6666++#########################################################################
6767++# #
6868++# Objective Caml #
6969++# #
7070++# Damien Doligez, projet Moscova, INRIA Rocquencourt #
7171++# #
7272++# Copyright 2003 Institut National de Recherche en Informatique et #
7373++# en Automatique. All rights reserved. This file is distributed #
7474++# under the terms of the Q Public License version 1.0. #
7575++# #
7676++#########################################################################
7777++
7878++# $Id: make-package-macosx,v 1.10.2.2 2006/01/04 13:05:49 doligez Exp $
7979++# adapted to findlib by Pietro.Abate <pietro.abate@anu.edu.au>
8080++
8181++set -x
8282++
8383++cd package-macosx
8484++rm -rf findlib.pkg findlib-rw.dmg
8585++mkdir -p resources
8686++
8787++cat >Description.plist <<EOF
8888++ <?xml version="1.0" encoding="UTF-8"?>
8989++ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
9090++ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
9191++ <plist version="1.0">
9292++ <dict>
9393++ <key>IFPkgDescriptionDeleteWarning</key>
9494++ <string></string>
9595++ <key>IFPkgDescriptionDescription</key>
9696++ <string>The findlib library manager</string>
9797++ <key>IFPkgDescriptionTitle</key>
9898++ <string>Findlib</string>
9999++ <key>IFPkgDescriptionVersion</key>
100100++ <string>${VERSION}</string>
101101++ </dict>
102102++ </plist>
103103++EOF
104104++
105105++cat >Info.plist <<EOF
106106++<?xml version="1.0" encoding="UTF-8"?>
107107++<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
108108++ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
109109++<plist version="1.0">
110110++<dict>
111111++ <key>CFBundleGetInfoString</key>
112112++ <string>The findlib library manager ${VERSION}</string>
113113++ <key>CFBundleIdentifier</key>
114114++ <string>http://www.ocaml-programming.de/packages/</string>
115115++ <key>CFBundleName</key>
116116++ <string>Findlib</string>
117117++ <key>CFBundleShortVersionString</key>
118118++ <string>${VERSION}</string>
119119++ <key>IFPkgFlagAllowBackRev</key>
120120++ <true/>
121121++ <key>IFPkgFlagAuthorizationAction</key>
122122++ <string>AdminAuthorization</string>
123123++ <key>IFPkgFlagDefaultLocation</key>
124124++ <string>/</string>
125125++ <key>IFPkgFlagInstallFat</key>
126126++ <false/>
127127++ <key>IFPkgFlagIsRequired</key>
128128++ <false/>
129129++ <key>IFPkgFlagRelocatable</key>
130130++ <false/>
131131++ <key>IFPkgFlagRestartAction</key>
132132++ <string>NoRestart</string>
133133++ <key>IFPkgFlagRootVolumeOnly</key>
134134++ <true/>
135135++ <key>IFPkgFlagUpdateInstalledLanguages</key>
136136++ <false/>
137137++ <key>IFPkgFormatVersion</key>
138138++ <real>0.10000000149011612</real>
139139++</dict>
140140++</plist>
141141++EOF
142142++
143143++# stop here -> |
144144++cat >resources/ReadMe.txt <<EOF
145145++This package installs The findlib library manager ${VERSION}.
146146++You need Mac OS X 10.4.x (Tiger).
147147++
148148++Files will be installed in the following directories:
149149++
150150++/usr/local/bin - command-line executables
151151++/usr/local/lib/ocaml - library and support files
152152++/usr/local/man - manual pages
153153++EOF
154154++
155155++chmod -R g-w root
156156++sudo chown -R root:admin root
157157++
158158++/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \
159159++-build -p "`pwd`/findlib.pkg" -f "`pwd`/root" -i "`pwd`/Info.plist" \
160160++ -d "`pwd`/Description.plist" -r "`pwd`/resources"
161161++
162162++size=`du -s findlib.pkg | cut -f 1`
163163++size=`expr $size + 8192`
164164++
165165++hdiutil create -sectors $size findlib-rw.dmg
166166++name=`hdid -nomount findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
167167++newfs_hfs -v 'Findlib' $name
168168++hdiutil detach $name
169169++
170170++name=`hdid findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
171171++if test -d '/Volumes/Findlib'; then
172172++ ditto -rsrcFork findlib.pkg "/Volumes/Findlib/findlib.pkg"
173173++ cp resources/ReadMe.txt "/Volumes/Findlib/"
174174++else
175175++ echo 'Unable to mount the disk image as "/Volumes/Findlib"' >&2
176176++ exit 3
177177++fi
178178++open "/Volumes/Findlib"
179179++hdiutil detach $name
180180++
181181++rm -rf "findlib-${VERSION}.dmg"
182182++hdiutil convert findlib-rw.dmg -format UDZO -o "findlib-${VERSION}.dmg"
···11+let _ = Num.num_of_int 5 in
22+33+print_string "OK\n";;
44+
+4
vendor/opam/ocamlfind/itest-aux/simple_str.ml
···11+let _ = Str.regexp ".*" in
22+33+print_string "OK\n";;
44+
+17
vendor/opam/ocamlfind/itest-aux/simple_threads.ml
···11+let tl =
22+ List.map
33+ (fun _ ->
44+ Thread.create
55+ (fun () ->
66+ for i = 1 to 1000 do
77+ let _ = 1+1 in ()
88+ done)
99+ ())
1010+ [ (); (); (); (); () ]
1111+ in
1212+1313+ List.iter Thread.join tl
1414+;;
1515+1616+print_string "OK\n";;
1717+
+4
vendor/opam/ocamlfind/itest-aux/simple_unix.ml
···11+let _ = Unix.getpid() in
22+33+print_string "OK\n";;
44+
+104
vendor/opam/ocamlfind/mini/README
···11+----------------------------------------------------------------------
22+ocamlfind-mini
33+----------------------------------------------------------------------
44+55+ocamlfind-mini is an OCaml script that implements a subset of the
66+full functionality of ocamlfind. It consists only of one file, so it
77+is easy to distribute it with any software.
88+99+The subset is normally sufficient to compile a library and to
1010+install the library; but it is insufficient to link the library
1111+into an executable.
1212+1313+----------------------------------------------------------------------
1414+SUPPORTED OPERATING SYSTEMS:
1515+----------------------------------------------------------------------
1616+1717+For Unixes, the script runs out of the box. It uses the ocaml system
1818+found in the command path.
1919+2020+I think the script also runs in Windows, but I have not yet checked that.
2121+Anyway, you cannot call it directly, but by doing
2222+ocaml ocamlfind-mini <args>...
2323+2424+Macintosh is not supported; I don't have enough knowledge for a Mac port.
2525+2626+----------------------------------------------------------------------
2727+FUNCTIONALITY:
2828+----------------------------------------------------------------------
2929+3030+Overall: The configuration file ocamlfind.conf is ignored. However,
3131+some environment variables are respected (see below).
3232+3333+A package directory is recognized by checking whether there is a META
3434+file in it. However, the contents of that file are ignored.
3535+3636+The following subset has been implemented:
3737+3838+- ocamlfind-mini [ocamlc|ocamlopt|ocamlcp|ocamlmktop] <args>...
3939+4040+ The -package option works, but you must set the environment variable
4141+ OCAMLPATH (see below).
4242+4343+ The options -linkpkg, -predicates, -dontlink, -syntax, -ppopt are
4444+ rejected.
4545+4646+ This normally means that you can compile modules as in:
4747+4848+ ocamlfind-mini ocamlc -c -package p1,p2,p3 my_module.ml
4949+5050+ However, you cannot create executables because -linkpkg is not
5151+ supported.
5252+5353+ Note that ocamlfind-mini is unable to figure out the prerequisite
5454+ packages, so the -package option must enumerate _all_ needed packages.
5555+5656+ Note that ocamlfind-mini does not support the alternate directory
5757+ layout where all META files are collected in one directory.
5858+5959+- ocamlfind-mini install <pkg> <file>...
6060+6161+ Installs the files in the package directory for <pkg>. You must help
6262+ ocamlfind-mini by specifying the destination directory:
6363+6464+ * Setting the -destdir option:
6565+6666+ ocamlfind-mini install -destdir <dir> <pkg> <file> ...
6767+6868+ This command installs the new package into <dir>/<pkg>.
6969+7070+ * Setting the OCAMLFIND_DESTDIR variable:
7171+7272+ export OCAMLFIND_DESTDIR=<dir>
7373+ ocamlfind-mini install <pkg> <file> ...
7474+7575+ This command installs the new package into <dir>/<pkg>, too.
7676+7777+- ocamlfind-mini remove <pkg>
7878+7979+ Removes the package <pkg>. Again, you must specify the destination
8080+ directory by either setting the -destdir option or by setting the
8181+ OCAMLFIND_DESTDIR variable.
8282+8383+----------------------------------------------------------------------
8484+ENVIRONMENT:
8585+----------------------------------------------------------------------
8686+8787+The following variables are supported:
8888+8989+- OCAMLPATH
9090+9191+ A colon (Win: semicolon)-separated list of directories:
9292+ OCAMLPATH=<dir1>:<dir2>:...
9393+9494+ When ocamlfind-mini searches a package <pkg>, it checks whether
9595+ <dirK>/<pkg>/META exists for K=1, 2, ...
9696+9797+- OCAMLFIND_DESTDIR
9898+9999+ The destination directory for "install" and "remove".
100100+101101+- OCAMLFIND_METADIR
102102+103103+ The destination directory for META files. It is not recommended to set
104104+ this variable.
+851
vendor/opam/ocamlfind/mini/ocamlfind-mini
···11+#! /bin/sh
22+# (*
33+exec ocaml "$0" "$@"
44+*) directory ".";;
55+66+(* $Id$
77+ * ----------------------------------------------------------------------
88+ *
99+ *)
1010+1111+(**********************************************************************)
1212+1313+(* Module split, rev. 1.2 *)
1414+1515+module Split = struct
1616+let in_words s =
1717+ (* splits s in words separated by commas and/or whitespace *)
1818+ let l = String.length s in
1919+ let rec split i j =
2020+ if j < l then
2121+ match s.[j] with
2222+ (' '|'\t'|'\n'|'\r'|',') ->
2323+ if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1))
2424+ else split (j+1) (j+1)
2525+ | _ ->
2626+ split i (j+1)
2727+ else
2828+ if i<j then [ String.sub s i (j-i) ] else []
2929+ in
3030+ split 0 0
3131+;;
3232+3333+3434+let in_words_ws s =
3535+ (* splits s in words separated by whitespace *)
3636+ let l = String.length s in
3737+ let rec split i j =
3838+ if j < l then
3939+ match s.[j] with
4040+ (' '|'\t'|'\n'|'\r') ->
4141+ if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1))
4242+ else split (j+1) (j+1)
4343+ | _ ->
4444+ split i (j+1)
4545+ else
4646+ if i<j then [ String.sub s i (j-i) ] else []
4747+ in
4848+ split 0 0
4949+;;
5050+5151+5252+let path_separator =
5353+ match Sys.os_type with
5454+ "Unix" -> ':'
5555+ | "Cygwin" -> ';' (* You might want to change this *)
5656+ | "Win32" -> ';'
5757+ | "MacOS" -> failwith "Findlib: I do not know what is the correct path separator for MacOS. If you can help me, write a mail to gerd@gerd-stolpmann.de"
5858+ | _ -> failwith "Findlib: unknown operating system"
5959+;;
6060+6161+6262+let path str =
6363+ (* split "str" into parts separated by "path_separator" *)
6464+ let l = String.length str in
6565+ let rec split_up j k =
6666+ if k < l then begin
6767+ let c = str.[k] in
6868+ if c = path_separator then begin
6969+ if k - j > 0 then
7070+ String.sub str j (k-j) :: split_up (k+1) (k+1)
7171+ else
7272+ split_up (k+1) (k+1)
7373+ end
7474+ else
7575+ split_up j (k+1)
7676+ end
7777+ else
7878+ if k - j > 0 then
7979+ [ String.sub str j (k-j) ]
8080+ else
8181+ []
8282+ in
8383+ split_up 0 0
8484+;;
8585+end;;
8686+8787+(**********************************************************************)
8888+8989+9090+9191+exception Usage;;
9292+9393+type mode =
9494+ M_use | M_query | M_install | M_remove | M_compiler of string
9595+ | M_printconf | M_guess | M_list
9696+;;
9797+9898+9999+let rec remove_dups l =
100100+ match l with
101101+ x :: l' ->
102102+ if List.mem x l' then remove_dups l' else x::remove_dups l'
103103+ | [] -> []
104104+;;
105105+106106+107107+let arg n =
108108+ if n < Array.length Sys.argv then Sys.argv.(n) else raise Not_found
109109+;;
110110+111111+112112+(**********************************************************************)
113113+114114+let ocaml_stdlib_default = "/usr/local/lib/ocaml";;
115115+116116+let ocaml_stdlib =
117117+ begin
118118+ (* Execute "ocamlc -v" and read the stdlib directory *)
119119+ let filename = Filename.temp_file "ocamlfind." ".dat" in
120120+ let command = "ocamlc -v >" ^ filename in (* SYS *)
121121+ let n = Sys.command command in
122122+ if n <> 0 then begin
123123+ prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default");
124124+ ocaml_stdlib_default
125125+ end
126126+ else begin
127127+ (* Search the line "Standard library directory: " *)
128128+ let tag = "Standard library directory: " in
129129+ let taglen = String.length tag in
130130+ let f = open_in filename in
131131+ let dir = ref ocaml_stdlib_default in
132132+ try
133133+ while true do
134134+ let s = input_line f in
135135+ if String.length s >= taglen && String.sub s 0 taglen = tag then begin
136136+ dir := String.sub s taglen (String.length s - taglen);
137137+ raise Exit;
138138+ end
139139+ done;
140140+ assert false
141141+ with
142142+ Exit ->
143143+ close_in f;
144144+ (try Sys.remove filename with _ -> ());
145145+ !dir
146146+ | End_of_file ->
147147+ close_in f;
148148+ prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default");
149149+ ocaml_stdlib_default
150150+ end
151151+ end
152152+;;
153153+154154+155155+let ocamlpath =
156156+ try
157157+ Split.path (Sys.getenv "OCAMLPATH")
158158+ with
159159+ Not_found ->
160160+ (* Use stdlib as default: *)
161161+ [ ocaml_stdlib ]
162162+;;
163163+164164+165165+let env_destdir =
166166+ try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> "";;
167167+168168+169169+let env_metadir =
170170+ try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> "";;
171171+172172+173173+let core_packages =
174174+ [ "bigarray", ocaml_stdlib;
175175+ "dbm", ocaml_stdlib;
176176+ "dynlink", ocaml_stdlib;
177177+ "graphics", ocaml_stdlib;
178178+ "labltk", (Filename.concat ocaml_stdlib "labltk");
179179+ "num", ocaml_stdlib;
180180+ "stdlib", ocaml_stdlib;
181181+ "str", ocaml_stdlib;
182182+ "threads", (Filename.concat ocaml_stdlib "threads");
183183+ "unix", ocaml_stdlib;
184184+ ]
185185+;;
186186+187187+188188+(**********************************************************************)
189189+190190+let package_directory pkg =
191191+ let rec lookup path =
192192+ match path with
193193+ | [] -> raise Not_found
194194+ | dir :: path' ->
195195+ let pkgdir = Filename.concat dir pkg in
196196+ let meta = Filename.concat pkgdir "META" in
197197+ if Sys.file_exists meta then
198198+ pkgdir
199199+ else
200200+ lookup path'
201201+ in
202202+203203+ try
204204+ List.assoc pkg core_packages
205205+ with
206206+ Not_found ->
207207+ lookup ocamlpath
208208+;;
209209+210210+211211+(**********************************************************************)
212212+213213+let use_package prefix pkgnames =
214214+ let pdirs =
215215+ List.map
216216+ (fun pname ->
217217+ try
218218+ "-I " ^ package_directory pname
219219+ with
220220+ Not_found -> failwith ("Cannot find package " ^ pname ^ " (check environment variable OCAMLPATH)"))
221221+ pkgnames
222222+ in
223223+224224+ print_endline (prefix ^ String.concat " " pdirs)
225225+;;
226226+227227+228228+(**************** OCAMLC/OCAMLMKTOP/OCAMLOPT subcommands ****************)
229229+230230+type pass_file_t =
231231+ Pass of string
232232+ | Impl of string
233233+ | Intf of string
234234+;;
235235+236236+237237+let ocamlc which () =
238238+ Arg.current := 1;
239239+240240+ let switches = ref [] in
241241+ let pass_options = ref [] in
242242+ let pass_files = ref [] in
243243+ let incpath = ref [] in
244244+245245+ let packages = ref [] in
246246+247247+ let add_switch name =
248248+ Arg.Unit (fun () ->
249249+ switches := name :: !switches;
250250+ pass_options := !pass_options @ [name]) in
251251+ let add_spec_fn name s =
252252+ pass_options := !pass_options @ [name; s] in
253253+ let add_spec name = Arg.String (add_spec_fn name) in
254254+ let add_pkg =
255255+ Arg.String (fun s -> packages := !packages @ (Split.in_words s)) in
256256+257257+258258+ Arg.parse
259259+ (List.flatten
260260+ [ [
261261+ "-package", add_pkg,
262262+ " <name> Refer to package when compiling";
263263+ "-linkpkg", Arg.Unit(fun _ -> raise (Arg.Bad "Not supported: -linkpkg")),
264264+ " Link the packages in (NOT SUPPORTED)";
265265+ "-predicates", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -predicates")),
266266+ " <p> Add predicate <p> when resolving package properties (NOT SUPPORTED)";
267267+ "-dontlink", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -dontlink")),
268268+ " <name> Do not link in package <name> and its ancestors (NOT SUPPORTED)";
269269+ "-syntax", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -syntax")),
270270+ " <p> Use preprocessor with predicate <p> (NOT SUPPORTED)";
271271+ "-ppopt", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -ppopt")),
272272+ " <opt> Append option <opt> to preprocessor invocation (NOT SUPPORTED)";
273273+ "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]),
274274+ " <opt> Pass option <opt> directly to ocamlc/opt/mktop\nSTANDARD OPTIONS:";
275275+276276+ "-a", add_switch "-a",
277277+ " Build a library";
278278+ "-c", add_switch "-c",
279279+ " Compile only (do not link)";
280280+ "-cc", add_spec "-cc",
281281+ " <comp> Use <comp> as the C compiler and linker";
282282+ "-cclib", add_spec "-cclib",
283283+ " <opt> Pass option <opt> to the C linker";
284284+ "-ccopt", add_spec "-ccopt",
285285+ " <opt> Pass option <opt> to the C compiler and linker";
286286+ ];
287287+ if which = "ocamlopt" then [
288288+ "-compact", add_switch "-compact",
289289+ " Optimize code size rather than speed"
290290+ ]
291291+ else [];
292292+ if which <> "ocamlopt" then [
293293+ "-custom", add_switch "-custom",
294294+ " Link in custom mode";
295295+ "-g", add_switch "-g",
296296+ " Save debugging information";
297297+ ] else [];
298298+ [
299299+ "-i", add_switch "-i",
300300+ " Print the types";
301301+ "-I", (Arg.String
302302+ (fun s ->
303303+ incpath := s :: !incpath;
304304+ add_spec_fn "-I" s)),
305305+ " <dir> Add <dir> to the list of include directories";
306306+ "-impl", Arg.String (fun s -> pass_files := !pass_files @ [ Impl s ]),
307307+ " <file> Compile <file> as a .ml file";
308308+ ] ;
309309+ if which = "ocamlopt" then [
310310+ "-inline", add_spec "-inline",
311311+ " <n> Set aggressiveness of inlining to <n>";
312312+ ] else [];
313313+ [
314314+ "-intf", Arg.String (fun s -> pass_files := !pass_files @ [ Intf s ]),
315315+ " <file> Compile <file> as a .mli file";
316316+ "-intf-suffix", add_spec "-intf-suffix",
317317+ " <s> Suffix for interface file (default: .mli)";
318318+ "-intf_suffix", add_spec "-intf_suffix",
319319+ " <s> same as -intf-suffix";
320320+ "-labels", add_switch "-labels",
321321+ " Use commuting label mode";
322322+ "-linkall", add_switch "-linkall",
323323+ " Link all modules, even unused ones";
324324+ ] ;
325325+ if which <> "ocamlopt" then [
326326+ "-make-runtime", add_switch "-make-runtime",
327327+ " Build a runtime system";
328328+ "-make_runtime", add_switch "-make_runtime",
329329+ " same as -make-runtime";
330330+ ] else [];
331331+ [
332332+ "-noautolink", add_switch "-noautolink",
333333+ " Don't automatically link C libraries specif'd in .cma files";
334334+ "-noassert", add_switch "-noassert",
335335+ " Do not compile assertion checks";
336336+ "-o", add_spec "-o",
337337+ " <file> Set output file name to <file>";
338338+ "-output-obj", add_switch "-output-obj",
339339+ " Output a C object file instead of an executable";
340340+ ];
341341+ if which = "ocamlopt" then [
342342+ "-p", add_switch "-p",
343343+ " Compile/link with profiling support for \"gprof\"
344344+ (implies -predicates gprof)";
345345+ ] else if which = "ocamlcp" then [
346346+ "-p", add_spec "-p",
347347+ " [afilmt] Profile constructs specified by argument:
348348+ a Everything
349349+ f Function calls
350350+ i if ... then ... else
351351+ l while, for
352352+ m match ... with
353353+ t try ... with";
354354+ ] else [];
355355+ [
356356+ "-pp", Arg.String (fun s -> add_spec_fn "-pp" s),
357357+ " <command> Pipe sources through preprocessor <command>";
358358+ "-rectypes", add_switch "-rectypes",
359359+ " Allow arbitrary recursive types";
360360+ ] ;
361361+ if which = "ocamlopt" then [
362362+ "-S", add_switch "-S",
363363+ " Keep intermediate assembly file";
364364+ ] else [];
365365+ [
366366+ "-thread", add_switch "-thread",
367367+ " Use thread-safe standard library (implies -predicate mt)";
368368+ "-unsafe", add_switch "-unsafe",
369369+ " No bounds checking on array and string access";
370370+ ] ;
371371+ if which <> "ocamlopt" then [
372372+ "-use-runtime", add_spec "-use-runtime",
373373+ " <path> Generate bytecode for the given runtime system";
374374+ "-use_runtime", add_spec "-use_runtime",
375375+ " same as -use-runtime";
376376+ ] else [];
377377+ [
378378+ "-v", add_switch "-v",
379379+ " Print compiler version number";
380380+ "-verbose", add_switch "-verbose",
381381+ " Print calls to external commands";
382382+ "-w", add_spec "-w",
383383+ " <flags> Enable or disable warnings according to <flags>:
384384+ A/a enable/disable all warnings
385385+ C/c enable/disable suspicious comment
386386+ F/f enable/disable partially applied function
387387+ M/m enable/disable overridden methods
388388+ P/p enable/disable partial match
389389+ S/s enable/disable non-unit statement
390390+ U/u enable/disable unused match case
391391+ V/v enable/disable hidden instance variables
392392+ X/x enable/disable all other warnings
393393+ default setting is A (all warnings enabled)";
394394+ "-warn-error", add_spec "-warn-error",
395395+ " Turn these warnings into errors";
396396+ "-where", add_switch "-where",
397397+ " Print standard library directory";
398398+ "-", Arg.String (fun s -> pass_files := !pass_files @ [ Pass s ]),
399399+ " <file> Treat <file> as a file name (even if it starts with `-')";
400400+ ]
401401+ ])
402402+ (fun s -> pass_files := !pass_files @ [ Pass s])
403403+ ("usage: ocamlfind-mini " ^ which ^ " [options] file ...");
404404+405405+ begin match which with
406406+ "ocamlc"
407407+ | "ocamlcp"
408408+ | "ocamlmktop"
409409+ | "ocamlopt" -> ()
410410+ | _ -> failwith "unsupported backend"
411411+ end;
412412+413413+ let verbose = List.mem "-verbose" !switches in
414414+415415+ (* check packages: *)
416416+ List.iter
417417+ (fun pkg ->
418418+ try
419419+ let _ = package_directory pkg in
420420+ ()
421421+ with
422422+ Not_found ->
423423+ failwith ("package '" ^ pkg ^ "' not found (check environment variable OCAMLPATH)"))
424424+ !packages;
425425+426426+ let eff_packages = !packages in
427427+428428+ let eff_packages_dl =
429429+ remove_dups (List.map package_directory eff_packages) in
430430+431431+ let stdlibdir =
432432+ (* normalized form of the stdlib directory *)
433433+ let d = ocaml_stdlib in
434434+ if d <> "" & d.[String.length d - 1] = '/' then
435435+ String.sub d 0 (String.length d - 1)
436436+ else
437437+ d
438438+ in
439439+ let stdlibdirslash = stdlibdir ^ "/" in
440440+441441+ let i_options =
442442+ List.flatten
443443+ (List.map
444444+ (fun pkgdir ->
445445+ if pkgdir = stdlibdir or pkgdir = stdlibdirslash then
446446+ []
447447+ else
448448+ [ "-I"; pkgdir;
449449+ "-ccopt"; "-I" ^ pkgdir; ])
450450+ eff_packages_dl) in
451451+452452+ let pass_files' =
453453+ List.flatten
454454+ (List.map
455455+ (function
456456+ Pass s ->
457457+ if s.[0] = '-'
458458+ then [ "-"; String.sub s 1 (String.length s - 1) ]
459459+ else [ s ]
460460+ | Impl s ->
461461+ [ "-impl"; s ]
462462+ | Intf s ->
463463+ [ "-intf"; s ]
464464+ )
465465+ !pass_files)
466466+ in
467467+468468+ let arguments =
469469+ !pass_options @
470470+ i_options @
471471+ pass_files'
472472+ in
473473+474474+ let actual_command = which in
475475+476476+ if verbose then
477477+ print_string ("+ " ^ actual_command ^ " " ^
478478+ String.concat " " arguments ^ "\n");
479479+480480+ flush stdout;
481481+482482+ let argstring =
483483+ String.concat " "
484484+ (List.map Filename.quote arguments)
485485+ in
486486+487487+ let status = Sys.command (actual_command ^ " " ^ argstring) in
488488+489489+ begin
490490+ match status with
491491+ 0 -> ()
492492+ | n ->
493493+ if verbose then
494494+ print_string (actual_command ^ " returned with exit code " ^ string_of_int n ^ "\n");
495495+ exit n
496496+ end;
497497+;;
498498+499499+500500+(************************************************************************)
501501+502502+let make_directory dirname =
503503+ (* Invoke the mkdir command *)
504504+ let cmd =
505505+ match Sys.os_type with
506506+ "Unix" -> "mkdir"
507507+ | "Cygwin" -> "mkdir" (* don't really know *)
508508+ | "Win32" -> "md"
509509+ | "MacOS" -> failwith "make_directory not implemented for MacOS"
510510+ | _ -> failwith "Findlib: unknown operating system"
511511+ in
512512+ let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in
513513+ if c <> 0 then
514514+ failwith ("Cannot make directory " ^ dirname)
515515+;;
516516+517517+518518+let remove_directory dirname =
519519+ (* Invoke the rmdir command *)
520520+ let cmd =
521521+ match Sys.os_type with
522522+ "Unix" -> "rmdir"
523523+ | "Cygwin" -> "rmdir" (* don't really know *)
524524+ | "Win32" -> "rd"
525525+ | "MacOS" -> failwith "remove_directory not implemented for MacOS"
526526+ | _ -> failwith "Findlib: unknown operating system"
527527+ in
528528+ let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in
529529+ if c <> 0 then
530530+ failwith ("Cannot remove directory " ^ dirname)
531531+;;
532532+533533+534534+let list_dir dirname =
535535+ let rec rd_dir f =
536536+ try
537537+ let s = input_line f in
538538+ if s = "" then rd_dir f else s::rd_dir f
539539+ with
540540+ End_of_file ->
541541+ close_in f;
542542+ []
543543+ in
544544+545545+ (* Invoke the ls command *)
546546+ let cmd =
547547+ match Sys.os_type with
548548+ "Unix" -> "ls -1"
549549+ | "Cygwin" -> "ls -1" (* don't really know *)
550550+ | "Win32" -> "dir /b"
551551+ | "MacOS" -> failwith "list_dir not implemented for MacOS"
552552+ | _ -> failwith "Findlib: unknown operating system"
553553+ in
554554+ let filename = Filename.temp_file "ocamlfind." ".dat" in
555555+ let fullcmd = cmd ^ " " ^ Filename.quote dirname ^ " >" ^ filename in
556556+ let n = Sys.command fullcmd in
557557+ if n <> 0 then
558558+ failwith ("Cannot execute: " ^ fullcmd);
559559+ let f = open_in filename in
560560+ let l = rd_dir f in
561561+ close_in f;
562562+ (try Sys.remove filename with _ -> ());
563563+ l
564564+;;
565565+566566+567567+let copy_file ?(rename = (fun name -> name)) ?(append = "") src dstdir =
568568+ (* A system-independent function to copy the file src to dstdir *)
569569+ let outname = rename (Filename.basename src) in
570570+ let ch_in = open_in_bin src in
571571+ try
572572+ let outpath = Filename.concat dstdir outname in
573573+ if Sys.file_exists outpath then
574574+ prerr_endline ("ocamlfind-mini: [WARNING] Overwriting file " ^ outpath);
575575+ let ch_out = open_out_bin outpath in
576576+ try
577577+ let buflen = 4096 in
578578+ let buf = Bytes.create buflen in
579579+ let pos = ref 0 in
580580+ let len = ref (input ch_in buf 0 buflen) in
581581+ while !len > 0 do
582582+ output ch_out buf !pos !len;
583583+ len := input ch_in buf !pos buflen;
584584+ done;
585585+ output_string ch_out append;
586586+ close_out ch_out;
587587+ close_in ch_in;
588588+ prerr_endline("Installed " ^ outpath);
589589+ with
590590+ exc -> close_out ch_out; raise exc
591591+ with
592592+ exc -> close_in ch_in; raise exc
593593+;;
594594+595595+596596+let install_create_directory pkgname dstdir =
597597+ if Sys.file_exists dstdir then
598598+ failwith ("Package " ^ pkgname ^ " is already installed; please remove it first");
599599+ make_directory dstdir
600600+;;
601601+602602+603603+exception Skip_file;;
604604+605605+let install_package () =
606606+ let destdir = ref (env_destdir) in
607607+ let metadir = ref (env_metadir) in
608608+ let don't_add_directory_directive = ref false in
609609+ let pkgname = ref "" in
610610+ let files = ref [] in
611611+612612+ let keywords =
613613+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
614614+ "<path> Set the destination directory";
615615+ "-metadir", (Arg.String (fun s -> metadir := s)),
616616+ "<path> Install the META file into this directory";
617617+ "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive),
618618+ " never append directory='...' to META";
619619+ ] in
620620+ let errmsg = "usage: ocamlfind-mini install [options] <package_name> <file> ..." in
621621+622622+ Arg.current := 1;
623623+ Arg.parse
624624+ keywords
625625+ (fun s ->
626626+ if !pkgname = ""
627627+ then pkgname := s
628628+ else files := s :: !files
629629+ )
630630+ errmsg;
631631+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
632632+633633+ (* Check destdir: *)
634634+ if !destdir = "" then
635635+ failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR");
636636+ if not (Sys.file_exists !destdir) then
637637+ failwith ("The destination directory " ^ !destdir ^ " does not exist");
638638+639639+ (* Check whether META exists: *)
640640+ let meta_dot_pkg = "META." ^ !pkgname in
641641+ let has_meta =
642642+ List.exists
643643+ (fun p ->
644644+ let b = Filename.basename p in
645645+ b = "META" || b = meta_dot_pkg)
646646+ !files
647647+ in
648648+ if not has_meta then
649649+ failwith "The META file is missing";
650650+651651+ (* Check that there is no meta_dot_pkg: *)
652652+ if Sys.file_exists (Filename.concat !metadir meta_dot_pkg) then
653653+ failwith ("Package " ^ !pkgname ^ " is already installed; please remove it first");
654654+655655+ (* Create the package directory: *)
656656+ let pkgdir = Filename.concat !destdir !pkgname in
657657+ install_create_directory !pkgname pkgdir;
658658+659659+ (* Now copy the files into the package directory: *)
660660+ let has_metadir = !metadir <> "" in
661661+ List.iter
662662+ (fun p ->
663663+ try
664664+ copy_file
665665+ ~rename: (fun f ->
666666+ if has_metadir then begin
667667+ if f = "META" || f = meta_dot_pkg
668668+ then raise Skip_file
669669+ else f
670670+ end
671671+ else
672672+ if f = meta_dot_pkg then "META" else f)
673673+ p
674674+ pkgdir
675675+ with
676676+ Skip_file -> ()
677677+ )
678678+ !files;
679679+680680+ (* Finally copy META into metadir, if this has been requested *)
681681+ if has_metadir then begin
682682+ List.iter
683683+ (fun p ->
684684+ let b = Filename.basename p in
685685+ if b = "META" || b = meta_dot_pkg then
686686+ copy_file
687687+ ~rename: (fun f ->
688688+ if f = "META" then meta_dot_pkg else f)
689689+ ~append: ("\ndirectory=\"" ^ pkgdir ^ "\" # auto-added by ocamlfind-mini\n")
690690+ p
691691+ !metadir
692692+ )
693693+ !files
694694+ end
695695+;;
696696+697697+698698+let remove_package () =
699699+ let destdir = ref (env_destdir) in
700700+ let metadir = ref (env_metadir) in
701701+ let pkgname = ref "" in
702702+703703+ let keywords =
704704+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
705705+ "<path> Set the destination directory";
706706+ "-metadir", (Arg.String (fun s -> metadir := s)),
707707+ "<path> Remove the META file from this directory";
708708+ ] in
709709+ let errmsg = "usage: ocamlfind-mini remove [options] <package_name>" in
710710+711711+ Arg.current := 1;
712712+ Arg.parse
713713+ keywords
714714+ (fun s ->
715715+ if !pkgname = ""
716716+ then pkgname := s
717717+ else raise (Arg.Bad "too many arguments")
718718+ )
719719+ errmsg;
720720+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
721721+722722+ (* Check destdir: *)
723723+ if !destdir = "" then
724724+ failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR");
725725+ if not (Sys.file_exists !destdir) then
726726+ failwith ("The destination directory " ^ !destdir ^ " does not exist");
727727+728728+ let meta_dot_pkg = "META." ^ !pkgname in
729729+ let has_metadir = !metadir <> "" in
730730+731731+ (* If there is a metadir, remove the META file from it: *)
732732+ if has_metadir then begin
733733+ let f = Filename.concat !metadir meta_dot_pkg in
734734+ if Sys.file_exists f then begin
735735+ Sys.remove f;
736736+ prerr_endline ("Removed " ^ f);
737737+ end
738738+ else
739739+ prerr_endline ("ocamlfind-mini: [WARNING] No such file: " ^ f)
740740+ end;
741741+742742+ (* Remove the files from the package directory: *)
743743+ let pkgdir = Filename.concat !destdir !pkgname in
744744+745745+ if Sys.file_exists pkgdir then begin
746746+ let files = list_dir pkgdir in
747747+ List.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files;
748748+ remove_directory pkgdir;
749749+ prerr_endline ("Removed " ^ pkgdir)
750750+ end
751751+ else
752752+ prerr_endline("ocamlfind-mini: [WARNING] No such directory: " ^ pkgdir);
753753+;;
754754+755755+756756+let select_mode() =
757757+ let m_string = try arg 1 with Not_found -> raise Usage in
758758+ let m =
759759+ match m_string with
760760+ ("use"|"-use") -> M_use
761761+ | ("query"|"-query") -> M_query
762762+ | ("install"|"-install") -> M_install
763763+ | ("remove"|"-remove") -> M_remove
764764+ | ("ocamlc"|"-ocamlc") -> M_compiler "ocamlc"
765765+ | ("ocamlcp"|"-ocamlcp") -> M_compiler "ocamlcp"
766766+ | ("ocamlmktop"|"-ocamlmktop") -> M_compiler "ocamlmktop"
767767+ | ("ocamlopt"|"-ocamlopt") -> M_compiler "ocamlopt"
768768+ | ("printconf"|"-printconf") -> M_printconf
769769+ | ("guess"|"-guess") -> M_guess
770770+ | ("list"|"-list") -> M_list
771771+ | _ -> raise Usage
772772+ in
773773+774774+ m
775775+;;
776776+777777+778778+let sorry() =
779779+ prerr_endline "ocamlfind-mini: sorry, this function is not implemented in the reduced version of ocamlfind";
780780+ exit 1
781781+;;
782782+783783+784784+let main() =
785785+ try
786786+ let m = select_mode() in
787787+ let l = Array.length Sys.argv in
788788+ let rest = Array.sub Sys.argv 2 (l-2) in
789789+ match m with
790790+ M_use -> if rest = [| |] then raise Usage;
791791+ if rest.(0) = "-p" then begin
792792+ if l<4 then raise Usage;
793793+ use_package rest.(1)
794794+ (List.tl(List.tl(Array.to_list rest)))
795795+ end
796796+ else
797797+ use_package "" (Array.to_list rest)
798798+ | M_query -> sorry()
799799+ | M_install -> install_package()
800800+ | M_remove -> remove_package ()
801801+ | M_printconf -> sorry()
802802+ | M_guess -> sorry()
803803+ | M_list -> sorry()
804804+ | M_compiler which -> ocamlc which ()
805805+ with
806806+ Usage ->
807807+ prerr_endline "usage: ocamlfind-mini ocamlc [-help | other options] <file> ...";
808808+ prerr_endline " or: ocamlfind-mini ocamlcp [-help | other options] <file> ...";
809809+ prerr_endline " or: ocamlfind-mini ocamlmktop [-help | other options] <file> ...";
810810+ prerr_endline " or: ocamlfind-mini ocamlopt [-help | other options] <file> ...";
811811+ prerr_endline " or: ocamlfind-mini install [-help | other options] <package_name> <file> ...";
812812+ prerr_endline " or: ocamlfind-mini remove [-help | other options] <package_name>";
813813+ exit 2
814814+ | Failure f ->
815815+ prerr_endline ("ocamlfind-mini: " ^ f);
816816+ exit 2
817817+;;
818818+819819+820820+try
821821+ Sys.catch_break true;
822822+ main()
823823+with
824824+ any ->
825825+ prerr_endline ("Uncaught exception: " ^ Printexc.to_string any);
826826+ let raise_again =
827827+ try ignore(Sys.getenv "OCAMLFIND_DEBUG"); true
828828+ with Not_found -> false
829829+ in
830830+ if raise_again then raise any;
831831+ exit 3
832832+;;
833833+834834+835835+(* ======================================================================
836836+ * History:
837837+ *
838838+ * $Log: ocamlfind-mini,v $
839839+ * Revision 1.4 2001/03/10 08:15:24 gerd
840840+ * -warn-error
841841+ *
842842+ * Revision 1.3 2001/03/06 20:18:03 gerd
843843+ * Option -where.
844844+ *
845845+ * Revision 1.2 2001/03/04 19:03:56 gerd
846846+ * list_dir: deletes the temp file after use
847847+ *
848848+ * Revision 1.1 2001/03/04 19:01:21 gerd
849849+ * Initial revision.
850850+ *
851851+ *)
···11+opam-version: "2.0"
22+name: "ocamlfind"
33+version: "1.9.8.git"
44+license: "MIT"
55+synopsis: "A library manager for OCaml"
66+maintainer: "Thomas Gazagnaire <thomas@gazagnaire.org>"
77+authors: "Gerd Stolpmann <gerd@gerd-stolpmann.de>"
88+homepage: "http://projects.camlcity.org/projects/findlib.html"
99+bug-reports: "https://github.com/ocaml/ocamlfind/issues"
1010+dev-repo: "git+https://github.com/ocaml/ocamlfind.git"
1111+description: """
1212+Findlib is a library manager for OCaml. It provides a convention how
1313+to store libraries, and a file format ("META") to describe the
1414+properties of libraries. There is also a tool (ocamlfind) for
1515+interpreting the META files, so that it is very easy to use libraries
1616+in programs and scripts.
1717+"""
1818+build: [
1919+ [
2020+ "./configure"
2121+ "-bindir" bin
2222+ "-sitelib" lib
2323+ "-mandir" man
2424+ "-config" "%{lib}%/findlib.conf"
2525+ "-no-custom"
2626+ "-no-camlp4" {!ocaml:preinstalled & ocaml:version >= "4.02.0"}
2727+ "-no-topfind" {ocaml:preinstalled}
2828+ ]
2929+ [make "all"]
3030+ [make "opt"] {ocaml:native}
3131+]
3232+install: [
3333+ [make "install"]
3434+ ["install" "-m" "0755" "ocaml-stub" "%{bin}%/ocaml"] {ocaml:preinstalled}
3535+]
3636+depends: [
3737+ "ocaml" {>= "3.08.0"}
3838+]
3939+depopts: ["graphics"]
···11+name="bytes"
22+version="[distributed with OCaml 4.02 or above]"
33+description="dummy backward-compatibility package for mutable strings"
44+requires=""
+8
vendor/opam/ocamlfind/site-lib-src/bytes/README
···11+dummy forward-compatibility package for the standard Bytes module
22+33+Starting from 4.02, the OCaml standard library splits String into two
44+modules, String for now-immutable strings and Bytes for mutable byte
55+sequences. A 'bytes' package is made available to older OCaml version
66+that wish to use a Bytes module. This dummy 'bytes' package, intended
77+to be installed on 4.02 and above, makes user-code depending on
88+'bytes' forward-compatible.
···11+# Specifications for the standard library:
22+# (Only included because of findlib-browser)
33+requires = ""
44+description = "Standard library"
55+version = "[distributed with Ocaml]"
66+directory = "^"
77+browse_interfaces = "%%interfaces%%"
88+99+
···11+name="bytes"
22+version="[OCaml strictly before 4.02]"
33+description="backward-compatibility package for mutable strings"
44+requires=""
55+browse_interfaces = "String"
66+archive(byte)="bytes.cma"
77+archive(native)="bytes.cmxa"
88+plugin(byte)="bytes.cma"
99+plugin(native)="bytes.cmxs"
+41
vendor/opam/ocamlfind/src/bytes/Makefile
···11+BYTE_FILES=bytes.cmi bytes.cma
22+NATIVE_FILES=bytes.cmx bytes$(LIB_SUFFIX) bytes.cmxa
33+NATIVE_FILES_DYNLINK=bytes.cmxs
44+55+TOP=../..
66+include $(TOP)/Makefile.config
77+88+OCAMLC = ocamlc
99+OCAMLOPT = ocamlopt $(OCAMLOPT_G)
1010+OCAMLOPT_SHARED = $(OCAMLOPT)
1111+1212+build: all opt
1313+1414+all:
1515+ $(OCAMLC) -a -o bytes.cma bytes.ml
1616+1717+opt:
1818+ $(OCAMLOPT) -a -o bytes.cmxa bytes.ml
1919+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
2020+ $(OCAMLOPT_SHARED) -shared -o bytes.cmxs bytes.cmxa; \
2121+ fi
2222+2323+install: all
2424+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes"
2525+ $(CP) META $(BYTE_FILES) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/"
2626+ for f in $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK); do if [ -f "$$f" ]; then $(CP) $$f "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/"; fi; done
2727+2828+uninstall:
2929+ rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes"
3030+3131+# install-self and uninstall-self use ocamlfind already. This is a bit
3232+# questionable here.
3333+3434+install-self: all
3535+ ocamlfind install bytes META $(BYTE_FILES) -optional $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK)
3636+3737+uninstall-self:
3838+ ocamlfind remove bytes
3939+4040+clean:
4141+ ocamlbuild -clean
+7
vendor/opam/ocamlfind/src/bytes/README
···11+backward-compatibility package for the standard Bytes module of 4.02
22+33+Starting from 4.02, the OCaml standard library splits String into two
44+modules, String for now-immutable strings and Bytes for mutable byte
55+sequences. This package exports a Bytes package mimicking the new
66+interface to older OCaml version, letting you write code using Bytes
77+that works with OCaml < 4.02.
+36
vendor/opam/ocamlfind/src/bytes/bytes.ml
···11+include String
22+33+let empty = ""
44+let of_string = copy
55+let to_string = copy
66+77+let sub_string = sub
88+let blit_string = blit
99+1010+let unsafe_to_string : t -> string = fun s -> s
1111+let unsafe_of_string : string -> t = fun s -> s
1212+1313+let extend s left right =
1414+ (* length of the final string *)
1515+ let dstlen = left + length s + right in
1616+ (* length of the included portion of the input string *)
1717+ let srclen = min 0 left + length s + min 0 right in
1818+ let t = create dstlen in
1919+ if srclen > 0 then blit s (max 0 (-left)) t (max 0 left) srclen;
2020+ t
2121+2222+let init len f =
2323+ let s = create len in
2424+ for i = 0 to len - 1 do
2525+ set s i (f i);
2626+ done;
2727+ s
2828+2929+let mapi f input =
3030+ let output = create (length input) in
3131+ for i = 0 to length input - 1 do
3232+ output.[i] <- f i input.[i];
3333+ done;
3434+ output
3535+3636+let cat = (^)
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+77+open Tk;;
88+open Widget;;
99+1010+(**********************************************************************)
1111+(* GLOBAL VARIABLES *)
1212+(**********************************************************************)
1313+1414+(* General *)
1515+1616+let wiz_package_name = ref "";;
1717+let wiz_package_version = ref "";;
1818+let wiz_package_description = ref "";;
1919+2020+(* Preprocessor *)
2121+2222+let wiz_enable_camlp4 = ref false;;
2323+let wiz_camlp4_syntax = ref "camlp4o";;
2424+let wiz_camlp4_extensions = ref [];; (* list of package names *)
2525+let wiz_camlp4_selected = ref [];; (* subset of wiz_camlp4_extensions *)
2626+let wiz_camlp4_options = ref "";;
2727+2828+(* Prerequisites *)
2929+3030+let wiz_all_packages = ref [];; (* list of package names *)
3131+let wiz_required_packages = ref [];; (* subset of wiz_all_packages *)
3232+3333+(* Build Library *)
3434+3535+let wiz_available = ref [];; (* list of module names *)
3636+let wiz_byte_enable = ref true;;
3737+let wiz_nat_enable = ref true;;
3838+let wiz_objects = ref [];; (* subset of wiz_available *)
3939+let wiz_source_suffixes = ref ".ml .mli .mll .mly";;
4040+4141+(* Build Executables *)
4242+4343+let wiz_executables = ref [];; (* list of executable names *)
4444+let wiz_exec_objects = (ref [] : (string * (string list ref)) list ref);;
4545+ (* an alist: for every executable, the corresponding list of modules is
4646+ * stored.
4747+ *)
4848+let wiz_exec_native = (ref [] : (string * bool ref) list ref);;
4949+ (* an alist: for every executable, whether it is natively compiled or not *)
5050+5151+(* Generate *)
5252+5353+let wiz_makefile_name = ref "Makefile";;
5454+let wiz_local_makefile_name = ref "";;
5555+let wiz_make_default = ref "byte" ;;
5656+5757+5858+(**********************************************************************)
5959+(* AUXILIARY FUNCTIONS *)
6060+(**********************************************************************)
6161+6262+let find_pos x l =
6363+ let rec find k l =
6464+ match l with
6565+ h :: l' ->
6666+ if x = h then k else find (k+1) l'
6767+ | [] ->
6868+ raise Not_found
6969+ in
7070+ find 0 l
7171+;;
7272+7373+7474+let rec delete_at k l =
7575+ match l with
7676+ h :: l' -> if k <= 0 then l' else h :: (delete_at (k-1) l')
7777+ | [] -> []
7878+;;
7979+8080+8181+let rec insert_at k x l =
8282+ if k <= 0 then
8383+ x :: l
8484+ else
8585+ match l with
8686+ h :: l' -> h :: (insert_at (k-1) x l')
8787+ | [] -> [] (* insert beyond end *)
8888+;;
8989+9090+9191+let rec remove_dups l =
9292+ (* Remove duplicate members in a sorted list *)
9393+ match l with
9494+ x :: (y :: l' as l1) when x = y ->
9595+ remove_dups l1
9696+ | x :: l' ->
9797+ x :: remove_dups l'
9898+ | [] ->
9999+ []
100100+;;
101101+102102+103103+(**********************************************************************)
104104+(* SAVE/LOAD STATE *)
105105+(**********************************************************************)
106106+107107+let save_var name printer out var =
108108+ output_string out ("V" ^ name ^ "\n");
109109+ printer out var
110110+;;
111111+112112+let save_string out var =
113113+ (* [var] must not contain linefeeds *)
114114+ output_string out ("S" ^ var ^ "\n")
115115+;;
116116+117117+let save_bool out var =
118118+ output_string out ("B" ^ string_of_bool var ^ "\n")
119119+;;
120120+121121+let save_list printer out var =
122122+ output_string out ("L" ^ string_of_int (List.length var) ^ "\n");
123123+ List.iter (printer out) var
124124+;;
125125+126126+let save_pair lprinter rprinter out (lvar,rvar) =
127127+ output_string out "P\n";
128128+ lprinter out lvar;
129129+ rprinter out rvar
130130+;;
131131+132132+let save_ref printer out var =
133133+ (* Actually doesn't save the reference! *)
134134+ printer out !var
135135+;;
136136+137137+let save_state out =
138138+ save_var "wiz_package_name" save_string out !wiz_package_name;
139139+ save_var "wiz_package_version" save_string out !wiz_package_version;
140140+ save_var "wiz_package_description" save_string out !wiz_package_description;
141141+ save_var "wiz_enable_camlp4" save_bool out !wiz_enable_camlp4;
142142+ save_var "wiz_camlp4_syntax" save_string out !wiz_camlp4_syntax;
143143+ save_var "wiz_camlp4_extensions" (save_list save_string) out
144144+ !wiz_camlp4_extensions;
145145+ save_var "wiz_camlp4_selected" (save_list save_string) out
146146+ !wiz_camlp4_selected;
147147+ save_var "wiz_camlp4_options" save_string out !wiz_camlp4_options;
148148+ save_var "wiz_all_packages" (save_list save_string) out
149149+ !wiz_all_packages;
150150+ save_var "wiz_required_packages" (save_list save_string) out
151151+ !wiz_required_packages;
152152+ save_var "wiz_available" (save_list save_string) out
153153+ !wiz_available;
154154+ save_var "wiz_byte_enable" save_bool out !wiz_byte_enable;
155155+ save_var "wiz_nat_enable" save_bool out !wiz_nat_enable;
156156+ save_var "wiz_objects" (save_list save_string) out
157157+ !wiz_objects;
158158+ save_var "wiz_source_suffixes" save_string out !wiz_source_suffixes;
159159+ save_var "wiz_executables" (save_list save_string) out
160160+ !wiz_executables;
161161+ save_var "wiz_exec_objects"
162162+ (save_list (save_pair save_string (save_ref (save_list save_string))))
163163+ out
164164+ !wiz_exec_objects;
165165+ save_var "wiz_exec_native"
166166+ (save_list (save_pair save_string (save_ref save_bool)))
167167+ out
168168+ !wiz_exec_native;
169169+ save_var "wiz_makefile_name" save_string out !wiz_makefile_name;
170170+ save_var "wiz_local_makefile_name" save_string out !wiz_local_makefile_name;
171171+ save_var "wiz_make_default" save_string out !wiz_make_default;
172172+;;
173173+174174+let save() =
175175+ let f = open_out ".make-wizard" in
176176+ save_state f;
177177+ close_out f
178178+;;
179179+180180+let check_char inch c_expected =
181181+ let c = input_char inch in
182182+ if c <> c_expected then failwith "Cannot read .make-wizard"
183183+;;
184184+185185+let load_string inch =
186186+ check_char inch 'S';
187187+ let line = input_line inch in
188188+ (* prerr_endline ("String = " ^ line); *)
189189+ line
190190+;;
191191+192192+let load_bool inch =
193193+ check_char inch 'B';
194194+ bool_of_string(input_line inch)
195195+;;
196196+197197+let load_list parse inch =
198198+ check_char inch 'L';
199199+ let n = int_of_string(input_line inch) in
200200+ let l = ref [] in
201201+ for i = 1 to n do
202202+ l := parse inch :: !l;
203203+ done;
204204+ List.rev !l
205205+;;
206206+207207+let load_pair lparse rparse inch =
208208+ check_char inch 'P';
209209+ ignore(input_line inch);
210210+ let l = lparse inch in
211211+ let r = rparse inch in
212212+ (l,r)
213213+;;
214214+215215+let load_ref parse inch =
216216+ ref(parse inch)
217217+;;
218218+219219+let load_var var parse inch =
220220+ let value = parse inch in
221221+ var := value
222222+;;
223223+224224+let load_variables spec inch =
225225+ try
226226+ while true do
227227+ try
228228+ check_char inch 'V';
229229+ let name = input_line inch in
230230+ (* prerr_endline name;*)
231231+ let loader = List.assoc name spec in (* or Not_found *)
232232+ loader inch
233233+ with
234234+ Not_found ->
235235+ ()
236236+ done;
237237+ assert false
238238+ with
239239+ End_of_file ->
240240+ ()
241241+;;
242242+243243+let load_state inch =
244244+ load_variables
245245+ [ "wiz_package_name",
246246+ (load_var wiz_package_name load_string);
247247+ "wiz_package_version",
248248+ (load_var wiz_package_version load_string);
249249+ "wiz_package_description",
250250+ (load_var wiz_package_description load_string);
251251+ "wiz_enable_camlp4",
252252+ (load_var wiz_enable_camlp4 load_bool);
253253+ "wiz_camlp4_syntax",
254254+ (load_var wiz_camlp4_syntax load_string);
255255+ "wiz_camlp4_extensions",
256256+ (load_var wiz_camlp4_extensions (load_list load_string));
257257+ "wiz_camlp4_selected",
258258+ (load_var wiz_camlp4_selected (load_list load_string));
259259+ "wiz_camlp4_options",
260260+ (load_var wiz_camlp4_options load_string);
261261+ "wiz_all_packages",
262262+ (load_var wiz_all_packages (load_list load_string));
263263+ "wiz_required_packages",
264264+ (load_var wiz_required_packages (load_list load_string));
265265+ "wiz_available",
266266+ (load_var wiz_available (load_list load_string));
267267+ "wiz_byte_enable",
268268+ (load_var wiz_byte_enable load_bool);
269269+ "wiz_nat_enable",
270270+ (load_var wiz_nat_enable load_bool);
271271+ "wiz_objects",
272272+ (load_var wiz_objects (load_list load_string));
273273+ "wiz_source_suffixes",
274274+ (load_var wiz_source_suffixes load_string);
275275+ "wiz_executables",
276276+ (load_var wiz_executables (load_list load_string));
277277+ "wiz_exec_objects",
278278+ (load_var wiz_exec_objects (load_list
279279+ (load_pair
280280+ load_string
281281+ (load_ref (load_list load_string)))));
282282+ "wiz_exec_native",
283283+ (load_var wiz_exec_native (load_list
284284+ (load_pair
285285+ load_string
286286+ (load_ref load_bool))));
287287+ "wiz_makefile_name",
288288+ (load_var wiz_makefile_name load_string);
289289+ "wiz_local_makefile_name",
290290+ (load_var wiz_local_makefile_name load_string);
291291+ "wiz_make_default",
292292+ (load_var wiz_make_default load_string);
293293+ ]
294294+ inch
295295+;;
296296+297297+298298+let load() =
299299+ let f = open_in ".make-wizard" in
300300+ load_state f;
301301+ close_in f
302302+;;
303303+304304+305305+(**********************************************************************)
306306+(* PARSE PATTERN FILE *)
307307+(**********************************************************************)
308308+309309+type sectiondata =
310310+ Sect_const of string
311311+ | Sect_var of string
312312+313313+let section_re = Str.regexp "^\\[\\([A-Za-z_0-9-]+\\)\\]$" ;;
314314+let var_re = Str.regexp "\\[\\([A-Za-z_0-9-]+\\)\\]" ;;
315315+316316+let parse_pattern inch =
317317+ let rec parse_section name sect =
318318+ try
319319+ let line = input_line inch in
320320+ if String.length line >= 2 && line.[0] = '#' && line.[1] = '#' then
321321+ (* Comment line *)
322322+ parse_section name sect
323323+ else
324324+ if Str.string_match section_re line 0 then
325325+ (* New section begins *)
326326+ let name' = Str.matched_group 1 line in
327327+ (name, List.rev sect) :: parse_section name' []
328328+ else
329329+ (* Normal data region *)
330330+ let plist = Str.full_split var_re line in
331331+ let slist =
332332+ List.map
333333+ (function
334334+ Str.Text t -> Sect_const t
335335+ | Str.Delim d -> Sect_var (String.sub d 1 (String.length d - 2))
336336+ )
337337+ plist @ [ Sect_const "\n" ] in
338338+ parse_section name (List.rev slist @ sect)
339339+ with
340340+ End_of_file ->
341341+ [ name, List.rev sect ]
342342+ in
343343+344344+ parse_section "_preamble_" []
345345+;;
346346+347347+let load_pattern() =
348348+ let where = Filename.dirname (Sys.argv.(0)) in
349349+ let name = Filename.concat where "make_wizard.pattern" in
350350+ let f = open_in name in
351351+ let p = parse_pattern f in
352352+ close_in f;
353353+ p
354354+;;
355355+356356+(**********************************************************************)
357357+(* MAKEFILE GENERATOR *)
358358+(**********************************************************************)
359359+360360+let dollar_re = Str.regexp "\\$";;
361361+let meta_re = Str.regexp "[\\\\\\\"]";;
362362+363363+let mkquote s =
364364+ (* Quote "$" *)
365365+ Str.global_replace dollar_re "$$" s
366366+;;
367367+368368+let metaquote s =
369369+ (* Quote backslash and double quotes for META files *)
370370+ Str.global_replace meta_re "\\\\0" s
371371+;;
372372+373373+let makemake() =
374374+ let b = Buffer.create 1024 in
375375+ let sections = load_pattern() in
376376+377377+ let write section vars =
378378+ let sectlist =
379379+ try List.assoc section sections
380380+ with Not_found -> failwith ("Cannot find section: " ^ section) in
381381+ List.iter
382382+ (function
383383+ Sect_const s ->
384384+ Buffer.add_string b s
385385+ | Sect_var v ->
386386+ let s =
387387+ try List.assoc v vars
388388+ with Not_found -> failwith ("No such variable: " ^ v) in
389389+ Buffer.add_string b s
390390+ )
391391+ sectlist
392392+ in
393393+394394+ let is_byte_exec execname =
395395+ try not (!(List.assoc execname !wiz_exec_native))
396396+ with Not_found -> true
397397+ in
398398+399399+ let byte_execs =
400400+ List.map
401401+ fst
402402+ (List.filter
403403+ (fun (execname,_) -> is_byte_exec execname)
404404+ !wiz_exec_objects
405405+ )
406406+ in
407407+408408+ let nat_execs =
409409+ List.map
410410+ fst
411411+ (List.filter
412412+ (fun (execname,_) -> not(is_byte_exec execname))
413413+ !wiz_exec_objects
414414+ )
415415+ in
416416+417417+ let byte_exec_modules =
418418+ remove_dups
419419+ (List.sort compare
420420+ (List.flatten
421421+ (List.map
422422+ (fun (_, l) -> !l)
423423+ (List.filter
424424+ (fun (execname, _) -> is_byte_exec execname)
425425+ !wiz_exec_objects
426426+ )
427427+ )
428428+ )
429429+ )
430430+ in
431431+432432+ let nat_exec_modules =
433433+ remove_dups
434434+ (List.sort compare
435435+ (List.flatten
436436+ (List.map
437437+ (fun (_, l) -> !l)
438438+ (List.filter
439439+ (fun (execname, _) -> not(is_byte_exec execname))
440440+ !wiz_exec_objects
441441+ )
442442+ )
443443+ )
444444+ )
445445+ in
446446+447447+ let required_packages =
448448+ (* magically add "camlp4" if missing *)
449449+ if !wiz_enable_camlp4 then (
450450+ ( if not (List.mem "camlp4" !wiz_required_packages) then
451451+ [ "camlp4" ]
452452+ else
453453+ []
454454+ ) @ !wiz_camlp4_selected @ !wiz_required_packages
455455+ )
456456+ else
457457+ !wiz_required_packages
458458+ in
459459+460460+ let variables =
461461+ [ "name",
462462+ mkquote !wiz_package_name;
463463+ "makefile_name",
464464+ mkquote !wiz_makefile_name;
465465+ "version",
466466+ mkquote(metaquote !wiz_package_version);
467467+ "description",
468468+ mkquote(metaquote !wiz_package_description);
469469+ "byte_objects",
470470+ String.concat " " (List.map
471471+ (fun m -> String.uncapitalize m ^ ".cmo")
472472+ !wiz_objects);
473473+ "nat_objects",
474474+ String.concat " " (List.map
475475+ (fun m -> String.uncapitalize m ^ ".cmx")
476476+ !wiz_objects);
477477+ "byte_executables",
478478+ String.concat " " byte_execs;
479479+ "byte_exec_objects",
480480+ String.concat " " (List.map
481481+ (fun m -> String.uncapitalize m ^ ".cmo")
482482+ byte_exec_modules);
483483+ "nat_executables",
484484+ String.concat " " nat_execs;
485485+ "nat_exec_objects",
486486+ String.concat " " (List.map
487487+ (fun m -> String.uncapitalize m ^ ".cmx")
488488+ nat_exec_modules);
489489+ "prereqs",
490490+ String.concat " " required_packages;
491491+ "ppopts",
492492+ if !wiz_enable_camlp4 then
493493+ "-syntax " ^ !wiz_camlp4_syntax ^
494494+ (String.concat " "
495495+ (List.map
496496+ (fun opt -> " -ppopt " ^ mkquote(Filename.quote opt))
497497+ (Fl_split.in_words_ws !wiz_camlp4_options)
498498+ ))
499499+ else
500500+ "";
501501+ "mtopts",
502502+ if List.mem "threads" !wiz_required_packages then "-thread" else "";
503503+ "default_target",
504504+ !wiz_make_default;
505505+ ] in
506506+507507+ write "intro" variables;
508508+ write "def_general" variables;
509509+ if !wiz_byte_enable then write "def_byte_archive" variables;
510510+ if !wiz_nat_enable then write "def_native_archive" variables;
511511+ write "def_byte_exec" variables;
512512+ write "def_nat_exec" variables;
513513+ write "def_props" variables;
514514+ write "def_tools" variables;
515515+ write "rules" variables;
516516+ write "default_target" variables;
517517+ write "suffix_rules" variables;
518518+ write "generate" variables;
519519+ List.iter
520520+ (fun (execname, modlist) ->
521521+ let switches =
522522+ if is_byte_exec execname then
523523+ "-bytecode-filter"
524524+ else
525525+ "-native-filter" in
526526+ let deptargets =
527527+ String.concat " " (List.map
528528+ (fun m ->
529529+ let m' = String.uncapitalize m in
530530+ m' ^ ".ml " ^ m' ^ ".mli")
531531+ !modlist) in
532532+ write "makemake_exec" ( [ "switches", switches;
533533+ "execname", execname;
534534+ "deptargets", deptargets ] @ variables )
535535+ )
536536+ !wiz_exec_objects;
537537+ write "byte" variables;
538538+ write "opt" variables;
539539+ if !wiz_byte_enable then write "byte_archive" variables;
540540+ if !wiz_nat_enable then write "native_archive" variables;
541541+ List.iter
542542+ (fun (execname, modlist) ->
543543+ if is_byte_exec execname then begin
544544+ let execobjs =
545545+ String.concat " " (List.map
546546+ (fun m -> String.uncapitalize m ^ ".cmo")
547547+ !modlist) in
548548+ write "byte_exec" ( ["execname", execname;
549549+ "execobjs", execobjs ] @ variables )
550550+ end
551551+ )
552552+ !wiz_exec_objects;
553553+ List.iter
554554+ (fun (execname, modlist) ->
555555+ if not (is_byte_exec execname) then begin
556556+ let execobjs =
557557+ String.concat " " (List.map
558558+ (fun m -> String.uncapitalize m ^ ".cmx")
559559+ !modlist) in
560560+ write "nat_exec" ( ["execname", execname;
561561+ "execobjs", execobjs ] @ variables )
562562+ end
563563+ )
564564+ !wiz_exec_objects;
565565+ write "clean" variables;
566566+ write "install" variables;
567567+568568+ if !wiz_local_makefile_name<> "" &&
569569+ Sys.file_exists !wiz_local_makefile_name then
570570+ begin
571571+ write "local" variables;
572572+ let f = open_in !wiz_local_makefile_name in
573573+ try
574574+ while true do
575575+ let s = input_line f in
576576+ Buffer.add_string b s;
577577+ Buffer.add_char b '\n';
578578+ done;
579579+ assert false
580580+ with
581581+ End_of_file ->
582582+ close_in f
583583+ end;
584584+585585+ Buffer.contents b
586586+;;
587587+588588+(**********************************************************************)
589589+(* GUI *)
590590+(**********************************************************************)
591591+592592+let headline_font = "-*-helvetica-bold-r-normal-*-*-140-*-*-*-*-iso8859-1" ;;
593593+let font = "-*-helvetica-medium-r-normal-*-*-120-*-*-*-*-iso8859-1" ;;
594594+595595+(**********************************************************************)
596596+597597+let top = ref Widget.default_toplevel;;
598598+let topframe = ref Widget.dummy;;
599599+let screens = ref [];;
600600+let current_screen = ref 0;;
601601+602602+let ( !! ) = fun x -> !(!x);;
603603+604604+let add_screen func =
605605+ screens := !screens @ [ func ]
606606+;;
607607+608608+let add_headline frame text =
609609+ let s1 = Frame.create ~height:15 frame in
610610+ let w = Label.create ~text ~font:headline_font ~anchor:`W frame in
611611+ let s2 = Frame.create ~height:10 frame in
612612+ pack [ s1 ];
613613+ pack ~anchor:`W [ w ];
614614+ pack [ s2 ]
615615+;;
616616+617617+let add_para frame text =
618618+ let s1 = Frame.create ~height:5 frame in
619619+ let w = Message.create ~padx:0 ~text ~font ~anchor:`W ~width:(pixels (`Pt 400.0)) frame in
620620+ let s2 = Frame.create ~height:5 frame in
621621+ pack [ s1 ];
622622+ pack ~anchor:`W [ w ];
623623+ pack [ s2 ]
624624+;;
625625+626626+627627+let dialog ~parent ~title ~message ~buttons ?(default = (-1)) () =
628628+ (* Like Dialog.create, but our own style. *)
629629+ let popup = Toplevel.create parent in
630630+ Wm.title_set popup title;
631631+ Wm.transient_set popup ~master:(Winfo.toplevel parent);
632632+ add_headline popup title;
633633+ add_para popup message;
634634+ let f_buttons = Frame.create popup in
635635+ let n = ref 0 in
636636+ let r = ref (-1) in
637637+ List.iter
638638+ (fun text ->
639639+ let k = !n in
640640+ let b =
641641+ Button.create ~font ~text ~command:(fun () -> r := k; destroy popup)
642642+ f_buttons in
643643+ (* --- Default buttons not yet supported because of deficiency in
644644+ * labltk:
645645+ if k = default then Button.configure ~default:`Active b;
646646+ *)
647647+ pack ~side:`Left [b];
648648+ incr n;
649649+ )
650650+ buttons;
651651+ pack [f_buttons];
652652+ Grab.set popup;
653653+ Tkwait.window popup;
654654+ !r
655655+;;
656656+657657+658658+let ask_and_save frame =
659659+ let reply =
660660+ dialog ~parent:frame ~title:"Save .make-wizard?"
661661+ ~message:"Do you want to save the current state in the file .make-wizard?"
662662+ ~buttons:["Yes"; "No"; "Cancel"]
663663+ ~default:0
664664+ ()
665665+ in
666666+ if reply = 0 then save();
667667+ reply < 2
668668+;;
669669+670670+671671+let string_tv ?(onchange = fun () -> ()) frame v =
672672+ let textvariable = Textvariable.create ~on:frame () in
673673+ Textvariable.set textvariable !v;
674674+ let rec set_handle() =
675675+ Textvariable.handle textvariable
676676+ ~callback:(fun () ->
677677+ v := Textvariable.get textvariable;
678678+ onchange();
679679+ set_handle());
680680+ in
681681+ set_handle();
682682+ textvariable
683683+;;
684684+685685+686686+let bool_tv ?(onchange = fun () -> ()) frame v =
687687+ let textvariable = Textvariable.create ~on:frame () in
688688+ Textvariable.set textvariable (if !v then "1" else "0");
689689+ let rec set_handle() =
690690+ Textvariable.handle textvariable
691691+ ~callback:(fun () ->
692692+ v := Textvariable.get textvariable = "1";
693693+ onchange();
694694+ set_handle());
695695+ in
696696+ set_handle();
697697+ textvariable
698698+;;
699699+700700+701701+let label_box frame box =
702702+ let sub = Frame.create frame in
703703+ let row = ref 0 in
704704+ List.iter
705705+ (fun (l, v) ->
706706+ let label = Label.create ~font ~text:l ~anchor:`E sub in
707707+ let textvariable = string_tv frame v in
708708+ let var = Entry.create ~font ~textvariable ~width:40 sub in
709709+ grid ~row:!row ~column:0 ~sticky:"e" [ label ];
710710+ grid ~row:!row ~column:1 ~sticky:"w" [ var ];
711711+ incr row;
712712+ )
713713+ box;
714714+ pack ~anchor:`W [ sub ]
715715+;;
716716+717717+718718+let scrolled_listbox ?(click = fun _ _ -> ()) ?(context = fun _ _ -> ())
719719+ ?(separator = true) ?(height = 8) frame =
720720+ let f = Frame.create frame in
721721+ let lb = Listbox.create ~selectmode:`Multiple ~width:20 ~height
722722+ ~exportselection:false f in
723723+ let sb = Scrollbar.create ~orient:`Vertical
724724+ ~command:(Listbox.yview lb)
725725+ f in
726726+ Listbox.configure ~yscrollcommand:(Scrollbar.set sb) ~font lb;
727727+ let sep = Frame.create ~width:30 f in
728728+ pack ~side:`Left [ lb ];
729729+ pack ~side:`Left ~fill:`Y [ sb ];
730730+ if separator then pack ~side:`Left [ sep ];
731731+732732+ bind ~events:[ `ButtonPressDetail 1 ] ~fields:[ `MouseY ]
733733+ ~action:(fun einfo ->
734734+ let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in
735735+ Timer.set ~ms:0 ~callback:(fun () -> click lb row)
736736+ )
737737+ lb;
738738+ bind ~events:[ `ButtonPressDetail 3 ] ~fields:[ `MouseY ]
739739+ ~action:(fun einfo ->
740740+ let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in
741741+ Timer.set ~ms:0 ~callback:(fun () -> context lb row)
742742+ )
743743+ lb;
744744+745745+ (f, lb)
746746+;;
747747+748748+749749+let listbox_select lb selection =
750750+ Listbox.selection_clear lb ~first:(`Num 0) ~last:`End;
751751+ for i = 0 to Listbox.size lb do
752752+ let s = Listbox.get lb (`Num i) in
753753+ if List.mem s selection then
754754+ Listbox.selection_set lb ~first:(`Num i) ~last:(`Num i)
755755+ done
756756+;;
757757+758758+759759+let listbox_get_selection lb =
760760+ List.map
761761+ (fun index -> Listbox.get lb ~index)
762762+ (Listbox.curselection lb)
763763+;;
764764+765765+766766+let indented_cond_frame frame enablers =
767767+ (* Returns a subframe of [frame] that is only mapped if the boolean
768768+ * variable [!enable] is true. [enable_text] is the text for the
769769+ * checkbox that toggles [!enable].
770770+ *)
771771+ let onchange_enable = ref (fun () -> ()) in
772772+773773+ List.iter
774774+ (fun (enable, enable_text) ->
775775+ let enable_tv = bool_tv
776776+ ~onchange:(fun () -> !onchange_enable())
777777+ frame enable in
778778+ let cb = Checkbutton.create
779779+ ~font ~text:enable_text ~variable:enable_tv frame in
780780+ pack ~anchor:`W [cb];
781781+ )
782782+ enablers;
783783+784784+ let is_enabled() =
785785+ let p = ref false in
786786+ List.iter (fun (enable, _) -> p := !p || !enable) enablers;
787787+ !p
788788+ in
789789+790790+ let frame' = Frame.create frame in
791791+ let indent = Frame.create ~width:30 frame' in
792792+ let frame'' = Frame.create frame' in
793793+ pack ~anchor:`W [frame'];
794794+795795+ let frame''_is_packed = ref false in
796796+ let frame''_pack b =
797797+ if b <> !frame''_is_packed then begin
798798+ if b then
799799+ pack ~side:`Left [indent; frame'']
800800+ else
801801+ Pack.forget [ frame'' ];
802802+ frame''_is_packed := b
803803+ end
804804+ in
805805+ frame''_pack (is_enabled());
806806+ onchange_enable := (fun () -> frame''_pack (is_enabled()));
807807+ frame''
808808+;;
809809+810810+811811+let double_listbox frame available objects scan =
812812+ let boxes = Frame.create frame in
813813+ let (f_left,lb_left) = scrolled_listbox boxes in
814814+ let (f_right,lb_right) = scrolled_listbox ~separator:false boxes in
815815+ let f_buttons = Frame.create boxes in
816816+ let b_add = Button.create ~font ~text:"Add >>" f_buttons in
817817+ let b_del = Button.create ~font ~text:"<< Del" f_buttons in
818818+ let b_up = Button.create ~font ~text:"Up ^" f_buttons in
819819+ let b_down= Button.create ~font ~text:"Down v" f_buttons in
820820+ let b_scan= Button.create ~font ~text:"Rescan" f_buttons in
821821+ let f_sep = Frame.create ~width:30 boxes in
822822+ pack ~fill:`X [ b_add; b_del; b_up; b_down; b_scan ];
823823+ pack ~side:`Left [ coe f_left; coe f_buttons; coe f_sep; coe f_right ];
824824+ pack [ boxes ];
825825+826826+ let update() =
827827+ let still_available = (* available - objects *)
828828+ List.filter (fun m -> not (List.mem m !!objects)) !!available in
829829+ Listbox.delete lb_left ~first:(`Num 0) ~last:`End;
830830+ Listbox.insert lb_left ~index:`End ~texts:still_available;
831831+ Listbox.delete lb_right ~first:(`Num 0) ~last:`End;
832832+ Listbox.insert lb_right ~index:`End ~texts:!!objects;
833833+ in
834834+835835+ let rescan() =
836836+ !available := scan();
837837+ update()
838838+ in
839839+840840+ let add() =
841841+ if Listbox.curselection lb_left = [] then begin
842842+ let popup = Toplevel.create frame in
843843+ Wm.title_set popup "Add File";
844844+ Wm.transient_set popup ~master:(Winfo.toplevel frame);
845845+ add_headline popup "Add File";
846846+ add_para popup "Enter the name of the module to add. Note that you can also select the modules in the left box and press 'Add' to quickly move the modules to the right box.";
847847+848848+ let modname = ref "" in
849849+ label_box popup [ "Name of new module: ", modname ];
850850+851851+ let p_buttons = Frame.create popup in
852852+ let b_ok = Button.create ~font ~text:"OK"
853853+ ~command:(fun () ->
854854+ if !modname <> "" then
855855+ !objects := !!objects @ [ !modname ];
856856+ update();
857857+ destroy popup) p_buttons in
858858+ let b_cancel = Button.create ~font ~text:"Cancel"
859859+ ~command:(fun () -> destroy popup) p_buttons in
860860+ pack ~side:`Left [b_ok; b_cancel];
861861+862862+ add_para popup "";
863863+864864+ pack [p_buttons];
865865+ end
866866+ else begin
867867+ let items =
868868+ List.map
869869+ (fun index -> Listbox.get lb_left ~index)
870870+ (Listbox.curselection lb_left)
871871+ in
872872+ !objects := !!objects @ items;
873873+ update()
874874+ end
875875+ in
876876+877877+ let del() =
878878+ if Listbox.curselection lb_right = [] then begin
879879+ ignore
880880+ (dialog
881881+ ~parent:!top
882882+ ~title:"Nothing selected"
883883+ ~message:"Please select the modules you want to delete in the right box!"
884884+ ~buttons:[ "OK" ]
885885+ ~default:0
886886+ ())
887887+ end
888888+ else begin
889889+ let items =
890890+ List.map
891891+ (fun index -> Listbox.get lb_right ~index)
892892+ (Listbox.curselection lb_right)
893893+ in
894894+ !objects := List.filter (fun m -> not (List.mem m items)) !!objects;
895895+ update()
896896+ end
897897+ in
898898+899899+ let move_dlg() =
900900+ ignore
901901+ (dialog
902902+ ~parent:!top
903903+ ~title:"Bad Selection"
904904+ ~message:"Please select the (single) module you want to move in the right box!"
905905+ ~buttons:[ "OK" ]
906906+ ~default:0
907907+ ())
908908+ in
909909+910910+ let move g () =
911911+ if List.length (Listbox.curselection lb_right) <> 1 then
912912+ move_dlg()
913913+ else begin
914914+ let index = List.hd (Listbox.curselection lb_right) in
915915+ let `Num n = index in
916916+ let n' = g n in
917917+ if n' >= 0 && n' < List.length !!objects then begin
918918+ let item = Listbox.get lb_right ~index:(index :> Tk.listbox_index) in
919919+ !objects := delete_at n !!objects;
920920+ !objects := insert_at n' item !!objects;
921921+ update();
922922+ Listbox.selection_set lb_right ~first:(`Num n') ~last:(`Num n');
923923+ end
924924+ end
925925+ in
926926+927927+ if !!available = [] then rescan() else update();
928928+ Button.configure ~command:add b_add;
929929+ Button.configure ~command:del b_del;
930930+ Button.configure ~command:(move pred) b_up;
931931+ Button.configure ~command:(move succ) b_down;
932932+ Button.configure ~command:rescan b_scan;
933933+934934+ (* Returns the [update] function *)
935935+ update
936936+;;
937937+938938+939939+let redraw() =
940940+ destroy !topframe;
941941+ let f = Frame.create !top in
942942+ let f1 = Frame.create ~width:5 f in
943943+ let f2 = Frame.create f in
944944+ let f3 = Frame.create ~width:5 f in
945945+ pack ~expand:true ~fill:`Y [f];
946946+ pack ~side:`Left [f1];
947947+ pack ~side:`Left ~fill:`Y [f2];
948948+ pack ~side:`Left [f3];
949949+ let func = List.nth !screens !current_screen in
950950+ topframe := coe f;
951951+ func f2
952952+;;
953953+954954+955955+let footer frame =
956956+ let box = Frame.create frame in
957957+ pack ~side:`Bottom ~fill:`X [box];
958958+ let sep1 = Frame.create ~height:15 box in
959959+ let b = Frame.create ~height:1 ~background:`Black box in
960960+ let sep2 = Frame.create ~height:15 box in
961961+ pack [ sep1 ];
962962+ pack ~fill:`X ~expand:true [b];
963963+ pack [ sep2 ];
964964+965965+ let f = Frame.create box in
966966+ let m1 = Frame.create f in
967967+ pack ~fill:`X ~expand:true ~side:`Left [ m1 ];
968968+ let prev_b =
969969+ Button.create ~font ~text:"Previous" ~state:`Disabled
970970+ ~command:(fun () -> decr current_screen; redraw()) m1 in
971971+ pack ~side:`Left [prev_b];
972972+ if !current_screen > 0 then
973973+ Button.configure ~state:`Normal prev_b;
974974+ let m2 = Frame.create f in
975975+ let k = ref 0 in
976976+ List.iter
977977+ (fun scr ->
978978+ let k' = !k in
979979+ let b =
980980+ Button.create ~font ~text:(string_of_int (!k+1))
981981+ ~command:(fun () -> current_screen := k'; redraw()) m2 in
982982+ if k' = !current_screen then
983983+ Button.configure
984984+ ~background:`Blue ~activebackground:`Blue ~foreground:`White b;
985985+ pack ~side:`Left [b];
986986+ incr k
987987+ )
988988+ !screens;
989989+ pack ~side:`Left [m2];
990990+ let m3 = Frame.create f in
991991+ pack ~fill:`X ~expand:true ~side:`Left [ m3 ];
992992+ let next_b =
993993+ Button.create ~font ~text:"Next" ~state:`Disabled
994994+ ~command:(fun () -> incr current_screen; redraw()) m3 in
995995+ pack ~side:`Right [next_b];
996996+ if !current_screen < List.length !screens - 1 then
997997+ Button.configure ~state:`Normal next_b;
998998+ pack ~fill:`X [ f ]
999999+;;
10001000+10011001+10021002+(**********************************************************************)
10031003+10041004+let first_time = ref true;;
10051005+10061006+let intro_screen frame =
10071007+ add_headline frame "The Makefile and META wizard";
10081008+ add_para frame "This wizard helps you creating Makefiles and META \
10091009+files for simple projects. It assumes that all your source files \
10101010+reside in a single directory, and that all source files are OCaml \
10111011+files (no support for mixed OCaml/C projects). ocamllex, ocamlyacc, \
10121012+and camlp4 are supported.";
10131013+ add_para frame "The wizard generates a Makefile, and the Makefile \
10141014+produces the META file. The Makefile is not perfect, and is not the ideal \
10151015+choice for everybody, but it is a starting point for your project. \
10161016+You can later fine-tune the contents of the Makefile by adding your own rules, \
10171017+and by overriding the definitions. The Makefile is commented, and not \
10181018+overly complicated.";
10191019+ add_para frame "The settings you enter here can be stored in a file \
10201020+containing the state of the wizard. This file is called .make-wizard. \
10211021+It is recommended to use this feature to save the state between the \
10221022+wizard sessions.";
10231023+ (* "" *)
10241024+10251025+ footer frame;
10261026+ update();
10271027+10281028+ if !first_time && Sys.file_exists ".make-wizard" then begin
10291029+ match dialog ~parent:frame ~title:"Load .make-wizard?"
10301030+ ~message:"Do you want to load the file .make-wizard, and continue your last session?"
10311031+ ~buttons:[ "Yes, please load the file"; "No, start with empty fields" ]
10321032+ ~default:0
10331033+ ()
10341034+ with
10351035+ 0 -> load()
10361036+ | _ -> ()
10371037+ end;
10381038+ first_time := false;
10391039+10401040+;;
10411041+10421042+10431043+add_screen intro_screen;;
10441044+10451045+(**********************************************************************)
10461046+10471047+let general_screen frame =
10481048+ add_headline frame "General";
10491049+ add_para frame "Please enter the name of the package, the version number, \
10501050+and the description first. The name must be a single, alphanumeric string \
10511051+(including _ and -). The version is an arbitrary string, like the description. \
10521052+All fields are mandatory."; (* "" *)
10531053+10541054+ label_box frame
10551055+ [ "Package name: ", wiz_package_name;
10561056+ "Package version: ", wiz_package_version;
10571057+ "Package description: ", wiz_package_description ];
10581058+ footer frame
10591059+;;
10601060+10611061+add_screen general_screen;;
10621062+10631063+(**********************************************************************)
10641064+10651065+let pkginfo lb row = (* when the user right-clicks at a listbox row *)
10661066+ let pkg = Listbox.get lb (`Num row) in
10671067+ let version =
10681068+ try Findlib.package_property [] pkg "version" with Not_found -> "N/A" in
10691069+ let description =
10701070+ try Findlib.package_property [] pkg "description" with Not_found -> "N/A"
10711071+ in
10721072+ let popup = Toplevel.create !top in
10731073+ Wm.transient_set popup ~master:(Winfo.toplevel !top);
10741074+ let f = Frame.create popup in
10751075+ let title = "About " ^ pkg ^ " (" ^ version ^ ")" in
10761076+ add_headline f title;
10771077+ Wm.title_set popup title;
10781078+ add_para f ("Description: " ^ description);
10791079+ add_para f "Modules:";
10801080+ let click sublb _ =
10811081+ Listbox.selection_clear sublb ~first:(`Num 0) ~last:`End in
10821082+ let (f_sublb, sublb) = scrolled_listbox ~click f in
10831083+ let modules =
10841084+ try
10851085+ Fl_split.in_words
10861086+ (Findlib.package_property [] pkg "browse_interfaces")
10871087+ with
10881088+ Not_found ->
10891089+ let dir = Findlib.package_directory pkg in
10901090+ let files = Array.to_list(Sys.readdir dir) in
10911091+ List.map
10921092+ (fun name ->
10931093+ String.capitalize (Filename.chop_suffix name ".cmi"))
10941094+ (List.filter
10951095+ (fun name ->
10961096+ Filename.check_suffix name ".cmi")
10971097+ files
10981098+ )
10991099+ in
11001100+ Listbox.insert sublb ~index:`End ~texts:modules;
11011101+ pack ~anchor:`W [ f_sublb ];
11021102+ pack ~anchor:`W [ f ];
11031103+ let close = Button.create ~text:"Close" ~font
11041104+ ~command:(fun () -> destroy popup) f_sublb in
11051105+ pack ~anchor:`Nw ~fill:`X [close]
11061106+;;
11071107+11081108+(**********************************************************************)
11091109+11101110+let preprocessor_scan_extensions() =
11111111+ (* Find out all packages with a "preprocessor" predicate *)
11121112+ let packages = Fl_package_base.list_packages() in
11131113+ let plist =
11141114+ List.filter
11151115+ (fun pkg ->
11161116+ try
11171117+ let _ =
11181118+ Findlib.package_property [ "preprocessor"; "syntax" ] pkg "archive"
11191119+ in true
11201120+ with
11211121+ Not_found -> false
11221122+ )
11231123+ packages in
11241124+ (* Add all selected extensions, if they do not occur yet: *)
11251125+ let plist' =
11261126+ List.filter
11271127+ (fun pkg ->
11281128+ not (List.mem pkg plist)
11291129+ )
11301130+ !wiz_camlp4_selected in
11311131+ List.sort Pervasives.compare (plist @ plist')
11321132+;;
11331133+11341134+11351135+let preprocessor_screen frame =
11361136+ add_headline frame "Preprocessing";
11371137+ add_para frame "Here you can specify whether your source files are \
11381138+preprocessed by camlp4. Simply skip this page if you do not want to \
11391139+invoke a preprocessor, or if you don't know what this means."; (* "" *)
11401140+11411141+ let frame'' = indented_cond_frame frame
11421142+ [ wiz_enable_camlp4, "Enable camlp4" ] in
11431143+11441144+ let tv = string_tv frame'' wiz_camlp4_syntax in
11451145+ let rb_o = Radiobutton.create
11461146+ ~font ~text:"Standard syntax" ~variable:tv ~value:"camlp4o"
11471147+ frame'' in
11481148+ let rb_r = Radiobutton.create
11491149+ ~font ~text:"Revised syntax" ~variable:tv ~value:"camlp4r"
11501150+ frame'' in
11511151+ pack ~anchor:`W [rb_o; rb_r];
11521152+11531153+ add_para frame'' "Use the following packaged syntax extensions (click the \
11541154+right mouse button to find out more about a package):"; (* "" *)
11551155+11561156+ if !wiz_camlp4_extensions = [] then
11571157+ wiz_camlp4_extensions := preprocessor_scan_extensions();
11581158+11591159+ let click lb row = (* when the user clicks at a listbox row *)
11601160+ wiz_camlp4_selected := listbox_get_selection lb;
11611161+ in
11621162+11631163+ let (f_lb,lb) = scrolled_listbox ~click ~context:pkginfo frame'' in
11641164+ Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions;
11651165+ listbox_select lb !wiz_camlp4_selected;
11661166+ pack ~anchor:`W [f_lb];
11671167+11681168+ let rescan = Button.create ~text:"Rescan" ~font
11691169+ ~command:(fun () ->
11701170+ wiz_camlp4_extensions := preprocessor_scan_extensions();
11711171+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
11721172+ Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions;
11731173+ listbox_select lb !wiz_camlp4_selected;
11741174+ )
11751175+ f_lb in
11761176+ let clear = Button.create ~text:"Clear" ~font
11771177+ ~command:(fun () ->
11781178+ wiz_camlp4_selected := [];
11791179+ listbox_select lb [])
11801180+ f_lb in
11811181+11821182+ pack ~anchor:`Nw ~fill:`X [ rescan; clear ];
11831183+11841184+ add_para frame'' "Specify here further options to the camlp4 invocation. \
11851185+For example, you can load camlp4 modules like pa_ifdef.cmo, and pass the -D \
11861186+options to it."; (* "" *)
11871187+11881188+ label_box frame'' [ "Camlp4 options: ", wiz_camlp4_options ];
11891189+11901190+ footer frame
11911191+;;
11921192+11931193+add_screen preprocessor_screen;;
11941194+11951195+(**********************************************************************)
11961196+11971197+let prerequisites_scan_packages() =
11981198+ (* Find out all packages *)
11991199+ List.sort Pervasives.compare (Fl_package_base.list_packages())
12001200+;;
12011201+12021202+12031203+let prerequisites_screen frame =
12041204+ add_headline frame "Prerequisites";
12051205+ add_para frame "If your modules use packages, you can specify these \
12061206+prerequisites here. It is sufficient to select the packages on which \
12071207+your modules depend directly. Indirect dependencies can be resolved \
12081208+by findlib automatically. Click the right mouse button to find out \
12091209+more about a package."; (* "" *)
12101210+12111211+ if !wiz_all_packages = [] then
12121212+ wiz_all_packages := prerequisites_scan_packages();
12131213+12141214+ let click lb row = (* when the user clicks at a listbox row *)
12151215+ wiz_required_packages := listbox_get_selection lb;
12161216+ in
12171217+12181218+ let (f_lb,lb) = scrolled_listbox ~height:18 ~click ~context:pkginfo frame in
12191219+ Listbox.insert lb ~index:`End ~texts:!wiz_all_packages;
12201220+ listbox_select lb !wiz_required_packages;
12211221+ pack ~anchor:`W [f_lb];
12221222+12231223+ let rescan = Button.create ~text:"Rescan" ~font
12241224+ ~command:(fun () ->
12251225+ wiz_all_packages := prerequisites_scan_packages();
12261226+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
12271227+ Listbox.insert lb ~index:`End ~texts:!wiz_all_packages;
12281228+ listbox_select lb !wiz_required_packages;
12291229+ )
12301230+ f_lb in
12311231+ let clear = Button.create ~text:"Clear" ~font
12321232+ ~command:(fun () ->
12331233+ wiz_required_packages := [];
12341234+ listbox_select lb [])
12351235+ f_lb in
12361236+12371237+ pack ~anchor:`Nw ~fill:`X [ rescan; clear ];
12381238+12391239+ footer frame
12401240+;;
12411241+12421242+add_screen prerequisites_screen;;
12431243+12441244+(**********************************************************************)
12451245+12461246+let buildlib_scan_modules() =
12471247+ let files = Array.to_list(Sys.readdir ".") in
12481248+ let suffixes = Fl_split.in_words_ws !wiz_source_suffixes in
12491249+ let files' =
12501250+ List.filter
12511251+ (fun f ->
12521252+ List.exists (Filename.check_suffix f) suffixes
12531253+ )
12541254+ files in
12551255+ let files'' =
12561256+ List.map
12571257+ (fun f ->
12581258+ String.capitalize (Filename.chop_extension f)
12591259+ )
12601260+ files' in
12611261+ remove_dups (List.sort Pervasives.compare files'')
12621262+;;
12631263+12641264+12651265+let buildlib_screen frame =
12661266+ add_headline frame "Build Library";
12671267+ add_para frame "The next question is how to build the library, i.e. the \
12681268+cma or cmxa archive. It is recommended to create such an archive even if \
12691269+the real target of the build process is an executable, because you can load \
12701270+it into the toploop at once. However, make sure that you do not put the \
12711271+main program of the executable into the archive, as it is usually stripped \
12721272+off from the executable, and nothing would happen when you start it.";
12731273+(*
12741274+ add_para frame "You can select whether you want to create only a bytecode \
12751275+archive, a native archive, or both. In the latter case, the simplest way \
12761276+is to begin with the bytecode archive, and to copy your specification to \
12771277+the native box by pressing the button \"Like bytecode\".";
12781278+ add_para frame "If you do not want to create an archive at all, \
12791279+skip this page.";
12801280+*)
12811281+(* "" *)
12821282+12831283+ let frame' = indented_cond_frame frame
12841284+ [ wiz_byte_enable, "Enable bytecode archive";
12851285+ wiz_nat_enable, "Enable native archive"; ] in
12861286+ add_para frame' "Move the available modules to the right-hand box in the required order.";
12871287+12881288+ let update =
12891289+ double_listbox frame' (ref wiz_available) (ref wiz_objects) buildlib_scan_modules in
12901290+12911291+ add_para frame "By default, only the suffixes .ml, .mli, .mll, and .mly are used to recognize source code files. You can add here additional suffixes (this requires that you extend the Makefile by your own rules).";
12921292+12931293+ label_box frame [ "Source code suffixes: ", wiz_source_suffixes ];
12941294+12951295+ footer frame
12961296+;;
12971297+12981298+add_screen buildlib_screen;;
12991299+13001300+(**********************************************************************)
13011301+13021302+let enter_name parent followup =
13031303+ let popup = Toplevel.create parent in
13041304+ let title = "New Executable" in
13051305+ Wm.transient_set popup ~master:(Winfo.toplevel parent);
13061306+ Wm.title_set popup title;
13071307+ let frame = Frame.create popup in
13081308+ pack [frame];
13091309+ add_headline frame title;
13101310+ add_para frame "Of course, the new executable must have a name.";
13111311+ let name = ref "" in
13121312+ label_box frame [ "Name: ", name ];
13131313+ pack [ Frame.create ~height:10 frame ];
13141314+ let buttons = Frame.create frame in
13151315+ let ok_b = Button.create ~font ~text:"OK"
13161316+ ~command:(fun () -> destroy popup; followup !name) buttons in
13171317+ let cancel_b = Button.create ~font ~text:"Cancel"
13181318+ ~command:(fun () -> destroy popup) buttons in
13191319+ pack ~side:`Left [ ok_b; cancel_b ];
13201320+ pack [buttons]
13211321+;;
13221322+13231323+13241324+let buildexec_screen frame =
13251325+ add_headline frame "Build Executables";
13261326+ add_para frame "You can specify the executables to build in the following \
13271327+way. Press \"New\" and enter the name of the executable, then add the modules \
13281328+to link in the box that appears. The cma/cmxa archive from the previous \
13291329+screen is linked anyway, so its modules cannot be selected again.";
13301330+ add_para frame "Leave the list of executables empty if you do not want to \
13311331+build any.";
13321332+ (* "" *)
13331333+13341334+ let update_listbox = ref (fun () -> ()) in
13351335+ let show = ref (fun _ -> ()) in
13361336+ let hide = ref (fun _ -> ()) in
13371337+13381338+ let click lb row =
13391339+ let name = Listbox.get lb ~index:(`Num row) in
13401340+ !show name
13411341+ in
13421342+13431343+ let newexec() =
13441344+ enter_name
13451345+ frame
13461346+ (fun name ->
13471347+ (* This function is called after the user pressed "OK" *)
13481348+ if List.mem name !wiz_executables then begin
13491349+ (* It is not allowed to enter the same name twice *)
13501350+ ignore(
13511351+ dialog ~parent:frame ~title:"Already exists"
13521352+ ~message:"This name already exists!" ~buttons:["OK"] ())
13531353+ end
13541354+ else begin
13551355+ wiz_executables :=
13561356+ List.sort Pervasives.compare (name :: !wiz_executables);
13571357+ wiz_exec_objects := (name, ref []) :: !wiz_exec_objects;
13581358+ wiz_exec_native := (name, ref false) :: !wiz_exec_native;
13591359+ !update_listbox();
13601360+ !show name
13611361+ end
13621362+ )
13631363+ in
13641364+13651365+ let remexec lb () =
13661366+ let sel = listbox_get_selection lb in
13671367+ if sel = [] then begin
13681368+ ignore(
13691369+ dialog ~parent:frame ~title:"Nothing selected"
13701370+ ~message:"Select the executable to remove first!" ~buttons:["OK"] ())
13711371+ end
13721372+ else begin
13731373+ wiz_executables :=
13741374+ List.filter (fun n -> not (List.mem n sel)) !wiz_executables;
13751375+ wiz_exec_objects :=
13761376+ List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_objects;
13771377+ wiz_exec_native :=
13781378+ List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_native;
13791379+ !update_listbox();
13801380+ !hide()
13811381+ end
13821382+ in
13831383+13841384+ let (f_lb,lb) = scrolled_listbox ~click ~height:3 frame in
13851385+ Listbox.configure ~selectmode:`Single lb;
13861386+ Listbox.insert lb ~index:`End ~texts:!wiz_executables;
13871387+ pack ~anchor:`W [f_lb];
13881388+13891389+ let new_b =
13901390+ Button.create ~font ~text:"New" ~command:newexec f_lb in
13911391+ let remove_b =
13921392+ Button.create ~font ~text:"Remove" ~command:(remexec lb) f_lb in
13931393+13941394+ pack ~anchor:`Nw ~fill:`X [ new_b; remove_b ];
13951395+13961396+ let f1 = Frame.create frame in
13971397+ pack [f1];
13981398+ let frame' = Frame.create f1 in
13991399+ let frame'_packed = ref false in
14001400+ let modbox_available = ref (ref []) in
14011401+ let modbox_objects = ref (ref []) in
14021402+ let modbox_scan() =
14031403+ let mlist = buildlib_scan_modules() in
14041404+ List.filter
14051405+ (fun m -> not (List.mem m !wiz_objects)) mlist
14061406+ in
14071407+ add_para frame' "Move the available modules to the right-hand box in the required order.";
14081408+ let update_modbox =
14091409+ double_listbox frame' modbox_available modbox_objects modbox_scan in
14101410+14111411+ add_para frame' "Select the type of the executable:";
14121412+ let radio = Frame.create frame' in
14131413+ let type_ref = ref false in
14141414+ let type_ref_ref = ref type_ref in
14151415+ let type_tv = bool_tv
14161416+ ~onchange:(fun () -> !type_ref_ref := !type_ref)
14171417+ frame' type_ref in
14181418+ let byte_r = Radiobutton.create ~font ~text:"Bytecode executable"
14191419+ ~variable:type_tv ~value:"0" radio in
14201420+ let nat_r = Radiobutton.create ~font ~text:"Native executable"
14211421+ ~variable:type_tv ~value:"1" radio in
14221422+ pack ~side:`Left [byte_r; nat_r ];
14231423+ pack ~anchor:`W [radio];
14241424+ let update_radio() =
14251425+ Textvariable.set type_tv (if !!type_ref_ref then "1" else "0")
14261426+ in
14271427+14281428+ footer frame;
14291429+14301430+ update_listbox := (fun () ->
14311431+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
14321432+ Listbox.insert lb ~index:`End ~texts:!wiz_executables;
14331433+ );
14341434+ show := (fun name ->
14351435+ let k = find_pos name !wiz_executables in
14361436+ Listbox.selection_clear lb ~first:( `Num 0 ) ~last:`End;
14371437+ Listbox.selection_set lb ~first:(`Num k) ~last:(`Num k);
14381438+ if not !frame'_packed then (
14391439+ pack [frame'];
14401440+ frame'_packed := true;
14411441+ );
14421442+ modbox_objects := List.assoc name !wiz_exec_objects;
14431443+ type_ref_ref := List.assoc name !wiz_exec_native;
14441444+ update_modbox();
14451445+ update_radio()
14461446+ );
14471447+ hide := (fun () ->
14481448+ if !frame'_packed then (
14491449+ Pack.forget [frame'];
14501450+ frame'_packed := false;
14511451+ );
14521452+ )
14531453+;;
14541454+14551455+add_screen buildexec_screen;;
14561456+14571457+(**********************************************************************)
14581458+14591459+let generate_screen frame =
14601460+ add_headline frame "Generate Makefile";
14611461+ add_para frame "Finally, the Makefile can be generated from your inputs. \
14621462+You can set the name of the Makefile to a non-standard name. Furthermore, \
14631463+you can specify a second file that will be appended to the generated Makefile, \
14641464+this is useful to extend the Makefile rules by your own additions.";
14651465+ (* "" *)
14661466+14671467+ label_box frame [ "Name of Makefile: ", wiz_makefile_name;
14681468+ "Local extensions in: ", wiz_local_makefile_name ;
14691469+ "Default target of 'make': ", wiz_make_default;
14701470+ ];
14711471+14721472+ add_para frame "";
14731473+14741474+ let show_b =
14751475+ Button.create ~font ~text:"Show Makefile"
14761476+ ~command:(fun () ->
14771477+ let maketext = makemake() in
14781478+ let popup = Toplevel.create frame in
14791479+ Wm.title_set popup "Generated Makefile";
14801480+ add_headline popup "Generated Makefile";
14811481+ let t = Text.create ~width:80 ~height:25 popup in
14821482+ pack [t];
14831483+ Text.insert ~index:(`End,[]) ~text:maketext t;
14841484+ )
14851485+ frame in
14861486+ let save_b =
14871487+ Button.create ~font ~text:"Save Makefile"
14881488+ ~command:(fun () ->
14891489+ let maketext = makemake() in
14901490+ let cont =
14911491+ not (Sys.file_exists !wiz_makefile_name) || (
14921492+ dialog ~parent:frame ~title:"File already exists"
14931493+ ~message:("The file " ^ !wiz_makefile_name ^
14941494+ " already exists. Overwrite?")
14951495+ ~buttons:[ "OK"; "Cancel" ] () = 0) in
14961496+ if cont then begin
14971497+ let f = open_out !wiz_makefile_name in
14981498+ output_string f maketext;
14991499+ close_out f
15001500+ end
15011501+ )
15021502+ frame in
15031503+15041504+ pack [show_b; save_b];
15051505+15061506+ add_headline frame "Quit";
15071507+15081508+ add_para frame "The following button quits the wizard. You are asked whether you want to save the state first.";
15091509+15101510+ let quit_b =
15111511+ Button.create ~font ~text:"Finish & Quit"
15121512+ ~command:(fun () ->
15131513+ if ask_and_save frame then destroy !top)
15141514+ frame in
15151515+15161516+15171517+15181518+ pack [show_b; quit_b];
15191519+15201520+ footer frame
15211521+;;
15221522+15231523+add_screen generate_screen;;
15241524+15251525+15261526+(**********************************************************************)
15271527+15281528+Findlib.init();
15291529+top := openTk();
15301530+(* current_screen := 5; *)
15311531+Wm.title_set !top "findlib/make-wizard";
15321532+Wm.protocol_set !top ~name:"WM_DELETE_WINDOW"
15331533+ ~command:(fun () -> if ask_and_save !top then destroy !top);
15341534+Toplevel.configure ~width:(pixels(`Pt 450.0))
15351535+ ~height:(pixels (`Pt 650.0)) (Winfo.toplevel !top);
15361536+Pack.propagate_set !top false;
15371537+topframe := coe(Frame.create !top);
15381538+redraw();
15391539+mainLoop();;
15401540+15411541+15421542+(* ======================================================================
15431543+ * History:
15441544+ *
15451545+ * $Log: make_wizard.ml,v $
15461546+ * Revision 1.3 2002/09/22 20:12:35 gerd
15471547+ * Renamed modules (prefix fl_)
15481548+ *
15491549+ * Revision 1.2 2002/07/29 19:52:23 gerd
15501550+ * Fixes for OCaml 3.05
15511551+ *
15521552+ * Revision 1.1 2002/05/26 14:09:07 gerd
15531553+ * Renaming
15541554+ *
15551555+ * Revision 1.1 2002/05/05 20:40:26 gerd
15561556+ * Initial revision
15571557+ *
15581558+ *
15591559+ *)
···11+## $Id$
22+## ----------------------------------------------------------------------
33+##
44+55+## This is the pattern for the Makefile. It consists of several sections,
66+## every section begins with [name] on a single line, and ends where the
77+## next section starts. Inside the sections, variables are written as
88+## [name], too.
99+## Comments that must not be copied to the output file begin with two
1010+## hash marks.
1111+1212+[intro]
1313+# ----------------------------------------------------------------------
1414+# How to build the package [name]:
1515+# ----------------------------------------------------------------------
1616+#
1717+# make: Same as "make all"
1818+# make all: Normally "make byte", but can also be set to "make opt"
1919+# make byte: Makes the bytecode archive and the bytecode executables
2020+# make opt: Makes the native archive and the native executable
2121+# make install: Install all installable files as package
2222+# make uninstall: Uninstall the package
2323+# make clean: Delete all files that can be remade
2424+#
2525+# The usual order of invocation is:
2626+# - make byte
2727+# - (optionally) make opt
2828+# - make install
2929+# - make clean
3030+#
3131+# You may want to give the -s option if you do not want to see the details
3232+# of the build process (e.g. make -s all).
3333+#
3434+# ----------------------------------------------------------------------
3535+# Important for developers
3636+# ----------------------------------------------------------------------
3737+#
3838+# This Makefile writes a copy of itself with appended dependencies.
3939+# The copy is usually stored in the file .make-wizard.[makefile_name].
4040+# If you want to invoke "make" for targets where the dependencies are
4141+# involved, you have to specify -f .make-wizard.[makefile_name] on
4242+# the command line, e.g.
4343+#
4444+# make -f .make-wizard.[makefile_name] sample.cmo
4545+#
4646+# Otherwise, the dependencies are ignored, and you get errors that are
4747+# hard to explain.
4848+#
4949+# If you want to modify this Makefile, it is a good idea to put the
5050+# modifications into a second file, and to enable the local Makefile
5151+# extension in the wizard. This effects that the modifications are appended
5252+# to this Makefile, so you can add rules and override variables without
5353+# coming into conflict with the wizard.
5454+5555+[def_general]
5656+# ----------------------------------------------------------------------
5757+# Definitions
5858+# ----------------------------------------------------------------------
5959+6060+NAME = [name]
6161+# The name of the package.
6262+6363+MFNAME = [makefile_name]
6464+# The name of this Makefile. (You must change this definition if you rename
6565+# the Makefile!)
6666+6767+MF2NAME = .make-wizard.$(MFNAME)
6868+# The name of the generated Makefile (a copy of this Makefile plus the
6969+# dependencies)
7070+7171+TEMPNAME = .make-wizard.temps
7272+# The name of a file containing the names of temporary files
7373+7474+VERSION = [version]
7575+# The version of this package
7676+7777+DESCRIPTION = [description]
7878+# The description of this package
7979+8080+GENERATOR_EXTS = .mll .mly
8181+# These suffixes indicate that a generator must be called for them
8282+8383+MAKE_META = _meta
8484+# Make the META file by this rule. (An empty definition turns META generation
8585+# off.)
8686+8787+INSTALL = _findlib_install
8888+# Which rule to use for installation
8989+9090+UNINSTALL = _findlib_uninstall
9191+# Which rule to use for deinstallation
9292+9393+MAKEMAKE_HOOK =
9494+# Set this to the name of a rule to add your own definitions to $(MF2NAME)
9595+9696+9797+## The def_byte_archive section is only included if the byte archive is
9898+## enabled:
9999+100100+[def_byte_archive]
101101+BYTE_ARCHIVE = $(NAME).cma
102102+# The name of the resulting bytecode archive.
103103+104104+BYTE_OBJECTS = [byte_objects]
105105+# The cmo objects that are linked together, and are put into the byte archive.
106106+107107+BYTE_FILES = $(BYTE_OBJECTS) $(BYTE_OBJECTS:.cmo=.cmi) $(BYTE_ARCHIVE)
108108+# The files that are generated in order to make the byte archive. Note
109109+# that .ml and .mli files are missing that are generated from
110110+# .mly and .mll files.
111111+112112+BYTE_INST = $(BYTE_OBJECTS:cmo=cmi) $(BYTE_OBJECTS:.cmo=.mli) $(BYTE_ARCHIVE)
113113+# The files that will be installed after the byte archive is made. Not
114114+# every file exists.
115115+116116+117117+## The def_native_archive section is only included if the native archive is
118118+## enabled:
119119+120120+[def_native_archive]
121121+NAT_ARCHIVE = $(NAME).cmxa
122122+# The name of the resulting native archive.
123123+124124+NAT_OBJECTS = [nat_objects]
125125+# The cmx objects that are linked together, and are put into the native archive.
126126+127127+NAT_FILES = $(NAT_OBJECTS) $(NAT_OBJECTS:.cmx=.o) $(NAT_OBJECTS:.cmo=.cmi) \
128128+ $(NAT_ARCHIVE) $(NAT_ARCHIVE:.cmxa=.a)
129129+# The files that are generated in order to make the native archive. Note
130130+# that .ml and .mli files are missing that are generated from
131131+# .mly and .mll files.
132132+133133+NAT_INST = $(NAT_OBJECTS:.cmo=.cmi) $(NAT_OBJECTS:.cmo=.mli) $(NAT_ARCHIVE) \
134134+ $(NAT_ARCHIVE:.cmxa=.a)
135135+# The files that will be installed after the native archive is made. Not
136136+# every file exists.
137137+138138+139139+[def_byte_exec]
140140+BYTE_EXEC_TARGETS = [byte_executables]
141141+# The list of bytecode executables.
142142+143143+BYTE_EXEC_OBJECTS = [byte_exec_objects]
144144+# The list of cmo modules that are linked into bytecode executables
145145+146146+BYTE_EXEC_FILES = $(BYTE_EXEC_OBJECTS) $(BYTE_EXEC_OBJECTS:.cmo=.cmi) \
147147+ $(BYTE_EXEC_TARGETS)
148148+# The list of files that are generated in order to make the bytecode
149149+# executables. Note that .ml and .mli files are missing that are generated
150150+# from .mly and .mll files.
151151+152152+BYTE_EXEC_INST = $(BYTE_EXEC_TARGETS)
153153+# The files to install as bytecode executables.
154154+155155+156156+[def_nat_exec]
157157+NAT_EXEC_TARGETS = [nat_executables]
158158+# The list of native executables.
159159+160160+NAT_EXEC_OBJECTS = [nat_exec_objects]
161161+# The list of cmx modules that are linked into native executables
162162+163163+NAT_EXEC_FILES = $(NAT_EXEC_OBJECTS) $(NAT_EXEC_OBJECTS:.cmx=.cmi) \
164164+ $(NAT_EXEC_OBJECTS:.cmx=.o) $(NAT_EXEC_TARGETS)
165165+# The list of files that are generated in order to make the native
166166+# executables. Note that .ml and .mli files are missing that are generated
167167+# from .mly and .mll files.
168168+169169+NAT_EXEC_INST = $(NAT_EXEC_TARGETS)
170170+# The files to install as native executables.
171171+172172+173173+[def_props]
174174+PREREQUISITES = [prereqs]
175175+# The required packages.
176176+177177+PPOPTS = [ppopts]
178178+# Preprocessor options.
179179+180180+MTOPTS = [mtopts]
181181+# Multi-threading options
182182+183183+INCOPTS =
184184+# -I options (currently unused, but this may change in the future)
185185+186186+OTHER_INST = META
187187+# Files to install that are not mentioned in the other XXX_INST variables
188188+189189+#TASKBYTELINKOPTS = -custom
190190+# Uncomment this line to create stand-alone executables
191191+192192+[def_tools]
193193+# Tools and tasks: "Tools" are the commands to call, and "tasks" are the tools
194194+# to use for certain situations.
195195+196196+OCAMLFIND = ocamlfind
197197+OCAMLLEX = ocamllex
198198+OCAMLYACC = ocamlyacc
199199+OCAMLDEP = $(OCAMLFIND) ocamldep
200200+OCAMLC = $(OCAMLFIND) ocamlc
201201+OCAMLCP = $(OCAMLFIND) ocamlcp
202202+OCAMLOPT = $(OCAMLFIND) ocamlopt
203203+#
204204+# These are the tools.
205205+206206+TASKLEX = $(OCAMLLEX) $(TASKLEXOPTS)
207207+TASKYACC = $(OCAMLYACC) $(TASKYACCOPTS)
208208+TASKDEP = $(OCAMLDEP) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" $(TASKDEPOPTS)
209209+TASKCI = $(OCAMLC) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" -c $(TASKCIOPTS)
210210+TASKBYTECO = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c -g $(TASKBYTECOOPTS)
211211+TASKBYTELINK = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKBYTELINKOPTS)
212212+TASKBYTEAR = $(OCAMLC) -a $(TASKBYTEAROPTS)
213213+TASKNATCO = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c $(TASKNATCOOPTS)
214214+TASKNATLINK = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKNATLINKOPTS)
215215+TASKNATAR = $(OCAMLOPT) -a $(TASKNATAROPTS)
216216+TASKINSTALL = $(OCAMLFIND) install $(NAME) $(TASKINSTALLOPTS)
217217+TASKREMOVE = $(OCAMLFIND) remove $(NAME) $(TASKREMOVEOPTS)
218218+#
219219+# These are the tasks. The names mean the following:
220220+# TASKLEX: Used to create a lexer
221221+# TASKYACC: Used to create a parser
222222+# TASKDEP: Used to analyze the dependencies
223223+# TASKCI: Used to compile interface files
224224+# TASKBYTECO, TASKNATCO: Used to compile implementation files
225225+# TASKBYTELINK, TASKNATLINK: Used to create executables
226226+# TASKBYTEAR, TASKNATAR: Used to create archives
227227+# TASKINSTALL: Used to install the package
228228+# TASKREMOVE: Used to remove the package
229229+# INCOPTS: -I options
230230+# PPOPTS: Options to specify the preprocessor
231231+# MTOPTS: -thread (if necessary)
232232+# NATONLY: -native (if necessary)
233233+# For every task <T>, there is a variable for task-specific options <T>OPTS.
234234+235235+236236+[rules]
237237+# ----------------------------------------------------------------------
238238+# Rules
239239+# ----------------------------------------------------------------------
240240+241241+242242+[default_target]
243243+.PHONY: all
244244+all: [default_target]
245245+246246+247247+[suffix_rules]
248248+# The suffix rules: They specify how to make a file ending in suffix X from
249249+# a source file ending in suffix Y. For every suffix rule, there is a task
250250+# defining what to do.
251251+252252+.SUFFIXES: .ml .mli .cmo .cmx .cmi .mll .mly
253253+254254+.mli.cmi:
255255+ @echo "<Making $@>"
256256+ $(TASKCI) $<
257257+258258+.ml.cmo:
259259+ @echo "<Making $@>"
260260+ $(TASKBYTECO) $<
261261+262262+.ml.cmx:
263263+ @echo "<Making $@>"
264264+ $(TASKNATCO) $<
265265+266266+# The generator rules record the generated files: The "grep" checks whether
267267+# the filename already occurs in $(TEMPNAME), and the "echo" appends the
268268+# filename when missing.
269269+270270+.mll.ml:
271271+ @echo "<Making $@>"
272272+ $(TASKLEX) $<
273273+ touch $(TEMPNAME)
274274+ grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME)
275275+276276+.mly.ml:
277277+ @echo "<Making $@>"
278278+ $(TASKYACC) $<
279279+ touch $(TEMPNAME)
280280+ grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME)
281281+282282+# The _dummy rule does nothing:
283283+284284+_dummy:
285285+ :
286286+287287+[generate]
288288+# The following rule checks which lex and yacc targets exist, and calls
289289+# MAKE recursively.
290290+291291+.PHONY: _meta
292292+_meta:
293293+ @echo "<Updating META>"
294294+ echo "name = \"$(NAME)\"" >META
295295+ echo "version = \"$(VERSION)\"" >>META
296296+ echo "description = \"$(DESCRIPTION)\"" >>META
297297+ echo "requires = \"$(PREREQUISITES)\"" >>META
298298+ test -z "$(BYTE_ARCHIVE)" || \
299299+ echo "archive(byte) = \"$(BYTE_ARCHIVE)\"" >>META
300300+ test -z "$(NAT_ARCHIVE)" || \
301301+ echo "archive(native) = \"$(NAT_ARCHIVE)\"" >>META
302302+303303+.PHONY: _generator
304304+_generator: $(MAKE_META)
305305+ @echo "<Checking for generator targets>"
306306+ targets=$$( \
307307+ { \
308308+ for obj in _dummy $(BYTE_OBJECTS) $(BYTE_EXEC_OBJECTS); do \
309309+ test "_dummy" != "$$obj" || continue; \
310310+ for ext in $(GENERATOR_EXTS); do \
311311+ if [ -f "$${obj%.cmo}$$ext" ]; then \
312312+ echo "$${obj%.cmo}.ml"; \
313313+ fi; \
314314+ done; \
315315+ done && \
316316+ for obj in _dummy $(NAT_OBJECTS) $(NAT_EXEC_OBJECTS); do \
317317+ test "_dummy" != "$$obj" || continue; \
318318+ for ext in $(GENERATOR_EXTS); do \
319319+ if [ -f "$${obj%.cmx}$$ext" ]; then \
320320+ echo "$${obj%.cmx}.ml"; \
321321+ fi; \
322322+ done; \
323323+ done; \
324324+ } | sort | uniq \
325325+ ) && \
326326+ { test -z "$$targets" || $(MAKE) -f $(MFNAME) $$targets; }
327327+328328+# The following rule calls ocamldep for the right files, and creates
329329+# a file that consists of the contents of this Makefile, and of the output
330330+# of ocamldep.
331331+332332+.PHONY: _makemake
333333+_makemake: _generator
334334+ @echo "<Analyzing dependencies and creating $(MF2NAME)>"
335335+ cat $(MFNAME) >$(MF2NAME)
336336+ test -z "$(MAKEMAKE_HOOK)" || $(MAKE) -f $(MFNAME) $(MAKEMAKE_HOOK)
337337+ echo "# ---------------------------------------- dependencies:" >>$(MF2NAME)
338338+ targets=$$( \
339339+ { \
340340+ nat=-native-filter && \
341341+ byte=-bytecode-filter && \
342342+ for obj in _dummy $(BYTE_OBJECTS); do \
343343+ test "_dummy" != "$$obj" || continue; \
344344+ echo "$${obj%.cmo}.ml"; \
345345+ echo "$${obj%.cmo}.mli"; \
346346+ nat=""; \
347347+ done && \
348348+ for obj in _dummy $(NAT_OBJECTS); do \
349349+ test "_dummy" != "$$obj" || continue; \
350350+ echo "$${obj%.cmx}.ml"; \
351351+ echo "$${obj%.cmx}.mli"; \
352352+ byte=""; \
353353+ done; \
354354+ echo "$$byte $$nat"; \
355355+ } | sort | uniq \
356356+ ) && \
357357+ $(TASKDEP) $$targets >>$(MF2NAME)
358358+## The following section is appended to _makemake for every executable:
359359+[makemake_exec]
360360+ echo "# --- dependencies for [execname]:" >>$(MF2NAME)
361361+ $(TASKDEP) [switches] [deptargets] >>$(MF2NAME)
362362+## Begin next section immediately to avoid empty lines:
363363+[dummy]
364364+365365+[byte]
366366+367367+368368+.PHONY: byte
369369+byte: _byte
370370+371371+.PHONY: _byte
372372+_byte: _makemake
373373+ @echo "<Starting with bytecode targets>"
374374+ if [ -n "$(BYTE_ARCHIVE)" ]; then \
375375+ $(MAKE) -f $(MF2NAME) $(BYTE_ARCHIVE); \
376376+ fi
377377+ if [ -n "$(BYTE_EXEC_TARGETS)" ]; then \
378378+ $(MAKE) -f $(MF2NAME) $(BYTE_EXEC_TARGETS); \
379379+ fi
380380+ @echo "<Done bytecode targets>"
381381+382382+383383+[opt]
384384+.PHONY: opt
385385+opt: _opt
386386+387387+.PHONY: _opt
388388+_opt: _makemake
389389+ @echo "<Starting with native targets>"
390390+ if [ -n "$(NAT_ARCHIVE)" ]; then \
391391+ $(MAKE) -f $(MF2NAME) $(NAT_ARCHIVE); \
392392+ fi
393393+ if [ -n "$(NAT_EXEC_TARGETS)" ]; then \
394394+ $(MAKE) -f $(MF2NAME) $(NAT_EXEC_TARGETS); \
395395+ fi
396396+ @echo "<Done native targets>"
397397+398398+399399+[byte_archive]
400400+$(BYTE_ARCHIVE): $(BYTE_OBJECTS)
401401+ @echo "<Making $(BYTE_ARCHIVE)>"
402402+ $(TASKBYTEAR) -o $(BYTE_ARCHIVE) $(BYTE_OBJECTS)
403403+404404+405405+[native_archive]
406406+$(NAT_ARCHIVE): $(NAT_OBJECTS)
407407+ @echo "<Making $(NAT_ARCHIVE)>"
408408+ $(TASKNATAR) -o $(NAT_ARCHIVE) $(NAT_OBJECTS)
409409+410410+411411+## The following section is included for every bytecode executable again.
412412+413413+[byte_exec]
414414+[execname]: $(BYTE_ARCHIVE) [execobjs]
415415+ @echo "<Making [execname]>"
416416+ $(TASKBYTELINK) -o [execname] $(BYTE_ARCHIVE) [execobjs]
417417+418418+419419+[nat_exec]
420420+[execname]: $(NAT_ARCHIVE) [execobjs]
421421+ @echo "<Making [execname]>"
422422+ $(TASKNATLINK) -o [execname] $(NAT_ARCHIVE) [execobjs]
423423+424424+425425+[clean]
426426+.PHONY: clean
427427+clean:
428428+ @echo "<Cleaning up>"
429429+ touch $(TEMPNAME)
430430+ rm -f $(BYTE_FILES) $(NAT_FILES) $(BYTE_EXEC_FILES) $(NAT_EXEC_FILES)
431431+ rm -f $(MF2NAME)
432432+ cat $(TEMPNAME) | xargs rm -f
433433+ rm -f $(TEMPNAME)
434434+435435+.PHONY: CLEAN
436436+CLEAN: clean
437437+438438+.PHONY: distclean
439439+distclean: clean
440440+441441+442442+[install]
443443+.PHONY: install
444444+install: $(INSTALL)
445445+446446+.PHONY: _findlib_install
447447+_findlib_install:
448448+ @echo "<Installing>"
449449+ files=$$( \
450450+ for f in $(BYTE_INST) $(NAT_INST) $(BYTE_EXEC_INST) $(NAT_EXEC_INST) $(OTHER_INST); do \
451451+ if [ -f "$$f" ]; then echo $$f; fi; \
452452+ done; \
453453+ ) && \
454454+ $(TASKINSTALL) $$files
455455+456456+.PHONY: uninstall
457457+uninstall: $(UNINSTALL)
458458+459459+.PHONY: _findlib_uninstall
460460+_findlib_uninstall:
461461+ @echo "<Uninstalling>"
462462+ $(TASKREMOVE)
463463+464464+# The following rules just print some variables.
465465+466466+.PHONY: _print_name
467467+_print_name:
468468+ echo "$(NAME)"
469469+470470+.PHONY: _print_version
471471+_print_version:
472472+ echo "$(VERSION)"
473473+474474+[local]
475475+# ----------------------------------------------------------------------
476476+# Local additions
477477+# ----------------------------------------------------------------------
478478+479479+[trailer]
480480+## ======================================================================
481481+## History:
482482+##
483483+## $Log: make_wizard.pattern,v $
484484+## Revision 1.2 2003/01/13 00:37:45 gerd
485485+## Bugfix NATIVE_ARCHIVE ==> NAT_ARCHIVE (reported by
486486+## Matt Gushee)
487487+##
488488+## Revision 1.1 2002/05/26 14:09:07 gerd
489489+## Renaming
490490+##
491491+## Revision 1.1 2002/05/05 20:40:26 gerd
492492+## Initial revision
493493+##
494494+##
···11+# make all: compile to bytecode
22+# make opt: compile to native code
33+# make install: install bytecode and/or native code
44+#
55+# See Makefile.config for configurable variables.
66+# Runtime configurations might also be necessary in the site-lib/*/META
77+# files.
88+#----------------------------------------------------------------------
99+1010+TOP=../..
1111+include $(TOP)/Makefile.config
1212+1313+NAME = findlib
1414+1515+# Need compiler-libs since ocaml-4.00
1616+OCAMLC = ocamlc -I +compiler-libs
1717+OCAMLOPT = ocamlopt -I +compiler-libs $(OCAMLOPT_G)
1818+OCAMLOPT_SHARED = $(OCAMLOPT)
1919+OCAMLDEP = ocamldep
2020+OCAMLLEX = ocamllex
2121+#CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_o.cmo --
2222+#CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_dump.cmo --
2323+2424+2525+OBJECTS = fl_compat.cmo fl_split.cmo findlib_config.cmo \
2626+ fl_metatoken.cmo fl_meta.cmo fl_metascanner.cmo fl_topo.cmo \
2727+ fl_package_base.cmo findlib.cmo fl_args.cmo fl_lint.cmo
2828+TOBJECTS = topfind.cmo
2929+3030+XOBJECTS = $(OBJECTS:.cmo=.cmx)
3131+TXOBJECTS = $(TOBJECTS:.cmo=.cmx)
3232+3333+OCAMLFIND_OBJECTS = ocaml_args.cmo frontend.cmo
3434+OCAMLFIND_XOBJECTS = $(OCAMLFIND_OBJECTS:.cmo=.cmx)
3535+3636+# OCAMLFIND_ARCHIVES: set in Makefile.config
3737+OCAMLFIND_XARCHIVES = $(OCAMLFIND_ARCHIVES:.cma=.cmxa)
3838+3939+NUMTOP_OBJECTS = num_top_printers.cmo num_top.cmo
4040+4141+DYNLOAD_OBJECTS = fl_dynload.cmo
4242+DYNLOAD_XOBJECTS = $(DYNLOAD_OBJECTS:.cmo=.cmx)
4343+4444+4545+all: ocamlfind$(EXEC_SUFFIX) findlib.cma findlib_top.cma topfind $(NUMTOP) \
4646+ findlib_dynload.cma
4747+4848+opt: ocamlfind_opt$(EXEC_SUFFIX) findlib.cmxa findlib_top.cmxa topfind \
4949+ findlib_dynload.cmxa
5050+5151+num-top: num_top.cma
5252+5353+ocamlfind$(EXEC_SUFFIX): findlib.cma $(OCAMLFIND_OBJECTS)
5454+ $(OCAMLC) $(CUSTOM) -o ocamlfind$(EXEC_SUFFIX) -g $(OCAMLFIND_ARCHIVES) \
5555+ $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_OBJECTS)
5656+5757+ocamlfind_opt$(EXEC_SUFFIX): findlib.cmxa $(OCAMLFIND_XOBJECTS)
5858+ $(OCAMLOPT) -o ocamlfind_opt$(EXEC_SUFFIX) $(OCAMLFIND_XARCHIVES) \
5959+ $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_XOBJECTS)
6060+6161+test_parser$(EXEC_SUFFIX): fl_metascanner.cmx test_parser.cmx fl_metatoken.cmx fl_meta.cmx
6262+ $(OCAMLOPT) -o test_parser$(EXEC_SUFFIX) fl_meta.cmx fl_metatoken.cmx fl_metascanner.cmx test_parser.cmx
6363+6464+findlib.cma: $(OBJECTS)
6565+ $(OCAMLC) -a -o findlib.cma $(OBJECTS)
6666+6767+findlib_top.cma: $(TOBJECTS)
6868+ $(OCAMLC) -a -o findlib_top.cma $(TOBJECTS)
6969+7070+findlib.cmxa: $(XOBJECTS)
7171+ $(OCAMLOPT) -a -o findlib.cmxa $(XOBJECTS)
7272+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
7373+ $(OCAMLOPT_SHARED) -shared -o findlib.cmxs $(XOBJECTS); \
7474+ fi
7575+7676+findlib_top.cmxa: $(TXOBJECTS)
7777+ $(OCAMLOPT) -a -o findlib_top.cmxa $(TXOBJECTS)
7878+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
7979+ $(OCAMLOPT_SHARED) -shared -o findlib_top.cmxs $(TXOBJECTS); \
8080+ fi
8181+8282+findlib_dynload.cma: $(DYNLOAD_OBJECTS)
8383+ $(OCAMLC) -a -o findlib_dynload.cma $(DYNLOAD_OBJECTS)
8484+8585+findlib_dynload.cmxa: $(DYNLOAD_XOBJECTS)
8686+ $(OCAMLOPT) -a -o findlib_dynload.cmxa $(DYNLOAD_XOBJECTS)
8787+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
8888+ $(OCAMLOPT_SHARED) -shared -o findlib_dynload.cmxs $(DYNLOAD_XOBJECTS); \
8989+ fi
9090+9191+findlib_config.ml: findlib_config.mlp $(TOP)/Makefile.config
9292+ USE_CYGPATH="$(USE_CYGPATH)"; \
9393+ export USE_CYGPATH; \
9494+ cat findlib_config.mlp | \
9595+ $(SH) $(TOP)/tools/patch '@CONFIGFILE@' '$(OCAMLFIND_CONF)' | \
9696+ $(SH) $(TOP)/tools/patch '@STDLIB@' '$(OCAML_CORE_STDLIB)' | \
9797+ $(SH) $(TOP)/tools/patch '@RELATIVE_PATHS@' '$(RELATIVE_PATHS)' | \
9898+ sed -e 's;@AUTOLINK@;$(OCAML_AUTOLINK);g' \
9999+ -e 's;@SYSTEM@;$(SYSTEM);g' \
100100+ >findlib_config.ml
101101+102102+topfind.ml: topfind.ml.in
103103+ if [ "$(ENABLE_TOPFIND_PPXOPT)" = "true" ]; then \
104104+ cp topfind.ml.in topfind.ml; \
105105+ else \
106106+ sed -e '/PPXOPT_BEGIN/,/PPXOPT_END/ d' topfind.ml.in \
107107+ > topfind.ml ; \
108108+ fi
109109+110110+topfind.compat.in: topfind.in
111111+ if [ "$(OCAML_REMOVE_DIRECTORY)" = "1" ]; then \
112112+ cp $< $@; \
113113+ else \
114114+ sed -e '/REMOVE_DIRECTORY_BEGIN/,/REMOVE_DIRECTORY_END/ d' $< \
115115+ > $@ ; \
116116+ fi
117117+118118+topfind: topfind.compat.in
119119+ USE_CYGPATH="$(USE_CYGPATH)"; \
120120+ export USE_CYGPATH; \
121121+ cat topfind.compat.in | \
122122+ $(SH) $(TOP)/tools/patch '@SITELIB@' '$(OCAML_SITELIB)' | \
123123+ $(SH) $(TOP)/tools/patch '@RELATIVE_PATHS@' '$(RELATIVE_PATHS)' \
124124+ >topfind
125125+126126+num_top.cma: $(NUMTOP_OBJECTS)
127127+ $(OCAMLC) -a -o num_top.cma $(NUMTOP_OBJECTS)
128128+129129+clean:
130130+ rm -f *.cmi *.cmo *.cma *.cmx *.a *.lib *.o *.obj *.cmxa \
131131+ fl_meta.ml findlib_config.ml topfind.ml topfind.compat.in topfind \
132132+ ocamlfind$(EXEC_SUFFIX) ocamlfind_opt$(EXEC_SUFFIX)
133133+134134+install: all
135135+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)"
136136+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
137137+ test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)"
138138+ test $(INSTALL_TOPFIND) -eq 0 || $(CP) topfind "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/"
139139+ files=`$(SH) $(TOP)/tools/collect_files $(TOP)/Makefile.config \
140140+ findlib.cmi findlib.mli findlib.cma findlib.cmxa findlib$(LIB_SUFFIX) findlib.cmxs \
141141+ findlib_config.cmi findlib_config.ml topfind.cmi topfind.mli \
142142+ fl_args.cmi fl_lint.cmi fl_meta.cmi fl_split.cmi fl_topo.cmi ocaml_args.cmi \
143143+ fl_package_base.mli fl_package_base.cmi fl_metascanner.mli fl_metascanner.cmi \
144144+ fl_metatoken.cmi findlib_top.cma findlib_top.cmxa findlib_top$(LIB_SUFFIX) findlib_top.cmxs \
145145+ findlib_dynload.cma findlib_dynload.cmxa findlib_dynload$(LIB_SUFFIX) findlib_dynload.cmxs fl_dynload.mli fl_dynload.cmi \
146146+ META` && \
147147+ $(CP) $$files "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/"
148148+ f="ocamlfind$(EXEC_SUFFIX)"; { test -f ocamlfind_opt$(EXEC_SUFFIX) && f="ocamlfind_opt$(EXEC_SUFFIX)"; }; \
149149+ $(INSTALLFILE) $$f "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX)"
150150+ # the following "if" block is only needed for 4.00beta2
151151+ if [ $(OCAML_REMOVE_DIRECTORY) -eq 0 -a -f "$(OCAML_CORE_STDLIB)/compiler-libs/topdirs.cmi" ]; then \
152152+ cd "$(OCAML_CORE_STDLIB)/compiler-libs/"; \
153153+ $(CP) topdirs.cmi toploop.cmi "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/"; \
154154+ fi
155155+156156+install-num-top:
157157+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top"
158158+ $(CP) num_top.cma num_top.cmi num_top_printers.cmi \
159159+ "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top/"
160160+161161+# Note: uninstall-num-top is part of the removal of the META files.
162162+163163+uninstall:
164164+ rm -f $(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/findlib
165165+ rm -rf $(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)
166166+ rm -f $(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX)
167167+168168+169169+depend: *.ml *.mli fl_meta.ml fl_metascanner.ml findlib_config.ml topfind.ml
170170+ $(OCAMLDEP) *.ml *.mli >depend
171171+172172+# Some 'make' implementations require that .SUFFIXES must occur before
173173+# the first suffix rule. (E.g. AIX)
174174+.SUFFIXES: .mll .cmo .cmi .cmx .ml .mli
175175+# .src
176176+177177+.ml.cmx:
178178+ $(OCAMLOPT) $(OPAQUE) $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $<
179179+180180+.ml.cmo:
181181+ $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -g -c $<
182182+183183+.mli.cmi:
184184+ $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $<
185185+186186+#.src.ml:
187187+# $(CAMLP4O) -impl $< -o $@
188188+189189+# Solaris make does not like the suffix rule .mll.ml,
190190+# so I replaced it by its single application:
191191+fl_meta.ml: fl_meta.mll
192192+ $(OCAMLLEX) fl_meta.mll
193193+194194+# Don't remove fl_metascanner.ml:
195195+.PRECIOUS: fl_metascanner.ml
196196+197197+include depend
198198+
+553
vendor/opam/ocamlfind/src/findlib/findlib.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+open Fl_compat
77+88+module StrSet = Set.Make(String)
99+1010+exception No_such_package
1111+ = Fl_package_base.No_such_package
1212+1313+1414+exception Package_loop
1515+ = Fl_package_base.Package_loop
1616+1717+type formal_pred =
1818+ [ `Pred of string
1919+ | `NegPred of string
2020+ ]
2121+2222+let init_called = ref false ;;
2323+2424+let conf_config_file = ref "";;
2525+let conf_default_location = ref "";;
2626+let conf_meta_directory = ref "";;
2727+let conf_search_path = ref [];;
2828+let conf_command = ref [];;
2929+let conf_stdlib = ref "";;
3030+let conf_ldconf = ref "";;
3131+let conf_ignore_dups_in = ref ([] : string list);;
3232+3333+let ocamlc_default = "ocamlc";;
3434+let ocamlopt_default = "ocamlopt";;
3535+let ocamlcp_default = "ocamlcp";;
3636+let ocamloptp_default = "ocamloptp";;
3737+let ocamlmklib_default = "ocamlmklib";;
3838+let ocamlmktop_default = "ocamlmktop";;
3939+let ocamldep_default = "ocamldep";;
4040+let ocamlbrowser_default = "ocamlbrowser";;
4141+let ocamldoc_default = "ocamldoc";;
4242+4343+4444+let init_manually
4545+ ?(ocamlc_command = ocamlc_default)
4646+ ?(ocamlopt_command = ocamlopt_default)
4747+ ?(ocamlcp_command = ocamlcp_default)
4848+ ?(ocamloptp_command = ocamloptp_default)
4949+ ?(ocamlmklib_command = ocamlmklib_default)
5050+ ?(ocamlmktop_command = ocamlmktop_default)
5151+ ?(ocamldep_command = ocamldep_default)
5252+ ?(ocamlbrowser_command = ocamlbrowser_default)
5353+ ?(ocamldoc_command = ocamldoc_default)
5454+ ?ignore_dups_in
5555+ ?(ignore_dups_in_list = [])
5656+ ?(stdlib = Findlib_config.ocaml_stdlib)
5757+ ?(ldconf = Findlib_config.ocaml_ldconf)
5858+ ?config
5959+ ~install_dir
6060+ ~meta_dir
6161+ ~search_path () =
6262+ conf_command := [ `ocamlc, ocamlc_command;
6363+ `ocamlopt, ocamlopt_command;
6464+ `ocamlcp, ocamlcp_command;
6565+ `ocamloptp, ocamloptp_command;
6666+ `ocamlmklib, ocamlmklib_command;
6767+ `ocamlmktop, ocamlmktop_command;
6868+ `ocamldep, ocamldep_command;
6969+ `ocamlbrowser, ocamlbrowser_command;
7070+ `ocamldoc, ocamldoc_command;
7171+ ];
7272+ let config = match config with
7373+ | Some config -> config
7474+ | None -> Lazy.force Findlib_config.config_file
7575+ in
7676+ conf_config_file := config;
7777+ conf_search_path := search_path;
7878+ conf_default_location := install_dir;
7979+ conf_meta_directory := meta_dir;
8080+ conf_stdlib := stdlib;
8181+ conf_ldconf := ldconf;
8282+ conf_ignore_dups_in :=
8383+ ( match ignore_dups_in with
8484+ | None -> []
8585+ | Some d -> [d]
8686+ ) @ ignore_dups_in_list;
8787+ Fl_package_base.init !conf_search_path stdlib !conf_ignore_dups_in;
8888+ init_called := true
8989+;;
9090+9191+9292+let command_names cmd_spec =
9393+ try
9494+ let cmd_list = Fl_split.in_words cmd_spec in
9595+ List.map
9696+ (fun cmd_setting ->
9797+ try
9898+ (* cmd_setting: formal_name=actual_name *)
9999+ let l = String.length cmd_setting in
100100+ let n = String.index cmd_setting '=' in
101101+ let cmd_formal_name = String.sub cmd_setting 0 n in
102102+ let cmd_actual_name = String.sub cmd_setting (n+1) (l-n-1) in
103103+ cmd_formal_name, cmd_actual_name
104104+ with
105105+ Not_found ->
106106+ prerr_endline ("Warning: Please check the environment variable OCAMLFIND_COMMANDS");
107107+ "", ""
108108+ )
109109+ cmd_list
110110+ with
111111+ Not_found ->
112112+ []
113113+;;
114114+115115+let auto_config_file() =
116116+ let p =
117117+ ( try Sys.getenv "OCAMLFIND_CONF" with Not_found -> "") in
118118+ if p = "" then Lazy.force Findlib_config.config_file else p
119119+120120+let path_to_relocate path =
121121+ let prefix = "$PREFIX" in
122122+ let len = String.length prefix in
123123+ match String.starts_with ~prefix path with
124124+ | false -> None
125125+ | true -> Some (String.sub path len (String.length path - len))
126126+127127+let relocate_paths paths =
128128+ let paths =
129129+ String.split_on_char Fl_split.path_separator paths
130130+ |> List.filter_map (fun path ->
131131+ match path_to_relocate path with
132132+ | None -> Some path
133133+ | Some path -> (
134134+ match Lazy.force Findlib_config.location with
135135+ | Some install_location ->
136136+ Some (Filename.concat install_location path)
137137+ | None -> None))
138138+ in
139139+ let sep = String.make 1 Fl_split.path_separator in
140140+ String.concat sep paths
141141+;;
142142+143143+let init
144144+ ?env_ocamlpath ?env_ocamlfind_destdir ?env_ocamlfind_metadir
145145+ ?env_ocamlfind_commands ?env_ocamlfind_ignore_dups_in
146146+ ?env_ocamlfind_ignore_dups_in_list ?env_camllib ?env_ldconf
147147+ ?config ?toolchain () =
148148+149149+ let config_file =
150150+ match config with
151151+ Some f -> f
152152+ | None -> auto_config_file()
153153+ in
154154+155155+ let configd_file =
156156+ config_file ^ ".d" in
157157+158158+ let vars_of_file f =
159159+ let ch = open_in f in
160160+ try
161161+ let vars =
162162+ (Fl_metascanner.parse ch).Fl_metascanner.pkg_defs in
163163+ close_in ch;
164164+ vars
165165+ with
166166+ | error -> close_in ch; raise error in
167167+168168+ let vars_of_dir d =
169169+ let files = Array.to_list (Sys.readdir d) in
170170+ List.flatten
171171+ (List.map
172172+ (fun file ->
173173+ if Filename.check_suffix file ".conf" then
174174+ vars_of_file (Filename.concat d file)
175175+ else
176176+ []
177177+ )
178178+ files)
179179+ in
180180+181181+ let config_preds =
182182+ match toolchain with
183183+ | None -> (try [Sys.getenv "OCAMLFIND_TOOLCHAIN"] with Not_found -> [])
184184+ | Some p -> [p] in
185185+186186+ let sys_ocamlc, sys_ocamlopt, sys_ocamlcp, sys_ocamloptp, sys_ocamlmklib,
187187+ sys_ocamlmktop, sys_ocamldep, sys_ocamlbrowser, sys_ocamldoc,
188188+ sys_search_path, sys_destdir, sys_metadir, sys_stdlib, sys_ldconf =
189189+ (
190190+ let config_vars =
191191+ if config_file <> "" &&
192192+ not(Sys.file_exists config_file) && not(Sys.file_exists configd_file)
193193+ then
194194+ failwith("Config file not found - neither " ^
195195+ config_file ^ " nor the directory " ^
196196+ configd_file);
197197+ if Sys.file_exists config_file then
198198+ vars_of_file config_file
199199+ else
200200+ [] in
201201+ let configd_vars =
202202+ if Sys.file_exists configd_file then
203203+ vars_of_dir configd_file
204204+ else
205205+ [] in
206206+ let vars = config_vars @ configd_vars in
207207+ if vars <> [] then (
208208+ let found = ref false in
209209+ let lookup name default =
210210+ let explicit_preds =
211211+ List.for_all
212212+ (fun p -> Fl_metascanner.predicate_exists p vars)
213213+ config_preds in
214214+ found := !found || explicit_preds;
215215+ try
216216+ Fl_metascanner.lookup name config_preds vars
217217+ |> relocate_paths
218218+ with Not_found -> default
219219+ in
220220+ let config_tuple =
221221+ ( (lookup "ocamlc" ocamlc_default),
222222+ (lookup "ocamlopt" ocamlopt_default),
223223+ (lookup "ocamlcp" ocamlcp_default),
224224+ (lookup "ocamloptp" ocamloptp_default),
225225+ (lookup "ocamlmklib" ocamlmklib_default),
226226+ (lookup "ocamlmktop" ocamlmktop_default),
227227+ (lookup "ocamldep" ocamldep_default),
228228+ (lookup "ocamlbrowser" ocamlbrowser_default),
229229+ (lookup "ocamldoc" ocamldoc_default),
230230+ Fl_split.path (lookup "path" ""),
231231+ (lookup "destdir" ""),
232232+ (lookup "metadir" "none"),
233233+ (lookup "stdlib" Findlib_config.ocaml_stdlib),
234234+ (lookup "ldconf" Findlib_config.ocaml_ldconf)
235235+ ) in
236236+ if not !found && config_preds <> [] then
237237+ prerr_endline("ocamlfind: [WARNING] Undefined toolchain: " ^
238238+ String.concat "" config_preds);
239239+ config_tuple
240240+ )
241241+ else
242242+ ( ocamlc_default, ocamlopt_default, ocamlcp_default, ocamloptp_default,
243243+ ocamlmklib_default,
244244+ ocamlmktop_default, ocamldep_default, ocamlbrowser_default,
245245+ ocamldoc_default,
246246+ [],
247247+ "",
248248+ "none",
249249+ Findlib_config.ocaml_stdlib,
250250+ Findlib_config.ocaml_ldconf
251251+ )
252252+ )
253253+ in
254254+255255+ let env_commands =
256256+ match env_ocamlfind_commands with
257257+ Some x -> command_names x
258258+ | None -> command_names (try Sys.getenv "OCAMLFIND_COMMANDS"
259259+ with Not_found -> "")
260260+ in
261261+ let env_destdir =
262262+ match env_ocamlfind_destdir with
263263+ Some x -> x
264264+ | None ->
265265+ try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> ""
266266+ in
267267+ let env_metadir =
268268+ match env_ocamlfind_metadir with
269269+ Some x -> x
270270+ | None ->
271271+ try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> ""
272272+ in
273273+ let env_search_path =
274274+ Fl_split.path
275275+ (match env_ocamlpath with
276276+ Some x -> x
277277+ | None ->
278278+ try Sys.getenv "OCAMLPATH" with Not_found -> ""
279279+ )
280280+ in
281281+ let env_stdlib =
282282+ match env_camllib with
283283+ Some x -> x
284284+ | None ->
285285+ ( try Sys.getenv "OCAMLLIB"
286286+ with
287287+ Not_found ->
288288+ (try Sys.getenv "CAMLLIB" with Not_found -> "" )
289289+ )
290290+ in
291291+ let env_ldconf =
292292+ match env_ldconf with
293293+ Some x -> x
294294+ | None ->
295295+ try Sys.getenv "OCAMLFIND_LDCONF" with Not_found -> ""
296296+ in
297297+ let ignore_dups_in_list =
298298+ match env_ocamlfind_ignore_dups_in, env_ocamlfind_ignore_dups_in_list with
299299+ | Some x0, Some l -> x0 :: l
300300+ | None, Some l -> l
301301+ | Some x0, None -> [x0]
302302+ | None, None ->
303303+ try Fl_split.path (Sys.getenv "OCAMLFIND_IGNORE_DUPS_IN")
304304+ with Not_found -> [] in
305305+306306+ let ocamlc, ocamlopt, ocamlcp, ocamloptp, ocamlmklib, ocamlmktop,
307307+ ocamldep, ocamlbrowser, ocamldoc,
308308+ search_path, destdir, metadir, stdlib, ldconf =
309309+ (try List.assoc "ocamlc" env_commands with Not_found -> sys_ocamlc),
310310+ (try List.assoc "ocamlopt" env_commands with Not_found -> sys_ocamlopt),
311311+ (try List.assoc "ocamlcp" env_commands with Not_found -> sys_ocamlcp),
312312+ (try List.assoc "ocamloptp" env_commands with Not_found -> sys_ocamloptp),
313313+ (try List.assoc "ocamlmklib" env_commands with Not_found -> sys_ocamlmklib),
314314+ (try List.assoc "ocamlmktop" env_commands with Not_found -> sys_ocamlmktop),
315315+ (try List.assoc "ocamldep" env_commands with Not_found -> sys_ocamldep),
316316+ (try List.assoc "ocamlbrowser" env_commands with Not_found -> sys_ocamlbrowser),
317317+ (try List.assoc "ocamldoc" env_commands with Not_found -> sys_ocamldoc),
318318+ (env_search_path @ sys_search_path),
319319+ (if env_destdir = "" then sys_destdir else env_destdir),
320320+ (if env_metadir = "" then sys_metadir else env_metadir),
321321+ (if env_stdlib = "" then sys_stdlib else env_stdlib),
322322+ (if env_ldconf = "" then sys_ldconf else env_ldconf)
323323+ in
324324+325325+ init_manually
326326+ ~ocamlc_command: ocamlc
327327+ ~ocamlopt_command: ocamlopt
328328+ ~ocamlcp_command: ocamlcp
329329+ ~ocamloptp_command: ocamloptp
330330+ ~ocamlmklib_command: ocamlmklib
331331+ ~ocamlmktop_command: ocamlmktop
332332+ ~ocamldep_command: ocamldep
333333+ ~ocamlbrowser_command: ocamlbrowser
334334+ ~ocamldoc_command: ocamldoc
335335+ ~ignore_dups_in_list
336336+ ~stdlib: stdlib
337337+ ~ldconf: ldconf
338338+ ~config: config_file
339339+ ~install_dir: destdir
340340+ ~meta_dir: metadir
341341+ ~search_path: search_path
342342+ ()
343343+;;
344344+345345+346346+let lazy_init() =
347347+ if not !init_called then init()
348348+349349+let config_file() =
350350+ lazy_init();
351351+ !conf_config_file;;
352352+353353+354354+let default_location() =
355355+ lazy_init();
356356+ !conf_default_location;;
357357+358358+359359+let meta_directory() =
360360+ lazy_init();
361361+ if !conf_meta_directory = "none" then "" else !conf_meta_directory;;
362362+363363+364364+let search_path() =
365365+ lazy_init();
366366+ !conf_search_path;;
367367+368368+369369+let command which =
370370+ lazy_init();
371371+ try
372372+ List.assoc which !conf_command
373373+ with
374374+ Not_found -> assert false
375375+;;
376376+377377+378378+let ocaml_stdlib() =
379379+ lazy_init();
380380+ !conf_stdlib;;
381381+382382+383383+let ocaml_ldconf() =
384384+ lazy_init();
385385+ !conf_ldconf;;
386386+387387+let ignore_dups_in() =
388388+ lazy_init();
389389+ !conf_ignore_dups_in;;
390390+391391+let package_directory pkg =
392392+ lazy_init();
393393+ (Fl_package_base.query pkg).Fl_package_base.package_dir
394394+;;
395395+396396+397397+let package_meta_file pkg =
398398+ lazy_init();
399399+ (Fl_package_base.query pkg).Fl_package_base.package_meta
400400+;;
401401+402402+403403+let package_property_2 predlist pkg propname =
404404+ lazy_init();
405405+ let l = Fl_package_base.query pkg in
406406+ Fl_metascanner.lookup_2 propname predlist l.Fl_package_base.package_defs
407407+;;
408408+409409+410410+let package_property predlist pkg propname =
411411+ lazy_init();
412412+ let l = Fl_package_base.query pkg in
413413+ Fl_metascanner.lookup propname predlist l.Fl_package_base.package_defs
414414+;;
415415+416416+417417+let package_ancestors preds pkg =
418418+ lazy_init();
419419+ Fl_package_base.requires ~preds pkg
420420+;;
421421+422422+423423+let package_deep_ancestors preds pkglist =
424424+ lazy_init();
425425+ Fl_package_base.requires_deeply ~preds pkglist
426426+;;
427427+428428+429429+let resolve_path ?base ?(explicit=false) p =
430430+ lazy_init();
431431+ if p = "" then "" else (
432432+ match p.[0] with
433433+ '^' | '+' ->
434434+ let stdlibdir = Fl_split.norm_dir (ocaml_stdlib()) in
435435+ Filename.concat
436436+ stdlibdir
437437+ (String.sub p 1 (String.length p - 1))
438438+ | '@' ->
439439+ (* Search slash *)
440440+ ( try
441441+ let k = String.index p '/' in (* or Not_found *)
442442+ let pkg = String.sub p 1 (k-1) in
443443+ let p' = String.sub p (k+1) (String.length p - k - 1) in
444444+ let pkgdir = package_directory pkg in
445445+ Filename.concat pkgdir p'
446446+ with
447447+ Not_found ->
448448+ let pkg = String.sub p 1 (String.length p - 1) in
449449+ package_directory pkg
450450+ )
451451+ | _ ->
452452+ ( match base with
453453+ None -> p
454454+ | Some b ->
455455+ if Filename.is_relative p &&
456456+ (not explicit || not (Filename.is_implicit p))
457457+ then
458458+ Filename.concat b p
459459+ else
460460+ p
461461+ )
462462+ )
463463+;;
464464+465465+466466+let list_packages ?(tab = 20) ?(descr = false) ch =
467467+ lazy_init();
468468+ let packages = Fl_package_base.list_packages() in
469469+ let packages_sorted = List.sort compare packages in
470470+471471+ List.iter
472472+ (fun p ->
473473+ let v_string =
474474+ try
475475+ let v = package_property [] p "version" in
476476+ "(version: " ^ v ^ ")"
477477+ with
478478+ Not_found -> "(version: n/a)"
479479+ in
480480+ let descr_string =
481481+ try package_property [] p "description"
482482+ with Not_found -> "(no description)" in
483483+ let spaces1 = String.make (max 1 (tab-String.length p)) ' ' in
484484+ let spaces2 = String.make tab ' ' in
485485+486486+ if descr then (
487487+ output_string ch (p ^ spaces1 ^ descr_string ^ "\n");
488488+ output_string ch (spaces2 ^ v_string ^ "\n")
489489+ )
490490+ else
491491+ output_string ch (p ^ spaces1 ^ v_string ^ "\n");
492492+ )
493493+ packages_sorted
494494+;;
495495+496496+let list_packages' ?prefix () =
497497+ lazy_init();
498498+ Fl_package_base.list_packages ?prefix ()
499499+500500+501501+type rectype =
502502+ | Record_core
503503+ | Record_load
504504+505505+let rec_core = ref StrSet.empty
506506+let rec_load = ref StrSet.empty
507507+let rec_preds = ref []
508508+509509+let record_package (rt:rectype) (p:string) =
510510+ match rt with
511511+ | Record_core ->
512512+ rec_core := StrSet.add p !rec_core
513513+ | Record_load ->
514514+ rec_load := StrSet.add p !rec_load
515515+516516+let recorded_packages rt =
517517+ match rt with
518518+ | Record_core ->
519519+ StrSet.elements !rec_core
520520+ | Record_load ->
521521+ StrSet.elements (StrSet.diff !rec_load !rec_core)
522522+523523+let reset_recordings() =
524524+ rec_load := StrSet.empty
525525+526526+let type_of_recorded_package p =
527527+ if StrSet.mem p !rec_core then
528528+ Record_core
529529+ else
530530+ if StrSet.mem p !rec_load then
531531+ Record_load
532532+ else
533533+ raise Not_found
534534+535535+let is_recorded_package p =
536536+ try ignore(type_of_recorded_package p); true with Not_found -> false
537537+538538+539539+let rm_preds =
540540+ [ "create_toploop"; "toploop"; "executable"; "plugin"; "autolink";
541541+ "preprocessor"; "syntax" ]
542542+543543+let rm_preds_set =
544544+ List.fold_right StrSet.add rm_preds StrSet.empty
545545+546546+let record_package_predicates preds =
547547+ let preds' =
548548+ List.filter (fun p -> not(StrSet.mem p rm_preds_set)) preds in
549549+ rec_preds := preds'
550550+551551+let recorded_predicates() =
552552+ !rec_preds
553553+
+276
vendor/opam/ocamlfind/src/findlib/findlib.mli
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(** The primary findlib interface
77+ *
88+ * The Findlib module is the primary interface of the findlib library. It
99+ * contains functions to look up packages, to interpret META
1010+ * files, and to determine the ancestors of packages.
1111+ *
1212+ * This module must be initialized before it can be used: Call either
1313+ * [init] or [init_manually] for this.
1414+ *)
1515+1616+exception No_such_package of string * string
1717+ (** First arg is the package name not found, second arg contains additional
1818+ * info for the user
1919+ *)
2020+2121+exception Package_loop of string
2222+ (** A package is required by itself. The arg is the name of the
2323+ * package
2424+ *)
2525+2626+2727+type formal_pred =
2828+ [ `Pred of string (** Positive occurrence of a formal predicate var *)
2929+ | `NegPred of string (** Negative occurrence of a formal predicate var *)
3030+ ]
3131+ (** A formal predicate as it occurs in a package definition *)
3232+3333+val init :
3434+ ?env_ocamlpath: string ->
3535+ ?env_ocamlfind_destdir: string ->
3636+ ?env_ocamlfind_metadir: string ->
3737+ ?env_ocamlfind_commands: string ->
3838+ ?env_ocamlfind_ignore_dups_in: string ->
3939+ ?env_ocamlfind_ignore_dups_in_list: string list ->
4040+ ?env_camllib: string ->
4141+ ?env_ldconf: string ->
4242+ ?config: string ->
4343+ ?toolchain: string ->
4444+ unit ->
4545+ unit
4646+ (** Initializes the library from the configuration file and the environment.
4747+ * By default the
4848+ * function reads the file specified at compile time, but you can also
4949+ * pass a different file name in the [config] argument.
5050+ * Furthermore, the environment variables OCAMLPATH, OCAMLFIND_DESTDIR,
5151+ * OCAMLFIND_COMMANDS, OCAMLFIND_IGNORE_DUPS_IN, and CAMLLIB are interpreted.
5252+ * By default, the function takes
5353+ * the values found in the environment, but you can pass different values
5454+ * using the [env_*] arguments. By setting these values to empty strings
5555+ * they are no longer considered.
5656+ * The result of the initialization is determined as follows:
5757+ * - The default installation directory is the env variable OCAMLFIND_DESTDIR
5858+ * (if present and non-empty), and otherwise the variable [destdir] of the
5959+ * configuration file.
6060+ * - The installation directory for META files is read from the env
6161+ * variable OCAMLFIND_METADIR (if present and non-empty), and otherwise
6262+ * from the variable [metadir] of the configuration file, and otherwise
6363+ * no such directory is used.
6464+ * The special value ["none"] turns this feature off.
6565+ * - The search path is the concatenation of the env variable OCAMLPATH
6666+ * and the variable [path] of the config file
6767+ * - The executables of (ocamlc|ocamlopt|ocamlcp|ocamlmklib|ocamlmktop) are
6868+ * determined as follows: if the env variable OCAMLFIND_COMMANDS is set
6969+ * and non-empty, its contents specify the executables. Otherwise, if the
7070+ * config file variables [ocamlc], [ocamlopt], [ocamlcp], [ocamlmklib] and
7171+ * [ocamlmktop] are set, their contents specify the executables. Otherwise,
7272+ * the obvious default values are chosen: ["ocamlc"] for [ocamlc],
7373+ * ["ocamlopt"] for [ocamlopt], and so on.
7474+ * - The directory of the standard library is the value of the environment
7575+ * variable CAMLLIB (or OCAMLLIB), or if unset or empty, the value of
7676+ * the configuration variable [stdlib], or if unset the built-in location
7777+ * - The [ld.conf] file (configuring the dynamic loader) is the value of
7878+ * the environment variable OCAMLFIND_LDCONF, or if unset or empty, the
7979+ * value of the configuration variable [ldconf], or if unset the
8080+ * built-in location.
8181+ * - The ocamlfind tool doesn't emit warnings about double cmi files
8282+ * for the directories listed in OCAMLFIND_IGNORE_DUPS_IN. Since
8383+ * findlib-1.8 this variable is interpreted as colon-separated path.
8484+ * (Before, only one directory could be given.) If the variable is not
8585+ * set there are no exceptions, and the warnings are always printed.
8686+ * Note that both the parameters [env_ocamlfind_ignore_dups_in] (a
8787+ * single directory) and [env_ocamlfind_ignore_dups_in_list] (a list
8888+ * of directories) override the default.
8989+ *)
9090+9191+9292+val init_manually :
9393+ ?ocamlc_command: string -> (* default: "ocamlc" *)
9494+ ?ocamlopt_command: string -> (* default: "ocamlopt" *)
9595+ ?ocamlcp_command: string -> (* default: "ocamlcp" *)
9696+ ?ocamloptp_command: string -> (* default: "ocamloptp" *)
9797+ ?ocamlmklib_command: string -> (* default: "ocamlmklib" *)
9898+ ?ocamlmktop_command: string -> (* default: "ocamlmktop" *)
9999+ ?ocamldep_command: string -> (* default: "ocamldep" *)
100100+ ?ocamlbrowser_command: string -> (* default: "ocamlbrowser" *)
101101+ ?ocamldoc_command: string -> (* default: "ocamldoc" *)
102102+ ?ignore_dups_in:string -> (* default: None *)
103103+ ?ignore_dups_in_list:string list -> (* default: [] *)
104104+ ?stdlib: string -> (* default: taken from Findlib_config *)
105105+ ?ldconf: string ->
106106+ ?config: string ->
107107+ install_dir: string ->
108108+ meta_dir: string ->
109109+ search_path: string list ->
110110+ unit ->
111111+ unit
112112+ (** This is an alternate way to initialize the library directly.
113113+ * Environment variables and configuration files are ignored. The
114114+ * parameter [config] just sets the file name reported by the
115115+ * [config_file] function below.
116116+ *)
117117+118118+119119+val config_file : unit -> string
120120+ (** The location of the configuration file *)
121121+122122+val default_location : unit -> string
123123+ (** Get the default installation directory for packages *)
124124+125125+val meta_directory : unit -> string
126126+ (** Get the META installation directory for packages.
127127+ * Returns [""] if no such directory is configured.
128128+ *)
129129+130130+val search_path : unit -> string list
131131+ (** Get the search path for packages *)
132132+133133+val command : [ `ocamlc | `ocamlopt | `ocamlcp | `ocamloptp | `ocamlmklib
134134+ | `ocamlmktop | `ocamldep | `ocamlbrowser | `ocamldoc
135135+ ] ->
136136+ string
137137+ (** Get the name/path of the executable *)
138138+139139+val ocaml_stdlib : unit -> string
140140+ (** Get the directory of the standard library *)
141141+142142+val ocaml_ldconf : unit -> string
143143+ (** Get the file name of [ld.conf] *)
144144+145145+val package_directory : string -> string
146146+ (** Get the absolute path of the directory where the given package is
147147+ * stored.
148148+ *
149149+ * Raises [No_such_package] if the package cannot be found.
150150+ *)
151151+152152+val package_meta_file : string -> string
153153+ (** Get the absolute path of the META file of the given package *)
154154+155155+val ignore_dups_in : unit -> string list
156156+ (** If [Some d], duplicate packages below [d] are ignored, and do not
157157+ * produce warnings. (Only affects the generation of warnings.)
158158+ *
159159+ * Since findlib-1.8 this configuration is a list. Before, it was a
160160+ * [string option].
161161+ *)
162162+163163+val package_property : string list -> string -> string -> string
164164+ (** [package_property predlist pkg propname]:
165165+ * Looks up the property [propname] of package [pkg] under the assumption
166166+ * that the predicates in [predlist] are true.
167167+ *
168168+ * Raises [No_such_package] if the package, and [Not_found] if the property
169169+ * cannot be found.
170170+ *
171171+ * EXAMPLES:
172172+ * - [package_property [] "p" "requires":]
173173+ * get the value of the [requires] clause of package [p]
174174+ * - [package_property [ "mt"; "byte" ] "p" "archive":]
175175+ * get the value of the [archive] property of package [p] for multi-
176176+ * threaded bytecode applications.
177177+ *)
178178+179179+val package_property_2 : string list -> string -> string ->
180180+ string * formal_pred list
181181+ (** [package_property_2 predlist pkg propname]: This returns two values
182182+ [(v, preds)]. The first one, [v], is computed as in [package_property].
183183+ The other list, [preds], contains the predicates that actually had to
184184+ be set or not set in order to select the particular variable definition.
185185+ *)
186186+187187+188188+val package_ancestors : string list -> string -> string list
189189+ (** [package_ancestors predlist pkg:]
190190+ * Determines the direct ancestors of package [pkg] under the assumption
191191+ * that the predicates in [predlist] are true, i.e. the names of the
192192+ * packages required by [pkg].
193193+ * The returned list is unsorted.
194194+ *
195195+ * Raises [No_such_package] if the package [pkg] or one of its ancestors
196196+ * could not be found.
197197+ *)
198198+199199+val package_deep_ancestors : string list -> string list -> string list
200200+ (** [package_deep_ancestors predlist pkglist:]
201201+ * determines the list of direct or indirect ancestors of the packages
202202+ * named in [pkglist] under the assumption that the predicates in [predlist]
203203+ * are true.
204204+ *
205205+ * The returned list is topologically sorted: The first element is the
206206+ * deepest ancestor; the last element is one of [pkglist].
207207+ *
208208+ * Raises [No_such_package] if one of the packages in [pkglist] or one of
209209+ * the ancestors cannot be found. Raises [Package_loop] if there is a
210210+ * cyclic dependency.
211211+ *)
212212+213213+val resolve_path : ?base:string -> ?explicit:bool -> string -> string
214214+ (** Resolves findlib notation in filename paths. The notation
215215+ * [ +name/path ] can be used to refer to the subdirectory [name]
216216+ * of the standard library directory; the continuation [ /path ] is
217217+ * optional. The notation [ \@name/path ] can be used to refer to
218218+ * the directory of the package [name]; the continuation [ /path ]
219219+ * is optional. For these two notations, absolute paths are returned.
220220+ *
221221+ * @param base When the function is applied on a relative path, the
222222+ * [base] path is prepended. Otherwise, the path is returned as
223223+ * it is.
224224+ * @param explicit Changes the meaning of [base] so that only paths
225225+ * count as relative that include at least one slash.
226226+ *)
227227+228228+val list_packages : ?tab:int -> ?descr:bool -> out_channel -> unit
229229+ (** Prints the list of available packages to the [out_channel].
230230+ *
231231+ * @param tab The tabulator width, by default 20
232232+ * @param descr Whether package descriptions are printed. Default: false
233233+ *)
234234+235235+val list_packages' : ?prefix:string -> unit -> string list
236236+ (** Returns the (unsorted) list of all packages.
237237+ *
238238+ * @param prefix Limit to the packages that starts with it. Default: unlimited
239239+ *)
240240+241241+(** Managing dynamically loaded packages *)
242242+243243+(** This is a registry of packages that are available in-core. This is both
244244+ used for toploops and for plugins.
245245+ *)
246246+247247+type rectype =
248248+ | Record_core (** The package is part of the executable core *)
249249+ | Record_load (** The package has been dynamically loaded *)
250250+251251+val record_package : rectype -> string -> unit
252252+ (** Record this package *)
253253+254254+val record_package_predicates : string list -> unit
255255+ (** Record the predicates to be used for package loading. Certain predicates
256256+ are automatically filtered out if inappropriate. A call of
257257+ [record_package_predicates] replaces the set of predicates that was
258258+ installed beforehand.
259259+ *)
260260+261261+val recorded_packages : rectype -> string list
262262+ (** The list of packages recorded with [record_package] *)
263263+264264+val is_recorded_package : string -> bool
265265+ (** Whether there is a recording for this package *)
266266+267267+val type_of_recorded_package : string -> rectype
268268+ (** Returns the type, or raises [Not_found] *)
269269+270270+val recorded_predicates : unit -> string list
271271+ (** The most recent version of the recorded predicate list *)
272272+273273+val reset_recordings : unit -> unit
274274+ (** Removes all [Record_load] packages from the list of recordings.
275275+ This forces that the packages are loaded again.
276276+ *)
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+open Fl_compat
66+77+let ( / ) = Filename.concat
88+99+let exists path =
1010+ match Sys.file_exists path with
1111+ | true -> Some path
1212+ | false -> None
1313+1414+let findlib_conf_of_path path =
1515+ match exists (path / "etc" / "findlib.conf") with
1616+ | Some etc_path -> etc_path
1717+ | None -> path / "lib" / "findlib.conf"
1818+1919+let install_dir_from_binary path =
2020+ let exe_dir = Filename.dirname path in
2121+ let install_dir = Filename.dirname exe_dir in
2222+ let config_path = findlib_conf_of_path install_dir in
2323+ match Sys.file_exists config_path with
2424+ | true -> Some install_dir
2525+ | false -> None
2626+;;
2727+2828+let find_in_path name =
2929+ match Sys.getenv_opt "PATH" with
3030+ | None -> None
3131+ | Some search_in -> (
3232+ let paths = String.split_on_char Fl_split.path_separator search_in in
3333+ match List.find_map (fun path -> path / name |> exists) paths with
3434+ | None -> None
3535+ | Some location -> install_dir_from_binary location)
3636+;;
3737+3838+let install_dir_from_ld_library_path paths =
3939+ String.split_on_char Fl_split.path_separator paths
4040+ |> List.find_map (fun path ->
4141+ let parent = Filename.dirname path in
4242+ let parent' = Filename.dirname parent in
4343+ match Sys.file_exists (findlib_conf_of_path parent') with
4444+ | true -> Some parent'
4545+ | false -> None)
4646+;;
4747+4848+let install_dir_from_ocaml_toplevel_path = install_dir_from_binary
4949+5050+let install_dir_from_opam_switch_prefix path =
5151+ match Sys.file_exists (findlib_conf_of_path path) with
5252+ | false -> None
5353+ | true -> Some path
5454+5555+let default = "@CONFIGFILE@"
5656+let fallback = Option.value ~default
5757+5858+let rec try_vars = function
5959+ | [] -> None
6060+ | (var, mapper)::xs -> (
6161+ match Sys.getenv_opt var with
6262+ | None -> try_vars xs
6363+ | Some content -> (
6464+ match mapper content with
6565+ | None -> try_vars xs
6666+ | Some _ as found -> found))
6767+6868+(* exposed condfigure-time setting *)
6969+let uses_relative_paths = @RELATIVE_PATHS@
7070+7171+(* the location where we assume to be installed in *)
7272+let location = lazy (
7373+ try_vars [
7474+ ("OPAM_SWITCH_PREFIX", install_dir_from_opam_switch_prefix);
7575+ ("CAML_LD_LIBRARY_PATH", install_dir_from_ld_library_path);
7676+ ("OCAML_TOPLEVEL_PATH", install_dir_from_ocaml_toplevel_path);
7777+ ])
7878+7979+let findlib_conf = lazy (
8080+ match Lazy.force location with
8181+ | None -> default
8282+ | Some location -> location
8383+ |> findlib_conf_of_path
8484+ |> exists
8585+ |> fallback)
8686+8787+let config_file = lazy (
8888+ match uses_relative_paths with
8989+ | false -> default
9090+ | true -> Lazy.force findlib_conf)
9191+9292+let ocaml_has_meta_files =
9393+ let ocaml_major =
9494+ String.sub Sys.ocaml_version 0 (String.index Sys.ocaml_version '.') in
9595+ int_of_string ocaml_major >= 5;;
9696+9797+let ocaml_stdlib = "@STDLIB@";;
9898+9999+let ocaml_ldconf = ocaml_stdlib / "ld.conf";;
100100+101101+let ocaml_has_autolinking = @AUTOLINK@;;
102102+103103+let libexec_name = "stublibs";;
104104+105105+let system = "@SYSTEM@";;
106106+(* - "mingw", "mingw64", "win32", "cygwin", "linux_elf", ... *)
107107+108108+let dll_suffix =
109109+ match Sys.os_type with
110110+ | "Unix" | "BeOS" -> ".so"
111111+ | "Win32" | "Cygwin" -> ".dll"
112112+ | "MacOS" -> "" (* don't know *)
113113+ | _ -> failwith "Unknown Sys.os_type"
114114+;;
+104
vendor/opam/ocamlfind/src/findlib/fl_args.ml
···11+(* $Id$ *)
22+33+(* Rewrite a list of arguments args (from Sys.args) so that contracted
44+ options like -L<arg> are transformed to -L <arg>, and become parseable
55+ by Arg.
66+ *)
77+88+let make_ht (l:string list) =
99+ let ht = Hashtbl.create 10 in
1010+ List.iter (fun x -> Hashtbl.add ht x ()) l;
1111+ ht
1212+1313+let is_prefix s1 s2 =
1414+ let l1 = String.length s1 in
1515+ let l2 = String.length s2 in
1616+ l2 >= l1 && String.sub s2 0 l1 = s1
1717+1818+let rewrite_contracted_args spec contracted_opts args =
1919+ let args = Array.to_list args in
2020+ let switches =
2121+ List.map
2222+ (fun (name,kind,text) -> name)
2323+ (List.filter
2424+ (fun (name,kind,text) ->
2525+ match kind with
2626+ | Arg.Unit _
2727+ | Arg.Set _
2828+ | Arg.Clear _ -> true
2929+ | Arg.Tuple _ ->
3030+ failwith
3131+ "Fl_args.rewrite_for_contracted_args: Arg.Tuple unsupported"
3232+ | _ -> false
3333+ )
3434+ spec
3535+ ) in
3636+ let unary_opts =
3737+ List.map
3838+ (fun (name,kind,text) -> name)
3939+ (List.filter
4040+ (fun (name,kind,text) ->
4141+ match kind with
4242+ | Arg.String _
4343+ | Arg.Set_string _
4444+ | Arg.Int _
4545+ | Arg.Set_int _
4646+ | Arg.Float _
4747+ | Arg.Set_float _ -> true
4848+ | _ -> false
4949+ )
5050+ spec
5151+ ) in
5252+ let rest_opts =
5353+ List.map
5454+ (fun (name,kind,text) -> name)
5555+ (List.filter
5656+ (fun (name,kind,text) ->
5757+ match kind with
5858+ | Arg.Rest _ -> true
5959+ | _ -> false
6060+ )
6161+ spec
6262+ ) in
6363+6464+ let sw_ht = make_ht switches in
6565+ let unary_ht = make_ht unary_opts in
6666+ let rest_ht = make_ht rest_opts in
6767+6868+ let rec rewrite (args:string list) =
6969+ match args with
7070+ | arg :: args_rest when Hashtbl.mem sw_ht arg ->
7171+ arg :: rewrite args_rest
7272+ | arg :: args_rest when Hashtbl.mem rest_ht arg ->
7373+ args
7474+ | arg1 :: arg2 :: args_rest when Hashtbl.mem unary_ht arg1 ->
7575+ arg1 :: arg2 :: rewrite args_rest
7676+ | arg :: args_rest ->
7777+ ( try
7878+ let args1 = expand arg contracted_opts in
7979+ let args2 = rewrite args_rest in
8080+ args1 @ args2
8181+ with
8282+ | Not_found ->
8383+ arg :: rewrite args_rest
8484+ )
8585+ | [] ->
8686+ []
8787+8888+ and expand arg olo =
8989+ match olo with
9090+ | olo1 :: olo_rest ->
9191+ if is_prefix olo1 arg then
9292+ let p = String.length olo1 in
9393+ let l = String.length arg in
9494+ [ olo1;
9595+ String.sub arg p (l-p)
9696+ ]
9797+ else
9898+ expand arg olo_rest
9999+ | [] ->
100100+ raise Not_found
101101+102102+ in
103103+104104+ Array.of_list (rewrite args)
+59
vendor/opam/ocamlfind/src/findlib/fl_compat.ml
···11+let ( |> ) x f = f x
22+33+module String = struct
44+ let split_on_char sep s =
55+ let r = ref [] in
66+ let j = ref (String.length s) in
77+ for i = String.length s - 1 downto 0 do
88+ if String.unsafe_get s i = sep then begin
99+ r := String.sub s (i + 1) (!j - i - 1) :: !r;
1010+ j := i
1111+ end
1212+ done;
1313+ String.sub s 0 !j :: !r
1414+1515+ let starts_with ~prefix s =
1616+ let len_s = String.length s
1717+ and len_pre = String.length prefix in
1818+ let rec aux i =
1919+ if i = len_pre then true
2020+ else if String.unsafe_get s i <> String.unsafe_get prefix i then false
2121+ else aux (i + 1)
2222+ in len_s >= len_pre && aux 0
2323+2424+ include String
2525+end
2626+2727+module List = struct
2828+ let rec find_map f = function
2929+ | [] -> None
3030+ | x :: l ->
3131+ begin match f x with
3232+ | Some _ as result -> result
3333+ | None -> find_map f l
3434+ end
3535+3636+ let rec filter_map f = function
3737+ | [] -> []
3838+ | x :: l -> (
3939+ match f x with
4040+ | None -> filter_map f l
4141+ | Some v -> v :: filter_map f l)
4242+4343+ include List
4444+end
4545+4646+module Option = struct
4747+ let value o ~default = match o with Some v -> v | None -> default
4848+4949+ (* can't include Option because it was only introduced in 4.08 *)
5050+ (* include Option *)
5151+end
5252+5353+module Sys = struct
5454+ let getenv_opt s =
5555+ try Some (Sys.getenv s)
5656+ with Not_found -> None
5757+5858+ include Sys
5959+end
+55
vendor/opam/ocamlfind/src/findlib/fl_dynload.ml
···11+(* $Id$ *)
22+33+(* Utilities for loading dynamically packages *)
44+55+open Printf
66+77+let load_pkg ~debug ~loadfile pkg =
88+ if not (Findlib.is_recorded_package pkg) then (
99+ if debug then
1010+ eprintf "[DEBUG] Fl_dynload: about to load: %s\n%!" pkg;
1111+ (* Determine the package directory: *)
1212+ let d = Findlib.package_directory pkg in
1313+ (* First try the new "plugin" variable: *)
1414+ let preds = Findlib.recorded_predicates() in
1515+ let archive =
1616+ try
1717+ Findlib.package_property preds pkg "plugin"
1818+ with
1919+ | Not_found ->
2020+ (* Legacy: use "archive" but require that the predicate
2121+ "plugin" is mentioned in the definition
2222+ *)
2323+ try
2424+ let v, fpreds =
2525+ Findlib.package_property_2 ("plugin"::preds) pkg "archive" in
2626+ let need_plugin =
2727+ List.mem "native" preds in
2828+ if need_plugin && not (List.mem (`Pred "plugin") fpreds) then
2929+ ""
3030+ else
3131+ v
3232+ with Not_found -> "" in
3333+ (* Split the plugin/archive property and resolve the files: *)
3434+ let files = Fl_split.in_words archive in
3535+ if debug then
3636+ eprintf "[DEBUG] Fl_dynload: files=%S\n%!" archive;
3737+ List.iter
3838+ (fun file ->
3939+ if debug then
4040+ eprintf "[DEBUG] Fl_dynload: loading %S\n%!" file;
4141+ let file = Findlib.resolve_path ~base:d file in
4242+ loadfile file
4343+ ) files;
4444+ Findlib.record_package Findlib.Record_load pkg
4545+ )
4646+ else
4747+ if debug then
4848+ eprintf "[DEBUG] Fl_dynload: not loading: %s\n%!" pkg
4949+5050+5151+let load_packages ?(debug=false) ?(loadfile=Dynlink.loadfile) pkgs =
5252+ let preds = Findlib.recorded_predicates() in
5353+ let eff_pkglist =
5454+ Findlib.package_deep_ancestors preds pkgs in
5555+ List.iter (load_pkg ~debug ~loadfile) eff_pkglist
+37
vendor/opam/ocamlfind/src/findlib/fl_dynload.mli
···11+(* $Id$ *)
22+33+(** Utilities for loading dynamically packages *)
44+55+val load_packages : ?debug:bool -> ?loadfile:(string -> unit) -> string list -> unit
66+(** Load the given packages and all their dependencies dynamically. Packages
77+ already loaded or already in-core are not loaded again. The predicates
88+ are taken from {!Findlib.recorded_predicates}, which are normally the
99+ predicates from the link-time of the executable.
1010+1111+ In order to initialize this module correctly, you need to link the
1212+ executable in a special way. This is done by including "findlib.dynload"
1313+ in the [ocamlfind] command, e.g.
1414+1515+ {[ ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg m.ml ]}
1616+1717+ It is not sufficient to just link [findlib_dynload.cm(x)a] into the
1818+ executable. The above command adds special initialization code that
1919+ (a) records the predicates and (b) records the packages already present
2020+ in the executable. Also [-linkall] is implicitly added.
2121+2222+ The dynamic package loader works both for bytecode and native code.
2323+ The META files of the packages need to specify the cma or cmxs files
2424+ in the following way:
2525+2626+ - First, the "plugin" variable is checked (instead of "archive"), e.g.
2727+ {[
2828+plugin(byte) = "my_plugin.cma"
2929+plugin(native) = "my_plugin.cmxs"
3030+ ]}
3131+ This is the preferred style.
3232+ - Second, for bytecode only, the normal "archive" variable is
3333+ also accepted if "plugin" is not present. (Because bytecode archives
3434+ can normally be dynamically loaded without special preparation.)
3535+ - Third, for native-code only, the "archive(plugin)" variable
3636+ is also accepted. This is for legacy packages.
3737+ *)
+113
vendor/opam/ocamlfind/src/findlib/fl_lint.ml
···11+(* $Id$ -*- tuareg -*-
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+open Fl_metascanner
77+88+module Have = struct
99+ module T = struct
1010+ type mode = [`Byte | `Native | `Toploop | `Preprocessor | `Ppx_driver]
1111+ type t = [
1212+ `Mode of [ `TooMany | `None]
1313+ (** problem in the number of mode (byte,native,syntax,...)
1414+ in the variable *)
1515+ | `Archive of [`Plugin|`NoPlugin] * mode
1616+ (** archive(plugin,...) or archive(...)) *)
1717+ | `Plugin of [`Plugin|`NoPlugin] * mode
1818+ (** plugin(...) *)
1919+ | `Description
2020+ | `Requires
2121+ | `Version
2222+ ]
2323+ let compare = compare
2424+ end
2525+ include T
2626+ module Set = Set.Make(T)
2727+ module Map = Map.Make(T)
2828+end
2929+3030+let scan_def acc def =
3131+ let add have = Have.Map.add have def acc in
3232+ let has_plugin_pred = List.mem (`Pred "plugin") def.def_preds in
3333+ let plugin = if has_plugin_pred then `Plugin else `NoPlugin in
3434+ let modes = [ "byte", `Byte;
3535+ "native", `Native;
3636+ "toploop", `Toploop;
3737+ "preprocessor", `Preprocessor;
3838+ "ppx_driver", `Ppx_driver
3939+ ] in
4040+ let modes =
4141+ List.filter
4242+ (fun (p,_) -> List.mem (`Pred p) def.def_preds)
4343+ modes
4444+ in
4545+ let modes = List.map snd modes in
4646+ match def.def_var, modes with
4747+ (** For archive the modes are used in multiple ways, so we can't
4848+ check exhaustiveness or presence.
4949+ *)
5050+ | "plugin", [] -> add (`Mode(`None))
5151+ | "plugin", _::_::_ -> add (`Mode(`TooMany))
5252+5353+ | "archive", [mode] -> add (`Archive(plugin,mode))
5454+ | "plugin", [mode] -> add (`Plugin(plugin,mode))
5555+ | "description", _ -> add `Description
5656+ | "requires", _ -> add `Requires
5757+ | "version", _ -> add `Version
5858+ | _ -> acc
5959+6060+6161+let warn_def ~warned pkg =
6262+ let haves =
6363+ List.fold_left scan_def Have.Map.empty pkg.pkg_defs
6464+ in
6565+ let mem x = Have.Map.mem x haves in
6666+ let find x = Have.Map.find x haves in
6767+ let warning fmt = warned := true; Printf.printf fmt in
6868+ let if_ ?has ?(has_not=[]) msg =
6969+ match has, has_not with
7070+ | Some has, [] when mem has ->
7171+ warning "%a%s\n\n" print_def (find has) msg;
7272+ | Some has, has_not when mem has && not (List.exists mem has_not) ->
7373+ warning "%a%s\n\n" print_def (find has) msg;
7474+ | None, has_not when not (List.exists mem has_not) ->
7575+ warning "%s\n\n" msg;
7676+ | _ -> ()
7777+ in
7878+ if_ ~has_not:[`Description]
7979+ "You should add a description.";
8080+ if_ ~has_not:[`Version]
8181+ "You should add a version.";
8282+ if_ ~has_not:[`Requires]
8383+ "You should add the required libraries. You can silent this \
8484+ warning by using the empty string.";
8585+ if_ ~has:(`Mode(`TooMany))
8686+ "This variable should have only one mode
8787+ (\"byte\", \"native\").";
8888+ if_ ~has:(`Mode(`None))
8989+ "This variable should have at least the predicate \
9090+ \"byte\" or \"native\".";
9191+ let with_mode mode =
9292+ if_ ~has:(`Plugin (`Plugin,mode))
9393+ "You must not add the predicate \"plugin\" to the variable \
9494+ \"plugin\".";
9595+ if_ ~has:(`Archive (`Plugin,mode)) ~has_not:[`Plugin (`NoPlugin,mode)]
9696+ "This specification of dynamic loading is deprecated, you should add a \
9797+ \"plugin(...)\" variable.";
9898+ if_ ~has:(`Archive (`NoPlugin,mode))
9999+ ~has_not:[`Plugin (`NoPlugin,mode);`Archive (`Plugin,mode)]
100100+ "This variable indicates how to link statically, you should add a \
101101+ \"plugin(...)\" variable for linking dynamically.";
102102+ in
103103+ with_mode `Byte;
104104+ with_mode `Native
105105+106106+let warn pkg =
107107+ let warned = ref false in
108108+ let rec aux pkg =
109109+ warn_def ~warned pkg;
110110+ List.iter (fun (_,pkg) -> aux pkg) pkg.pkg_children;
111111+ in
112112+ aux pkg;
113113+ !warned
+90
vendor/opam/ocamlfind/src/findlib/fl_meta.mll
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+{ open Fl_metatoken }
77+88+rule token =
99+ parse [ 'A'-'Z' 'a'-'z' '_' '0'-'9' '.' ]+
1010+ {
1111+ Name (Lexing.lexeme lexbuf)
1212+ }
1313+1414+ | '('
1515+ {
1616+ LParen
1717+ }
1818+1919+ | ')'
2020+ {
2121+ RParen
2222+ }
2323+2424+ | "+="
2525+ {
2626+ PlusEqual
2727+ }
2828+2929+ | '='
3030+ {
3131+ Equal
3232+ }
3333+3434+ | '-'
3535+ {
3636+ Minus
3737+ }
3838+3939+ | ','
4040+ {
4141+ Comma
4242+ }
4343+4444+ | '"' [^ '"' '\\' ]* ( ( "\\\\" | "\\\"" ) [^ '"' '\\' ]* )* '"'
4545+ {
4646+ let s1 = Lexing.lexeme lexbuf in
4747+ let s2 = String.sub s1 1 (String.length s1 - 2) in
4848+ let l2 = String.length s2 in
4949+ let b = Buffer.create 80 in
5050+ let rec fill i =
5151+ if i<l2 then
5252+ match s2.[i] with
5353+ | '\\' -> Buffer.add_char b s2.[i+1]; fill (i+2)
5454+ | c -> Buffer.add_char b c; fill (i+1) in
5555+ fill 0;
5656+ String (Buffer.contents b)
5757+ }
5858+5959+ | [ ' ' '\t' '\r' ]
6060+ {
6161+ Space
6262+ }
6363+6464+ | '\n'
6565+ {
6666+ Newline
6767+ }
6868+6969+ | '#' [^ '\n']* '\n'
7070+ {
7171+ Newline
7272+ }
7373+7474+ | '#' [^ '\n']* eof
7575+ {
7676+ Eof
7777+ }
7878+7979+ | eof
8080+ {
8181+ Eof
8282+ }
8383+8484+ | _
8585+ {
8686+ Unknown
8787+ }
8888+8989+{}
9090+
···11+(* $Id$ -*- tuareg -*-
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+open Fl_metatoken
66+77+open Printf
88+99+type formal_pred = [ | `Pred of string | `NegPred of string ]
1010+1111+type flavour = [ | `BaseDef | `Appendix ]
1212+1313+type pkg_definition =
1414+ { def_var : string; def_flav : flavour; def_preds : formal_pred list;
1515+ def_value : string
1616+ }
1717+1818+type pkg_expr =
1919+ { pkg_defs : pkg_definition list; pkg_children : (string * pkg_expr) list
2020+ }
2121+2222+exception Error of string
2323+2424+let string_of_preds pl =
2525+ let print = function | `Pred n -> n | `NegPred n -> "-" ^ n
2626+ in
2727+ if pl = []
2828+ then ""
2929+ else "(" ^ ((String.concat "," (List.map print pl)) ^ ")")
3030+3131+3232+let scan_lexing buf =
3333+ (* transform an in_channel to a token stream; 'Space' tokens are left
3434+ * out.
3535+ *)
3636+ let (line_ref, pos0_ref, eof_found) = ((ref 1), (ref 0), (ref false))
3737+ in
3838+ fun () ->
3939+ let rec next line pos0 =
4040+ let t = Fl_meta.token buf
4141+ in
4242+ match t with
4343+ | Space -> next line pos0
4444+ | Newline -> next (line + 1) (Lexing.lexeme_end buf)
4545+ | Eof -> (eof_found := true; produce line pos0 Eof)
4646+ | _ -> produce line pos0 t
4747+ and produce line pos0 t =
4848+ (line_ref := line;
4949+ pos0_ref := pos0;
5050+ let pos = (Lexing.lexeme_start buf) - pos0 in (line, pos, t))
5151+ in
5252+ if !eof_found
5353+ then produce !line_ref !pos0_ref Eof
5454+ else next !line_ref !pos0_ref
5555+5656+let scan ch = scan_lexing (Lexing.from_channel ch)
5757+5858+let parse_lexing lexbuf =
5959+ let rec mk_set l =
6060+ match l with
6161+ | x :: l' -> if List.mem x l' then mk_set l' else x :: (mk_set l')
6262+ | [] -> [] in
6363+ let error_msg msg line col =
6464+ Printf.sprintf "%s at line %d position %d" msg line col in
6565+ let next_token = scan_lexing lexbuf in
6666+ let raise_err error_fun line col =
6767+ raise (Error (error_fun line col)) in
6868+ let get_tok test error_fun =
6969+ let (line, col, tok) = next_token ()
7070+ in
7171+ match test tok with
7272+ | None -> raise_err error_fun line col
7373+ | Some result -> result in
7474+ let get_rule rule arg error_fmt line col =
7575+ try rule arg with | Error _ -> raise_err error_fmt line col in
7676+ let rec parse_all need_rparen =
7777+ match next_token () with
7878+ | (line, col, Name "package") ->
7979+ let n =
8080+ get_tok string_tok
8181+ (error_msg "String literal expected after 'package'") in
8282+ let () =
8383+ get_tok (const_tok LParen) (error_msg "'(' expected after string") in
8484+ let subpkg =
8585+ get_rule parse_all true
8686+ (error_msg "Error in subpackage definition") line col in
8787+ let rest = parse_all need_rparen
8888+ in
8989+ {
9090+ pkg_defs = rest.pkg_defs;
9191+ pkg_children = (n, subpkg) :: rest.pkg_children;
9292+ }
9393+ | (line, col, Name n) ->
9494+ let (args, flav, value) =
9595+ get_rule parse_properties ()
9696+ (error_msg "Error in 'name = value' clause") line col in
9797+ let rest = parse_all need_rparen in (* TODO: Check args *)
9898+ let args' = List.sort compare (mk_set args) in
9999+ let def =
100100+ {
101101+ def_var = n;
102102+ def_flav = flav;
103103+ def_preds = args';
104104+ def_value = value;
105105+ }
106106+ in
107107+ {
108108+ pkg_defs = def :: rest.pkg_defs;
109109+ pkg_children = rest.pkg_children;
110110+ }
111111+ | (line, col, Eof) ->
112112+ (if need_rparen
113113+ then
114114+ raise_err
115115+ (Printf.sprintf "Unexpected end of file in line %d position %d")
116116+ line col
117117+ else ();
118118+ { pkg_defs = []; pkg_children = []; })
119119+ | (line, col, RParen) ->
120120+ (if not need_rparen
121121+ then
122122+ raise_err
123123+ (Printf.sprintf "Unexpected end of file in line %d position %d")
124124+ line col
125125+ else ();
126126+ { pkg_defs = []; pkg_children = []; })
127127+ | (line, col, _) ->
128128+ raise_err (error_msg "Expected 'name = value' clause") line col
129129+ and parse_properties () =
130130+ match next_token () with
131131+ | (line, col, LParen) ->
132132+ let arg1 = parse_argument () in
133133+ let args = parse_arguments () in
134134+ let flav = parse_flavour () in
135135+ let s =
136136+ get_tok string_tok (error_msg "Expected string constant after '='")
137137+ in ((arg1 :: args), flav, s)
138138+ | (line, col, Equal) ->
139139+ let s =
140140+ get_tok string_tok
141141+ (error_msg "'=' must be followed by a string constant")
142142+ in ([], `BaseDef, s)
143143+ | (line, col, PlusEqual) ->
144144+ let s =
145145+ get_tok string_tok
146146+ (error_msg "'+=' must be followed by a string constant")
147147+ in ([], `Appendix, s)
148148+ | (line, col, _) ->
149149+ raise_err (error_msg "Expected a '=' or a '(arguments,...)=' clause")
150150+ line col
151151+ and parse_arguments () =
152152+ match next_token () with
153153+ | (line, col, Comma) ->
154154+ let arg = parse_argument () in
155155+ let args = parse_arguments () in arg :: args
156156+ | (_, _, RParen) -> []
157157+ | (line, col, _) ->
158158+ raise_err (error_msg "Another predicate or a ')' expected") line col
159159+ and parse_argument () =
160160+ match next_token () with
161161+ | (line, col, Name n) -> `Pred n
162162+ | (line, col, Minus) ->
163163+ let n = get_tok name_tok (error_msg "Name expected after '-'")
164164+ in `NegPred n
165165+ | (line, col, _) ->
166166+ raise_err (error_msg "Name or -Name expected") line col
167167+ and parse_flavour () =
168168+ match next_token () with
169169+ | (line, col, Equal) -> `BaseDef
170170+ | (line, col, PlusEqual) -> `Appendix
171171+ | (line, col, _) -> raise_err (error_msg "'+' or '+=' expected") line col in
172172+ let rec check_defs p l =
173173+ match l with
174174+ | [] -> ()
175175+ | def :: l' ->
176176+ (List.iter
177177+ (fun def' ->
178178+ if
179179+ (def.def_var = def'.def_var) &&
180180+ ((def.def_preds = def'.def_preds) &&
181181+ ((def.def_flav = `BaseDef) && (def'.def_flav = `BaseDef)))
182182+ then
183183+ (let prefix =
184184+ if p = "" then "" else "In subpackage " ^ (p ^ ": ") in
185185+ let args = string_of_preds def.def_preds
186186+ in
187187+ raise
188188+ (Error
189189+ (prefix ^
190190+ ("Double definition of '" ^
191191+ (def.def_var ^ (args ^ "'"))))))
192192+ else ())
193193+ l';
194194+ check_defs p l') in
195195+ let rec check_pkg p pkg =
196196+ (check_defs p pkg.pkg_defs;
197197+ let l = ref []
198198+ in
199199+ List.iter
200200+ (fun (n, subpkg) ->
201201+ let p' = if p = "" then n else p ^ ("." ^ n)
202202+ in
203203+ (if List.mem n !l
204204+ then
205205+ raise
206206+ (Error ("Double definition for subpackage " ^ p'))
207207+ else ();
208208+ if String.contains n '.'
209209+ then
210210+ raise
211211+ (Error
212212+ ("Subpackage name must not contain '.': \"" ^
213213+ (n ^ "\"")))
214214+ else ();
215215+ check_pkg p' subpkg;
216216+ l := n :: !l))
217217+ pkg.pkg_children)
218218+ in
219219+ try let pkg = parse_all false in (check_pkg "" pkg; pkg)
220220+ with | Error "" -> raise (Error "Syntax Error")
221221+222222+let parse ch = parse_lexing (Lexing.from_channel ch)
223223+224224+let escape s = (* no Str available :-( *)
225225+ let b = Buffer.create (String.length s)
226226+ in
227227+ (for k = 0 to (String.length s) - 1 do
228228+ (match s.[k] with
229229+ | '\\' -> Buffer.add_string b "\\\\"
230230+ | '"' -> Buffer.add_string b "\\\""
231231+ | c -> Buffer.add_char b c)
232232+ done;
233233+ Buffer.contents b)
234234+235235+let print_def f def =
236236+ let format_pred = function | `Pred s -> s | `NegPred s -> "-" ^ s in
237237+ fprintf f "%s%s %s \"%s\"\n" def.def_var
238238+ (match def.def_preds with
239239+ | [] -> ""
240240+ | l -> "(" ^ ((String.concat "," (List.map format_pred l)) ^ ")"))
241241+ (match def.def_flav with | `BaseDef -> "=" | `Appendix -> "+=")
242242+ (escape def.def_value)
243243+244244+245245+let rec print f pkg =
246246+ (List.iter (print_def f) pkg.pkg_defs;
247247+ List.iter
248248+ (fun (name, child) ->
249249+ (fprintf f "\npackage \"%s\" (\n" (escape name);
250250+ print f child;
251251+ fprintf f ")\n"))
252252+ pkg.pkg_children)
253253+254254+let rec remove_dups l =
255255+ (* FIXME: O(n^2) *)
256256+ match l with
257257+ x :: l' ->
258258+ if List.mem x l' then remove_dups l' else x::remove_dups l'
259259+ | [] -> []
260260+261261+let lookup_2 name predicate_list def =
262262+ let fulfills actual_preds formal_preds =
263263+ List.for_all
264264+ (function
265265+ | `Pred n -> List.mem n predicate_list
266266+ | `NegPred n -> not (List.mem n predicate_list))
267267+ formal_preds in
268268+ let rec search_base best_n best_value l =
269269+ match l with
270270+ | [] -> if best_n >= 0 then best_value else raise Not_found
271271+ | def :: l' ->
272272+ if
273273+ (name = def.def_var) &&
274274+ ((def.def_flav = `BaseDef) &&
275275+ ((fulfills predicate_list def.def_preds) &&
276276+ ((List.length def.def_preds) > best_n)))
277277+ then search_base
278278+ (List.length def.def_preds)
279279+ (def.def_value, def.def_preds)
280280+ l'
281281+ else search_base best_n best_value l' in
282282+ let rec search_appdx l =
283283+ match l with
284284+ | [] -> []
285285+ | def :: l' ->
286286+ if
287287+ (name = def.def_var) &&
288288+ ((def.def_flav = `Appendix) &&
289289+ (fulfills predicate_list def.def_preds))
290290+ then (def.def_value, def.def_preds) :: (search_appdx l')
291291+ else search_appdx l' in
292292+ let value_a, preds_a = search_base (-1) ("",[]) def in
293293+ let additions = search_appdx def in
294294+ let values_b = List.map fst additions in
295295+ let preds_b = List.flatten (List.map snd additions) in
296296+ let value = String.concat " " (value_a :: values_b) in
297297+ let preds = remove_dups (preds_a @ preds_b) in
298298+ (value, preds)
299299+300300+let lookup name predicate_list def =
301301+ fst(lookup_2 name predicate_list def)
302302+303303+let predicate_exists p defs =
304304+ List.exists
305305+ (fun def ->
306306+ List.exists (function | `Pred n -> n = p | `NegPred n -> n = p)
307307+ def.def_preds)
308308+ defs
309309+310310+
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(** Parses META files *)
77+88+open Fl_metatoken
99+1010+type formal_pred =
1111+ [ `Pred of string (** Positive occurrence of a formal predicate var *)
1212+ | `NegPred of string (** Negative occurrence of a formal predicate var *)
1313+ ]
1414+1515+type flavour =
1616+ [ `BaseDef
1717+ | `Appendix
1818+ ]
1919+ (** [`BaseDef] refers to META definitions using the "=" operator,
2020+ * and [`Appendix] refers to definitions using the "+=" operator.
2121+ *)
2222+2323+type pkg_definition =
2424+ { def_var : string; (** The name of the defined variable *)
2525+ def_flav : flavour; (** The flavour of the definition *)
2626+ def_preds : formal_pred list; (** The formal predicates of the def *)
2727+ def_value : string; (** The value assigned to the variable *)
2828+ }
2929+ (** A [pkg_definition] is expressed by the syntax
3030+ * {[ var(p1,p2,...) = "value" ]} (flavour `BaseDef),
3131+ * or the syntax
3232+ * {[ var(p1,p2,...) += "value" ]} (flavour `Appendix)
3333+ * in the META file. The list of predicates may be omitted. Predicates
3434+ * may be negated by using "-", e.g. "-x".
3535+ *)
3636+3737+type pkg_expr =
3838+ { pkg_defs : pkg_definition list;
3939+ pkg_children : (string * pkg_expr) list;
4040+ }
4141+ (** A value of type [pkg_expr] denotes the contents of a META file.
4242+ * The component [pkg_defs] are the variable definitions.
4343+ * The component [pkg_children] contains
4444+ * the definitions of the subpackages.
4545+ *)
4646+4747+exception Error of string
4848+4949+5050+val parse : in_channel -> pkg_expr
5151+ (** [parse ch:]
5252+ * scans and parses the file connected with channel [ch]. The file must
5353+ * have a syntax compatible with the META format. The return value
5454+ * contains the found definitions for the package and all subpackages.
5555+ *
5656+ * [exception Error of string:] is
5757+ * raised on syntax errors. The string explains the error.
5858+ *)
5959+6060+val parse_lexing : Lexing.lexbuf -> pkg_expr
6161+6262+6363+val print_def : out_channel -> pkg_definition -> unit
6464+ (** [print_def ch def]:
6565+ * Outputs the definition to a channel.
6666+ *)
6767+6868+val print : out_channel -> pkg_expr -> unit
6969+ (** [print ch expr]:
7070+ * Outputs the package expression to a channel.
7171+ *)
7272+7373+7474+val lookup :
7575+ string -> string list -> pkg_definition list -> string
7676+ (** [lookup variable_name predicate_list def]:
7777+ *
7878+ * Returns the value of [variable_name] in [def] under the assumption
7979+ * that the predicates in [predicate_list] hold, but no other predicates.
8080+ *
8181+ * The rules are as follows: In the step (A), only the [`BaseDef]
8282+ * definitions are considered. The first base definition is determined where
8383+ * all predicates are satisfied and that has the longest predicate list.
8484+ * In the step (B) only the [`Appendix] definitions are considered.
8585+ * All definitions are determined where all predicates are satisfied.
8686+ * The final result is the concatenation of the single result of (A)
8787+ * and all results of (B) (in the order they are defined). A space
8888+ * character is inserted between two concatenated strings.
8989+ *
9090+ * When step (A) does not find any matching definition, the exception
9191+ * [Not_found] is raised.
9292+ *)
9393+9494+9595+val lookup_2 :
9696+ string -> string list -> pkg_definition list -> string * formal_pred list
9797+ (** Like [lookup], but also returns the list of predicates that had to
9898+ be considered to select the particular variable definition.
9999+ *)
100100+101101+102102+val predicate_exists :
103103+ string -> pkg_definition list -> bool
104104+ (** [predicate_exists variable_name def]:
105105+106106+ Whether [variable_name] is explicitly mentioned in [def].
107107+ *)
+37
vendor/opam/ocamlfind/src/findlib/fl_metatoken.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+77+type token =
88+ Name of string
99+ | LParen
1010+ | RParen
1111+ | Equal
1212+ | PlusEqual
1313+ | Minus
1414+ | Comma
1515+ | String of string
1616+ | Space
1717+ | Newline
1818+ | Eof
1919+ | Unknown
2020+;;
2121+2222+2323+let name_tok = function
2424+ | Name s -> Some s
2525+ | _ -> None
2626+2727+let string_tok = function
2828+ | String s -> Some s
2929+ | _ -> None
3030+3131+let const_tok constant tok =
3232+ match constant with
3333+ | Name _ | String _ -> failwith "expect: only for constant tokens"
3434+ | LParen | RParen | Equal | PlusEqual | Minus
3535+ | Comma | Space | Newline | Eof | Unknown ->
3636+ if constant = tok then Some ()
3737+ else None
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+open Fl_metascanner
77+88+exception No_such_package of string * string
99+ (* (name, reason) *)
1010+1111+type package =
1212+ { package_name : string;
1313+ package_dir : string;
1414+ package_meta : string;
1515+ package_defs : Fl_metascanner.pkg_definition list;
1616+ package_priv : package_priv
1717+ }
1818+and package_priv =
1919+ { mutable missing_reqs : (string * string) list;
2020+ (* If non-empty the package is broken. This may be set by
2121+ add_all_relations, and should be checked before using the
2222+ package later. Each element corresponds to No_such_package.
2323+ *)
2424+ }
2525+;;
2626+2727+2828+module Fl_metaentry =
2929+ struct
3030+ type t = package
3131+ type id_t = string
3232+ let id m = m.package_name
3333+ end
3434+;;
3535+3636+3737+module Fl_metastore =
3838+ Fl_topo.Make(Fl_metaentry)
3939+;;
4040+4141+4242+module StringSet = Set.Make(String);;
4343+4444+4545+let has_prefix s pref =
4646+ String.length s >= String.length pref &&
4747+ String.sub s 0 (String.length pref) = pref
4848+;;
4949+5050+5151+let ocamlpath = ref [];;
5252+let ocamlstdlib = ref "";;
5353+5454+let conf_ignore_dups_in = ref ([] : string list)
5555+5656+let store = Fl_metastore.create();;
5757+ (* We collect here only nodes, but no relations. First copy [store]
5858+ * and put relations into the copy.
5959+ *)
6060+6161+6262+let init path stdlib ignore_dups_in =
6363+ ocamlpath := path;
6464+ ocamlstdlib := stdlib;
6565+ conf_ignore_dups_in := ignore_dups_in
6666+;;
6767+6868+6969+let packages_in_meta_file ?(directory_required = false)
7070+ ~name:package_name ~dir:package_dir ~meta_file () =
7171+ (* Parses the META file whose name is [meta_file]. In [package_name], the
7272+ * name of the main package must be passed. [package_dir] is the
7373+ * directory associated with the package by default (i.e. before
7474+ * it is overridden by the "directory" directive).
7575+ *
7676+ * directory_required: If true, a "directory" directive is necessary.
7777+ *
7878+ * Returns the [package] records found in this file. The "directory"
7979+ * directive is already applied.
8080+ *)
8181+ let rec flatten_meta pkg_name_prefix pkg_dir (pkg_name_component,pkg_expr) =
8282+ (* Turns the recursive [pkg_expr] into a flat list of [package]s.
8383+ * [pkg_dir] is the default package directory. [pkg_name_prefix] is
8484+ * the name prefix to prepend to the fully qualified package name, or
8585+ * "". [pkg_name_component] is the local package name.
8686+ *)
8787+ (* Determine the final package directory: *)
8888+ let d =
8989+ (* The value of "directory", or "" if not applicable *)
9090+ try
9191+ lookup "directory" [] pkg_expr.pkg_defs
9292+ with
9393+ Not_found ->
9494+ if pkg_name_prefix="" && directory_required then
9595+ failwith ("The `directory' directive is required in this META definition");
9696+9797+ ""
9898+ in
9999+ let d' =
100100+ if d = "" then
101101+ pkg_dir
102102+ else
103103+ match d.[0] with
104104+ | '^'
105105+ | '+' ->
106106+ let rest = String.sub d 1 (String.length d - 1) in
107107+ if rest = "" then
108108+ !ocamlstdlib
109109+ else
110110+ Filename.concat !ocamlstdlib rest
111111+ | _ ->
112112+ if Filename.is_relative d then
113113+ Filename.concat pkg_dir d
114114+ else
115115+ d
116116+ in
117117+ let p_name =
118118+ if pkg_name_prefix = "" then
119119+ pkg_name_component
120120+ else
121121+ pkg_name_prefix ^ "." ^ pkg_name_component in
122122+ let p =
123123+ { package_name = p_name;
124124+ package_dir = d';
125125+ package_meta = meta_file;
126126+ package_defs = pkg_expr.pkg_defs;
127127+ package_priv = { missing_reqs = [] }
128128+ } in
129129+ (* Check for exists_if: *)
130130+ let p_exists =
131131+ try
132132+ let def =
133133+ List.find (fun def -> def.def_var = "exists_if") p.package_defs in
134134+ let files = Fl_split.in_words def.def_value in
135135+ List.exists
136136+ (fun file -> Sys.file_exists (Filename.concat d' file))
137137+ files
138138+ with Not_found -> true in
139139+140140+ if p_exists then
141141+ p :: (List.flatten
142142+ (List.map (flatten_meta p_name d') pkg_expr.pkg_children))
143143+ else
144144+ []
145145+ in
146146+147147+ let ch = open_in meta_file in
148148+ try
149149+ let pkg_expr = Fl_metascanner.parse ch in
150150+ let packages = flatten_meta "" package_dir (package_name, pkg_expr) in
151151+ close_in ch;
152152+ packages
153153+ with
154154+ Failure s ->
155155+ close_in ch;
156156+ failwith ("While parsing '" ^ meta_file ^ "': " ^ s)
157157+ | Fl_metascanner.Error s ->
158158+ close_in ch;
159159+ failwith ("While parsing '" ^ meta_file ^ "': " ^ s)
160160+ | any ->
161161+ close_in ch;
162162+ raise any
163163+;;
164164+165165+166166+let query package_name =
167167+168168+ let package_name_comps = Fl_split.package_name package_name in
169169+ if package_name_comps = [] then invalid_arg "Fl_package_base.query";
170170+ let main_name = List.hd package_name_comps in
171171+172172+ let process_file_and_lookup ?directory_required package_dir meta_file =
173173+ let packages =
174174+ packages_in_meta_file
175175+ ?directory_required ~name:main_name ~dir:package_dir ~meta_file () in
176176+ let p =
177177+ ( try
178178+ List.find
179179+ (fun p -> p.package_name = package_name)
180180+ packages
181181+ with
182182+ Not_found ->
183183+ raise (No_such_package (package_name, ""))
184184+ ) in
185185+ List.iter (Fl_metastore.add store) packages;
186186+ p
187187+ in
188188+189189+ let rec run_ocamlpath path =
190190+ match path with
191191+ [] -> raise(No_such_package(package_name, ""))
192192+ | dir :: path' ->
193193+ let package_dir = Filename.concat dir main_name in
194194+ let meta_file_1 = Filename.concat package_dir "META" in
195195+ let meta_file_2 = Filename.concat dir ("META." ^ main_name) in
196196+ if Sys.file_exists meta_file_1 then
197197+ process_file_and_lookup package_dir meta_file_1
198198+ else
199199+ if Sys.file_exists meta_file_2 then
200200+ process_file_and_lookup ~directory_required:true dir meta_file_2
201201+ (* Note: It is allowed to have relative "directory" directives.
202202+ * The base directory is [dir] in this case.
203203+ *)
204204+ else
205205+ run_ocamlpath path'
206206+ in
207207+208208+ try
209209+ Fl_metastore.find store package_name
210210+ with
211211+ Not_found ->
212212+ run_ocamlpath !ocamlpath
213213+;;
214214+215215+216216+exception Package_loop of string
217217+ (* A package is required by itself. The arg is the name of the
218218+ * package
219219+ *)
220220+221221+222222+let fixup_thread_needed_1 predlist =
223223+ (* When the thread fixup is required to apply, 1st criterion *)
224224+ List.mem "mt" predlist
225225+;;
226226+227227+228228+let fixup_thread_needed_2 pkg =
229229+ (* When the thread fixup is required to apply, 2nd criterion *)
230230+ (pkg <> "unix" && pkg <> "threads" && not (has_prefix pkg "threads."))
231231+;;
232232+233233+234234+let fixup_thread_base predlist pkg =
235235+ (* Add the package "threads" if required *)
236236+ if fixup_thread_needed_1 predlist && fixup_thread_needed_2 pkg then
237237+ [ "threads" ]
238238+ else
239239+ []
240240+;;
241241+242242+243243+let query_requirements ~preds:predlist package_name =
244244+ (* Part of [requires] implementation: Load all required packages, but
245245+ * do not add relations
246246+ *)
247247+ let m = query package_name in
248248+ (* may raise No_such_package *)
249249+ let r =
250250+ try Fl_metascanner.lookup "requires" predlist m.package_defs
251251+ with Not_found -> ""
252252+ in
253253+ let ancestors = Fl_split.in_words r @
254254+ fixup_thread_base predlist package_name in
255255+ List.iter
256256+ (fun p ->
257257+ try
258258+ let _ = query p in (* may raise No_such_package *)
259259+ ()
260260+ with
261261+ No_such_package(pname,_) ->
262262+ raise(No_such_package(pname, "required by `" ^ package_name ^ "'"))
263263+ )
264264+ ancestors;
265265+ ancestors
266266+;;
267267+268268+269269+let add_relations s ancestors package_name =
270270+ (* Part of [requires] implementation: Adds the relations from [package_name]
271271+ * to [ancestors]. Target store is [s].
272272+ *)
273273+ List.iter
274274+ (fun p ->
275275+ try
276276+ Fl_metastore.let_le s p package_name (* add relation *)
277277+ with
278278+ | Fl_topo.Inconsistent_ordering ->
279279+ raise(Package_loop p)
280280+ | Not_found ->
281281+ (* A relation to a package not part of [s]. We ignore it here. *)
282282+ ()
283283+ )
284284+ ancestors
285285+;;
286286+287287+288288+let add_all_relations preds s =
289289+ (* Adds all relations for the packages currently defined in [s].
290290+ Note that missing requirements are not reported immediately (we do
291291+ not know here which part of the graph [s] is really accessed), and
292292+ instead the error is added to the missing_reqs field, where
293293+ it should be checked before used.
294294+ *)
295295+ let pkgs = ref [] in
296296+ Fl_metastore.iter_up
297297+ (fun p -> pkgs := p :: !pkgs)
298298+ s;
299299+300300+ List.iter
301301+ (fun p ->
302302+ let pkg = p.package_name in
303303+ try
304304+ let pkg_ancestors = query_requirements ~preds pkg in
305305+ add_relations s pkg_ancestors pkg
306306+ with
307307+ | No_such_package(n,reason) ->
308308+ p.package_priv.missing_reqs <-
309309+ (n,reason) :: p.package_priv.missing_reqs
310310+ )
311311+ !pkgs
312312+;;
313313+314314+315315+let fixup_thread_deps s =
316316+ (* All packages (except "threads", "threads.*", and "unix") are made
317317+ * dependent on "threads"
318318+ *)
319319+ let pkgs = ref [] in
320320+ Fl_metastore.iter_up
321321+ (fun p -> pkgs := p.package_name :: !pkgs)
322322+ s;
323323+324324+ List.iter
325325+ (fun pkg ->
326326+ if fixup_thread_needed_2 pkg then (
327327+ try
328328+ Fl_metastore.let_le s "threads" pkg (* add relation *)
329329+ with
330330+ Not_found ->
331331+ (* Because "threads" does not exist! Normally this is an
332332+ * error, because "threads" is also magically added by
333333+ * query_requirements. However, there are situations
334334+ * where it cannot be expected that required packages
335335+ * are loaded, so ignore this case.
336336+ *)
337337+ ()
338338+ )
339339+ )
340340+ !pkgs
341341+;;
342342+343343+344344+let requires ~preds package_name =
345345+ (* returns names of packages required by [package_name], the fully qualified
346346+ * name of the package. It is checked that the packages really exist.
347347+ * [preds]: list of true predicates
348348+ * May raise [No_such_package] or [Package_loop].
349349+ *)
350350+ let ancestors = query_requirements ~preds package_name in
351351+ let store' = Fl_metastore.copy store in (* work with a copy *)
352352+ add_relations store' ancestors package_name;
353353+ if List.mem "mt" preds then fixup_thread_deps store';
354354+ ancestors
355355+;;
356356+357357+358358+let requires_deeply ~preds package_list =
359359+ (* returns names of packages required by the packages in [package_list],
360360+ * either directly or indirectly.
361361+ * It is checked that the packages really exist.
362362+ * The list of names is sorted topologically; first comes the deepest
363363+ * ancestor.
364364+ * [preds]: list of true predicates
365365+ * - raises [Not_found] if there is no 'package'
366366+ * - raises [Failure] if some of the ancestors do not exist
367367+ *)
368368+369369+ let pkgset = ref StringSet.empty in
370370+371371+ let rec query_packages pkglist =
372372+ match pkglist with
373373+ pkg :: pkglist' ->
374374+ if not(StringSet.mem pkg !pkgset) then begin
375375+ let pkg_ancestors = query_requirements ~preds pkg in
376376+ pkgset := StringSet.add pkg !pkgset;
377377+ query_packages pkg_ancestors
378378+ end;
379379+ query_packages pkglist'
380380+ | [] ->
381381+ ()
382382+ in
383383+384384+ (* First query for all packages, such that they are loaded: *)
385385+ query_packages package_list;
386386+387387+ (* Now make a copy of the store, and add the relations: *)
388388+ let store' = Fl_metastore.copy store in
389389+ add_all_relations preds store';
390390+ if List.mem "mt" preds then fixup_thread_deps store';
391391+392392+ (* Finally, iterate through the graph. Note that the graph may
393393+ * contain more members than required, so we have to test explicitly
394394+ * whether the packages are contained in pkgset.
395395+ *)
396396+397397+ let l = ref [] in
398398+399399+ Fl_metastore.iter_up_at
400400+ (fun m ->
401401+ if StringSet.mem m.package_name !pkgset then (
402402+ if m.package_priv.missing_reqs <> [] then (
403403+ let (n,reason) = List.hd m.package_priv.missing_reqs in
404404+ raise(No_such_package(n,reason))
405405+ );
406406+ l := m.package_name :: !l
407407+ )
408408+ )
409409+ store'
410410+ package_list;
411411+412412+ List.rev !l
413413+;;
414414+415415+416416+(**********************************************************************)
417417+418418+(* The following two functions do not use !ocamlpath, because there may
419419+ * be duplicates in it.
420420+ *)
421421+422422+let package_definitions ~search_path package_name =
423423+ (* Return all META files defining this [package_name] that occur in the
424424+ * directories mentioned in [search_path]
425425+ *)
426426+427427+ let package_name_comps = Fl_split.package_name package_name in
428428+ if package_name_comps = [] then invalid_arg "Fl_package_base.package_definitions";
429429+ let main_name = List.hd package_name_comps in
430430+431431+ let rec run_ocamlpath path =
432432+ match path with
433433+ [] -> []
434434+ | dir :: path' ->
435435+ let package_dir = Filename.concat dir main_name in
436436+ let meta_file_1 = Filename.concat package_dir "META" in
437437+ let meta_file_2 = Filename.concat dir ("META." ^ main_name) in
438438+ if Sys.file_exists meta_file_1 then
439439+ meta_file_1 :: run_ocamlpath path'
440440+ else
441441+ if Sys.file_exists meta_file_2 then
442442+ meta_file_2 :: run_ocamlpath path'
443443+ else
444444+ run_ocamlpath path'
445445+ in
446446+ run_ocamlpath search_path
447447+;;
448448+449449+450450+let in_report_search_path identify_dir d =
451451+ (* Whether package dir d is to be considered for generating reports.
452452+ d is sorted out when the ignore_dups_in option is set
453453+ *)
454454+ List.for_all
455455+ (fun id ->
456456+ try identify_dir d <> identify_dir id
457457+ with _ -> Fl_split.norm_dir d <> Fl_split.norm_dir id
458458+ )
459459+ !conf_ignore_dups_in
460460+;;
461461+462462+463463+let package_conflict_report_1 identify_dir () =
464464+ let remove_dups_from_path p =
465465+ (* Removes directories which are physically the same from the path [p],
466466+ * and returns the shortened path
467467+ *)
468468+469469+ let dir_identity = Hashtbl.create 20 in
470470+471471+ let rec remove p =
472472+ match p with
473473+ d :: p' ->
474474+ begin try
475475+ let id = identify_dir d in (* may raise exceptions *)
476476+ if Hashtbl.mem dir_identity id then
477477+ remove p'
478478+ else begin
479479+ Hashtbl.add dir_identity id ();
480480+ d :: (remove p')
481481+ end
482482+ with error ->
483483+ (* Don't know anything, so the "directory" remains in the path *)
484484+ d :: (remove p')
485485+ end
486486+ | [] ->
487487+ []
488488+ in
489489+490490+ remove p
491491+ in
492492+493493+ (* If we have ignore_dups_in this directory is removed from our search
494494+ path first
495495+ *)
496496+ let search_path0 =
497497+ List.filter (in_report_search_path identify_dir) !ocamlpath in
498498+499499+ (* Now eliminate all duplicates *)
500500+ let search_path =
501501+ remove_dups_from_path search_path0 in
502502+503503+ Fl_metastore.iter_up
504504+ (fun pkg ->
505505+ (* Check only main packages: *)
506506+ let package_name_comps = Fl_split.package_name pkg.package_name in
507507+ match package_name_comps with
508508+ [_] ->
509509+ (* pkg is a main package *)
510510+ ( let c = package_definitions ~search_path pkg.package_name in
511511+ match c with
512512+ []
513513+ | [_] ->
514514+ ()
515515+ | _ ->
516516+ Printf.eprintf "findlib: [WARNING] Package %s has multiple definitions in %s\n"
517517+ pkg.package_name
518518+ (String.concat ", " c)
519519+ )
520520+ | _ ->
521521+ ()
522522+ )
523523+ store;
524524+ flush stderr
525525+;;
526526+527527+528528+let package_conflict_report ?identify_dir () =
529529+ match identify_dir with
530530+ None -> package_conflict_report_1 (fun s -> s) ()
531531+ | Some f -> package_conflict_report_1 f ()
532532+;;
533533+534534+let check_prefix ?prefix f =
535535+ match prefix with
536536+ | None -> true
537537+ | Some prefix ->
538538+ let len = String.length prefix in
539539+ String.length f >= len && String.sub f 0 len = prefix
540540+541541+let load_base ?prefix () =
542542+ (* Ensures that the cache is completely filled with every package
543543+ * of the system that match prefix
544544+ *)
545545+ let list_directory d =
546546+ try
547547+ Array.to_list(Sys.readdir d)
548548+ with
549549+ Sys_error msg ->
550550+ prerr_endline ("findlib: [WARNING] cannot read directory " ^ msg);
551551+ []
552552+ in
553553+554554+ let process_file ?directory_required main_name package_dir meta_file =
555555+ try
556556+ let _ = Fl_metastore.find store main_name in
557557+ (* Note: If the main package is already loaded into the graph, we
558558+ * do not even look at the subpackages!
559559+ *)
560560+ ()
561561+ with
562562+ Not_found ->
563563+ let packages =
564564+ try
565565+ packages_in_meta_file
566566+ ?directory_required ~name:main_name ~dir:package_dir ~meta_file ()
567567+ with
568568+ Failure s ->
569569+ prerr_endline ("findlib: [WARNING] " ^ s); []
570570+ in
571571+ List.iter (Fl_metastore.add store) packages;
572572+ (* Nothing evil can happen! *)
573573+ in
574574+575575+ let rec run_ocamlpath path =
576576+ match path with
577577+ [] -> ()
578578+ | dir :: path' ->
579579+ let files = list_directory dir in
580580+ List.iter
581581+ (fun f ->
582582+ if check_prefix ?prefix f
583583+ then
584584+ (* If f/META exists: Add package f *)
585585+ let package_dir = Filename.concat dir f in
586586+ let meta_file_1 = Filename.concat package_dir "META" in
587587+ if Sys.file_exists meta_file_1 then
588588+ process_file f package_dir meta_file_1
589589+ else
590590+ (* If f is META.pkgname: Add package pkgname *)
591591+ (* We skip over filenames ending in '~' *)
592592+ if String.length f >= 6 && String.sub f 0 5 = "META." &&
593593+ String.sub f (String.length f - 1) 1 <> "~" then begin
594594+ let name = String.sub f 5 (String.length f - 5) in
595595+ let meta_file_2 = Filename.concat dir f in
596596+ process_file ~directory_required:true name dir meta_file_2
597597+ end;
598598+ )
599599+ files;
600600+ run_ocamlpath path'
601601+ in
602602+603603+ run_ocamlpath !ocamlpath
604604+;;
605605+606606+607607+let list_packages ?prefix () =
608608+ load_base ?prefix ();
609609+610610+ let l = ref [] in
611611+612612+ Fl_metastore.iter_up
613613+ (fun m ->
614614+ if check_prefix ?prefix m.package_name then
615615+ l := m.package_name :: !l
616616+ )
617617+ store;
618618+619619+ !l
620620+;;
621621+622622+623623+let package_users ~preds pl =
624624+ (* Check that all packages in [pl] really exist, or raise No_such_package: *)
625625+ List.iter
626626+ (fun p -> let _ = query p in ())
627627+ pl;
628628+ load_base();
629629+ let store' = Fl_metastore.copy store in
630630+ add_all_relations preds store';
631631+ if List.mem "mt" preds then fixup_thread_deps store';
632632+633633+ let l = ref [] in
634634+635635+ Fl_metastore.iter_down_at
636636+ (fun m ->
637637+ if m.package_priv.missing_reqs <> [] then (
638638+ let (n,reason) = List.hd m.package_priv.missing_reqs in
639639+ raise(No_such_package(n,reason))
640640+ );
641641+ l := m.package_name :: !l
642642+ )
643643+ store'
644644+ pl;
645645+646646+ !l
647647+;;
648648+649649+650650+let module_conflict_report_1 identify_dir incpath =
651651+ (* Find any *.cmi files occurring twice in incpath.
652652+ *)
653653+ let dir_of_module = Hashtbl.create 100 in
654654+ let dirs = ref [] in
655655+656656+ let examine_dir d =
657657+ try
658658+ let d = Fl_split.norm_dir d in
659659+ let d_id = identify_dir d in
660660+661661+ (* Is d new? *)
662662+ if not (List.mem d_id !dirs) then begin
663663+ dirs := d_id :: !dirs;
664664+ (* Yes: Get all files ending in .cmi *)
665665+ try
666666+ let d_all = Array.to_list(Sys.readdir d) in (* or Sys_error *)
667667+ let d_cmi =
668668+ List.filter
669669+ (fun n -> Filename.check_suffix n ".cmi")
670670+ d_all in
671671+ (* Add the modules to dir_of_module: *)
672672+ List.iter
673673+ (fun m ->
674674+ try
675675+ let entry = Hashtbl.find dir_of_module m in (* or Not_found *)
676676+ entry := d :: !entry
677677+ with
678678+ Not_found ->
679679+ Hashtbl.add dir_of_module m (ref [d])
680680+ )
681681+ d_cmi
682682+ with
683683+ Sys_error msg ->
684684+ prerr_endline ("findlib: [WARNING] cannot read directory " ^ msg)
685685+ end
686686+ with
687687+ | _ -> () (* identify_dir fails *)
688688+ in
689689+690690+ let print_report() =
691691+ Hashtbl.iter
692692+ (fun m dlist ->
693693+ match !dlist with
694694+ []
695695+ | [_] ->
696696+ ()
697697+ | _ ->
698698+ Printf.eprintf "findlib: [WARNING] Interface %s occurs in several directories: %s\n"
699699+ m
700700+ (String.concat ", " !dlist)
701701+ )
702702+ dir_of_module
703703+ in
704704+705705+ (* If we have ignore_dups_in this directory is removed from our search
706706+ path first
707707+ *)
708708+ let incpath1 =
709709+ List.filter (in_report_search_path identify_dir) incpath in
710710+711711+712712+ List.iter examine_dir incpath1;
713713+714714+ print_report();
715715+ flush stderr
716716+;;
717717+718718+719719+let module_conflict_report ?identify_dir incpath =
720720+ match identify_dir with
721721+ None -> module_conflict_report_1 (fun s -> s) incpath
722722+ | Some f -> module_conflict_report_1 f incpath
723723+;;
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(** Direct access to the package graph and package files *)
77+88+type package =
99+ { package_name : string;
1010+ (** The fully qualified package name, i.e. for subpackages the
1111+ * names of the containing packages are prepended and the name
1212+ * components are separated by '.'
1313+ *)
1414+ package_dir : string;
1515+ (** The directory where to lookup package files *)
1616+ package_meta : string;
1717+ (** The path to the META file *)
1818+ package_defs : Fl_metascanner.pkg_definition list;
1919+ (** The definitions in the META file *)
2020+ package_priv : package_priv;
2121+ (** Private part of the definition *)
2222+ }
2323+ (** The definition of a package *)
2424+2525+and package_priv
2626+2727+2828+val init : string list -> string -> string list -> unit
2929+ (** This function must be called before [Fl_package_base] can be used.
3030+ * The first string corresponds to the [OCAMLPATH] setting, the second
3131+ * string is the location of the standard library. The second is the
3232+ * list of directories with ignored duplicate cmi files.
3333+ *
3434+ * This function is called by {!Findlib.init} and {!Findlib.init_manually},
3535+ * so it is already sufficient to initialize the [Findlib] module.
3636+ *)
3737+3838+3939+(** {1 The package graph} *)
4040+4141+(** The functions in this section operate on a representation of the
4242+ * package graph in memory. The graph is usually only partially available,
4343+ * as only packages are loaded that are queried for.
4444+ *)
4545+4646+4747+exception No_such_package of string * string
4848+ (** First arg is the package name not found, second arg contains additional
4949+ * info for the user. - This is the same exception as in [Findlib].
5050+ *)
5151+5252+exception Package_loop of string
5353+ (** A package is required by itself. The arg is the name of the
5454+ * package. - This is the same exception as in [Findlib].
5555+ *)
5656+5757+val query : string -> package
5858+ (** Returns the [package] definition for the fully-qualified package name,
5959+ * or raises [No_such_package]. It is allowed to query for subpackages.
6060+ *
6161+ * This function loads package definitions into the graph kept in memory.
6262+ *)
6363+6464+val requires : preds:string list -> string -> string list
6565+ (** Analyzes the direct requirements of the package whose name is passed as
6666+ * second argument under the assumption that the predicates [preds]
6767+ * hold. The function returns the names of the required packages.
6868+ * It is checked whether these packages exist.
6969+ *
7070+ * If there is the "mt" predicate, missing dependencies on "threads"
7171+ * are silently added.
7272+ *
7373+ * The function may raise [No_such_package] or [Package_loop].
7474+ *
7575+ * This function loads package definitions into the graph kept in memory.
7676+ *)
7777+7878+val requires_deeply : preds:string list -> string list -> string list
7979+ (** Analyzes the direct or indirect requirements of the packages whose names
8080+ * are passed as second argument under the assumption that the predicates
8181+ * [preds] hold. The function returns the names of the required packages.
8282+ * It is checked whether these packages exist.
8383+ *
8484+ * If there is the "mt" predicate, missing dependencies on "threads"
8585+ * are silently added.
8686+ *
8787+ * The function may raise [No_such_package] or [Package_loop].
8888+ *
8989+ * This function loads package definitions into the graph kept in memory.
9090+ *)
9191+9292+val package_conflict_report :
9393+ ?identify_dir:(string -> 'a) -> unit -> unit
9494+ (** Checks whether there are several META files for the same main
9595+ * packages. Complaints are printed to stderr.
9696+ *
9797+ * Only packages in the loaded part of the package graph are checked (i.e.
9898+ * packages for which there was a query).
9999+ *
100100+ * It is recommended to pass the ~identify_dir function whose task
101101+ * it is to return a unique value for every existing directory.
102102+ * For example,
103103+ * {[ fun d ->
104104+ * let s = Unix.stat d in
105105+ * (s.Unix.st_dev, s.Unix.st_ino)
106106+ * ]}
107107+ * could be an implementation for this function. The default is
108108+ * the identity (and not this nice implementation to avoid dependencies
109109+ * on the Unix module).
110110+ *)
111111+112112+val module_conflict_report : ?identify_dir:(string -> 'a) -> string list -> unit
113113+ (** Checks whether there are cmi files for the same modules. The
114114+ * directories passed as first argument are checked. (Note:
115115+ * Neither the '+' nor the '@' notation are recognized.)
116116+ * Complaints about double cmi files are printed to stderr.
117117+ *
118118+ * @param identify_dir See [package_conflict_report].
119119+ *)
120120+121121+val load_base : ?prefix:string -> unit -> unit
122122+ (** Ensures that the complete package graph is loaded into memory.
123123+ * This is a time-consuming operation. Warnings may be printed to
124124+ * stderr.
125125+ *
126126+ * @param prefix Limit to the packages that starts with it. Default: unlimited
127127+ *)
128128+129129+val list_packages : ?prefix:string -> unit -> string list
130130+ (** Ensures that the complete package graph is loaded into memory
131131+ * (like [load_base]), and returns the (unsorted) list of all
132132+ * packages.
133133+ *
134134+ * @param prefix Limit to the packages that starts with it. Default: unlimited
135135+ *)
136136+137137+val package_users : preds:string list -> string list -> string list
138138+ (** Ensures that the complete package graph is loaded into memory
139139+ * (like [load_base]), and determines the packages using one of
140140+ * the packages passed as second argument. The [preds] are assumed
141141+ * for the evaluation of the [requires] directives.
142142+ * The returned list is sorted in ascending order.
143143+ *
144144+ * If there is the "mt" predicate, missing dependencies on "threads"
145145+ * are silently added.
146146+ *
147147+ * Raises [No_such_package] if one of the passed packages cannot
148148+ * be found.
149149+ *)
150150+151151+152152+(** {1 Parsing META files} *)
153153+154154+(** The functions in this section access directly files and directories.
155155+ * The package graph is unknown.
156156+ *)
157157+158158+val packages_in_meta_file :
159159+ ?directory_required:bool ->
160160+ name:string -> dir:string -> meta_file:string -> unit -> package list
161161+ (** Parses the META file whose name is [meta_file]. In [name], the
162162+ * name of the main package must be passed. [dir] is the
163163+ * directory associated with the package by default (i.e. before
164164+ * it is overridden by the "directory" directive).
165165+ *
166166+ * Returns the package records found in this file. The "directory"
167167+ * directive is already applied.
168168+ *
169169+ * @param directory_required If true, it is checked whether there is a
170170+ * "directory" directive in the main package. If this directive is missing,
171171+ * the function will fail.
172172+ *)
173173+174174+val package_definitions : search_path:string list -> string -> string list
175175+ (** Return all META files defining this package that occur in the
176176+ * directories mentioned in [search_path]. The package name must be
177177+ * fully-qualified. For simplicity, however, only the name of the main
178178+ * package is taken into account (so it is a good idea to call this
179179+ * function only for main packages).
180180+ *)
181181+
+146
vendor/opam/ocamlfind/src/findlib/fl_split.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+77+let in_words s =
88+ (* splits s in words separated by commas and/or whitespace *)
99+ let l = String.length s in
1010+ let rec split i j =
1111+ if j < l then
1212+ match s.[j] with
1313+ (' '|'\t'|'\n'|'\r'|',') ->
1414+ if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1))
1515+ else split (j+1) (j+1)
1616+ | _ ->
1717+ split i (j+1)
1818+ else
1919+ if i<j then [ String.sub s i (j-i) ] else []
2020+ in
2121+ split 0 0
2222+;;
2323+2424+2525+let in_words_ws s =
2626+ (* splits s in words separated by whitespace *)
2727+ let l = String.length s in
2828+ let rec split i j =
2929+ if j < l then
3030+ match s.[j] with
3131+ (' '|'\t'|'\n'|'\r') ->
3232+ if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1))
3333+ else split (j+1) (j+1)
3434+ | _ ->
3535+ split i (j+1)
3636+ else
3737+ if i<j then [ String.sub s i (j-i) ] else []
3838+ in
3939+ split 0 0
4040+;;
4141+4242+4343+let package_name s =
4444+ (* splits s in words separated by dots.
4545+ * As a special case, when s="." the package "." is returned.
4646+ *)
4747+ let l = String.length s in
4848+ let rec split i j =
4949+ if j < l then
5050+ match s.[j] with
5151+ '.' ->
5252+ if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1))
5353+ else split (j+1) (j+1)
5454+ | _ ->
5555+ split i (j+1)
5656+ else
5757+ if i<j then [ String.sub s i (j-i) ] else []
5858+ in
5959+ if s="." then
6060+ ["."]
6161+ else
6262+ split 0 0
6363+;;
6464+6565+6666+let is_valid_package_name s =
6767+ (* Use this only for installation/deinstallation of packages! *)
6868+ not(String.contains s '.')
6969+;;
7070+7171+7272+let path_separator =
7373+ match Sys.os_type with
7474+ | "Unix" | "BeOS" -> ':'
7575+ | "Cygwin" -> ';' (* You might want to change this *)
7676+ | "Win32" -> ';'
7777+ | "MacOS" -> failwith "Findlib: I do not know what is the correct path separator for MacOS. If you can help me, write a mail to gerd@gerd-stolpmann.de"
7878+ | _ -> failwith "Findlib: unknown operating system"
7979+;;
8080+8181+8282+let path str =
8383+ (* split "str" into parts separated by "path_separator" *)
8484+ let l = String.length str in
8585+ let rec split_up j k =
8686+ if k < l then begin
8787+ let c = str.[k] in
8888+ if c = path_separator then begin
8989+ if k - j > 0 then
9090+ String.sub str j (k-j) :: split_up (k+1) (k+1)
9191+ else
9292+ split_up (k+1) (k+1)
9393+ end
9494+ else
9595+ split_up j (k+1)
9696+ end
9797+ else
9898+ if k - j > 0 then
9999+ [ String.sub str j (k-j) ]
100100+ else
101101+ []
102102+ in
103103+ split_up 0 0
104104+;;
105105+106106+107107+let norm_dir s =
108108+ (* Converts the file name of the directory [d] to the normal form.
109109+ * For Unix, the '/' characters at the end are removed, and multiple
110110+ * '/' are deleted.
111111+ * For Windows, all '/' characters are converted to '\'. Two
112112+ * backslashes at the beginning are tolerated.
113113+ *)
114114+ let b = Buffer.create 80 in
115115+ let l = String.length s in
116116+ let norm_dir_unix() =
117117+ Buffer.add_char b s.[0];
118118+ for k = 1 to l - 1 do
119119+ let c = s.[k] in
120120+ if not ((c = '/' && s.[k-1] = '/') || (c = '/' && k = l-1)) then
121121+ Buffer.add_char b c
122122+ done
123123+ in
124124+ let is_slash =
125125+ function
126126+ | '/' | '\\' -> true
127127+ | _ -> false in
128128+ let norm_dir_win() =
129129+ if l >= 1 then
130130+ if s.[0] = '/' then Buffer.add_char b '\\' else Buffer.add_char b s.[0];
131131+ if l >= 2 then
132132+ if s.[1] = '/' then Buffer.add_char b '\\' else Buffer.add_char b s.[1];
133133+ for k = 2 to l - 1 do
134134+ let c = s.[k] in
135135+ if is_slash c then (
136136+ if not (is_slash s.[k-1] || k = l-1) then
137137+ Buffer.add_char b '\\'
138138+ ) else
139139+ Buffer.add_char b c
140140+ done
141141+ in
142142+ match Sys.os_type with
143143+ "Unix" | "BeOS" | "Cygwin" -> norm_dir_unix(); Buffer.contents b
144144+ | "Win32" -> norm_dir_win(); Buffer.contents b
145145+ | _ -> failwith "This os_type is not supported"
146146+;;
+344
vendor/opam/ocamlfind/src/findlib/fl_topo.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(* TODO:
77+ * - Use a hashtable in 'find'
88+ * - implement le_than with an 'iter' like method
99+ *)
1010+1111+1212+(**********************************************************************)
1313+1414+1515+module type IdentifiedType =
1616+ sig
1717+ type t
1818+ type id_t
1919+ val id : t -> id_t
2020+ end
2121+2222+exception Inconsistent_ordering
2323+2424+module type S =
2525+ sig
2626+ type key
2727+ type el_t
2828+ type t
2929+ val create : unit -> t
3030+ val add : t -> el_t -> unit
3131+ val let_le : t -> key -> key -> unit
3232+ val find : t -> key -> el_t
3333+ val le_than : t -> key -> key -> bool
3434+ val key : el_t -> key
3535+ val iter_up : (el_t -> unit) -> t -> unit
3636+ val iter_down : (el_t -> unit) -> t -> unit
3737+ val iter_up_at : (el_t -> unit) -> t -> key list -> unit
3838+ val iter_down_at : (el_t -> unit) -> t -> key list -> unit
3939+4040+ val clear : t -> unit
4141+ val replace : t -> key -> el_t -> unit
4242+ val delete : t -> key -> unit
4343+4444+ val copy : t -> t
4545+ end
4646+4747+4848+(**********************************************************************)
4949+5050+module Make(H: IdentifiedType) =
5151+ struct
5252+5353+ type key = H.id_t
5454+5555+ type el_t = H.t
5656+5757+ type 'a node =
5858+ { mutable content : 'a;
5959+ mutable smaller : 'a node list;
6060+ mutable bigger : 'a node list;
6161+ mutable mark : bool; (* used in 'iter' *)
6262+ (* mutable ppmark : bool *) (* used in 'private_property' *)
6363+ }
6464+6565+ type t =
6666+ { mutable cnt : el_t node list;
6767+ mutable lock : bool
6868+ }
6969+7070+ let copy ord =
7171+ (* This operation is quite expensive when the graph has already
7272+ * relations. In findlib, this case is avoided, and is here only
7373+ * implemented for completeness.
7474+ *)
7575+ let ord' =
7676+ { cnt = List.map (fun n -> { n with
7777+ smaller = [];
7878+ bigger = [];
7979+ mark = false }) ord.cnt;
8080+ lock = false
8181+ } in
8282+ let combined_list = List.combine ord.cnt ord'.cnt in
8383+ let lookup_node n =
8484+ (* Find the new node corresponding to old node n *)
8585+ try List.assq n combined_list
8686+ with Not_found -> assert false
8787+ in
8888+ List.iter2
8989+ (fun n n' ->
9090+ (* n: old node, n': new node *)
9191+ let smaller = List.map lookup_node n.smaller in
9292+ let bigger = List.map lookup_node n.bigger in
9393+ n'.smaller <- smaller;
9494+ n'.bigger <- bigger;
9595+ )
9696+ ord.cnt
9797+ ord'.cnt;
9898+ ord'
9999+100100+101101+ let rec delete_all p l =
102102+ match l with
103103+ x::l' ->
104104+ if p x then delete_all p l' else x :: delete_all p l'
105105+ | [] -> []
106106+107107+108108+ (******************************************************************)
109109+110110+ let create () = { cnt = []; lock = false }
111111+112112+ let clear ordering =
113113+ ordering.cnt <- [];
114114+ ordering.lock <- false
115115+116116+ (******************************************************************)
117117+118118+ let add ordering x =
119119+ (* Is there already a node with the same key? *)
120120+ let k = H.id x in
121121+ if List.exists (fun y -> H.id y.content = k) ordering.cnt then
122122+ raise Inconsistent_ordering;
123123+124124+ (* Ok, add the node to the list *)
125125+ let nx = { content = x;
126126+ smaller = [];
127127+ bigger = [];
128128+ mark = false
129129+ } in
130130+ ordering.cnt <- nx :: ordering.cnt
131131+132132+133133+ (******************************************************************)
134134+135135+ let find_node ordering kx =
136136+ let rec search l =
137137+ match l with
138138+ [] -> raise Not_found
139139+ | y :: l' -> if H.id y.content = kx then y else search l'
140140+ in
141141+ search ordering.cnt
142142+143143+144144+ let find ordering kx = (find_node ordering kx).content
145145+146146+ (******************************************************************)
147147+148148+ let replace ordering kx x' =
149149+ let x = find_node ordering kx in
150150+ x.content <- x'
151151+152152+ (******************************************************************)
153153+154154+ let delete ordering kx =
155155+ let x = find_node ordering kx in
156156+ ordering.cnt <- delete_all (fun a -> a == x) ordering.cnt;
157157+ List.iter
158158+ (fun x ->
159159+ x.smaller <- delete_all (fun a -> a == x) x.smaller;
160160+ x.bigger <- delete_all (fun a -> a == x) x.bigger)
161161+ ordering.cnt
162162+163163+164164+ (******************************************************************)
165165+166166+ let le_than ordering kx ky =
167167+ (* Find x, y: *)
168168+ let x = find_node ordering kx in
169169+ let y = find_node ordering ky in
170170+171171+ let rec search x1 =
172172+ if x1 == y then
173173+ true
174174+ else
175175+ List.exists search x1.bigger
176176+177177+ in
178178+ search x
179179+180180+ (******************************************************************)
181181+182182+ let let_le ordering kx ky =
183183+ (* Find x, y: *)
184184+ let x = find_node ordering kx in
185185+ let y = find_node ordering ky in
186186+187187+ (* If already done just return (this is an idempotent function) *)
188188+ if not (List.memq x y.smaller) then begin
189189+190190+ (* let x <= y. This is only allowed if not (y <= x) *)
191191+ if le_than ordering ky kx then
192192+ raise Inconsistent_ordering;
193193+194194+ (* Ok, add the relation *)
195195+ x.bigger <- y :: x.bigger;
196196+ y.smaller <- x :: y.smaller
197197+ end
198198+199199+ (******************************************************************)
200200+201201+ let key x = H.id x
202202+203203+ (******************************************************************)
204204+205205+ let iter upwards f ordering =
206206+207207+ let in_direction n =
208208+ if upwards then n.bigger else n.smaller in
209209+210210+ let against_direction n =
211211+ if upwards then n.smaller else n.bigger in
212212+213213+ (* the following is written as if for iter_up. *)
214214+215215+ let rec find_biggest ordlist =
216216+ (* find biggest, non-marked node *)
217217+ match ordlist with
218218+ [] -> raise Not_found
219219+ | nx :: ordlist' -> if not nx.mark && in_direction nx = []
220220+ then nx
221221+ else find_biggest ordlist'
222222+ in
223223+224224+ let rec run_up n =
225225+ (* iterate over all nodes <= x and return their number *)
226226+227227+ let rec run_up_list l =
228228+ match l with
229229+ [] -> 0
230230+ | x :: l' -> run_up x + run_up_list l'
231231+ in
232232+233233+ if n.mark then
234234+ (* have already visited this node *)
235235+ 0
236236+ else
237237+ let u = run_up_list (against_direction n) in
238238+ n.mark <- true;
239239+ f n.content;
240240+ u + 1
241241+ in
242242+243243+ (* Lock *)
244244+ if ordering.lock then
245245+ failwith "iter_up: recursive application not allowed";
246246+ ordering.lock <- true;
247247+248248+ (* clear all marks *)
249249+ List.iter (fun nx -> nx.mark <- false) ordering.cnt;
250250+251251+ (* Catch exceptions *)
252252+253253+ try
254254+ (* while there is a biggest node... *)
255255+ let c = ref 0 in (* counter *)
256256+ while !c < List.length ordering.cnt do
257257+258258+ (* Find a biggest node *)
259259+ let n_biggest = find_biggest ordering.cnt in
260260+261261+ (* run through the graph *)
262262+ c := !c + run_up n_biggest
263263+264264+ done;
265265+266266+ (* unlock *)
267267+ ordering.lock <- false
268268+269269+ with
270270+ any -> (* unlock, too *)
271271+ ordering.lock <- false;
272272+ raise any
273273+274274+275275+ let iter_up = iter true
276276+ let iter_down = iter false
277277+278278+279279+ (******************************************************************)
280280+281281+ let iter_at upwards f ordering startpoints =
282282+283283+(*
284284+ let in_direction n =
285285+ if upwards then n.bigger else n.smaller in
286286+ *)
287287+288288+ let against_direction n =
289289+ if upwards then n.smaller else n.bigger in
290290+291291+ (* the following is written as if for iter_up. *)
292292+293293+ let rec run_up n =
294294+ (* iterate over all nodes <= x and return their number *)
295295+296296+ let rec run_up_list l =
297297+ match l with
298298+ [] -> 0
299299+ | x :: l' -> run_up x + run_up_list l'
300300+ in
301301+302302+ if n.mark then
303303+ (* have already visited this node *)
304304+ 0
305305+ else
306306+ let u = run_up_list (against_direction n) in
307307+ n.mark <- true;
308308+ f n.content;
309309+ u + 1
310310+ in
311311+312312+ (* Lock *)
313313+ if ordering.lock then
314314+ failwith "iter_up: recursive application not allowed";
315315+ ordering.lock <- true;
316316+317317+ (* clear all marks *)
318318+ List.iter (fun nx -> nx.mark <- false) ordering.cnt;
319319+320320+ (* Catch exceptions *)
321321+322322+ try
323323+324324+ List.iter
325325+ (fun start ->
326326+ let _ = run_up (find_node ordering start) in ())
327327+ startpoints;
328328+329329+ (* unlock *)
330330+ ordering.lock <- false
331331+332332+ with
333333+ any -> (* unlock, too *)
334334+ ordering.lock <- false;
335335+ raise any
336336+337337+338338+ let iter_up_at = iter_at true
339339+ let iter_down_at = iter_at false
340340+341341+342342+ (******************************************************************)
343343+344344+ end
+42
vendor/opam/ocamlfind/src/findlib/fl_topo.mli
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(* The type topo.t is a partially ordered relation. You can add an element
77+ * by giving all descendents ...
88+ *)
99+1010+module type IdentifiedType =
1111+ sig
1212+ type t
1313+ type id_t
1414+ val id : t -> id_t
1515+ end
1616+1717+exception Inconsistent_ordering
1818+1919+module type S =
2020+ sig
2121+ type key
2222+ type el_t
2323+ type t
2424+ val create : unit -> t
2525+ val add : t -> el_t -> unit
2626+ val let_le : t -> key -> key -> unit
2727+ val find : t -> key -> el_t
2828+ val le_than : t -> key -> key -> bool
2929+ val key : el_t -> key
3030+ val iter_up : (el_t -> unit) -> t -> unit
3131+ val iter_down : (el_t -> unit) -> t -> unit
3232+ val iter_up_at : (el_t -> unit) -> t -> key list -> unit
3333+ val iter_down_at : (el_t -> unit) -> t -> key list -> unit
3434+ val clear : t -> unit
3535+ val replace : t -> key -> el_t -> unit
3636+ val delete : t -> key -> unit
3737+ val copy : t -> t
3838+ end
3939+4040+module Make(H: IdentifiedType):
4141+ (S with type el_t = H.t
4242+ and type key = H.id_t)
+2694
vendor/opam/ocamlfind/src/findlib/frontend.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+open Findlib;;
77+88+exception Usage;;
99+exception Silent_error;;
1010+1111+type mode =
1212+ M_use | M_query | M_install | M_remove | M_compiler of string | M_dep
1313+ | M_printconf | M_list | M_browser | M_call of (string*string)
1414+ | M_doc | M_lint | M_printppx
1515+;;
1616+1717+1818+type psubst =
1919+ Const of string
2020+ | Percent of string * modifier
2121+ | Lookup of string * modifier
2222+2323+and modifier =
2424+ | Plain
2525+ | Plus
2626+;;
2727+2828+let sys_error code arg =
2929+ if arg = "" then
3030+ Sys_error (Unix.error_message code)
3131+ else
3232+ Sys_error (arg ^ ": " ^ Unix.error_message code)
3333+3434+3535+let slashify s =
3636+ match Findlib_config.system with
3737+ | "mingw" | "mingw64" | "cygwin" ->
3838+ let b = Buffer.create 80 in
3939+ String.iter
4040+ (function
4141+ | '\\' -> Buffer.add_char b '/'
4242+ | c -> Buffer.add_char b c
4343+ )
4444+ s;
4545+ Buffer.contents b
4646+ | _ ->
4747+ s
4848+4949+5050+let out_path ?(prefix="") s =
5151+ match Findlib_config.system with
5252+ | "mingw" | "mingw64" | "cygwin" ->
5353+ let u = slashify s in
5454+ prefix ^
5555+ (if String.contains u ' ' then
5656+ (* Desperate attempt to fix the space problem in paths.
5757+ Note that we invoke commands via Unix.open_process, and
5858+ this function already quotes the arguments on win32.
5959+ However, for -ccopt arguments, one quoting level seems
6060+ to be lost, and we have to add another level to compensate.
6161+ E.g. for the list of args
6262+ [ -ccopt; -L/my programs/include -L/somewhere ]
6363+ we get after out_path
6464+ [ -ccopt; "-I/my programs/include -L/somewhere" ]
6565+ which actually translates to
6666+ -ccopt "\"-I/my programs/include\" \"-L/somewhere\""
6767+ on the command line, i.e. a double-quoted argument.
6868+ *)
6969+ "\"" ^ u ^ "\""
7070+ else
7171+ u
7272+ )
7373+ | _ ->
7474+ prefix ^ slashify s
7575+7676+7777+7878+let percent_subst ?base spec lookup s =
7979+ (* spec = [ "%c", [ "ctext1"; "ctext2"; ... ];
8080+ * "%d", [ "dtext1"; "dtext2"; ... ] ]
8181+ * All occurrences of %c in the string s are replaced as specified in spec.
8282+ * spec is an association list with the %-notation as keys
8383+ * and lists of strings as values. The result is a list of strings containing
8484+ * every combination of substituted values.
8585+ *
8686+ * Support for the %(name) syntax: In this case, the name is taken as
8787+ * key for the [lookup] function, which either returns the string value
8888+ * or raises Not_found.
8989+ *
9090+ * "+" modifier: A "+" after "%" causes that Findlib.resolve_path is
9191+ * called for the substitution string (e.g. %+c, %+(name)).
9292+ *
9393+ * Example:
9494+ * spec = [ "%a", [ "file1" ] ]
9595+ * lookup = function "archive" -> "file2" | _ -> raise Not_found
9696+ * Here, %a is substituted by file1, and %(archive) is substituted by
9797+ * file2.
9898+ *
9999+ * ?base: The base parameter for Findlib.resolve_path.
100100+ *)
101101+ let l = String.length s in
102102+103103+ let fail() =
104104+ failwith "bad format string" in
105105+106106+ let parenthesized_name j =
107107+ try
108108+ if j+1>=l then raise Not_found;
109109+ let k = String.index_from s (j+1) ')' in
110110+ let name = String.sub s (j+1) (k-j-1) in
111111+ (name, k+1)
112112+ with Not_found ->
113113+ fail() in
114114+115115+ let rec preprocess i j =
116116+ if j<l then begin
117117+ match s.[j] with
118118+ '%' ->
119119+ if j+1<l then begin
120120+ let prev = Const(String.sub s i (j-i)) in
121121+ let c = s.[j+1] in
122122+ match c with
123123+ '%' ->
124124+ prev :: Const "%" :: preprocess (j+2) (j+2)
125125+ | '(' ->
126126+ let name, j_next = parenthesized_name (j+1) in
127127+ prev :: Lookup(name,Plain) :: preprocess j_next j_next
128128+ | '+' ->
129129+ if j+2<l then begin
130130+ let c = s.[j+2] in
131131+ match c with
132132+ | '%' | '+' -> fail()
133133+ | '(' ->
134134+ let name, j_next = parenthesized_name (j+2) in
135135+ prev :: Lookup(name,Plus) :: preprocess j_next j_next
136136+ | _ ->
137137+ let name = "%" ^ String.make 1 c in
138138+ prev :: Percent(name,Plus) :: preprocess (j+3) (j+3)
139139+ end
140140+ else fail()
141141+ | _ ->
142142+ let name = "%" ^ String.make 1 c in
143143+ prev :: Percent(name,Plain) :: preprocess (j+2) (j+2)
144144+ end
145145+ else fail()
146146+ | _ ->
147147+ preprocess i (j+1)
148148+ end
149149+ else
150150+ if i<j then
151151+ [Const(String.sub s i (j-i))]
152152+ else
153153+ []
154154+ in
155155+156156+ let plus_subst u =
157157+ String.concat
158158+ " "
159159+ (List.map
160160+ (Findlib.resolve_path ?base)
161161+ (Fl_split.in_words u)) in
162162+163163+ let any_subst modi u =
164164+ match modi with
165165+ | Plain -> u
166166+ | Plus -> plus_subst u in
167167+168168+ let rec subst prefix l =
169169+ match l with
170170+ [] -> [prefix]
171171+ | Const s :: l' ->
172172+ subst (prefix ^ s) l'
173173+ | Percent(name,modi) :: l' ->
174174+ let replacements0 =
175175+ try List.assoc name spec
176176+ with Not_found -> failwith "bad format string" in
177177+ let replacements =
178178+ List.map (any_subst modi) replacements0 in
179179+ List.flatten
180180+ (List.map
181181+ (fun replacement ->
182182+ subst (prefix ^ replacement) l')
183183+ replacements)
184184+ | Lookup(name,modi) :: l' ->
185185+ let replacement0 =
186186+ try lookup name
187187+ with Not_found -> "" in
188188+ let replacement =
189189+ any_subst modi replacement0 in
190190+ subst (prefix ^ replacement) l'
191191+ in
192192+193193+ subst "" (preprocess 0 0)
194194+;;
195195+196196+197197+let rec remove_dups l =
198198+ match l with
199199+ x :: l' ->
200200+ if List.mem x l' then remove_dups l' else x::remove_dups l'
201201+ | [] -> []
202202+;;
203203+204204+205205+let arg n =
206206+ if n < Array.length Sys.argv then Sys.argv.(n) else raise Not_found
207207+;;
208208+209209+210210+let escape_if_needed s =
211211+ if String.contains s ' ' then "\"" ^ String.escaped s ^ "\"" else s
212212+;;
213213+214214+215215+let use_package prefix pkgnames =
216216+ (* may raise No_such_package *)
217217+ let pdirs =
218218+ List.map
219219+ (fun pname ->
220220+ "-I " ^ out_path(package_directory pname)
221221+ )
222222+ pkgnames
223223+ in
224224+225225+ print_endline (prefix ^ String.concat " " pdirs)
226226+;;
227227+228228+229229+let read_ldconf filename =
230230+ let lines = ref [] in
231231+ let f = open_in filename in
232232+ try
233233+ while true do
234234+ let line = input_line f in
235235+ if line <> "" then
236236+ lines := line :: !lines
237237+ done;
238238+ assert false
239239+ with
240240+ End_of_file ->
241241+ close_in f;
242242+ List.rev !lines
243243+ | other ->
244244+ close_in f;
245245+ raise other
246246+;;
247247+248248+249249+let write_ldconf filename lines new_lines =
250250+ let f = open_out filename in
251251+ try
252252+ List.iter
253253+ (fun line -> output_string f (line ^ "\n"))
254254+ (lines @ new_lines);
255255+ close_out f;
256256+ prerr_endline("Updated " ^ filename);
257257+ with
258258+ Sys_error e ->
259259+ prerr_endline ("ocamlfind: [WARNING] Cannot write " ^ filename);
260260+ prerr_endline ("Reason: " ^ e);
261261+ prerr_endline ("This file contains the directories with DLLs.");
262262+ if new_lines <> [] then begin
263263+ prerr_endline ("It is recommended to add the following line(s) to this file:");
264264+ List.iter prerr_endline new_lines
265265+ end
266266+;;
267267+268268+269269+let is_dll p =
270270+ let sfx = Findlib_config.dll_suffix in
271271+ sfx <> "" && Filename.check_suffix p sfx
272272+;;
273273+274274+275275+let identify_dir d =
276276+ match Sys.os_type with
277277+ | "Win32" ->
278278+ failwith "identify_dir" (* not available *)
279279+ | _ ->
280280+ let s = Unix.stat d in
281281+ (s.Unix.st_dev, s.Unix.st_ino)
282282+;;
283283+284284+285285+let conflict_report incpath pkglist =
286286+ (* Check whether there are several definitions for packages
287287+ * in the current path. We remove duplicate directories first.
288288+ * Note that all other checks are not sensitive to duplicate directories.
289289+ *)
290290+ Fl_package_base.package_conflict_report ~identify_dir ();
291291+292292+ (* Second check whether there are module conflicts *)
293293+ let pkgpath =
294294+ List.map Findlib.package_directory pkglist in
295295+ Fl_package_base.module_conflict_report ~identify_dir (pkgpath @ incpath);
296296+297297+ (* Finally check whether there are multiple DLLs: *)
298298+ (* Note: Only the directories mentioned in ld.conf are checked, but not the
299299+ * directories in [incpath], and not the directories in CAML_LD_LIBRARY_PATH.
300300+ * The idea of this check is to ensure a proper installation, and not to
301301+ * complain about the user's special configuration.
302302+ *)
303303+ let ldconf = ocaml_ldconf() in
304304+ if ldconf <> "ignore" then begin
305305+ let dll_dirs = remove_dups (read_ldconf ldconf) in
306306+ let dll_pairs =
307307+ List.flatten
308308+ (List.map
309309+ (fun dll_dir ->
310310+ let files =
311311+ try Array.to_list (Sys.readdir dll_dir)
312312+ with _ ->
313313+ prerr_endline ("ocamlfind: [WARNING] Cannot read directory " ^
314314+ dll_dir ^ " which is mentioned in ld.conf");
315315+ []
316316+ in
317317+ List.map
318318+ (fun file -> (file, dll_dir))
319319+ (List.filter is_dll files)
320320+ )
321321+ dll_dirs
322322+ ) in
323323+ let dll_hash = Hashtbl.create 50 in
324324+ List.iter
325325+ (fun (file, dll_dir) -> Hashtbl.add dll_hash file dll_dir)
326326+ dll_pairs;
327327+ Hashtbl.iter
328328+ (fun file dll_dir ->
329329+ let locations = Hashtbl.find_all dll_hash file in
330330+ if List.length locations > 1 then begin
331331+ prerr_endline ("ocamlfind: [WARNING] The DLL " ^ file ^
332332+ " occurs in multiple directories: " ^ dll_dir)
333333+ end
334334+ )
335335+ dll_hash
336336+ end
337337+;;
338338+339339+340340+let check_package_list l =
341341+ (* may raise No_such_package *)
342342+ List.iter
343343+ (fun pkg ->
344344+ let _ = package_directory pkg in
345345+ ()
346346+ )
347347+ l
348348+;;
349349+350350+351351+type verbosity =
352352+ | Normal
353353+ | Verbose
354354+ | Only_show
355355+356356+357357+let run_command ?filter verbose cmd args =
358358+ let printable_cmd =
359359+ cmd ^ " " ^ String.concat " " (List.map escape_if_needed args) in
360360+ ( match verbose with
361361+ | Normal ->
362362+ ()
363363+ | Verbose ->
364364+ print_endline ("+ " ^ printable_cmd);
365365+ if filter <> None then
366366+ print_string
367367+ (" (output of this command is filtered by ocamlfind)\n")
368368+ | Only_show ->
369369+ print_endline printable_cmd
370370+ );
371371+ flush stdout;
372372+373373+ if verbose <> Only_show then (
374374+ let filter_input, cmd_output =
375375+ match filter with
376376+ None -> Unix.stdin (* dummy *), Unix.stdout
377377+ | Some f -> Unix.pipe()
378378+ in
379379+380380+ (* Signals: On SIGINT, we wait until the subprocess finishes, and
381381+ * die then. This allows us to call interactive commands as subprocesses.
382382+ *)
383383+384384+ let old_sigint =
385385+ Sys.signal Sys.sigint Sys.Signal_ignore in
386386+387387+ let need_exe =
388388+ List.mem Findlib_config.system [ "win32"; "win64"; "mingw"; "mingw64" ] in
389389+390390+ let fixed_cmd =
391391+ if need_exe then (
392392+ if Filename.check_suffix cmd ".exe" then cmd else cmd ^ ".exe"
393393+ )
394394+ else
395395+ cmd in
396396+397397+ let pid =
398398+ Unix.create_process
399399+ fixed_cmd
400400+ (Array.of_list (cmd :: args))
401401+ Unix.stdin
402402+ cmd_output
403403+ Unix.stderr
404404+ in
405405+406406+ begin match filter with
407407+ Some filter_fun ->
408408+ begin
409409+ Unix.close cmd_output;
410410+ let ch = Unix.in_channel_of_descr filter_input in
411411+ try
412412+ while true do
413413+ let line = input_line ch in
414414+ match filter_fun line with
415415+ None -> () (* Suppress line *)
416416+ | Some line' -> print_endline line'
417417+ done;
418418+ assert false
419419+ with
420420+ End_of_file ->
421421+ close_in ch;
422422+ flush stdout
423423+ end
424424+ | None -> ()
425425+ end;
426426+427427+ let (_,status) = Unix.waitpid [] pid in
428428+ Sys.set_signal Sys.sigint old_sigint;
429429+ begin
430430+ match status with
431431+ Unix.WEXITED 0 -> ()
432432+ | Unix.WEXITED n ->
433433+ if verbose = Verbose then
434434+ print_string (cmd ^ " returned with exit code " ^ string_of_int n ^ "\n");
435435+ exit n
436436+ | Unix.WSIGNALED _ ->
437437+ print_string (cmd ^ " got signal and exited\n");
438438+ exit 2
439439+ | Unix.WSTOPPED _ ->
440440+ failwith "Your operating system does not work correctly"
441441+ end
442442+ )
443443+;;
444444+445445+446446+(**************** preprocessor ******************************************)
447447+448448+let select_pp_packages syntax_preds packages =
449449+ if syntax_preds = [] then
450450+ (* No syntax predicates, no preprocessor! *)
451451+ []
452452+ else
453453+ List.filter
454454+ (fun pkg ->
455455+ let al = try package_property syntax_preds pkg "archive"
456456+ with Not_found -> "" in
457457+ let w = Fl_split.in_words al in
458458+ w <> []
459459+ )
460460+ packages
461461+462462+463463+let process_pp_spec syntax_preds packages pp_opts =
464464+ (* Returns: pp_command *)
465465+ (* may raise No_such_package *)
466466+467467+ (* [packages]: all packages given on the command line. May include
468468+ * packages for compilation and for preprocessing.
469469+ *
470470+ * The difficulty is now that the preprocessor packages may have
471471+ * requirements that are non-preprocessor packages. To get exactly
472472+ * the preprocessor packages and its requirements, we do:
473473+ *
474474+ * 1. Determine the subset of [packages] that are preprocessor
475475+ * packages by checking whether they have an "archive" for
476476+ * [syntax_preds], i.e. the preprocessor packages mentioned
477477+ * on the command line = [cl_pp_packages].
478478+ *
479479+ * 2. Add their requirements = [pp_packages]
480480+ *
481481+ * Because the packages are now mixed, we must evaluate for
482482+ * [syntax_preds] + "byte".
483483+ *)
484484+485485+ (* One packages must now have the variable "preprocessor", usually camlp4 *)
486486+ let cl_pp_packages = select_pp_packages syntax_preds packages in
487487+ let pp_packages =
488488+ package_deep_ancestors syntax_preds cl_pp_packages in
489489+490490+ let preprocessor_cmds =
491491+ List.flatten
492492+ (List.map (fun pname ->
493493+ try
494494+ [ pname,
495495+ package_property syntax_preds pname "preprocessor"
496496+ ]
497497+ with
498498+ Not_found -> []
499499+ )
500500+ pp_packages
501501+ )
502502+ in
503503+504504+ let preprocessor_cmd =
505505+ if syntax_preds <> [] then
506506+ match preprocessor_cmds with
507507+ [] ->
508508+ failwith("Using -syntax, but no package is selected specifying \
509509+ a preprocessor as required for -syntax")
510510+ | [_, cmd] -> Some cmd
511511+ | _ ->
512512+ failwith("Several packages are selected that specify \
513513+ preprocessors: " ^
514514+ String.concat ", "
515515+ (List.map
516516+ (fun (n,v) ->
517517+ "package " ^ n ^ " defines `" ^ v ^ "'")
518518+ preprocessor_cmds
519519+ )
520520+ )
521521+ else
522522+ None
523523+ in
524524+525525+ let pp_i_options =
526526+ List.flatten
527527+ (List.map
528528+ (fun pkg ->
529529+ let pkgdir = package_directory pkg in
530530+ [ "-I"; slashify pkgdir ]
531531+ )
532532+ pp_packages) in
533533+534534+ let pp_archives =
535535+ if preprocessor_cmd = None then
536536+ []
537537+ else
538538+ List.flatten
539539+ (List.map
540540+ (fun pkg ->
541541+ let al =
542542+ try package_property ("byte" :: syntax_preds) pkg "archive"
543543+ with Not_found -> "" in
544544+ Fl_split.in_words al
545545+ )
546546+ pp_packages) in
547547+548548+ match preprocessor_cmd with
549549+ None -> []
550550+ | Some cmd ->
551551+ ["-pp";
552552+ cmd ^ " " ^
553553+ String.concat " " (List.map Filename.quote pp_i_options) ^ " " ^
554554+ String.concat " " (List.map Filename.quote pp_archives) ^ " " ^
555555+ String.concat " " (List.map Filename.quote pp_opts)]
556556+;;
557557+558558+(**************** ppx extensions ****************************************)
559559+560560+let process_ppx_spec predicates packages ppx_opts =
561561+ (* Returns: ppx_commands *)
562562+ (* may raise No_such_package *)
563563+564564+ let ppx_packages =
565565+ package_deep_ancestors predicates packages in
566566+567567+ let ppx_opts =
568568+ List.map
569569+ (fun opt ->
570570+ match Fl_split.in_words opt with
571571+ | pkg :: ((_ :: _) as opts) ->
572572+ let exists =
573573+ try ignore(package_directory pkg); true
574574+ with No_such_package _ -> false in
575575+ if not exists then
576576+ failwith ("The package named in -ppxopt does not exist: " ^
577577+ pkg);
578578+ pkg, opts
579579+ | _ ->
580580+ failwith "-ppxopt must include package name, e.g. -ppxopt \"foo,-name bar\""
581581+ )
582582+ ppx_opts in
583583+584584+ let meta_ppx_opts =
585585+ List.concat
586586+ (List.map
587587+ (fun pname ->
588588+ try
589589+ let opts = package_property predicates pname "ppxopt" in
590590+ (* Split by whitespace to get (package,options) combinations.
591591+ Then, split by commas to get individual options. *)
592592+ List.map
593593+ (fun opts ->
594594+ match Fl_split.in_words opts with
595595+ | pkg :: ((_ :: _) as opts) ->
596596+ let exists =
597597+ try ignore(package_directory pkg); true
598598+ with No_such_package _ -> false in
599599+ if not exists then
600600+ failwith ("The package named in ppxopt variable does not exist: " ^
601601+ pkg ^ " (from " ^ pname ^ ")");
602602+ let base = package_directory pname in
603603+ pkg, List.map (resolve_path ~base ~explicit:true) opts
604604+ | _ ->
605605+ failwith ("ppxopt variable must include package name, e.g. " ^
606606+ "ppxopt=\"foo,-name bar\" (from " ^ pname ^ ")")
607607+ )
608608+ (Fl_split.in_words_ws opts)
609609+ with Not_found -> []
610610+ )
611611+ ppx_packages
612612+ ) in
613613+614614+ List.flatten
615615+ (List.map
616616+ (fun pname ->
617617+ let base = package_directory pname in
618618+ let options =
619619+ try
620620+ List.concat
621621+ (List.map (fun (_, opts) -> opts)
622622+ (List.filter (fun (pname', _) -> pname' = pname)
623623+ (meta_ppx_opts @ ppx_opts)))
624624+ with Not_found -> []
625625+ in
626626+ try
627627+ let preprocessor =
628628+ resolve_path
629629+ ~base ~explicit:true
630630+ (package_property predicates pname "ppx") in
631631+ ["-ppx"; String.concat " " (preprocessor :: options)]
632632+ with Not_found -> []
633633+ )
634634+ ppx_packages)
635635+636636+(**************** Generic argument processing *************************)
637637+638638+let merge_native_arguments native_spec f_unit f_string f_special_list =
639639+ List.map
640640+ (fun (switch_name, switch_has_arg, help_text) ->
641641+ let f =
642642+ try
643643+ List.assoc switch_name f_special_list
644644+ with
645645+ Not_found ->
646646+ if switch_has_arg then
647647+ f_string switch_name
648648+ else
649649+ f_unit switch_name in
650650+ (switch_name, f, help_text)
651651+ )
652652+ native_spec
653653+;;
654654+655655+656656+let parse_args
657657+ ?(current = Arg.current) ?(args = Sys.argv)
658658+ ?(align = true)
659659+ spec anon usage =
660660+ try
661661+ Arg.parse_argv
662662+ ~current
663663+ args
664664+ (if align then Arg.align spec else spec)
665665+ anon
666666+ usage
667667+ with
668668+ | Arg.Help text ->
669669+ print_string text;
670670+ exit 0
671671+ | Arg.Bad text ->
672672+ prerr_string text;
673673+ exit 2
674674+675675+676676+(************************* format expansion *************************)
677677+678678+679679+let expand predicates eff_packages format =
680680+ (* may raise No_such_package *)
681681+682682+ (* format:
683683+ * %p package name
684684+ * %d package directory
685685+ * %m META file
686686+ * %D description
687687+ * %v version
688688+ * %a archive file(s)
689689+ * %A archive files as single string
690690+ * %o link option(s)
691691+ * %O link options as single string
692692+ *)
693693+694694+ List.flatten
695695+ (List.map
696696+ (fun pkg ->
697697+ let dir = package_directory pkg in
698698+ (* May raise No_such_package *)
699699+ let spec =
700700+ [ "%p", [pkg];
701701+ "%d", [out_path dir];
702702+ "%m", [out_path (package_meta_file pkg)];
703703+ "%D", [try package_property predicates pkg "description"
704704+ with Not_found -> "[n/a]"];
705705+ "%v", [try package_property predicates pkg "version"
706706+ with Not_found -> "[unspecified]"];
707707+ "%a", Fl_split.in_words
708708+ (try package_property predicates pkg "archive"
709709+ with Not_found -> "");
710710+ "%A", [String.concat " "
711711+ (Fl_split.in_words
712712+ (try package_property predicates pkg "archive"
713713+ with Not_found -> ""))];
714714+ "%o", Fl_split.in_words_ws
715715+ (try package_property predicates pkg "linkopts"
716716+ with Not_found -> "");
717717+ "%O", [String.concat " "
718718+ (Fl_split.in_words_ws
719719+ (try package_property predicates pkg "linkopts"
720720+ with Not_found -> ""))];
721721+ ]
722722+ in
723723+ let lookup = package_property predicates pkg in
724724+ percent_subst ~base:dir spec lookup format)
725725+ eff_packages)
726726+;;
727727+728728+729729+let help_format() =
730730+ print_endline
731731+ "Formats for -format strings:
732732+733733+ %p package name
734734+ %d package directory
735735+ %m META file
736736+ %D description
737737+ %v version
738738+ %a archive file(s)
739739+ %+a archive file(s), converted to absolute paths
740740+ %A archive files as single string
741741+ %+A archive files as single string, converted to absolute paths
742742+ %o link option(s)
743743+ %O link options as single string
744744+ %(name) the value of the property <name>
745745+ %+(name) the value of the property <name>, converted to absolute paths
746746+ (like <archive>)";
747747+ flush stdout
748748+749749+750750+751751+(************************** QUERY SUBCOMMAND ***************************)
752752+753753+let query_package () =
754754+755755+ let long_format =
756756+ "package: %p\ndescription: %D\nversion: %v\narchive(s): %A\nlinkopts: %O\nlocation: %d\n" in
757757+ let i_format =
758758+ "-I %d" in
759759+ let l_format =
760760+ if Findlib_config.system = "win32" || Findlib_config.system = "win64" then
761761+ (* Microsoft toolchain *)
762762+ "-ccopt \"/link /libpath:%d\""
763763+ else
764764+ "-ccopt -L%d" in
765765+ let a_format =
766766+ "%+a" in
767767+ let o_format =
768768+ "%o" in
769769+ let p_format =
770770+ "%p" in
771771+772772+ let predicates = ref [] in
773773+ let format = ref "%d" in
774774+ let separator = ref "\n" in
775775+ let prefix = ref "" in
776776+ let suffix = ref "\n" in
777777+ let recursive = ref false in
778778+ let descendants = ref false in
779779+ let pp = ref false in
780780+ let qe = ref false in
781781+ let qo = ref false in
782782+783783+ let packages = ref [] in
784784+785785+ let append_predicate s =
786786+ let pl = Fl_split.in_words s in
787787+ predicates := !predicates @ pl
788788+ in
789789+790790+791791+ parse_args
792792+ [ "-predicates", Arg.String append_predicate,
793793+ " specifies comma-separated list of assumed predicates";
794794+ "-format", Arg.String (fun s -> format := s),
795795+ "<fmt> specifies the output format";
796796+ "-separator", Arg.String (fun s -> separator := s),
797797+ " specifies the string that separates multiple answers";
798798+ "-prefix", Arg.String (fun s -> prefix := s),
799799+ "<p> a string printed before the first answer";
800800+ "-suffix", Arg.String (fun s -> suffix := s),
801801+ "<s> a string printed after the last answer";
802802+ "-recursive", Arg.Set recursive,
803803+ " select direct and indirect ancestors/descendants, too";
804804+ "-r", Arg.Set recursive,
805805+ " same as -recursive";
806806+ "-descendants", Arg.Unit (fun () -> descendants := true; recursive := true),
807807+ " query descendants instead of ancestors; implies -recursive";
808808+ "-d", Arg.Unit (fun () -> descendants := true; recursive := true),
809809+ " same as -descendants";
810810+ "-pp", Arg.Unit (fun () -> pp := true; recursive := true),
811811+ " get preprocessor pkgs (predicates are taken as syntax preds)";
812812+ "-long-format", Arg.Unit (fun () -> format := long_format),
813813+ " specifies long output format";
814814+ "-l", Arg.Unit (fun () -> format := long_format),
815815+ " same as -long-format";
816816+ "-i-format", Arg.Unit (fun () -> format := i_format),
817817+ " prints -I options for ocamlc";
818818+ "-l-format", Arg.Unit (fun () -> format := l_format),
819819+ " prints -ccopt -L options for ocamlc";
820820+ "-a-format", Arg.Unit (fun () -> format := a_format),
821821+ " prints names of archives to be linked in for ocamlc";
822822+ "-o-format", Arg.Unit (fun () -> format := o_format),
823823+ " prints link options for ocamlc";
824824+ "-p-format", Arg.Unit (fun () -> format := p_format),
825825+ " prints package names";
826826+ "-help-format", Arg.Unit help_format,
827827+ " lists the supported formats for -format";
828828+ "-qe", Arg.Set qe,
829829+ " do not print most errors, just set the exit code";
830830+ "-qo", Arg.Set qo,
831831+ " do not print regular output";
832832+ ]
833833+ (fun p -> packages := !packages @ Fl_split.in_words p)
834834+"usage: ocamlfind query [ -predicates <p> | -format <f> |
835835+ -long-format | -i-format |
836836+ -l-format | -a-format |
837837+ -o-format | -p-format |
838838+ -prefix <p> | -suffix <s> |
839839+ -separator <s> |
840840+ -descendants | -recursive ] package ...";
841841+842842+ ignore(config_file()); (* ensure findlib is initialized *)
843843+ try
844844+ let predicates1 =
845845+ if !pp then
846846+ "preprocessor" :: "syntax" :: !predicates
847847+ else
848848+ !predicates in
849849+ let packages1 =
850850+ if !pp then
851851+ let predicates2 =
852852+ List.filter (fun p -> p <> "byte" && p <> "native") predicates1 in
853853+ select_pp_packages predicates2 !packages
854854+ else
855855+ !packages in
856856+ let eff_packages =
857857+ if !recursive then begin
858858+ if !descendants then
859859+ Fl_package_base.package_users ~preds:predicates1 packages1
860860+ else
861861+ package_deep_ancestors predicates1 packages1
862862+ end
863863+ else
864864+ packages1
865865+ in
866866+867867+ let answers = expand predicates1 eff_packages !format in
868868+869869+ if not !qo then (
870870+ print_string !prefix;
871871+ print_string (String.concat !separator answers);
872872+ print_string !suffix;
873873+ )
874874+ with
875875+ ( Findlib.No_such_package _
876876+ | Failure _
877877+ | Sys_error _
878878+ ) when !qe -> raise Silent_error
879879+;;
880880+881881+882882+(**************** OCAMLC/OCAMLMKTOP/OCAMLOPT subcommands ****************)
883883+884884+type pass_file_t =
885885+ Pass of string
886886+ | Impl of string (* Forces module implementation: -impl <file> *)
887887+ | Intf of string (* Forces module interface: -intf <file> *)
888888+ | Cclib of string (* Option for the C linker: -cclib <opt> *)
889889+;;
890890+891891+892892+let contracted_ocamlmklib_options =
893893+ [ "-l"; "-L"; "-R"; "-F"; "-Wl,-rpath,"; "-Wl,-R" ]
894894+ (* The ocamlmklib options where the argument is directly attached to the
895895+ switch (e.g. -L<path> instead of -L <path>)
896896+ *)
897897+898898+899899+let ocamlc which () =
900900+901901+ (* let destdir = ref (default_location()) in *)
902902+903903+ let switches = ref [] in
904904+ let pass_options = ref [] in
905905+ let pass_files = ref [] in
906906+ let incpath = ref [] in
907907+ let only_show = ref false in
908908+909909+ let dll_pkgs = ref [] in
910910+ let dll_pkgs_all = ref false in
911911+912912+ let linkpkg = ref false in
913913+914914+ let packages = ref [] in
915915+ let predicates = ref [] in
916916+ let dontlink = ref [] in
917917+918918+ let syntax_preds = ref [] in
919919+ let pp_opts = ref [] in
920920+ let ppx_opts = ref [] in
921921+ let pp_specified = ref false in
922922+923923+ let type_of_threads =
924924+ try package_property [] "threads" "type_of_threads"
925925+ with Not_found -> "ignore"
926926+ in
927927+ let threads_default =
928928+ match type_of_threads with
929929+ "posix" -> `POSIX_threads
930930+ | "vm" -> `VM_threads
931931+ | _ -> `None
932932+ in
933933+ let threads = ref `None in
934934+ let support_threads() =
935935+ if threads_default = `None then
936936+ failwith "threading is not supported on this platform" in
937937+938938+ let add_switch name =
939939+ Arg.Unit (fun () ->
940940+ switches := name :: !switches;
941941+ pass_options := !pass_options @ [name]) in
942942+ let add_spec_fn name s =
943943+ pass_options := !pass_options @ [name; s] in
944944+ let add_spec name =
945945+ Arg.String (add_spec_fn name) in
946946+ let add_contracted_spec_fn name s =
947947+ pass_options := !pass_options @ [name ^ s] in
948948+ let add_contracted_spec name =
949949+ Arg.String (add_contracted_spec_fn name) in
950950+ let add_pkg =
951951+ Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in
952952+ let add_pred =
953953+ Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in
954954+ let add_dontlink =
955955+ Arg.String (fun s -> dontlink := !dontlink @ (Fl_split.in_words s)) in
956956+ let add_syntax_pred =
957957+ Arg.String (fun s -> syntax_preds := !syntax_preds @ (Fl_split.in_words s)) in
958958+ let add_pp_opt =
959959+ Arg.String (fun s -> pp_opts := !pp_opts @ [s]) in
960960+ let add_dll_pkg =
961961+ Arg.String (fun s -> dll_pkgs := !dll_pkgs @ (Fl_split.in_words s)) in
962962+ let ignore_error = ref false in
963963+964964+ let native_spec_opt =
965965+ match which with
966966+ | "ocamlc" -> Ocaml_args.ocamlc_spec
967967+ | "ocamlcp" -> Ocaml_args.ocamlcp_spec
968968+ | "ocamlmklib" -> Ocaml_args.ocamlmklib_spec
969969+ | "ocamlmktop" -> Ocaml_args.ocamlmktop_spec
970970+ | "ocamlopt" -> Ocaml_args.ocamlopt_spec
971971+ | "ocamloptp" -> Ocaml_args.ocamloptp_spec
972972+ | _ -> None in
973973+ let native_spec =
974974+ match native_spec_opt with
975975+ | None -> failwith ("Not supported in your configuration: " ^ which)
976976+ | Some s -> s in
977977+978978+ let arg_spec =
979979+ List.flatten
980980+ [ [
981981+ "-package", add_pkg,
982982+ "<name> Refer to package when compiling";
983983+ "-linkpkg", Arg.Set linkpkg,
984984+ " Link the packages in";
985985+ "-predicates", add_pred,
986986+ "<p> Add predicate <p> when resolving package properties";
987987+ "-dontlink", add_dontlink,
988988+ "<name> Do not link in package <name> and its ancestors";
989989+ "-syntax", add_syntax_pred,
990990+ "<p> Use preprocessor with predicate <p>";
991991+ "-ppopt", add_pp_opt,
992992+ "<opt> Append option <opt> to preprocessor invocation";
993993+ "-ppxopt", Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]),
994994+ "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>";
995995+ "-dllpath-pkg", add_dll_pkg,
996996+ "<pkg> Add -dllpath for this package";
997997+ "-dllpath-all", Arg.Set dll_pkgs_all,
998998+ " Add -dllpath for all linked packages";
999999+ "-ignore-error", Arg.Set ignore_error,
10001000+ " Ignore the 'error' directive in META files";
10011001+ "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]),
10021002+ "<opt> Pass option <opt> directly to ocamlc/opt/mklib/mktop";
10031003+ "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]),
10041004+ " Pass all remaining options directly";
10051005+ "-only-show", Arg.Set only_show,
10061006+ " Only show the constructed command, but do not exec it\nSTANDARD OPTIONS:";
10071007+ ];
10081008+10091009+ merge_native_arguments
10101010+ native_spec
10111011+ add_switch
10121012+ add_spec
10131013+ (
10141014+ [ "-cclib",
10151015+ Arg.String (fun s -> pass_files := !pass_files @ [ Cclib s ]);
10161016+10171017+ "-I", (Arg.String
10181018+ (fun s ->
10191019+ let s = resolve_path s in
10201020+ if Sys.file_exists s then incpath := s :: !incpath; (* reverted below *)
10211021+ add_spec_fn "-I" (slashify s) ));
10221022+10231023+ "-impl",
10241024+ Arg.String (fun s -> pass_files := !pass_files @ [ Impl(slashify s) ]);
10251025+10261026+ "-intf",
10271027+ Arg.String (fun s -> pass_files := !pass_files @ [ Intf(slashify s) ]);
10281028+10291029+ "-pp",
10301030+ Arg.String (fun s -> pp_specified := true; add_spec_fn "-pp" s);
10311031+10321032+ "-thread",
10331033+ Arg.Unit (fun _ -> support_threads(); threads := threads_default);
10341034+10351035+ "-vmthread",
10361036+ Arg.Unit (fun _ -> support_threads(); threads := `VM_threads);
10371037+10381038+ "-",
10391039+ Arg.String (fun s -> pass_files := !pass_files @ [ Pass s ]);
10401040+10411041+ ] @
10421042+ if which = "ocamlmklib" then
10431043+ List.map
10441044+ (fun opt ->
10451045+ (opt, add_contracted_spec opt)
10461046+ )
10471047+ contracted_ocamlmklib_options
10481048+ else
10491049+ []
10501050+ )
10511051+ ] in
10521052+10531053+ let (current,args) =
10541054+ if which = "ocamlmklib" then
10551055+ (* Special processing for -L, -R etc. *)
10561056+ let c = !(Arg.current) in
10571057+ let l = Array.length Sys.argv in
10581058+ let args1 = Array.sub Sys.argv (c+1) (l-c-1) in
10591059+ let args2 =
10601060+ Array.append
10611061+ [| Sys.argv.(0) |]
10621062+ (Fl_args.rewrite_contracted_args
10631063+ arg_spec
10641064+ contracted_ocamlmklib_options
10651065+ args1
10661066+ ) in
10671067+ (ref 0, args2)
10681068+ else
10691069+ (Arg.current, Sys.argv) in
10701070+10711071+ parse_args
10721072+ ~current
10731073+ ~args
10741074+ arg_spec
10751075+ (fun s -> pass_files := !pass_files @ [ Pass s])
10761076+ ("usage: ocamlfind " ^ which ^ " [options] file ...");
10771077+10781078+ (* ---- Start requirements analysis ---- *)
10791079+10801080+ begin match which with
10811081+ "ocamlc" -> predicates := "byte" :: !predicates;
10821082+ | "ocamlcp" -> predicates := "byte" :: !predicates;
10831083+ | "ocamlmklib" -> predicates := "byte" :: "native" :: !predicates;
10841084+ | "ocamlmktop" -> predicates := "byte" :: "create_toploop" :: !predicates;
10851085+ | "ocamlopt" -> predicates := "native" :: !predicates;
10861086+ | "ocamloptp" -> predicates := "native" :: !predicates;
10871087+ | _ -> failwith "unsupported backend"
10881088+ end;
10891089+10901090+ incpath := List.rev !incpath;
10911091+10921092+ ( match !threads with
10931093+ `None ->
10941094+ ()
10951095+10961096+ | `VM_threads ->
10971097+ if which = "ocamlopt" then
10981098+ failwith "ocamlopt does not support multi-threaded programs for your configuration";
10991099+ pass_options := !pass_options @ [ "-vmthread" ];
11001100+ predicates := "mt" :: "mt_vm" :: !predicates;
11011101+11021102+ | `POSIX_threads ->
11031103+ if not Findlib_config.ocaml_has_meta_files then
11041104+ pass_options := !pass_options @ [ "-thread" ];
11051105+ predicates := "mt" :: "mt_posix" :: !predicates;
11061106+ );
11071107+11081108+ if List.mem "-p" !switches then
11091109+ predicates := "gprof" :: !predicates;
11101110+11111111+ if Findlib_config.ocaml_has_autolinking &&
11121112+ not (List.mem "-noautolink" !switches)
11131113+ then
11141114+ predicates := "autolink" :: !predicates;
11151115+11161116+ if !syntax_preds <> [] then begin
11171117+ predicates := "syntax" :: !predicates;
11181118+ syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds;
11191119+ end;
11201120+11211121+ let verbose =
11221122+ if List.mem "-verbose" !switches then Verbose else
11231123+ if !only_show then Only_show else
11241124+ Normal in
11251125+11261126+ if !pp_specified && !syntax_preds <> [] then
11271127+ prerr_endline("ocamlfind: [WARNING] -pp overrides the effect of -syntax partly");
11281128+11291129+ (* check packages: *)
11301130+ check_package_list !packages;
11311131+ check_package_list !dontlink;
11321132+11331133+ let eff_packages =
11341134+ package_deep_ancestors !predicates !packages in
11351135+11361136+ let eff_dontlink =
11371137+ package_deep_ancestors !predicates !dontlink in
11381138+11391139+ let eff_link =
11401140+ List.flatten
11411141+ (List.map
11421142+ (fun pkg -> if List.mem pkg eff_dontlink then [] else [pkg])
11431143+ eff_packages) in
11441144+11451145+11461146+ let eff_packages_dl =
11471147+ remove_dups (List.map package_directory eff_packages) in
11481148+11491149+ let eff_link_dl =
11501150+ remove_dups (List.map package_directory eff_link) in
11511151+11521152+ (* Conflict report: *)
11531153+ conflict_report (!incpath @ ["."; Findlib.ocaml_stdlib() ]) eff_packages;
11541154+11551155+ (* ---- End of requirements analysis ---- *)
11561156+11571157+ (* Add the pkg_<name> predicates: *)
11581158+ predicates := List.map (fun pkg -> "pkg_" ^ pkg) eff_packages @ !predicates;
11591159+11601160+ (* Check on [warning] directives: *)
11611161+ List.iter
11621162+ (fun pkg ->
11631163+ try
11641164+ let warning = package_property !predicates pkg "warning" in
11651165+ prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^
11661166+ "': " ^ warning)
11671167+ with
11681168+ Not_found -> ()
11691169+ )
11701170+ eff_packages;
11711171+11721172+ (* Check on [error] directives: *)
11731173+ List.iter
11741174+ (fun pkg ->
11751175+ try
11761176+ let error = package_property !predicates pkg "error" in
11771177+ if !ignore_error then
11781178+ prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^
11791179+ "' signals error: " ^ error)
11801180+ else
11811181+ failwith ("Error from package `" ^ pkg ^ "': " ^ error)
11821182+ with
11831183+ Not_found -> ()
11841184+ )
11851185+ eff_packages;
11861186+11871187+ if verbose = Verbose then begin
11881188+ if !syntax_preds <> [] then
11891189+ print_string ("Effective set of preprocessor predicates: " ^
11901190+ String.concat "," !syntax_preds ^ "\n");
11911191+ print_string ("Effective set of compiler predicates: " ^
11921192+ String.concat "," !predicates ^ "\n");
11931193+ end;
11941194+11951195+ let stdlibdir = Fl_split.norm_dir (Findlib.ocaml_stdlib()) in
11961196+ let threads_dir = Filename.concat stdlibdir "threads" in
11971197+ let vmthreads_dir = Filename.concat stdlibdir "vmthreads" in
11981198+11991199+ let create_toploop =
12001200+ List.mem "create_toploop" !predicates && List.mem "findlib" eff_link in
12011201+ let have_dynload =
12021202+ List.mem "findlib.dynload" eff_link in
12031203+ let initl_file_needed =
12041204+ create_toploop || have_dynload in
12051205+12061206+ let initl_file_name =
12071207+ if initl_file_needed then
12081208+ Filename.temp_file "findlib_initl" ".ml"
12091209+ else
12101210+ ""
12111211+ in
12121212+12131213+ (* initl_file_name: the initialization code inserted at the end of
12141214+ * the cma/cmo list (initl = init last)
12151215+ *)
12161216+12171217+ if initl_file_needed then begin
12181218+ (* Generate initializer for "findlib_top.cma" *)
12191219+ let initl = open_out_gen
12201220+ [Open_wronly; Open_trunc; Open_text]
12211221+ 0o777
12221222+ initl_file_name in
12231223+ try
12241224+ List.iter
12251225+ (fun pkg ->
12261226+ Printf.fprintf
12271227+ initl
12281228+ "let () = Findlib.record_package Findlib.Record_core %S;;\n"
12291229+ pkg
12301230+ )
12311231+ eff_packages;
12321232+ output_string initl
12331233+ ("let () = Findlib.record_package_predicates [" ^
12341234+ String.concat ";"
12351235+ (List.map
12361236+ (fun pred -> "\"" ^ String.escaped pred ^ "\"")
12371237+ !predicates
12381238+ ) ^
12391239+ "];;\n");
12401240+ close_out initl;
12411241+ with
12421242+ any ->
12431243+ close_out initl;
12441244+ Sys.remove initl_file_name;
12451245+ raise any
12461246+ end;
12471247+12481248+ if initl_file_needed && verbose <> Only_show then
12491249+ at_exit
12501250+ (fun () ->
12511251+ let tr f x = try f x with _ -> () in
12521252+ tr Sys.remove initl_file_name;
12531253+ tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmi");
12541254+ tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmo");
12551255+ );
12561256+12571257+ let exclude_list =
12581258+ if Findlib_config.ocaml_has_meta_files then
12591259+ [ stdlibdir ]
12601260+ else
12611261+ [ stdlibdir; threads_dir; vmthreads_dir ] in
12621262+ (* Don't generate -I options for these directories because there is
12631263+ * also some magic in ocamlc/ocamlopt that would not work otherwise
12641264+ *)
12651265+12661266+ let i_options =
12671267+ List.flatten
12681268+ (List.map
12691269+ (fun pkgdir ->
12701270+ let npkgdir = Fl_split.norm_dir pkgdir in
12711271+ if List.mem npkgdir exclude_list then
12721272+ []
12731273+ else
12741274+ [ "-I"; slashify pkgdir;
12751275+ (* "-ccopt"; out_path ~prefix:"-I" pkgdir; -- see comment *)
12761276+ ])
12771277+ eff_packages_dl) in
12781278+ (* We no longer emit -ccopt options, because ocamlc/ocamlopt already
12791279+ do that for each -I if the C compiler needs to be invoked
12801280+ (so far I tracked it, ocamlc/ocamlopt have always done this, even
12811281+ back in 1996).
12821282+ *)
12831283+12841284+ let l_options = [] in
12851285+ (* Also, no longer -ccopt -L options. Current ocamlc/ocamlopt do that
12861286+ for each -I option passed to them anyway, so we can omit that here.
12871287+ See ocaml change (quite old, but I was not aware of it):
12881288+ http://camlcvs.inria.fr/cgi-bin/cvsweb/ocaml/asmcomp/asmlink.ml.diff?r1=1.38;r2=1.39
12891289+ *)
12901290+(*
12911291+ let l_options =
12921292+ List.flatten
12931293+ (List.map
12941294+ (fun pkgdir ->
12951295+ let npkgdir = Fl_split.norm_dir pkgdir in
12961296+ if List.mem npkgdir exclude_list then
12971297+ []
12981298+ else
12991299+ if Findlib_config.system = "win32" || Findlib_config.system = "win64" then
13001300+ (* Microsoft toolchain *)
13011301+ [ "-ccopt"; out_path ~prefix:"/link /libpath:" pkgdir ]
13021302+ else
13031303+ [ "-ccopt"; out_path ~prefix:"-L" pkgdir; ])
13041304+ eff_link_dl) in
13051305+ *)
13061306+13071307+ let archives =
13081308+ List.flatten
13091309+ (List.map
13101310+ (fun pkg ->
13111311+ let al = try package_property !predicates pkg "archive"
13121312+ with Not_found -> "" in
13131313+ let al_ext =
13141314+ if have_dynload && pkg = "findlib.dynload" then
13151315+ [ initl_file_name ]
13161316+ else
13171317+ [] in
13181318+ let pkg_dir =
13191319+ if not Findlib_config.ocaml_has_meta_files && pkg = "threads" then
13201320+ (* MAGIC for pre-5.x days *)
13211321+ match !threads with
13221322+ `None -> stdlibdir
13231323+ | `VM_threads -> vmthreads_dir
13241324+ | `POSIX_threads -> threads_dir
13251325+ else
13261326+ package_directory pkg in
13271327+ let pkg_dir = slashify pkg_dir in
13281328+ List.map
13291329+ (fun arch ->
13301330+ resolve_path ~base:pkg_dir arch)
13311331+ (Fl_split.in_words al @ al_ext)
13321332+ )
13331333+ eff_link)
13341334+ @
13351335+ (if create_toploop then
13361336+ [ initl_file_name ]
13371337+ else
13381338+ []
13391339+ )
13401340+ in
13411341+13421342+ let linkopts =
13431343+ List.flatten
13441344+ (List.map
13451345+ (fun pkg ->
13461346+ let ol = try package_property !predicates pkg "linkopts"
13471347+ with Not_found -> "" in
13481348+ Fl_split.in_words_ws ol)
13491349+ (List.rev eff_link)) in
13501350+13511351+ let pp_command =
13521352+ if !pp_specified then
13531353+ []
13541354+ else
13551355+ process_pp_spec !syntax_preds !packages !pp_opts
13561356+ in
13571357+13581358+ let ppx_commands =
13591359+ process_ppx_spec !predicates !packages !ppx_opts
13601360+ in
13611361+13621362+ let pass_files' =
13631363+ List.flatten
13641364+ (List.map
13651365+ (function
13661366+ Pass s ->
13671367+ if s <> "" && s.[0] = '-'
13681368+ then [ "-"; String.sub s 1 (String.length s - 1) ]
13691369+ else [ resolve_path s ]
13701370+ | Impl s ->
13711371+ [ "-impl"; resolve_path s ]
13721372+ | Intf s ->
13731373+ [ "-intf"; resolve_path s ]
13741374+ | Cclib s ->
13751375+ [ "-cclib"; s ]
13761376+ )
13771377+ !pass_files)
13781378+ in
13791379+13801380+ let dll_dirs =
13811381+ remove_dups
13821382+ ((List.map package_directory !dll_pkgs) @
13831383+ (if !dll_pkgs_all then eff_link_dl else [])) in
13841384+13851385+ let dll_options =
13861386+ List.flatten
13871387+ (List.map
13881388+ (fun pkg -> ["-dllpath"; slashify pkg] )
13891389+ dll_dirs) in
13901390+13911391+ let mklib_options =
13921392+ ["-ocamlc"; Findlib.command `ocamlc;
13931393+ "-ocamlopt"; Findlib.command `ocamlopt] in
13941394+13951395+ let arguments =
13961396+ (if which = "ocamlmklib" then mklib_options else []) @
13971397+ !pass_options @ (* other options from the command line *)
13981398+ i_options @ (* Generated -I options from package analysis *)
13991399+ pp_command @ (* Optional preprocessor command *)
14001400+ ppx_commands @ (* Optional ppx extension commands *)
14011401+ (if !linkpkg then l_options else []) @ (* Generated -ccopt -L options *)
14021402+ (if !linkpkg then archives else []) @ (* Gen file names to link *)
14031403+ pass_files' @ (* File names from cmd line *)
14041404+ (if !linkpkg then linkopts else []) @ (* Generated link options *)
14051405+ dll_options (* Generated -dllpath options *)
14061406+ in
14071407+14081408+ let actual_command =
14091409+ match which with
14101410+ "ocamlc" -> Findlib.command `ocamlc
14111411+ | "ocamlopt" -> Findlib.command `ocamlopt
14121412+ | "ocamlcp" -> Findlib.command `ocamlcp
14131413+ | "ocamlmklib" -> Findlib.command `ocamlmklib
14141414+ | "ocamlmktop" -> Findlib.command `ocamlmktop
14151415+ | "ocamloptp" -> Findlib.command `ocamloptp
14161416+ | _ -> assert false
14171417+ in
14181418+14191419+ run_command verbose actual_command arguments
14201420+;;
14211421+14221422+14231423+(************************************************************************)
14241424+14251425+let ocamldoc() =
14261426+14271427+ let packages = ref [] in
14281428+ let predicates = ref [] in
14291429+ let syntax_preds = ref [] in
14301430+ let pp_opts = ref [] in
14311431+ let ppx_opts = ref [] in
14321432+ let pp_specified = ref false in
14331433+14341434+ let verbose = ref Normal in
14351435+14361436+ let options = ref [] in
14371437+14381438+ let native_spec =
14391439+ match Ocaml_args.ocamldoc_spec with
14401440+ | None -> failwith "Not supported in your configuration: ocamldoc"
14411441+ | Some s -> s in
14421442+14431443+ parse_args
14441444+ ~align:false
14451445+ ( Arg.align
14461446+ [ "-package",
14471447+ Arg.String (fun s ->
14481448+ packages := !packages @ Fl_split.in_words s),
14491449+ "<name> Add this package to the search path";
14501450+14511451+ "-predicates",
14521452+ Arg.String (fun s ->
14531453+ predicates := !predicates @ Fl_split.in_words s),
14541454+ "<p> Add predicate <p> when calculating dependencies";
14551455+14561456+ "-syntax",
14571457+ Arg.String (fun s ->
14581458+ syntax_preds := !syntax_preds @ Fl_split.in_words s),
14591459+ "<p> Use preprocessor with predicate <p>";
14601460+14611461+ "-ppopt",
14621462+ Arg.String (fun s -> pp_opts := !pp_opts @ [s]),
14631463+ "<opt> Append option <opt> to preprocessor invocation";
14641464+14651465+ "-ppxopt",
14661466+ Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]),
14671467+ "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>";
14681468+14691469+ "-thread",
14701470+ Arg.Unit (fun () -> predicates := "mt" :: "mt_posix" :: !predicates),
14711471+ " Assume kernel multi-threading when doing dependency analyses";
14721472+14731473+ "-vmthread",
14741474+ Arg.Unit (fun () -> predicates := "mt" :: "mt_vm" :: !predicates),
14751475+ " Assume bytecode multi-threading when doing dependency analyses";
14761476+14771477+ "-passopt",
14781478+ Arg.String (fun s -> options := !options @ [s]),
14791479+ "<opt> Pass this option directly to ocamldoc";
14801480+14811481+ "-passrest",
14821482+ Arg.Rest (fun s -> options := !options @ [s]),
14831483+ " Pass all remaining options directly to ocamldoc";
14841484+14851485+ "-only-show",
14861486+ Arg.Unit (fun () -> verbose := Only_show),
14871487+ " Only show the constructed command but do not exec it";
14881488+14891489+ "-verbose",
14901490+ Arg.Unit (fun () -> verbose := Verbose),
14911491+ " Be verbose\nSTANDARD OPTIONS:";
14921492+ ]
14931493+ @
14941494+ ( merge_native_arguments
14951495+ native_spec
14961496+ (fun s ->
14971497+ Arg.Unit (fun () ->
14981498+ options := !options @ [s]))
14991499+ (fun s ->
15001500+ Arg.String (fun arg ->
15011501+ options := !options @ [s; arg]))
15021502+ [ "-v", Arg.Unit (fun () -> verbose := Verbose);
15031503+ "-pp", Arg.String (fun s ->
15041504+ pp_specified := true;
15051505+ options := !options @ ["-pp"; s]);
15061506+ ]
15071507+ )
15081508+ )
15091509+ (fun s -> options := !options @ [s])
15101510+ "usage: ocamlfind ocamldoc <options> <files>...";
15111511+15121512+ check_package_list !packages;
15131513+15141514+ if !syntax_preds <> [] then (
15151515+ predicates := "syntax" :: !predicates;
15161516+ syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds;
15171517+ );
15181518+15191519+ if !verbose = Verbose then begin
15201520+ if !syntax_preds <> [] then
15211521+ print_string ("Effective set of preprocessor predicates: " ^
15221522+ String.concat "," !syntax_preds ^ "\n");
15231523+ print_string ("Effective set of compiler predicates: " ^
15241524+ String.concat "," !predicates ^ "\n");
15251525+ end;
15261526+15271527+ if !pp_specified && !syntax_preds <> [] then
15281528+ prerr_endline("Warning: -pp overrides the effect of -syntax partly");
15291529+15301530+ let pp_command =
15311531+ if !pp_specified then
15321532+ []
15331533+ else
15341534+ process_pp_spec !syntax_preds !packages !pp_opts
15351535+ in
15361536+15371537+ let ppx_commands =
15381538+ process_ppx_spec !predicates !packages !ppx_opts
15391539+ in
15401540+15411541+ let eff_packages =
15421542+ package_deep_ancestors !predicates !packages in
15431543+15441544+ (* Check on [error] directives (turned into warnings): *)
15451545+ List.iter
15461546+ (fun pkg ->
15471547+ try
15481548+ let error = package_property !predicates pkg "error" in
15491549+ prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^
15501550+ "' signals error: " ^ error)
15511551+ with
15521552+ Not_found -> ()
15531553+ )
15541554+ eff_packages;
15551555+15561556+ let eff_packages_dl =
15571557+ remove_dups (List.map package_directory eff_packages) in
15581558+15591559+ let arguments =
15601560+ (List.flatten (List.map (fun d -> [ "-I"; slashify d ]) eff_packages_dl)) @
15611561+ pp_command @
15621562+ ppx_commands @
15631563+ !options in
15641564+15651565+ let actual_command = Findlib.command `ocamldoc in
15661566+15671567+ run_command !verbose actual_command arguments
15681568+;;
15691569+15701570+15711571+(************************************************************************)
15721572+15731573+(* From ocamldep source code: *)
15741574+let depends_on_char, continuation_char =
15751575+ match Sys.os_type with
15761576+ | "Unix" | "BeOS" | "Win32" | "Cygwin" -> ':', '\\'
15771577+ | "MacOS" -> '\196', '\182'
15781578+ | _ -> assert false
15791579+;;
15801580+15811581+15821582+let suppress_targets suffix =
15831583+ (* If [line] begins with "target: dependencies ...", and [target] is a
15841584+ * file name ending in [suffix], this line is suppressed, and all
15851585+ * follow-up lines.
15861586+ *)
15871587+ let do_suppress = ref false in
15881588+ fun line ->
15891589+ let target =
15901590+ try
15911591+ let k = String.index_from line 0 depends_on_char in (* or Not_found *)
15921592+ let target_string = String.sub line 0 k in
15931593+ if String.contains target_string ' ' then raise Not_found;
15941594+ Some target_string
15951595+ with
15961596+ Not_found -> None
15971597+ in
15981598+ begin match target with
15991599+ Some target_string ->
16001600+ do_suppress := Filename.check_suffix target_string suffix;
16011601+ | None ->
16021602+ ()
16031603+ end;
16041604+ if !do_suppress then
16051605+ None
16061606+ else
16071607+ Some line
16081608+;;
16091609+16101610+16111611+let ocamldep () =
16121612+16131613+ let switches = ref [] in
16141614+ let pass_options = ref [] in
16151615+ let pass_files = ref [] in
16161616+16171617+ let packages = ref [] in
16181618+ let predicates = ref [] in
16191619+ let syntax_preds = ref [] in
16201620+ let pp_opts = ref [] in
16211621+ let ppx_opts = ref [] in
16221622+ let pp_specified = ref false in
16231623+16241624+ let verbose = ref Normal in
16251625+ let native_filter = ref false in
16261626+ let bytecode_filter = ref false in
16271627+16281628+ let add_switch name =
16291629+ Arg.Unit (fun () ->
16301630+ switches := name :: !switches;
16311631+ pass_options := !pass_options @ [name]) in
16321632+ let add_spec_fn name s =
16331633+ pass_options := !pass_options @ [name; s] in
16341634+ let add_spec name = Arg.String (add_spec_fn name) in
16351635+ let add_pred =
16361636+ Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in
16371637+ let add_syntax_pred =
16381638+ Arg.String (fun s -> syntax_preds := !syntax_preds @ (Fl_split.in_words s)) in
16391639+ let add_pp_opt =
16401640+ Arg.String (fun s -> pp_opts := !pp_opts @ [s]) in
16411641+ let add_pkg =
16421642+ Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in
16431643+16441644+ let native_spec =
16451645+ match Ocaml_args.ocamldep_spec with
16461646+ | None -> failwith "Not supported in your configuration: ocamldep"
16471647+ | Some s -> s in
16481648+16491649+ parse_args
16501650+ ( [
16511651+ "-syntax", add_syntax_pred,
16521652+ "<p> Use preprocessor with predicate <p>";
16531653+ "-package", add_pkg,
16541654+ "<p> Add preprocessor package <p>";
16551655+ "-predicates", add_pred,
16561656+ "<p> Add predicate <p> when calculating dependencies";
16571657+ "-ppopt", add_pp_opt,
16581658+ "<opt> Append option <opt> to preprocessor invocation";
16591659+ "-ppxopt", Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]),
16601660+ "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>";
16611661+ "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]),
16621662+ "<opt> Pass option <opt> directly to ocamlc/opt/mktop";
16631663+ "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]),
16641664+ " Pass all remaining options directly";
16651665+ "-native-filter", Arg.Set native_filter,
16661666+ " Output only dependencies for native code (implies -native)";
16671667+ "-bytecode-filter", Arg.Set bytecode_filter,
16681668+ " Output only dependencies for bytecode";
16691669+ "-only-show", Arg.Unit (fun () -> verbose := Only_show),
16701670+ " Only show the constructed command but do not exec it";
16711671+16721672+ "-verbose", Arg.Unit (fun () -> verbose := Verbose),
16731673+ " Print calls to external commands\nSTANDARD OPTIONS:";
16741674+ ]
16751675+ @
16761676+ ( merge_native_arguments
16771677+ native_spec
16781678+ add_switch
16791679+ add_spec
16801680+ [ "-I",
16811681+ Arg.String (fun s -> add_spec_fn "-I" (slashify (resolve_path s)));
16821682+16831683+ "-pp", Arg.String (fun s -> pp_specified := true;
16841684+ add_spec_fn "-pp" s);
16851685+ ]
16861686+ )
16871687+ )
16881688+ (fun s -> pass_files := !pass_files @ [ s])
16891689+ ("usage: ocamlfind ocamldep [options] file ...");
16901690+16911691+ check_package_list !packages;
16921692+16931693+ if !native_filter && !bytecode_filter then
16941694+ failwith "The options -native-filter and -bytecode-filter are incompatible";
16951695+16961696+ if !native_filter && not (List.mem "-native" !switches) then
16971697+ pass_options := "-native" :: !pass_options;
16981698+16991699+ if !syntax_preds <> [] then
17001700+ syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds;
17011701+17021702+ if !verbose = Verbose && !syntax_preds <> [] then
17031703+ print_string ("Effective set of preprocessor predicates: " ^
17041704+ String.concat "," !syntax_preds ^ "\n");
17051705+17061706+ if !pp_specified && !syntax_preds <> [] then
17071707+ prerr_endline("Warning: -pp overrides the effect of -syntax partly");
17081708+17091709+ let pp_command =
17101710+ if !pp_specified then
17111711+ []
17121712+ else
17131713+ process_pp_spec !syntax_preds !packages !pp_opts
17141714+ in
17151715+17161716+ let ppx_commands =
17171717+ process_ppx_spec !predicates !packages !ppx_opts
17181718+ in
17191719+17201720+ let arguments =
17211721+ !pass_options @
17221722+ pp_command @
17231723+ ppx_commands @
17241724+ !pass_files
17251725+ in
17261726+17271727+ let actual_command = Findlib.command `ocamldep in
17281728+ let filter =
17291729+ if !native_filter then
17301730+ (* Suppress when target is ".cmo": *)
17311731+ Some (suppress_targets ".cmo")
17321732+ else
17331733+ if !bytecode_filter then
17341734+ (* Suppress when target is ".cmx": *)
17351735+ Some (suppress_targets ".cmx")
17361736+ else
17371737+ None
17381738+ in
17391739+17401740+ run_command ?filter !verbose actual_command arguments
17411741+;;
17421742+17431743+17441744+(************************************************************************)
17451745+17461746+let ocamlbrowser () =
17471747+ (* let switches = ref [] in *)
17481748+ let pass_options = ref [] in
17491749+ let add_all = ref false in
17501750+17511751+ let packages = ref [] in
17521752+17531753+(*
17541754+ let add_switch name =
17551755+ Arg.Unit (fun () ->
17561756+ switches := name :: !switches;
17571757+ pass_options := !pass_options @ [name]) in
17581758+ *)
17591759+ let add_spec_fn name s =
17601760+ pass_options := !pass_options @ [name; s] in
17611761+(* let add_spec name = Arg.String (add_spec_fn name) in *)
17621762+ let add_pkg =
17631763+ Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in
17641764+17651765+ parse_args
17661766+ [
17671767+ "-I", Arg.String (fun s -> add_spec_fn "-I" (slashify(resolve_path s))),
17681768+ "<dir> Add <dir> to the list of include directories";
17691769+ "-all", Arg.Set add_all,
17701770+ " Add all packages to include path";
17711771+ "-package", add_pkg,
17721772+ "<p> Add package <p> to include path";
17731773+ "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]),
17741774+ "<opt> Pass option <opt> directly to ocamlbrowser";
17751775+ "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]),
17761776+ " Pass all remaining options directly";
17771777+ ]
17781778+ (fun s -> raise (Arg.Bad ("Unexpected argument: " ^ s)))
17791779+ ("usage: ocamlfind ocamlbrowser [options] file ...");
17801780+17811781+ if !add_all then packages := Fl_package_base.list_packages();
17821782+ check_package_list !packages;
17831783+17841784+ let arguments =
17851785+ !pass_options @
17861786+ (List.flatten
17871787+ (List.map
17881788+ (fun pkg ->
17891789+ let dir = Findlib.package_directory pkg in
17901790+ [ "-I"; slashify dir ]
17911791+ )
17921792+ !packages
17931793+ )
17941794+ )
17951795+ in
17961796+17971797+ let actual_command = Findlib.command `ocamlbrowser in
17981798+17991799+ run_command Normal actual_command arguments
18001800+;;
18011801+18021802+18031803+(************************************************************************)
18041804+18051805+18061806+let copy_file ?(rename = (fun name -> name)) ?(append = "") src dstdir =
18071807+ (* A system-independent function to copy the file src to dstdir *)
18081808+ let outname = rename (Filename.basename src) in
18091809+ let ch_in = open_in_bin src in
18101810+ (* Determine the permissions of the file: the permissions of the
18111811+ * user bits are extended to all groups (user, group, world bits),
18121812+ * and the umask is applied to the result.
18131813+ * Furthermore, the mtime of the file is preserved. This seems to be
18141814+ * important for BSD-style archives (otherwise the system is confused
18151815+ * and wants that ranlib is run again). For simplicity, the atime is
18161816+ * set to the mtime, too.
18171817+ *)
18181818+ let s = Unix.stat src in
18191819+ let perm = s.Unix.st_perm in
18201820+ let user_perm = (perm land 0o700) lsr 6 in
18211821+ let perm' = user_perm lor (user_perm lsl 3) lor (user_perm lsl 6) in
18221822+ try
18231823+ let outpath = Filename.concat dstdir outname in
18241824+ if Sys.file_exists outpath then
18251825+ prerr_endline ("ocamlfind: [WARNING] Overwriting file " ^ outpath);
18261826+ let ch_out = open_out_gen
18271827+ [Open_wronly; Open_creat; Open_trunc; Open_binary]
18281828+ perm'
18291829+ outpath in
18301830+ try
18311831+ let buflen = 4096 in
18321832+ let buf = Bytes.create buflen in
18331833+ let pos = ref 0 in
18341834+ let len = ref (input ch_in buf 0 buflen) in
18351835+ while !len > 0 do
18361836+ output ch_out buf !pos !len;
18371837+ len := input ch_in buf !pos buflen;
18381838+ done;
18391839+ output_string ch_out append;
18401840+ close_out ch_out;
18411841+ close_in ch_in;
18421842+ Unix.utimes outpath s.Unix.st_mtime s.Unix.st_mtime;
18431843+18441844+ prerr_endline("Installed " ^ outpath);
18451845+ with
18461846+ exc -> close_out ch_out; raise exc
18471847+ with
18481848+ exc -> close_in ch_in; raise exc
18491849+;;
18501850+18511851+18521852+let install_create_directory pkgname dstdir =
18531853+ try
18541854+ Unix.mkdir dstdir 0o777
18551855+ with
18561856+ Unix.Unix_error(Unix.EEXIST,_,_) ->
18571857+ ()
18581858+ | Unix.Unix_error(Unix.ENOENT,_,_)
18591859+ | Unix.Unix_error(Unix.ENOTDIR,_,_) ->
18601860+ failwith ("Bad configuration: Cannot mkdir " ^ dstdir ^ " because a path component does not exist or is not a directory")
18611861+ | Unix.Unix_error(e,_,_) ->
18621862+ failwith ("Cannot mkdir " ^ dstdir ^ ": " ^
18631863+ Unix.error_message e)
18641864+;;
18651865+18661866+18671867+let create_owner_file pkg file =
18681868+ let outpath = file ^ ".owner" in
18691869+ let f = open_out outpath in
18701870+ try
18711871+ output_string f (pkg ^ "\n");
18721872+ close_out f;
18731873+ prerr_endline("Installed " ^ outpath);
18741874+ with
18751875+ exc -> close_out f; raise exc
18761876+;;
18771877+18781878+let trim_cr s =
18791879+ let len = String.length s in
18801880+ if len > 0 && String.get s (len-1) = '\r' then
18811881+ String.sub s 0 (len-1)
18821882+ else
18831883+ s
18841884+18851885+let find_owned_files pkg dir =
18861886+ let files = Array.to_list(Sys.readdir dir) in
18871887+ List.filter
18881888+ (fun file ->
18891889+ let owner_file =
18901890+ if Filename.check_suffix file ".owner" then
18911891+ file
18921892+ else
18931893+ file ^ ".owner" in
18941894+ (List.mem owner_file files) && (
18951895+ try
18961896+ let fd =
18971897+ Unix.openfile (Filename.concat dir owner_file) [Unix.O_RDONLY] 0 in
18981898+ let f =
18991899+ Unix.in_channel_of_descr fd in
19001900+ try
19011901+ let line = trim_cr (input_line f) in
19021902+ let is_my_file = (line = pkg) in
19031903+ close_in f;
19041904+ is_my_file
19051905+ with
19061906+ | End_of_file -> close_in f; false
19071907+ | exc -> close_in f; raise exc
19081908+ with
19091909+ | Unix.Unix_error(Unix.ENOENT,_,_) ->
19101910+ (* the owner file might have been removed by a package
19111911+ removal that is being done in parallel
19121912+ *)
19131913+ false
19141914+ | Unix.Unix_error(code, _, arg) ->
19151915+ raise(sys_error code arg)
19161916+ )
19171917+ )
19181918+ files
19191919+;;
19201920+19211921+19221922+19231923+exception Missing_archives of Fl_metascanner.pkg_expr
19241924+19251925+let rec patch_archives pkgdir pkg =
19261926+ (* First remove all missing files from archive variables: *)
19271927+ let defs' =
19281928+ List.map
19291929+ (fun def ->
19301930+ if def.Fl_metascanner.def_var = "archive" then (
19311931+ let files = Fl_split.in_words def.Fl_metascanner.def_value in
19321932+ let files' =
19331933+ List.filter
19341934+ (fun file ->
19351935+ let p = Findlib.resolve_path ~base:pkgdir file in
19361936+ Sys.file_exists p)
19371937+ files in
19381938+ { def with
19391939+ Fl_metascanner.def_value = String.concat " " files'
19401940+ }
19411941+ )
19421942+ else def
19431943+ )
19441944+ pkg.Fl_metascanner.pkg_defs in
19451945+ (* Remove empty archive variables: *)
19461946+ let defs'' =
19471947+ List.filter
19481948+ (fun def ->
19491949+ def.Fl_metascanner.def_var <> "archive" ||
19501950+ Fl_split.in_words def.Fl_metascanner.def_value <> []
19511951+ )
19521952+ defs' in
19531953+ (* Return the package or raise Not_found if all archives vanished: *)
19541954+ let children =
19551955+ (* Recursive patch, remove all Not_found packages: *)
19561956+ List.flatten
19571957+ (List.map
19581958+ (fun (name, child) ->
19591959+ try [ name, patch_archives pkgdir child ]
19601960+ with Missing_archives _ -> []
19611961+ )
19621962+ pkg.Fl_metascanner.pkg_children) in
19631963+ let pkg' =
19641964+ { Fl_metascanner.pkg_defs = defs'';
19651965+ pkg_children = children
19661966+ } in
19671967+ if List.exists (fun def -> def.Fl_metascanner.def_var = "archive") defs'' then
19681968+ pkg'
19691969+ else
19701970+ raise (Missing_archives pkg')
19711971+;;
19721972+19731973+19741974+let rec patch_pkg pkgdir pkg patches =
19751975+ match patches with
19761976+ | [] -> pkg
19771977+ | (`Version v) :: patches' ->
19781978+ let def =
19791979+ { Fl_metascanner.def_var = "version";
19801980+ def_flav = `BaseDef;
19811981+ def_preds = [];
19821982+ def_value = v
19831983+ } in
19841984+ let defs =
19851985+ List.filter
19861986+ (fun d -> d.Fl_metascanner.def_var <> "version")
19871987+ pkg.Fl_metascanner.pkg_defs in
19881988+ let pkg' =
19891989+ { pkg with
19901990+ Fl_metascanner.pkg_defs = def :: defs
19911991+ } in
19921992+ patch_pkg pkgdir pkg' patches'
19931993+ | (`Rmpkg n) :: patches' ->
19941994+ let children =
19951995+ List.filter
19961996+ (fun (name,_) -> name <> n)
19971997+ pkg.Fl_metascanner.pkg_children in
19981998+ let pkg' =
19991999+ { pkg with
20002000+ Fl_metascanner.pkg_children = children
20012001+ } in
20022002+ patch_pkg pkgdir pkg' patches'
20032003+ | `Archives :: patches' ->
20042004+ let pkg' =
20052005+ try patch_archives pkgdir pkg
20062006+ with
20072007+ Missing_archives p -> p in
20082008+ patch_pkg pkgdir pkg' patches'
20092009+;;
20102010+20112011+20122012+exception Skip_file;;
20132013+20142014+type which = Auto | Dll | No_dll;;
20152015+20162016+let meta_pkg meta_name =
20172017+ let f = open_in meta_name in
20182018+ try
20192019+ let pkg = Fl_metascanner.parse f in
20202020+ close_in f;
20212021+ pkg
20222022+ with
20232023+ | Failure s
20242024+ | Fl_metascanner.Error s ->
20252025+ close_in f;
20262026+ failwith ("Cannot parse '" ^ meta_name ^ "': " ^ s)
20272027+20282028+let char_lowercase_ascii c =
20292029+ (* Char.lowercase_ascii and String.lowercase_ascii first available in
20302030+ OCaml-4.03, but we want to support earlier versions too
20312031+ *)
20322032+ if (c >= 'A' && c <= 'Z')
20332033+ then Char.unsafe_chr(Char.code c + 32)
20342034+ else c
20352035+20362036+let string_lowercase_ascii s =
20372037+ let n = String.length s in
20382038+ let b = Bytes.create n in
20392039+ for i = 0 to n - 1 do
20402040+ Bytes.unsafe_set b i (char_lowercase_ascii (String.unsafe_get s i))
20412041+ done;
20422042+ Bytes.to_string b
20432043+20442044+20452045+let install_package () =
20462046+ let destdir = ref (default_location()) in
20472047+ let metadir = ref (meta_directory()) in
20482048+ let ldconf = ref (ocaml_ldconf()) in
20492049+ let don't_add_directory_directive = ref false in
20502050+ let pkgname = ref "" in
20512051+ let auto_files = ref [] in
20522052+ let dll_files = ref [] in
20532053+ let nodll_files = ref [] in
20542054+ let which = ref Auto in
20552055+ let add_files = ref false in
20562056+ let optional = ref false in
20572057+ let patches = ref [] in
20582058+20592059+ let keywords =
20602060+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
20612061+ ("<path> Set the destination directory (default: " ^
20622062+ !destdir ^ ")");
20632063+ "-metadir", (Arg.String (fun s -> metadir := s)),
20642064+ ("<path> Install the META file into this directory (default: "^
20652065+ (if !metadir = "" then "none" else !metadir) ^ ")");
20662066+ "-ldconf", (Arg.String (fun s -> ldconf := s)),
20672067+ ("<path> Update this ld.conf file (default: " ^ !ldconf ^ ")");
20682068+ "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive),
20692069+ " never append directory='...' to META";
20702070+ "-dll", Arg.Unit (fun () -> which := Dll),
20712071+ " The following files are DLLs";
20722072+ "-nodll", Arg.Unit (fun () -> which := No_dll),
20732073+ " The following files are not DLLs";
20742074+ "-add", Arg.Unit (fun () -> add_files := true),
20752075+ " Add files to the package";
20762076+ "-optional", Arg.Set optional,
20772077+ " The following files are optional";
20782078+ "-patch-version", Arg.String (fun s -> patches := !patches @ [`Version s]),
20792079+ "<v> Set the package version to <v>";
20802080+ "-patch-rmpkg", Arg.String (fun s -> patches := !patches @ [`Rmpkg s]),
20812081+ "<n> Remove the subpackage <n>";
20822082+ "-patch-archives", Arg.Unit (fun () -> patches := !patches @ [`Archives]),
20832083+ " Remove non-existing archives";
20842084+ ] in
20852085+ let errmsg = "usage: ocamlfind install [options] <package_name> <file> ..." in
20862086+20872087+ parse_args
20882088+ keywords
20892089+ (fun s ->
20902090+ if !pkgname = ""
20912091+ then pkgname := s
20922092+ else
20932093+ if not !optional || Sys.file_exists s then
20942094+ match !which with
20952095+ Auto -> auto_files := s :: !auto_files
20962096+ | Dll -> dll_files := s :: !dll_files
20972097+ | No_dll -> nodll_files := s :: !nodll_files
20982098+ )
20992099+ errmsg;
21002100+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
21012101+ if not (Fl_split.is_valid_package_name !pkgname) then
21022102+ failwith "Package names must not contain the character '.'!";
21032103+21042104+ let pkgdir = Filename.concat !destdir !pkgname in
21052105+ let dlldir = Filename.concat !destdir Findlib_config.libexec_name in
21062106+ let has_metadir = !metadir <> "" in
21072107+ let meta_dot_pkg = "META." ^ !pkgname in
21082108+21092109+ (* The list of all files to install: *)
21102110+ let full_list = !auto_files @ !dll_files @ !nodll_files in
21112111+ (* Check whether there are DLLs: *)
21122112+ let (l1,l2) = List.partition is_dll !auto_files in
21132113+ let dll_list = l1 @ !dll_files in
21142114+ let nodll_list = l2 @ !nodll_files in
21152115+ let have_libexec = Sys.file_exists dlldir in
21162116+ let pkgdir_list = if have_libexec then nodll_list else full_list in
21172117+ let pkgdir_eff_list =
21182118+ (* The files that will be placed into pkgdir: *)
21192119+ List.map
21202120+ (fun f ->
21212121+ if f = meta_dot_pkg then "META" else f)
21222122+ (List.filter
21232123+ (fun f ->
21242124+ not has_metadir ||
21252125+ (f <> "META" && f <> meta_dot_pkg))
21262126+ pkgdir_list) in
21272127+21282128+ (* Check whether META exists: (And check syntax) *)
21292129+ let meta_name =
21302130+ try
21312131+ List.find
21322132+ (fun p ->
21332133+ let b = Filename.basename p in
21342134+ b = "META" || b = meta_dot_pkg)
21352135+ nodll_list
21362136+ with
21372137+ | Not_found ->
21382138+ if !add_files then (
21392139+ let m1 = Filename.concat !metadir meta_dot_pkg in
21402140+ let m2 = Filename.concat pkgdir "META" in
21412141+ if Sys.file_exists m1 then
21422142+ m1
21432143+ else
21442144+ if Sys.file_exists m2 then
21452145+ m2
21462146+ else
21472147+ failwith "Cannot find META in package dir"
21482148+ )
21492149+ else
21502150+ failwith "The META file is missing" in
21512151+21522152+ let meta_pkg = meta_pkg meta_name in
21532153+21542154+ if not !add_files then (
21552155+ (* Check for frequent reasons why installation can go wrong *)
21562156+ if Sys.file_exists (Filename.concat !metadir meta_dot_pkg) then
21572157+ failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ Filename.concat !metadir meta_dot_pkg ^ " already exists)");
21582158+21592159+ if Sys.file_exists (Filename.concat pkgdir "META") then
21602160+ failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ pkgdir ^ "/META already exists)");
21612161+ );
21622162+ List.iter
21632163+ (fun f ->
21642164+ let f' = Filename.concat pkgdir f in
21652165+ if Sys.file_exists f' then
21662166+ failwith ("Conflict with file: " ^ f'))
21672167+ pkgdir_eff_list;
21682168+21692169+ if have_libexec then begin
21702170+ List.iter
21712171+ (fun dll ->
21722172+ let b = Filename.basename dll in
21732173+ if Sys.file_exists (Filename.concat dlldir b) then
21742174+ failwith ("Conflict with another package: Library " ^ b ^
21752175+ " is already installed");
21762176+ )
21772177+ dll_list
21782178+ end;
21792179+21802180+ (* Create the package directory: *)
21812181+ install_create_directory !pkgname pkgdir;
21822182+21832183+ (* Now copy the files into the package directory (except META): *)
21842184+ List.iter
21852185+ (fun p ->
21862186+ try
21872187+ copy_file
21882188+ ~rename: (fun f ->
21892189+ if f = "META" || f = meta_dot_pkg then
21902190+ raise Skip_file
21912191+ else
21922192+ f)
21932193+ p
21942194+ pkgdir
21952195+ with
21962196+ Skip_file -> ()
21972197+ )
21982198+ pkgdir_list;
21992199+22002200+ (* Copy the DLLs into the libexec directory if necessary *)
22012201+ if have_libexec then begin
22022202+ List.iter
22032203+ (fun p ->
22042204+ copy_file p dlldir;
22052205+ create_owner_file !pkgname
22062206+ (Filename.concat dlldir (Filename.basename p))
22072207+ )
22082208+ dll_list
22092209+ end;
22102210+22112211+ (* Extend ld.conf if necessary: *)
22122212+ if dll_list <> [] && !ldconf <> "ignore" && not have_libexec then begin
22132213+ if Sys.file_exists !ldconf then
22142214+ begin
22152215+ let lines = read_ldconf !ldconf in
22162216+ write_ldconf !ldconf lines [ pkgdir ]
22172217+ end
22182218+ else
22192219+ prerr_endline("ocamlfind: [WARNING] You have installed DLLs but there is no ld.conf")
22202220+ end;
22212221+22222222+ if dll_list <> [] && have_libexec && !ldconf <> "ignore" then begin
22232223+ (* Check whether libexec is mentioned in ldconf *)
22242224+ (* FIXME: We have to be careful with case-insensitive filesystems.
22252225+ Currently, we only check for Win32, but also OS X may have ci
22262226+ filesystems. So some better check would be nice.
22272227+ *)
22282228+ let lines = read_ldconf !ldconf in
22292229+ let dlldir_norm = Fl_split.norm_dir dlldir in
22302230+ let dlldir_norm_lc = string_lowercase_ascii dlldir_norm in
22312231+ let ci_filesys = (Sys.os_type = "Win32") in
22322232+ let check_dir d =
22332233+ let d' = Fl_split.norm_dir d in
22342234+ (d' = dlldir_norm) ||
22352235+ (ci_filesys && string_lowercase_ascii d' = dlldir_norm_lc) in
22362236+ if not (List.exists check_dir lines) then
22372237+ prerr_endline("ocamlfind: [WARNING] You have installed DLLs but the directory " ^ dlldir_norm ^ " is not mentioned in ld.conf");
22382238+ end;
22392239+22402240+ (* Finally, write the META file: *)
22412241+ let write_meta append_directory dir name =
22422242+ (* If there are patches, write the patched META, else copy the file: *)
22432243+ if !patches = [] then
22442244+ copy_file
22452245+ ~rename:(fun _ -> name)
22462246+ ?append:(if append_directory then
22472247+ Some("\ndirectory=\"" ^ pkgdir ^
22482248+ "\" # auto-added by ocamlfind\n")
22492249+ else
22502250+ None)
22512251+ meta_name
22522252+ dir
22532253+ else (
22542254+ let p = Filename.concat dir name in
22552255+ let patched_pkg = patch_pkg pkgdir meta_pkg !patches in
22562256+ let out = open_out p in
22572257+ Fl_metascanner.print out patched_pkg;
22582258+ if append_directory then
22592259+ output_string out ("\ndirectory=\"" ^ pkgdir ^
22602260+ "\" # auto-added by ocamlfind\n");
22612261+ close_out out;
22622262+ prerr_endline ("Installed " ^ p);
22632263+ )
22642264+ in
22652265+ if not !add_files then (
22662266+ if has_metadir then
22672267+ write_meta true !metadir meta_dot_pkg
22682268+ else
22692269+ write_meta false pkgdir "META";
22702270+ );
22712271+22722272+ (* Check if there is a postinstall script: *)
22732273+ let postinstall = Filename.concat !destdir "postinstall" in
22742274+ if Sys.file_exists postinstall then
22752275+ run_command Verbose postinstall [ slashify !destdir; !pkgname ]
22762276+;;
22772277+22782278+22792279+let reserved_names = [ Findlib_config.libexec_name; "postinstall"; "postremove" ];;
22802280+22812281+let remove_package () =
22822282+ let destdir = ref (default_location()) in
22832283+ let destdir_set = ref false in
22842284+ let metadir = ref (meta_directory()) in
22852285+ let ldconf = ref (ocaml_ldconf()) in
22862286+ let pkgname = ref "" in
22872287+22882288+ let keywords =
22892289+ [ "-destdir", (Arg.String (fun s -> destdir := s; destdir_set := true)),
22902290+ ("<path> Set the destination directory (default: " ^
22912291+ !destdir ^ ")");
22922292+ "-metadir", (Arg.String (fun s -> metadir := s)),
22932293+ ("<path> Remove the META file from this directory (default: " ^
22942294+ (if !metadir = "" then "none" else !metadir) ^ ")");
22952295+ "-ldconf", (Arg.String (fun s -> ldconf := s)),
22962296+ ("<path> Update this ld.conf file (default: " ^ !ldconf ^ ")");
22972297+ ] in
22982298+ let errmsg = "usage: ocamlfind remove [options] <package_name>" in
22992299+23002300+ parse_args
23012301+ keywords
23022302+ (fun s ->
23032303+ if !pkgname = ""
23042304+ then pkgname := s
23052305+ else raise (Arg.Bad "too many arguments")
23062306+ )
23072307+ errmsg;
23082308+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
23092309+ if List.mem !pkgname reserved_names then
23102310+ failwith ("You are not allowed to remove this thing by ocamlfind!");
23112311+ if not (Fl_split.is_valid_package_name !pkgname) then
23122312+ failwith "Package names must not contain the character '.'!";
23132313+23142314+ let meta_dot_pkg = "META." ^ !pkgname in
23152315+ let has_metadir = !metadir <> "" in
23162316+ let pkgdir = Filename.concat !destdir !pkgname in
23172317+ let dlldir = Filename.concat !destdir Findlib_config.libexec_name in
23182318+ let have_libexec = Sys.file_exists dlldir in
23192319+23202320+ (* Warn if there is another package with the same name: *)
23212321+ let other_pkgdir =
23222322+ try Findlib.package_directory !pkgname with No_such_package _ -> "" in
23232323+ if other_pkgdir <> "" && not !destdir_set then begin
23242324+ (* Is pkgdir = other_pkgdir? - We check physical identity: *)
23252325+ try
23262326+ let s_other_pkgdir = Unix.stat other_pkgdir in
23272327+ try
23282328+ let s_pkgdir = Unix.stat pkgdir in
23292329+ if (s_pkgdir.Unix.st_dev <> s_other_pkgdir.Unix.st_dev) ||
23302330+ (s_pkgdir.Unix.st_ino <> s_other_pkgdir.Unix.st_ino)
23312331+ then
23322332+ prerr_endline("ocamlfind: [WARNING] You are removing the package from " ^ pkgdir ^ " but the currently visible package is at " ^ other_pkgdir ^ "; you may want to specify the -destdir option");
23332333+ with
23342334+ Unix.Unix_error(Unix.ENOENT,_,_) ->
23352335+ prerr_endline("ocamlfind: [WARNING] You are trying to remove the package from " ^ pkgdir ^ " but the currently visible package is at " ^ other_pkgdir ^ "; you may want to specify the -destdir option");
23362336+ with
23372337+ Unix.Unix_error(_,_,_) -> () (* ignore, it's only a warning *)
23382338+ end;
23392339+23402340+ (* First remove the META file. If it is already gone, assume that a
23412341+ parallel running removal removed it already.
23422342+ *)
23432343+23442344+ (* If there is a metadir, remove the META file from it: *)
23452345+ let meta_removal_ok =
23462346+ if has_metadir then (
23472347+ let f = Filename.concat !metadir meta_dot_pkg in
23482348+ try
23492349+ Unix.unlink f;
23502350+ prerr_endline ("Removed " ^ f);
23512351+ true
23522352+ with
23532353+ | Unix.Unix_error(Unix.ENOENT,_,_) ->
23542354+ prerr_endline ("ocamlfind: [WARNING] No such file: " ^ f);
23552355+ false
23562356+ | Unix.Unix_error(code, _, arg) ->
23572357+ raise(sys_error code arg)
23582358+ ) else
23592359+ let f = Filename.concat pkgdir "META" in
23602360+ try
23612361+ Unix.unlink f;
23622362+ prerr_endline ("Removed " ^ f);
23632363+ true
23642364+ with
23652365+ | Unix.Unix_error(Unix.ENOENT,_,_) ->
23662366+ prerr_endline ("ocamlfind: [WARNING] No such file: " ^ f);
23672367+ false
23682368+ | Unix.Unix_error(code, _, arg) ->
23692369+ raise(sys_error code arg) in
23702370+23712371+ if meta_removal_ok then (
23722372+23732373+ (* Remove files from libexec directory: *)
23742374+ if have_libexec then begin
23752375+ let dll_files = find_owned_files !pkgname dlldir in
23762376+ List.iter
23772377+ (fun file ->
23782378+ let absfile = Filename.concat dlldir file in
23792379+ Sys.remove absfile;
23802380+ prerr_endline ("Removed " ^ absfile)
23812381+ )
23822382+ dll_files
23832383+ end;
23842384+23852385+ (* Remove the files from the package directory: *)
23862386+ if Sys.file_exists pkgdir then begin
23872387+ let files = Sys.readdir pkgdir in
23882388+ Array.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files;
23892389+ Unix.rmdir pkgdir;
23902390+ prerr_endline ("Removed " ^ pkgdir)
23912391+ end
23922392+ else
23932393+ prerr_endline("ocamlfind: [WARNING] No such directory: " ^ pkgdir);
23942394+23952395+ (* Modify ld.conf *)
23962396+ if !ldconf <> "ignore" then begin
23972397+ if Sys.file_exists !ldconf then
23982398+ begin
23992399+ let lines = read_ldconf !ldconf in
24002400+ let d = Fl_split.norm_dir pkgdir in
24012401+ let exists = List.exists (fun p -> Fl_split.norm_dir p = d) lines in
24022402+ if exists then begin
24032403+ let lines' = List.filter (fun p -> Fl_split.norm_dir p <> d) lines in
24042404+ write_ldconf !ldconf lines' []
24052405+ end
24062406+ end
24072407+ end;
24082408+24092409+ (* Check if there is a postremove script: *)
24102410+ let postremove = Filename.concat !destdir "postremove" in
24112411+ if Sys.file_exists postremove then
24122412+ run_command Verbose postremove [ slashify !destdir; !pkgname ]
24132413+ )
24142414+;;
24152415+24162416+24172417+let list_packages() =
24182418+24192419+ let descr = ref false in
24202420+24212421+ let keywords =
24222422+ [ "-describe", Arg.Set descr,
24232423+ " Output package descriptions";
24242424+ ] in
24252425+ let errmsg = "usage: ocamlfind list [options]" in
24262426+24272427+ parse_args
24282428+ keywords
24292429+ (fun _ -> Arg.usage keywords errmsg; exit 1)
24302430+ errmsg;
24312431+24322432+ Findlib.list_packages ~descr:!descr stdout;
24332433+ Fl_package_base.package_conflict_report ~identify_dir ()
24342434+;;
24352435+24362436+24372437+let print_configuration() =
24382438+ let dir s =
24392439+ if Sys.file_exists s then
24402440+ s
24412441+ else
24422442+ s ^ " (not found)"
24432443+ in
24442444+24452445+ let var = ref None in
24462446+ let errmsg = "usage: ocamlfind printconf (conf|path|destdir|metadir|metapath|stdlib|ldconf)" in
24472447+24482448+ parse_args
24492449+ []
24502450+ (fun s ->
24512451+ if !var <> None then raise(Arg.Bad "Unexpected argument");
24522452+ match s with
24532453+ ("conf" | "path" | "destdir" | "metadir" | "metapath" | "stdlib" | "ldconf") ->
24542454+ var := Some s
24552455+ | _ ->
24562456+ raise(Arg.Bad "Bad argument");
24572457+ )
24582458+ errmsg;
24592459+24602460+ match !var with
24612461+ None ->
24622462+ print_endline "Effective configuration:";
24632463+ Printf.printf "Configuration file:\n %s\n"
24642464+ (dir (Findlib.config_file()));
24652465+ Printf.printf "Search path:\n";
24662466+ List.iter
24672467+ (fun p -> Printf.printf " %s\n" (dir p))
24682468+ (Findlib.search_path());
24692469+ Printf.printf "Packages will be installed in/removed from:\n %s\n"
24702470+ (dir (Findlib.default_location()));
24712471+ Printf.printf "META files will be installed in/removed from:\n %s\n"
24722472+ (let md = Findlib.meta_directory() in
24732473+ if md = "" then "the corresponding package directories" else dir md
24742474+ );
24752475+ Printf.printf "The standard library is assumed to reside in:\n %s\n"
24762476+ (Findlib.ocaml_stdlib());
24772477+ Printf.printf "The ld.conf file can be found here:\n %s\n"
24782478+ (Findlib.ocaml_ldconf());
24792479+ flush stdout
24802480+ | Some "conf" ->
24812481+ print_endline (Findlib.config_file())
24822482+ | Some "path" ->
24832483+ List.iter print_endline (Findlib.search_path())
24842484+ | Some "destdir" ->
24852485+ print_endline (Findlib.default_location())
24862486+ | Some "metadir" ->
24872487+ print_endline (Findlib.meta_directory())
24882488+ | Some "metapath" ->
24892489+ let mdir = Findlib.meta_directory() in
24902490+ let ddir = Findlib.default_location() in
24912491+ print_endline
24922492+ (if mdir <> "" then mdir ^ "/META.%s" else ddir ^ "/%s/META")
24932493+ | Some "stdlib" ->
24942494+ print_endline (Findlib.ocaml_stdlib())
24952495+ | Some "ldconf" ->
24962496+ print_endline (Findlib.ocaml_ldconf())
24972497+ | _ ->
24982498+ assert false
24992499+;;
25002500+25012501+25022502+let ocamlcall pkg cmd =
25032503+ let dir = package_directory pkg in
25042504+ let path = Filename.concat dir cmd in
25052505+ begin
25062506+ try Unix.access path [ Unix.X_OK ]
25072507+ with
25082508+ Unix.Unix_error (Unix.ENOENT, _, _) ->
25092509+ failwith ("Cannot find command: " ^ path)
25102510+ | Unix.Unix_error (Unix.EACCES, _, _) ->
25112511+ failwith ("Cannot execute: " ^ path)
25122512+ | other ->
25132513+ Unix.handle_unix_error (fun () -> raise other) ()
25142514+ end;
25152515+ let args = Array.to_list (Array.sub Sys.argv 2 (Array.length Sys.argv -2)) in
25162516+ run_command Normal path args
25172517+;;
25182518+25192519+(** lint META file *)
25202520+let lint () =
25212521+25222522+ let meta_files = Queue.create () in
25232523+25242524+ parse_args
25252525+ ~align:false
25262526+ ( Arg.align [
25272527+ ])
25282528+ (fun s -> if Sys.file_exists s
25292529+ then Queue.add s meta_files
25302530+ else raise(Arg.Bad (Printf.sprintf "%s: file doesn't exists" s)))
25312531+ "usage: ocamlfind lint <options> <files>...";
25322532+25332533+ let error =
25342534+ Queue.fold (fun error file ->
25352535+ let pkg = meta_pkg file in
25362536+ let error = Fl_lint.warn pkg || error in
25372537+ error
25382538+ ) false meta_files in
25392539+ exit (if error then 1 else 0)
25402540+;;
25412541+25422542+25432543+(** print ppx options *)
25442544+let print_ppx () =
25452545+25462546+ let packages = ref [] in
25472547+ let predicates = ref [] in
25482548+ let ppx_opts = ref [] in
25492549+25502550+ let add_pred =
25512551+ Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in
25522552+ let add_ppx_opt =
25532553+ Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]) in
25542554+25552555+ parse_args
25562556+ [ "-predicates", add_pred,
25572557+ " specifies comma-separated list of assumed predicates";
25582558+ "-ppxopt", add_ppx_opt,
25592559+ "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>";
25602560+ ]
25612561+ (fun p -> packages := !packages @ [p])
25622562+"usage: ocamlfind printppx [options] package ...";
25632563+25642564+ let ppx_commands =
25652565+ process_ppx_spec !predicates !packages !ppx_opts
25662566+ in
25672567+ print_endline (String.concat " " (List.map escape_if_needed ppx_commands))
25682568+;;
25692569+25702570+25712571+let rec select_mode () =
25722572+ let k = !Arg.current in
25732573+ let m_string = try arg (k+1) with Not_found -> raise Usage in
25742574+ let m =
25752575+ match m_string with
25762576+ ("use"|"-use") -> incr Arg.current; M_use
25772577+ | ("query"|"-query") -> incr Arg.current; M_query
25782578+ | ("install"|"-install") -> incr Arg.current; M_install
25792579+ | ("remove"|"-remove") -> incr Arg.current; M_remove
25802580+ | ("ocamlc"|"-ocamlc"|"c") -> incr Arg.current; M_compiler "ocamlc"
25812581+ | ("ocamlcp"|"-ocamlcp"|"cp") -> incr Arg.current; M_compiler "ocamlcp"
25822582+ | ("ocamloptp"|"-ocamloptp"|"optp") -> incr Arg.current; M_compiler "ocamloptp"
25832583+ | ("ocamlmklib"|"-ocamlmklib"|"mklib") -> incr Arg.current; M_compiler "ocamlmklib"
25842584+ | ("ocamlmktop"|"-ocamlmktop"|"mktop") -> incr Arg.current; M_compiler "ocamlmktop"
25852585+ | ("ocamlopt"|"-ocamlopt"|"opt") -> incr Arg.current; M_compiler "ocamlopt"
25862586+ | ("ocamldep"|"-ocamldep"|"dep") -> incr Arg.current; M_dep
25872587+ | ("ocamlbrowser"|"-ocamlbrowser"|"browser") -> incr Arg.current; M_browser
25882588+ | ("ocamldoc"|"-ocamldoc"|"doc") -> incr Arg.current; M_doc
25892589+ | ("printconf"|"-printconf") -> incr Arg.current; M_printconf
25902590+ | ("list"|"-list") -> incr Arg.current; M_list
25912591+ | ("lint"|"-lint") -> incr Arg.current; M_lint
25922592+ | ("printppx"|"-printppx") -> incr Arg.current; M_printppx
25932593+ | "-toolchain" ->
25942594+ let t = try arg (k+2) with Not_found -> raise Usage in
25952595+ Findlib.init ~toolchain:t ();
25962596+ Arg.current := k+2;
25972597+ select_mode()
25982598+ | s when String.contains m_string '/' ->
25992599+ incr Arg.current;
26002600+ let k = String.index m_string '/' in
26012601+ let pkg = String.sub m_string 0 k in
26022602+ let cmd = String.sub m_string (k+1) (String.length m_string - k - 1) in
26032603+ M_call(pkg,cmd)
26042604+ | _ -> raise Usage
26052605+ in
26062606+26072607+ m
26082608+;;
26092609+26102610+26112611+let main() =
26122612+ try
26132613+ let m = select_mode() in
26142614+ let l = Array.length Sys.argv in
26152615+ let k = !Arg.current in
26162616+ let rest = Array.sub Sys.argv (k+1) (l-k-1) in
26172617+ match m with
26182618+ M_use -> if rest = [| |] then raise Usage;
26192619+ if rest.(0) = "-p" then begin
26202620+ if l<4 then raise Usage;
26212621+ use_package rest.(1)
26222622+ (List.tl(List.tl(Array.to_list rest)))
26232623+ end
26242624+ else
26252625+ use_package "" (Array.to_list rest)
26262626+ | M_query -> query_package ()
26272627+ | M_install -> install_package()
26282628+ | M_remove -> remove_package ()
26292629+ | M_printconf -> print_configuration ()
26302630+ | M_list -> list_packages()
26312631+ | M_dep -> ocamldep()
26322632+ | M_browser -> ocamlbrowser()
26332633+ | M_doc -> ocamldoc()
26342634+ | M_call(pkg,cmd) -> ocamlcall pkg cmd
26352635+ | M_compiler which -> ocamlc which ()
26362636+ | M_lint -> lint()
26372637+ | M_printppx -> print_ppx()
26382638+ with
26392639+ Usage ->
26402640+ prerr_endline "Usage: ocamlfind query [-help | other options] <package_name> ...";
26412641+ prerr_endline " or: ocamlfind ocamlc [-help | other options] <file> ...";
26422642+ prerr_endline " or: ocamlfind ocamlcp [-help | other options] <file> ...";
26432643+ prerr_endline " or: ocamlfind ocamlmklib [-help | other options] <file> ...";
26442644+ prerr_endline " or: ocamlfind ocamlmktop [-help | other options] <file> ...";
26452645+ if Ocaml_args.ocamlopt_spec <> None then
26462646+ prerr_endline " or: ocamlfind ocamlopt [-help | other options] <file> ...";
26472647+ if Ocaml_args.ocamloptp_spec <> None then
26482648+ prerr_endline " or: ocamlfind ocamloptp [-help | other options] <file> ...";
26492649+ prerr_endline " or: ocamlfind ocamldep [-help | other options] <file> ...";
26502650+ prerr_endline " or: ocamlfind ocamlbrowser [-help | other options]";
26512651+ prerr_endline " or: ocamlfind ocamldoc [-help | other options] <file> ...";
26522652+ prerr_endline " or: ocamlfind install [-help | other options] <package_name> <file> ...";
26532653+ prerr_endline " or: ocamlfind remove [-help | other options] <package_name>";
26542654+ prerr_endline " or: ocamlfind printppx [-help | other options] <package_name> ...";
26552655+ prerr_endline " or: ocamlfind printconf [-help] [variable]";
26562656+ prerr_endline " or: ocamlfind lint [-help] <file>";
26572657+ prerr_endline " or: ocamlfind list";
26582658+ prerr_endline " or: ocamlfind pkg/cmd arg ...";
26592659+ prerr_endline "Select toolchain with:";
26602660+ prerr_endline " ocamlfind -toolchain <t> <command>";
26612661+ prerr_endline "Abbreviations:";
26622662+ prerr_endline " e.g. ocamlfind opt instead of ocamlfind ocamlopt";
26632663+ exit 2
26642664+ | Failure f ->
26652665+ prerr_endline ("ocamlfind: " ^ f);
26662666+ exit 2
26672667+ | Sys_error f ->
26682668+ prerr_endline ("ocamlfind: " ^ f);
26692669+ exit 2
26702670+ | Findlib.No_such_package(pkg,info) ->
26712671+ prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' not found" ^
26722672+ (if info <> "" then " - " ^ info else ""));
26732673+ exit 2
26742674+ | Findlib.Package_loop pkg ->
26752675+ prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' requires itself");
26762676+ exit 2
26772677+ | Silent_error ->
26782678+ exit 2
26792679+;;
26802680+26812681+26822682+try
26832683+ Sys.catch_break true;
26842684+ main()
26852685+with
26862686+ any ->
26872687+ prerr_endline ("Uncaught exception: " ^ Printexc.to_string any);
26882688+ let raise_again =
26892689+ try ignore(Sys.getenv "OCAMLFIND_DEBUG"); true
26902690+ with Not_found -> false
26912691+ in
26922692+ if raise_again then raise any;
26932693+ exit 3
26942694+;;
+32
vendor/opam/ocamlfind/src/findlib/num_top.ml
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+let print_outcome = false
77+let error_fmt = Format.err_formatter
88+99+let printers = [
1010+ "Num_top_printers.nat_printer";
1111+ "Num_top_printers.big_int_printer";
1212+ "Num_top_printers.ratio_printer";
1313+ "Num_top_printers.num_printer";
1414+]
1515+1616+let eval_phrase s =
1717+ let lexbuf = Lexing.from_string s in
1818+ let phrase = !Toploop.parse_toplevel_phrase lexbuf in
1919+ Toploop.execute_phrase print_outcome error_fmt phrase
2020+2121+let install_all () =
2222+ List.fold_left
2323+ (fun outcome phrase ->
2424+ outcome && eval_phrase (Printf.sprintf "#install_printer %s;;" phrase))
2525+ true printers
2626+2727+let _ =
2828+ if not (install_all ()) then begin
2929+ Format.fprintf error_fmt
3030+ "Something weird happened while installing Num library printers";
3131+ Format.pp_print_flush error_fmt ()
3232+ end
+18
vendor/opam/ocamlfind/src/findlib/num_top.mli
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(**
77+ Load this module in the toplevel to install printers for the following types
88+ defined in the "num" library:
99+ - Nat.nat
1010+ - Big_int.big_int
1111+ - Ratio.ratio
1212+ - Num.num
1313+1414+ No functions exported.
1515+1616+ Copyright (C) 2003 Stefano Zacchiroli <zack@debian.org>
1717+*)
1818+
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(**
77+ Printers for types defined in the "num" library. Meant to be used as printers
88+ in the ocaml toplevel. See num_top.mli.
99+1010+ Copyright (C) 2003 Stefano Zacchiroli <zack@debian.org>
1111+1212+ Released under the same terms as findlib.
1313+*)
1414+1515+val nat_printer : Format.formatter -> Nat.nat -> unit
1616+val big_int_printer : Format.formatter -> Big_int.big_int -> unit
1717+val ratio_printer : Format.formatter -> Ratio.ratio -> unit
1818+val num_printer: Format.formatter -> Num.num -> unit
1919+
+87
vendor/opam/ocamlfind/src/findlib/test_parser.ml
···11+let with_open_in file func =
22+ let chan = open_in file in
33+ let result =
44+ try func chan
55+ with exn -> close_in chan; raise exn
66+ in
77+ close_in chan; result
88+;;
99+1010+type test_mode = Compare_both | Only of (old_or_new * int)
1111+and old_or_new = Old | New
1212+1313+let read_file file =
1414+ let buf = Buffer.create 100 in
1515+ with_open_in file (fun ch ->
1616+ try while true do Buffer.add_string buf (input_line ch) done
1717+ with End_of_file -> ());
1818+ Buffer.contents buf
1919+2020+let test mode file =
2121+ match mode with
2222+ | Compare_both ->
2323+ let ast1 = with_open_in file Fl_metascanner.parse in
2424+ let ast2 = with_open_in file Fl_metascanner.parse2 in
2525+ Printf.printf "%s tested %s\n" file (if ast1 = ast2 then "OK" else "FAIL")
2626+ | Only (old_or_new, niter) ->
2727+ let content = read_file file in
2828+ for i = 1 to niter do
2929+ let parse = match old_or_new with
3030+ | Old -> Fl_metascanner.parse_lexing
3131+ | New -> Fl_metascanner.parse2_lexing in
3232+ ignore (parse (Lexing.from_string content))
3333+ done
3434+3535+let rec explore mode path =
3636+ if Sys.is_directory path then
3737+ let traverse file = explore mode (Filename.concat path file) in
3838+ Array.iter traverse (Sys.readdir path)
3939+ else if Filename.basename path = "META" then
4040+ test mode path
4141+4242+let () =
4343+ let test_mode, targets = (* command-line option handling *)
4444+ let only_old = ref false in
4545+ let only_new = ref false in
4646+ let niter = ref 1 in
4747+ let targets = ref [] in
4848+ let usage = "test_parser <options> <path> <path> ....\n \
4949+ recursively traverse paths and compare the two parsers \
5050+ on each file named META"
5151+ in
5252+ let options = [
5353+ ("--niter", Arg.Set_int niter, "iterate the parser for performance comparison (only in --only-old or --only-new modes)");
5454+ ("--only-old", Arg.Set only_old, "only test the old parser");
5555+ ("--only-new", Arg.Set only_new, "only test the new parser");
5656+ ] in
5757+ let action path = targets := path :: !targets in
5858+ Arg.parse options action usage;
5959+ let quit_with_usage () = Arg.usage options usage; exit 1 in
6060+ let test_mode =
6161+ match !only_old, !only_new with
6262+ | false, false -> Compare_both
6363+ | false, true -> Only (New, !niter)
6464+ | true, false -> Only (Old, !niter)
6565+ | true, true ->
6666+ prerr_endline "--only-only and --new-only cannot be \
6767+ both set at the same time";
6868+ quit_with_usage ();
6969+ in
7070+ if !targets = [] then quit_with_usage ();
7171+ test_mode, !targets
7272+ in
7373+ let traverse path =
7474+ if Sys.file_exists path then explore test_mode path
7575+ else Printf.eprintf "Error: path %s does not exist and was ignored.\n" path
7676+ in
7777+ List.iter traverse targets
7878+7979+8080+8181+8282+8383+8484+8585+8686+8787+
+148
vendor/opam/ocamlfind/src/findlib/topfind.in
···11+(* $Id$ -*- tuareg -*- *)
22+33+(* For Ocaml-3.03 and up, so you can do: #use "topfind" and get a
44+ * working findlib toploop.
55+ *)
66+77+(* To access Toploop in OCaml >= 4.00. This directory will be later removed from path if possible *)
88+#directory "+compiler-libs";;
99+1010+let exists path =
1111+ match Sys.file_exists path with
1212+ | true -> Some path
1313+ | false -> None
1414+in
1515+1616+let ( / ) = Filename.concat in
1717+1818+let findlib_conf_of_path path =
1919+ match exists (path / "etc" / "findlib.conf") with
2020+ | Some etc_path -> etc_path
2121+ | None -> path / "lib" / "findlib.conf"
2222+in
2323+2424+let install_dir_from_opam_switch_prefix path =
2525+ match Sys.file_exists (findlib_conf_of_path path) with
2626+ | false -> None
2727+ | true -> Some path
2828+in
2929+3030+let install_dir_from_ocaml_toplevel_path path =
3131+ let exe_dir = Filename.dirname path in
3232+ let install_dir = Filename.dirname exe_dir in
3333+ let config_path = findlib_conf_of_path install_dir in
3434+ match Sys.file_exists config_path with
3535+ | true -> Some install_dir
3636+ | false -> None
3737+in
3838+3939+let fl_split_path_separator =
4040+ match Sys.os_type with
4141+ | "Unix" | "BeOS" -> ':'
4242+ | "Cygwin" -> ';' (* You might want to change this *)
4343+ | "Win32" -> ';'
4444+ | "MacOS" -> failwith "Findlib: I do not know what is the correct path separator for MacOS. If you can help me, write a mail to gerd@gerd-stolpmann.de"
4545+ | _ -> failwith "Findlib: unknown operating system"
4646+in
4747+4848+let string_split_on_char sep s =
4949+ let r = ref [] in
5050+ let j = ref (String.length s) in
5151+ for i = String.length s - 1 downto 0 do
5252+ if String.unsafe_get s i = sep then begin
5353+ r := String.sub s (i + 1) (!j - i - 1) :: !r;
5454+ j := i
5555+ end
5656+ done;
5757+ String.sub s 0 !j :: !r
5858+in
5959+6060+let rec list_find_map f = function
6161+ | [] -> None
6262+ | x :: l ->
6363+ begin match f x with
6464+ | Some _ as result -> result
6565+ | None -> list_find_map f l
6666+ end
6767+in
6868+6969+let install_dir_from_ld_library_path paths =
7070+ let v = string_split_on_char fl_split_path_separator paths in
7171+ list_find_map (fun path ->
7272+ let parent = Filename.dirname path in
7373+ let parent' = Filename.dirname parent in
7474+ match Sys.file_exists (findlib_conf_of_path parent') with
7575+ | true -> Some parent'
7676+ | false -> None) v
7777+in
7878+7979+let getenv_opt v = try Some (Sys.getenv v) with Not_found -> None in
8080+8181+let rec try_vars = function
8282+ | [] -> None
8383+ | (var, mapper)::xs -> (
8484+ match getenv_opt var with
8585+ | None -> try_vars xs
8686+ | Some content -> (
8787+ match mapper content with
8888+ | None -> try_vars xs
8989+ | Some _ as found -> found))
9090+in
9191+9292+let location =
9393+ match try_vars [
9494+ ("OPAM_SWITCH_PREFIX", install_dir_from_opam_switch_prefix);
9595+ ("CAML_LD_LIBRARY_PATH", install_dir_from_ld_library_path);
9696+ ("OCAML_TOPLEVEL_PATH", install_dir_from_ocaml_toplevel_path);
9797+ ] with
9898+ | Some location -> location
9999+ | None -> "@SITELIB@"
100100+in
101101+102102+let findlib_directory = match @RELATIVE_PATHS@ with
103103+ | true -> location / "lib" / "findlib"
104104+ | false -> "@SITELIB@/findlib"
105105+in
106106+107107+let () = Topdirs.dir_directory findlib_directory in
108108+ (* OCaml-4.00 requires to use dir_directory before we load anything *)
109109+110110+let exec_test s =
111111+ let l = Lexing.from_string s in
112112+ let ph = !Toploop.parse_toplevel_phrase l in
113113+ let fmt = Format.make_formatter (fun _ _ _ -> ()) (fun _ -> ()) in
114114+ try
115115+ Toploop.execute_phrase false fmt ph
116116+ with
117117+ _ -> false
118118+in
119119+120120+(* one of the few observable differences... *)
121121+let is_native = (Gc.get ()).Gc.stack_limit = 0 in
122122+123123+let suffix = if is_native then "cmxs" else "cma" in
124124+125125+(* First test whether findlib_top is already loaded. If not, load it now.
126126+ * The test works by executing the toplevel phrase "Topfind.reset" and
127127+ * checking whether this causes an error.
128128+ *)
129129+if not (exec_test "Topfind.reset;;") then (
130130+ Topdirs.dir_load Format.err_formatter (findlib_directory / ("findlib." ^ suffix));
131131+ Topdirs.dir_load Format.err_formatter (findlib_directory / ("findlib_top." ^ suffix)))
132132+;;
133133+(* phrase has to end here otherwise Topfind is not accessible *)
134134+135135+(* REMOVE_DIRECTORY_BEGIN *)
136136+(* OCaml < 4.00 do not have this so only include this code if it was detected *)
137137+let () = Topdirs.dir_remove_directory "+compiler-libs" in
138138+(* REMOVE_DIRECTORY_END *)
139139+140140+(* The following is always executed. It is harmless if findlib was already
141141+ * initialized
142142+ *)
143143+let is_native = (Gc.get ()).Gc.stack_limit = 0 in
144144+let pred = if is_native then "native" else "byte" in
145145+146146+Topfind.add_predicates [ pred; "toploop" ];
147147+Topfind.don't_load ["findlib"];
148148+Topfind.announce ();;
+342
vendor/opam/ocamlfind/src/findlib/topfind.ml.in
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+let predicates = ref ("toploop" :: Findlib.recorded_predicates());;
77+ (* We also want things like "syntax" here which are not allowed in
88+ Findlib, hence we maintain our own list
99+ *)
1010+1111+let ocaml_stdlib = lazy (Findlib.ocaml_stdlib ());;
1212+let directories = ref [ ] ;;
1313+1414+1515+(* Note: Sys.interactive is always _true_ during toploop startup.
1616+ * When a script is executed, it is set to false just before the
1717+ * script starts. This is important for ocamlmktop-generated toploops:
1818+ * For initialization code linked into the toploop, Sys.interactive
1919+ * is _true_. It is set to false just before the script starts.
2020+ *)
2121+2222+let real_toploop =
2323+ !Sys.interactive;;
2424+2525+let log = ref (if real_toploop then prerr_endline else ignore)
2626+2727+let rec remove_dups l =
2828+ match l with
2929+ x :: l' ->
3030+ if List.mem x l' then remove_dups l' else x::remove_dups l'
3131+ | [] -> []
3232+;;
3333+3434+let add_predicates pl =
3535+ predicates := remove_dups (pl @ !predicates);
3636+ Findlib.record_package_predicates !predicates;;
3737+3838+let syntax s =
3939+ add_predicates [ "syntax"; s ];;
4040+4141+let standard_syntax () = syntax "camlp4o";;
4242+let revised_syntax () = syntax "camlp4r";;
4343+4444+4545+let add_dir d =
4646+ let d = Fl_split.norm_dir d in
4747+ let ocaml_stdlib = Lazy.force ocaml_stdlib in
4848+ if d <> ocaml_stdlib && not (List.mem d !directories) then begin
4949+ Topdirs.dir_directory d;
5050+ directories := d :: !directories;
5151+ !log (d ^ ": added to search path")
5252+ end
5353+;;
5454+5555+let exec_string s =
5656+ let l = Lexing.from_string s in
5757+ let ph = !Toploop.parse_toplevel_phrase l in
5858+(* PPXOPT_BEGIN *)
5959+ let ph = Toploop.preprocess_phrase Format.err_formatter ph in
6060+(* PPXOPT_END *)
6161+ let fmt = Format.make_formatter (fun _ _ _ -> ()) (fun _ -> ()) in
6262+ try
6363+ Toploop.execute_phrase false fmt ph
6464+ with
6565+ _ -> false
6666+;;
6767+6868+let load pkglist =
6969+ List.iter
7070+ (fun pkg ->
7171+ let _stdlibdir = Findlib.ocaml_stdlib() in
7272+ let loaded =
7373+ Findlib.is_recorded_package pkg &&
7474+ Findlib.type_of_recorded_package pkg = Findlib.Record_load in
7575+ let incore =
7676+ Findlib.is_recorded_package pkg &&
7777+ Findlib.type_of_recorded_package pkg = Findlib.Record_core in
7878+ if not loaded then begin
7979+ (* Determine the package directory: *)
8080+ let d = Findlib.package_directory pkg in
8181+ add_dir d;
8282+ (* Leave pkg out if mentioned in !forbidden *)
8383+ if not incore then begin
8484+ (* Determine the 'archive' property: *)
8585+ let archive =
8686+ try Findlib.package_property !predicates pkg "archive"
8787+ with
8888+ Not_found -> ""
8989+ in
9090+ (* Split the 'archive' property and load the files: *)
9191+ let archives = Fl_split.in_words archive in
9292+ List.iter
9393+ (fun arch ->
9494+ let arch' = Findlib.resolve_path ~base:d arch in
9595+ !log (arch' ^ ": loaded");
9696+ Topdirs.dir_load
9797+ Format.std_formatter arch')
9898+ archives;
9999+ (* Determine the 'ppx' property: *)
100100+ let ppx =
101101+ try
102102+ Some(Findlib.resolve_path
103103+ ~base:d ~explicit:true
104104+ (Findlib.package_property !predicates pkg "ppx")
105105+ )
106106+ with Not_found -> None
107107+ and ppxopts =
108108+ try
109109+ List.map
110110+ (fun opt ->
111111+ match Fl_split.in_words opt with
112112+ | pkg :: opts ->
113113+ pkg,
114114+ List.map
115115+ (Findlib.resolve_path ~base:d ~explicit:true) opts
116116+ | _ -> assert false)
117117+ (Fl_split.in_words_ws
118118+ (Findlib.package_property !predicates pkg "ppxopt"))
119119+ with Not_found -> [] in
120120+ (* Feed the 'ppx' property into the toplevel. To remain compatible
121121+ with pre-4.01 OCaml, construct and execute a phrase instead of directly
122122+ altering Clflags. *)
123123+ begin match ppx with
124124+ | Some ppx ->
125125+126126+127127+ begin try
128128+ match Hashtbl.find Toploop.directive_table "ppx" with
129129+ | Toploop.Directive_string fn ->
130130+ fn ppx; !log (ppx ^ ": activated")
131131+ | _ -> assert false
132132+ with Not_found ->
133133+ failwith "Package defines a ppx preprocessor, but OCaml is too old. \
134134+ Use OCaml >= 4.02.0 for ppx support."
135135+ end
136136+ | None -> ()
137137+ end;
138138+ (* Feed the 'ppxopt' property into the toplevel. *)
139139+ match ppxopts with
140140+ | [] -> ()
141141+ | _ ->
142142+(* PPXOPT_BEGIN *)
143143+ List.iter
144144+ (fun (pkg, opts) ->
145145+ ignore (exec_string ("[@@@findlib.ppxopt " ^
146146+ (String.concat ", "
147147+ (List.map (Printf.sprintf "%S") (pkg :: opts))) ^
148148+ "];;"));
149149+ !log (pkg ^ ": " ^ (String.concat " " opts) ^
150150+ ": option added"))
151151+ ppxopts
152152+(*
153153+(* PPXOPT_END *)
154154+ failwith "Package defines a ppx preprocessor option, but OCaml is too old. \
155155+ Use OCaml >=4.02.1 for ppxopt support."
156156+(* PPXOPT_BEGIN *)
157157+*)
158158+(* PPXOPT_END *)
159159+ end;
160160+ (* The package is loaded: *)
161161+ Findlib.record_package Findlib.Record_load pkg
162162+ end)
163163+ pkglist
164164+;;
165165+166166+167167+let load_deeply pkglist =
168168+ (* Get the sorted list of ancestors *)
169169+ let eff_pkglist =
170170+ Findlib.package_deep_ancestors !predicates pkglist in
171171+ List.iter (fun pkg ->
172172+ try let error = Findlib.package_property !predicates pkg "error" in
173173+ failwith ("Error from package `" ^ pkg ^ "': " ^ error)
174174+ with Not_found -> ()) eff_pkglist ;
175175+ (* Load the packages in turn: *)
176176+ load eff_pkglist
177177+;;
178178+179179+180180+let check_existence pkglist =
181181+ List.iter
182182+ (fun pkg ->
183183+ let _ = Findlib.package_directory pkg in ()
184184+ )
185185+ pkglist
186186+;;
187187+188188+189189+let don't_load pkglist =
190190+ check_existence pkglist;
191191+ List.iter (Findlib.record_package Findlib.Record_core) pkglist
192192+;;
193193+194194+195195+let don't_load_deeply pkglist =
196196+ (* Check if packages exist: *)
197197+ check_existence pkglist;
198198+ (* Get the sorted list of ancestors *)
199199+ let eff_pkglist =
200200+ Findlib.package_deep_ancestors !predicates pkglist in
201201+ (* Add this to the list of core packages: *)
202202+ List.iter (Findlib.record_package Findlib.Record_core) eff_pkglist
203203+;;
204204+205205+206206+let reset() =
207207+ Findlib.reset_recordings()
208208+;;
209209+210210+211211+let have_mt_support() =
212212+ Findlib.package_property [] "threads" "type_of_threads" = "posix"
213213+;;
214214+215215+216216+let load_mt_support() =
217217+ (* Load only if package "threads" is not yet loaded. *)
218218+ if not(Findlib.is_recorded_package "threads") then (
219219+ (* This works only for POSIX threads. *)
220220+ if have_mt_support() then (
221221+ add_predicates ["mt"; "mt_posix"];
222222+ add_dir (Filename.concat (Findlib.ocaml_stdlib()) "threads");
223223+ load_deeply ["unix"];
224224+ load_deeply ["threads"];
225225+ )
226226+ else (
227227+ failwith "It is not possible to load support for vmthreads dynamically. Use\n
228228+'ocamlfind ocamlmktop -o vmtop -package threads,findlib -linkpkg -vmthread'\n
229229+to create a toploop with integrated vmthreads library."
230230+ )
231231+ )
232232+;;
233233+234234+235235+let list_packages() =
236236+ Findlib.list_packages stdout;
237237+ flush stdout
238238+;;
239239+240240+241241+let protect f arg =
242242+ try
243243+ let _ = f arg in ()
244244+ with
245245+ Failure s ->
246246+ print_endline s
247247+ | Fl_package_base.No_such_package(pkg, reason) ->
248248+ print_endline ("No such package: " ^ pkg ^
249249+ (if reason <> "" then " - " ^ reason else ""))
250250+ | Fl_package_base.Package_loop pkg ->
251251+ print_endline ("Package requires itself: " ^ pkg)
252252+;;
253253+254254+255255+(* Add "#require" directive: *)
256256+257257+Hashtbl.add
258258+ Toploop.directive_table
259259+ "require"
260260+ (Toploop.Directive_string
261261+ (fun s ->
262262+ protect load_deeply (Fl_split.in_words s)
263263+ ))
264264+;;
265265+266266+(* Add "#predicates" directive: *)
267267+Hashtbl.add
268268+ Toploop.directive_table
269269+ "predicates"
270270+ (Toploop.Directive_string
271271+ (fun s ->
272272+ protect add_predicates (Fl_split.in_words s)
273273+ ))
274274+;;
275275+276276+277277+(* Add "#camlp4o" directive: *)
278278+279279+Hashtbl.add
280280+ Toploop.directive_table
281281+ "camlp4o"
282282+ (Toploop.Directive_none
283283+ (fun () ->
284284+ protect (fun () ->
285285+ standard_syntax();
286286+ load_deeply ["camlp4"]) ()
287287+ ))
288288+;;
289289+290290+(* Add "#camlp4r" directive: *)
291291+292292+Hashtbl.add
293293+ Toploop.directive_table
294294+ "camlp4r"
295295+ (Toploop.Directive_none
296296+ (fun () ->
297297+ protect (fun () ->
298298+ revised_syntax();
299299+ load_deeply ["camlp4"]) ()
300300+ ))
301301+;;
302302+303303+304304+(* Add "#list" directive: *)
305305+306306+Hashtbl.add
307307+ Toploop.directive_table
308308+ "list"
309309+ (Toploop.Directive_none
310310+ (fun () ->
311311+ protect list_packages ()
312312+ ))
313313+;;
314314+315315+316316+(* Add "#thread" directive: *)
317317+318318+Hashtbl.add
319319+ Toploop.directive_table
320320+ "thread"
321321+ (Toploop.Directive_none
322322+ (fun () ->
323323+ protect load_mt_support ()
324324+ ))
325325+;;
326326+327327+328328+let announce() =
329329+ if real_toploop then begin
330330+ (* Assume we are in a toploop and not a script *)
331331+ let msg_thread =
332332+ " #thread;; to enable threads\n" in
333333+ print_endline
334334+ ("Findlib has been successfully loaded. Additional directives:\n" ^
335335+ " #require \"package\";; to load a package\n" ^
336336+ " #list;; to list the available packages\n" ^
337337+ " #camlp4o;; to load camlp4 (standard syntax)\n" ^
338338+ " #camlp4r;; to load camlp4 (revised syntax)\n" ^
339339+ " #predicates \"p,q,...\";; to set these predicates\n" ^
340340+ " Topfind.reset();; to force that packages will be reloaded\n" ^
341341+ (if have_mt_support() then msg_thread else ""))
342342+ end ;;
+122
vendor/opam/ocamlfind/src/findlib/topfind.mli
···11+(* $Id$
22+ * ----------------------------------------------------------------------
33+ *
44+ *)
55+66+(** Load packages from toploops and scripts
77+ *
88+ * The [Topfind] module is part of the [findlib] package. The module
99+ * depends on the presence of a toploop. When building a toploop, it is
1010+ * automatically linked in if "findlib" is linked in, e.g.
1111+ * {[
1212+ * ocamlfind ocamlmktop ...options... -package findlib -linkpkg
1313+ * ]}
1414+ *
1515+ * When the platform supports DLLs, another possibility to get a toploop
1616+ * with findlib directives is to load the file "topfind" (normally installed
1717+ * in the standard library directory):
1818+ * {[
1919+ * $ ocaml
2020+ * Objective Caml version 3.04
2121+ * # #use "topfind";;
2222+ * Findlib has been successfully loaded. Additional directives:
2323+ * #require "package";; to load a package
2424+ * #list;; to list the available packages
2525+ * #camlp4o;; to load camlp4 (standard syntax)
2626+ * #camlp4r;; to load camlp4 (revised syntax)
2727+ * Topfind.reset();; to force that packages will be reloaded
2828+ * ~ : unit = ()
2929+ * # _
3030+ * ]}
3131+ *
3232+ * This works even in scripts (but the startup message is suppressed in this
3333+ * case).
3434+ *
3535+ * The module is not thread-safe; if used in a multi-threaded script, all
3636+ * packgage loading must have happened before the first thread forks.
3737+ *
3838+ * The Topfind module contains some functions simplifying package loading
3939+ * in scripts. Most important, there is a new directive [#require] for
4040+ * the same purpose (see below).
4141+ *
4242+ * The [Topfind] module needs some initialization, in particular the
4343+ * [predicates] variable needs to be
4444+ * set, and the packages already compiled into the toploop needs to be
4545+ * declared by the [don't_load]
4646+ * function. If the toploop has been built by [ocamlfind],
4747+ * the necessary initialization is
4848+ * automatically compiled in.
4949+ *)
5050+5151+(** {1 Directives}
5252+ *
5353+ * This module also defines the following directives for the toploop:
5454+ *
5555+ * - [#require "<package>"]
5656+ * loads the package (and if necessary the prerequisites of the package)
5757+ * - [#camlp4o]
5858+ * loads camlp4 and selects standard syntax
5959+ * - [#camlp4r]
6060+ * loads camlp4 and selects revised syntax
6161+ * - [#list]
6262+ * lists the available packages (calls external command "ocamlfind")
6363+ * - [#thread]
6464+ * enables multi-threading if possible
6565+ * - [#predicates "p1,p2,..."]
6666+ * adds these predicates
6767+ *)
6868+6969+(** {1 Functions and variables} *)
7070+7171+val predicates : string list ref
7272+ (** The list of predicates used for package loading *)
7373+7474+val add_predicates : string list -> unit
7575+ (** Adds predicates to the list of predicates *)
7676+7777+val syntax : string -> unit
7878+ (** Emulates the [-syntax] option *)
7979+8080+val standard_syntax : unit -> unit
8181+ (** Adds predicates that select the standard syntax. Same as
8282+ * [syntax "camlp4o"]
8383+ *)
8484+8585+val revised_syntax : unit -> unit
8686+ (** Adds predicates that select the revised syntax. Same as
8787+ * [syntax "camlp4r"]
8888+ *)
8989+9090+val don't_load : string list -> unit
9191+ (** The packages named in pkglist are added to the list of packages which
9292+ * are already loaded.
9393+ *)
9494+9595+val don't_load_deeply : string list -> unit
9696+ (** The packages named in pkglist and all direct and indirect ancestors
9797+ * are added to the list of packages which are already loaded.
9898+ *)
9999+100100+val load : string list -> unit
101101+ (** The packages from the passed package list are loaded, from left to
102102+ * right, but packages that have already been loaded are left out.
103103+ *)
104104+105105+val load_deeply : string list -> unit
106106+ (** The packages from the passed package list and all direct or indirect
107107+ * ancestors are loaded in topological order. Packages that have already
108108+ * been loaded are left out.
109109+ *)
110110+111111+val reset : unit -> unit
112112+ (** All entries in the list of loaded packages that have been added by
113113+ * [load] or [load_deeply] functions are removed from this list. This
114114+ * means that if you execute the same [load] or [load_deeply] functions
115115+ * again, the packages will be reloaded.
116116+ *)
117117+118118+val announce : unit -> unit
119119+ (** Output the startup message *)
120120+121121+val log : (string -> unit) ref
122122+ (** Function used to log messages from this module. *)
+30
vendor/opam/ocamlfind/tools/cmd_from_same_dir
···11+#! /bin/sh
22+33+# Check whether ocamlc and ocamlc.opt are installed in the same
44+# directory (or whatever command names are passed as $1).
55+66+get_path () {
77+ IFS=":"
88+ for d in $PATH; do
99+ if test -x "$d/$1"; then
1010+ IFS="$oldifs"
1111+ echo "$d/$1"
1212+ return
1313+ fi
1414+ done
1515+ IFS="$oldifs"
1616+#--- The following is not portable enough:
1717+# if test -x `type -p ls`; then
1818+# # type -p works!
1919+# type -p $1
2020+# else
2121+# # use 'which' instead
2222+# p=`which $1`
2323+# test -x "$p" && echo $p
2424+# fi
2525+}
2626+2727+p1="$(get_path "$1").opt"
2828+p2="$(get_path "$1.opt")"
2929+3030+[ "X$p1" = "X$p2" ]
+16
vendor/opam/ocamlfind/tools/collect_files
···11+#! /bin/sh
22+#
33+# $Id$
44+# ----------------------------------------------------------------------
55+#
66+# usage: collect_files file ...
77+#
88+# Prints the names of the files passed as arguments which actually
99+# exist and are regular files.
1010+1111+for x in "$@"; do
1212+ if [ -f "$x" ]; then
1313+ echo "$x"
1414+ fi
1515+done
1616+
···11+#!/bin/sh
22+33+# Shell script from Pietro Abate <pietro.abate@anu.edu.au> to create
44+# Mac OS X packages. Call from Makefile by "make package-macosx".
55+66+#########################################################################
77+# #
88+# Objective Caml #
99+# #
1010+# Damien Doligez, projet Moscova, INRIA Rocquencourt #
1111+# #
1212+# Copyright 2003 Institut National de Recherche en Informatique et #
1313+# en Automatique. All rights reserved. This file is distributed #
1414+# under the terms of the Q Public License version 1.0. #
1515+# #
1616+#########################################################################
1717+1818+# $Id: make-package-macosx,v 1.10.2.2 2006/01/04 13:05:49 doligez Exp $
1919+# adapted to findlib by Pietro.Abate <pietro.abate@anu.edu.au>
2020+2121+set -x
2222+2323+cd package-macosx
2424+rm -rf findlib.pkg findlib-rw.dmg
2525+mkdir -p resources
2626+2727+cat >Description.plist <<EOF
2828+ <?xml version="1.0" encoding="UTF-8"?>
2929+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
3030+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3131+ <plist version="1.0">
3232+ <dict>
3333+ <key>IFPkgDescriptionDeleteWarning</key>
3434+ <string></string>
3535+ <key>IFPkgDescriptionDescription</key>
3636+ <string>The findlib library manager</string>
3737+ <key>IFPkgDescriptionTitle</key>
3838+ <string>Findlib</string>
3939+ <key>IFPkgDescriptionVersion</key>
4040+ <string>${VERSION}</string>
4141+ </dict>
4242+ </plist>
4343+EOF
4444+4545+cat >Info.plist <<EOF
4646+<?xml version="1.0" encoding="UTF-8"?>
4747+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
4848+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4949+<plist version="1.0">
5050+<dict>
5151+ <key>CFBundleGetInfoString</key>
5252+ <string>The findlib library manager ${VERSION}</string>
5353+ <key>CFBundleIdentifier</key>
5454+ <string>http://www.ocaml-programming.de/packages/</string>
5555+ <key>CFBundleName</key>
5656+ <string>Findlib</string>
5757+ <key>CFBundleShortVersionString</key>
5858+ <string>${VERSION}</string>
5959+ <key>IFPkgFlagAllowBackRev</key>
6060+ <true/>
6161+ <key>IFPkgFlagAuthorizationAction</key>
6262+ <string>AdminAuthorization</string>
6363+ <key>IFPkgFlagDefaultLocation</key>
6464+ <string>/</string>
6565+ <key>IFPkgFlagInstallFat</key>
6666+ <false/>
6767+ <key>IFPkgFlagIsRequired</key>
6868+ <false/>
6969+ <key>IFPkgFlagRelocatable</key>
7070+ <false/>
7171+ <key>IFPkgFlagRestartAction</key>
7272+ <string>NoRestart</string>
7373+ <key>IFPkgFlagRootVolumeOnly</key>
7474+ <true/>
7575+ <key>IFPkgFlagUpdateInstalledLanguages</key>
7676+ <false/>
7777+ <key>IFPkgFormatVersion</key>
7878+ <real>0.10000000149011612</real>
7979+</dict>
8080+</plist>
8181+EOF
8282+8383+# stop here -> |
8484+cat >resources/ReadMe.txt <<EOF
8585+This package installs The findlib library manager ${VERSION}.
8686+You need Mac OS X 10.4.x (Tiger).
8787+8888+Files will be installed in the following directories:
8989+9090+/usr/local/bin - command-line executables
9191+/usr/local/lib/ocaml - library and support files
9292+/usr/local/man - manual pages
9393+EOF
9494+9595+chmod -R g-w root
9696+sudo chown -R root:admin root
9797+9898+/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \
9999+-build -p "`pwd`/findlib.pkg" -f "`pwd`/root" -i "`pwd`/Info.plist" \
100100+ -d "`pwd`/Description.plist" -r "`pwd`/resources"
101101+102102+size=`du -s findlib.pkg | cut -f 1`
103103+size=`expr $size + 8192`
104104+105105+hdiutil create -sectors $size findlib-rw.dmg
106106+name=`hdid -nomount findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
107107+newfs_hfs -v 'Findlib' $name
108108+hdiutil detach $name
109109+110110+name=`hdid findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
111111+if test -d '/Volumes/Findlib'; then
112112+ ditto -rsrcFork findlib.pkg "/Volumes/Findlib/findlib.pkg"
113113+ cp resources/ReadMe.txt "/Volumes/Findlib/"
114114+else
115115+ echo 'Unable to mount the disk image as "/Volumes/Findlib"' >&2
116116+ exit 3
117117+fi
118118+open "/Volumes/Findlib"
119119+hdiutil detach $name
120120+121121+rm -rf "findlib-${VERSION}.dmg"
122122+hdiutil convert findlib-rw.dmg -format UDZO -o "findlib-${VERSION}.dmg"
+28
vendor/opam/ocamlfind/tools/patch
···11+#! /bin/sh
22+33+# Usage: patch @VARIABLE@ value [extra-args-for-cygpath]
44+# Environment variable USE_CYGPATH is honoured.
55+66+varname="$1"
77+varvalue="$2"
88+99+if [ "${USE_CYGPATH}" = "1" ]; then
1010+ #varvalue="$(echo "$varvalue" | sed -e 's;/;\\;g')"
1111+ varvalue="$(cygpath -w -l $3 "$varvalue")"
1212+ varvalue="$(echo "$varvalue" | sed -e 's;\\;\\\\\\\\;g;s/;/\\;/g')"
1313+ # e.g. c:\file is transformed to c:\\\\file
1414+else
1515+ case `uname` in
1616+ MINGW*)
1717+ varvalue="$(echo "$varvalue" | sed -e 's;\\;\\\\\\\\;g')"
1818+ # Convert the first letter drive to DOS style (naive).
1919+ # This is necessary because OCaml uses DOS paths even if
2020+ # run under MSYS.
2121+ varvalue="$(echo "$varvalue" | sed -e 's;^/\([a-z]\)/;\1:/;g')"
2222+ ;;
2323+ esac
2424+fi
2525+2626+sed -e 's;'"$varname"';'"$varvalue"';g'
2727+# e.g. c:\\\\file is parsed by sed as c:\\file which is correct for the
2828+# ocaml string
+52
vendor/opam/ocamlfind/tools/safe_camlp4
···11+#! /bin/sh
22+33+# Call camlp4 with fallback method if dynamic loading is not supported
44+55+dl_string="dynamic loading not supported on this platform"
66+fn_string="The external function .* is not available"
77+88+tmp_stderr="tmp.safe_camlp4_stderr.$$"
99+tmp_camlp4="tmp.safe_camlp4_camlp4.$$"
1010+1111+trap "rm -f $tmp_stderr $tmp_camlp4" 0
1212+1313+print_stderr=1
1414+code=0
1515+1616+camlp4 "$@" 2>$tmp_stderr || {
1717+ code=$?
1818+ grep "$dl_string" $tmp_stderr >/dev/null 2>&1; t1=$?
1919+ grep "$fn_string" $tmp_stderr >/dev/null 2>&1; t2=$?
2020+ if [ $t1 -eq 0 -o $t2 -eq 0 ]; then
2121+ # Fallback:
2222+ print_stderr=0
2323+ cp4_mods=""
2424+ cp4_args=""
2525+ i=0
2626+ for arg in "$@"; do
2727+ if [ $i -gt 0 ]; then
2828+ cp4_mods="$cp4_mods -I $arg"
2929+ cp4_args="$cp4_args -I $arg"
3030+ i=0
3131+ else
3232+ case "$arg" in
3333+ *.cma|*.cmo)
3434+ cp4_mods="$cp4_mods $arg" ;;
3535+ -I)
3636+ i=1 ;;
3737+ *)
3838+ cp4_args="$cp4_args $arg" ;;
3939+ esac
4040+ fi
4141+ done
4242+ mkcamlp4 -o $tmp_camlp4 $cp4_mods || exit
4343+ ./$tmp_camlp4 $cp4_args || exit
4444+ code=0
4545+ fi
4646+}
4747+4848+if [ $print_stderr -gt 0 ]; then
4949+ cat $tmp_stderr >&2
5050+fi
5151+5252+exit $code