My working unpac space for OCaml projects in development
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge opam/patches/ocamlfind

+21203
+26
vendor/opam/ocamlfind/.gitignore
··· 1 + *~ 2 + *.cmi 3 + *.cmo 4 + *.cma 5 + *.cmx 6 + *.o 7 + *.cmxa 8 + *.cmxs 9 + *.a 10 + *.so 11 + META 12 + 13 + Makefile.config 14 + Makefile.packages 15 + findlib.conf 16 + ocargs.log 17 + src/findlib/depend 18 + src/findlib/findlib_config.ml 19 + src/findlib/fl_meta.ml 20 + src/findlib/ocaml_args.ml 21 + src/findlib/ocamlfind 22 + src/findlib/topfind 23 + src/findlib/topfind.ml 24 + src/findlib/topfind.compat.in 25 + tools/extract_args/extract_args 26 + tools/extract_args/extract_args.ml
+187
vendor/opam/ocamlfind/INSTALL
··· 1 + The installation procedure consists of the steps: 2 + 3 + 1) configure the "findlib" library 4 + 2) compile "findlib" and the "ocamlfind" frontend of "findlib" 5 + 3) install "findlib" and the core library configuration 6 + 7 + Optionally, you can run ./itest after step 2 to check the 8 + configuration. Problems with the configuration are unlikely, however. 9 + 10 + At the end of this file you find notes about MacOS and Windows. 11 + 12 + 13 + ---------------------------------------------------------------------- 14 + 15 + STEP 1: DEFAULT CONFIGURATION 16 + 17 + The findlib module and its ocamlfind frontend come with a "configure" 18 + script that should almost always be able to figure out a good 19 + configuration. 20 + 21 + Just type: 22 + 23 + ./configure 24 + 25 + First the linker options for the various core libraries are figured 26 + out, then reasonable installation paths are checked. 27 + 28 + If the results are not ok, you can modify them using the following 29 + options: 30 + 31 + -bindir <path> 32 + 33 + set the location where the ocamlfind command should be 34 + installed. 35 + Default: same location as "ocamlc" 36 + 37 + -mandir <path> 38 + 39 + set the location where the man page should be installed. 40 + Default: a heuristics, and "/usr/local/man" as fallback. 41 + 42 + -sitelib <path> 43 + 44 + set the default "site-lib" directory. 45 + Default: For installations in the /usr hierarchy, 46 + "$stdlib/site-lib", where $stdlib is the location of 47 + Ocaml's standard library. 48 + 49 + For installations in the /opt hierarchy, 50 + "$stdlib/../site-lib", i.e. parallel to $stdlib. 51 + 52 + -config <file> 53 + 54 + set the location of the configuration file. 55 + Default: <bindir>/../etc/findlib.conf 56 + 57 + -no-topfind 58 + 59 + the "topfind" script is not installed in the standard 60 + library directory. (This is not a good idea in general, 61 + because #use "topfind" will not work when this option 62 + is enabled.) 63 + 64 + -with-toolbox 65 + also compile and install the "toolbox". This requires 66 + that labltk is available. The toolbox contains the 67 + "make_wizard" to easily create findlib-enabled Makefiles. 68 + 69 + -cygpath 70 + Cygwin environment only: If "ocamlc -where" does not 71 + output a Unix-style path, this option can be used 72 + to apply the "cygpath" command to it. Use this option 73 + if you see backslashes or drive letters in Makefile.config. 74 + 75 + ALTERNATIVES: 76 + 77 + If the "configure" script does not work properly (very unlikely), do 78 + 79 + cp Makefile.config.pattern Makefile.config 80 + 81 + and edit Makefile.config by hand. 82 + 83 + If the generated META files do not work, edit them (this is very very unlikely). 84 + 85 + Note: The META files are generated from the META.in files in the same 86 + directories by sed: 87 + 88 + sed -e 's/%%findlib_version%%/<version>/g' <more parameters...> site-lib/<name>/META.in 89 + >site-lib/<name>/META 90 + 91 + You may invoke sed manually to create different META files, but this 92 + is currently not documented. 93 + 94 + 95 + 96 + ---------------------------------------------------------------------- 97 + 98 + STEP 2: COMPILATION 99 + 100 + After configuration has been done, compile with 101 + 102 + make all 103 + 104 + This creates findlib.cma, findlib_mt.cma (the thread-safe version), 105 + and ocamlfind. 106 + 107 + If you have ocamlopt, do also 108 + 109 + make opt 110 + 111 + This creates findlib.cmxa, findlib_mt.cmxa, and ocamlfind_opt. 112 + 113 + ---------------------------------------------------------------------- 114 + 115 + STEP 3: INSTALLATION 116 + 117 + Install the findlib library, the ocamlfind frontend, and the core library 118 + configurations with: 119 + 120 + make install 121 + 122 + (A "make uninstall" removes them.) 123 + 124 + With 125 + make clean 126 + 127 + the build directory is cleaned up. 128 + 129 + 130 + OPTIONAL (BUT RECOMMENDED): 131 + 132 + If you want a separate directory for DLLs, create this directory 133 + now: 134 + 135 + mkdir `ocamlfind printconf destdir`/stublibs 136 + 137 + If you do this, you must also tell OCaml that DLLs can be found in 138 + this directory: Add the absolute path of this directory to 139 + the ld.conf file (type "ocamlfind printconf ldconf" to get the 140 + location of the ld.conf file). Every line of this text file lists 141 + one possible directory for DLLs. 142 + 143 + ---------------------------------------------------------------------- 144 + 145 + MACOS X: 146 + 147 + Findlib can be installed as described. There is even a script to 148 + create a MacOS X package, use "make package-macosx" to invoke it. As I 149 + do not have access to a Mac box, I cannot test this script, but I 150 + fully trust the author that it works. 151 + 152 + ---------------------------------------------------------------------- 153 + 154 + WINDOWS: 155 + 156 + Ocaml for Windows exists in three flavours: 157 + 158 + (1) Ocaml as Cygwin program 159 + (2) Ocaml as Mingw program (i.e. the gcc toolchain is used but 160 + Ocaml is a native Windows program) 161 + (3) Ocaml as VC program 162 + 163 + In all three cases you need Cygwin to build and install findlib, 164 + because "configure" and the Makefile are both Cygwin scripts. The 165 + golden rule to make everything work is this: 166 + 167 + PASS CYGWIN-STYLE PATHS TO CONFIGURE! 168 + 169 + Even in cases (2) and (3)! That means use something like 170 + /cygdrive/c/path and not c:\path when you specify where -bindir, 171 + -config etc. are. The point is that "configure" itself is a Cygwin 172 + script, and therefore expects Cygwin input. At the right moment, the 173 + paths are back-translated to their Windows counterparts. 174 + 175 + Until OCaml 3.08 you must specify whether you have (2) or (3) by 176 + the configure switches 177 + 178 + - "-system mingw" for (2) 179 + - "-system win32" for (3) 180 + - nothing for (1) 181 + 182 + Since OCaml 3.09 this is no longer necessary because "ocamlc -config" 183 + outputs the required information. 184 + 185 + In previous versions of Findlib there was a single switch -cygpath 186 + for both (2) and (3). It is now interpreted as -system mingw (as 187 + it was meant as that).
+22
vendor/opam/ocamlfind/LICENSE
··· 1 + Copyright 1999 by Gerd Stolpmann 2 + 3 + The package "findlib" is copyright by Gerd Stolpmann. 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining 6 + a copy of this document and the "findlib" software (the 7 + "Software"), to deal in the Software without restriction, including 8 + without limitation the rights to use, copy, modify, merge, publish, 9 + distribute, sublicense, and/or sell copies of the Software, and to 10 + permit persons to whom the Software is furnished to do so, subject to 11 + the following conditions: 12 + 13 + The above copyright notice and this permission notice shall be included 14 + in all copies or substantial portions of the Software. 15 + 16 + The Software is provided ``as is'', without warranty of any kind, express 17 + or implied, including but not limited to the warranties of 18 + merchantability, fitness for a particular purpose and noninfringement. 19 + In no event shall Gerd Stolpmann be liable for any claim, damages or 20 + other liability, whether in an action of contract, tort or otherwise, 21 + arising from, out of or in connection with the Software or the use or 22 + other dealings in the software.
+169
vendor/opam/ocamlfind/Makefile
··· 1 + # make all: compile to bytecode 2 + # make opt: compile to native code 3 + # make install: install bytecode and/or native code 4 + #---------------------------------------------------------------------- 5 + 6 + include Makefile.config 7 + -include Makefile.packages 8 + 9 + TOP=. 10 + 11 + .PHONY: all opt install uninstall clean 12 + 13 + all: 14 + for p in $(PARTS); do ( cd src/$$p; $(MAKE) all ) || exit; done 15 + $(MAKE) all-config 16 + 17 + opt: 18 + for p in $(PARTS); do ( cd src/$$p; $(MAKE) opt ) || exit; done 19 + 20 + install: check-installation 21 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)" 22 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)" 23 + $(MAKE) install-config 24 + for p in $(PARTS); do ( cd src/$$p; $(MAKE) install ); done 25 + $(MAKE) install-meta 26 + test ! -f 'site-lib-src/num-top/META' || { cd src/findlib; $(MAKE) install-num-top; } 27 + test ! -f 'site-lib-src/camlp4/META' || $(INSTALLFILE) tools/safe_camlp4 "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)" 28 + $(MAKE) install-doc 29 + 30 + uninstall: check-installation 31 + $(MAKE) uninstall-doc 32 + $(MAKE) uninstall-meta 33 + for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) uninstall ); done 34 + $(MAKE) uninstall-config 35 + 36 + clean: 37 + for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) clean ); done 38 + (cd itest-aux; $(MAKE) clean) 39 + (cd tools/extract_args; $(MAKE) clean) 40 + rm -f findlib.conf Makefile.packages 41 + 42 + .PHONY: release 43 + release: README 44 + ./release 45 + 46 + README: doc/README 47 + ln -s doc/README . 48 + 49 + 50 + .PHONY: all-config 51 + all-config: findlib.conf 52 + 53 + .PHONY: findlib-template 54 + findlib-template: findlib.conf.in 55 + USE_CYGPATH="$(USE_CYGPATH)"; \ 56 + export USE_CYGPATH; \ 57 + cat findlib.conf.in | \ 58 + $(SH) tools/patch '@SITELIB@' '$(FINDLIB_OCAML_SITELIB)' | \ 59 + $(SH) tools/patch '@FINDLIB_PATH@' '$(FINDLIB_PATH)' -p >findlib.conf 60 + if ./tools/cmd_from_same_dir ocamlc; then \ 61 + echo 'ocamlc="ocamlc.opt"' >>findlib.conf; \ 62 + fi 63 + if ./tools/cmd_from_same_dir ocamlopt; then \ 64 + echo 'ocamlopt="ocamlopt.opt"' >>findlib.conf; \ 65 + fi 66 + if ./tools/cmd_from_same_dir ocamldep; then \ 67 + echo 'ocamldep="ocamldep.opt"' >>findlib.conf; \ 68 + fi 69 + if ./tools/cmd_from_same_dir ocamldoc; then \ 70 + echo 'ocamldoc="ocamldoc.opt"' >>findlib.conf; \ 71 + fi 72 + 73 + .PHONY: findlib-relative 74 + findlib-relative: FINDLIB_OCAML_SITELIB=$(RELATIVE_OCAML_SITELIB) 75 + findlib-relative: findlib-template 76 + 77 + .PHONY: findlib-absolute 78 + findlib-absolute: FINDLIB_OCAML_SITELIB=$(OCAML_SITELIB) 79 + findlib-absolute: findlib-template 80 + 81 + findlib.conf: findlib.conf.in 82 + if [ "$(RELATIVE_PATHS)" = "true" ]; then \ 83 + $(MAKE) findlib-relative; \ 84 + else \ 85 + $(MAKE) findlib-absolute; \ 86 + fi 87 + 88 + .PHONY: install-doc 89 + install-doc: 90 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5" 91 + -$(CP) doc/ref-man/ocamlfind.1 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1" 92 + -$(CP) doc/ref-man/META.5 doc/ref-man/site-lib.5 doc/ref-man/findlib.conf.5 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5" 93 + 94 + .PHONY: uninstall-doc 95 + uninstall-doc: 96 + rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1/ocamlfind.1" 97 + rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Findlib.3" 98 + rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Topfind.3" 99 + rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/META.5" 100 + rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/site-lib.5" 101 + 102 + 103 + .PHONY: check-installation 104 + check-installation: 105 + if [ "$(CHECK_BEFORE_INSTALL)" -eq 1 ]; then \ 106 + for x in camlp4 dbm graphics labltk num ocamlbuild; do \ 107 + if [ -f "$(prefix)$(OCAML_SITELIB)/$$x/META" ]; then \ 108 + if ! grep -Fq '[distributed with Ocaml]' "$(prefix)/$(OCAML_SITELIB)/$$x/META"; then \ 109 + rm -f site-lib-src/$$x/META; \ 110 + fi; \ 111 + fi; \ 112 + done; \ 113 + test -f "site-lib-src/num/META" || rm -f "site-lib-src/num-top/META"; \ 114 + fi 115 + echo 'SITELIB_META =' > Makefile.packages.in 116 + for x in `ls site-lib-src`; do test ! -f "site-lib-src/$$x/META" || echo $$x >> Makefile.packages.in; done 117 + tr '\n' ' ' < Makefile.packages.in > Makefile.packages 118 + rm Makefile.packages.in 119 + 120 + .PHONY: install-meta 121 + install-meta: 122 + 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 123 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib"; $(CP) Makefile.packages "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib/Makefile.packages" 124 + 125 + .PHONY: uninstall-meta 126 + uninstall-meta: 127 + for x in $(SITELIB_META); do rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x"; done 128 + 129 + .PHONY: install-config 130 + install-config: 131 + $(INSTALLDIR) "`dirname \"$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)\"`" 132 + @if [ -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" ]; then echo "!!! Keeping old $(DESTDIR)$(prefix)$(OCAMLFIND_CONF) !!!"; fi 133 + test -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" || $(CP) findlib.conf "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" 134 + 135 + .PHONY: uninstall-config 136 + uninstall-config: 137 + @echo Leaving "$(OCAMLFIND_CONF)" installed, consider manual removal 138 + 139 + .PHONY: interface-lists 140 + interface-lists: 141 + d=`ocamlc -where`; \ 142 + for x in `ls site-lib-src`; do \ 143 + iflist=""; \ 144 + if [ ! -f "site-lib-src/$$x/interfaces.in" ]; then continue; fi; \ 145 + cma_spec=`cat site-lib-src/$$x/interfaces.in`; \ 146 + for cma in $$d/$$cma_spec; do \ 147 + intf=`ocamlobjinfo $$cma | \ 148 + grep 'Unit name:' | \ 149 + sed -e 's/^ Unit name: //' | \ 150 + sort | \ 151 + tr '\n' ' '`; \ 152 + iflist="$$iflist $$intf"; \ 153 + done; \ 154 + echo "$$iflist" >"site-lib-src/$$x/interfaces.out"; \ 155 + done 156 + 157 + ###################################################################### 158 + # The following is from Pietro Abata <pietro.abate@anu.edu.au> 159 + # to create MacOS X packages. I did not test it, just include it. 160 + 161 + .PHONY: package-macosx 162 + 163 + package-macosx: all opt 164 + $(INSTALLDIR) package-macosx/root 165 + export prefix=`pwd`/package-macosx/root && make install 166 + export VERSION=1.1.2 && sh tools/make-package-macosx 167 + 168 + clean-macosx: 169 + sudo rm -rf package-macosx
+79
vendor/opam/ocamlfind/Makefile.config.pattern
··· 1 + # You can manually set up your configuration using this 2 + # pattern. The final name of the file must be "Makefile.config". 3 + # Note that there are other files containing parts of the 4 + # configuration, especially the site-lib/*/META files. 5 + # 6 + #---------------------------------------------------------------------- 7 + # Where the OCAML core is installed: 8 + #---------------------------------------------------------------------- 9 + OCAML_CORE_STDLIB=/usr/local/lib/ocaml 10 + OCAML_CORE_BIN=/usr/local/bin 11 + OCAML_CORE_MAN=/usr/local/man 12 + 13 + #---------------------------------------------------------------------- 14 + # Type of multi-threading support: either vm or posix 15 + # (Note: Since OCaml 3.07, "posix" includes "vm", because a build 16 + # supporting posix also supports vm.) 17 + #---------------------------------------------------------------------- 18 + OCAML_THREADS=vm 19 + #OCAML_THREADS=posix 20 + 21 + #---------------------------------------------------------------------- 22 + # Where the site-lib directory will be 23 + #---------------------------------------------------------------------- 24 + OCAML_SITELIB=/usr/local/lib/ocaml/site-lib 25 + 26 + #---------------------------------------------------------------------- 27 + # What the path setting will be 28 + #---------------------------------------------------------------------- 29 + FINDLIB_PATH=/usr/local/lib/ocaml/site-lib:/usr/local/lib/ocaml 30 + 31 + #---------------------------------------------------------------------- 32 + # Where binaries and manual pages will be installed 33 + #---------------------------------------------------------------------- 34 + OCAMLFIND_BIN=/usr/local/bin 35 + OCAMLFIND_MAN=/usr/local/man 36 + 37 + #---------------------------------------------------------------------- 38 + # The absolute location of the configuration file 39 + #---------------------------------------------------------------------- 40 + OCAMLFIND_CONF=/usr/local/etc/ocamlfind.conf 41 + 42 + #---------------------------------------------------------------------- 43 + # Autolinking is usually on 44 + #---------------------------------------------------------------------- 45 + OCAML_AUTOLINK=true 46 + 47 + #---------------------------------------------------------------------- 48 + # Windows only: set this to .exe 49 + #---------------------------------------------------------------------- 50 + EXEC_SUFFIX= 51 + 52 + #---------------------------------------------------------------------- 53 + # Windows MSVC port: set this to .lib 54 + #---------------------------------------------------------------------- 55 + LIB_SUFFIX=.a 56 + 57 + #---------------------------------------------------------------------- 58 + # Which parts are to be built: findlib, findlib-toolbox (space-separated 59 + # list) 60 + #---------------------------------------------------------------------- 61 + PARTS=findlib findlib-toolbox 62 + 63 + #---------------------------------------------------------------------- 64 + # Whether the "topfind" script is installed in $(OCAML_CORE_STDLIB): 65 + #---------------------------------------------------------------------- 66 + INSTALL_TOPFIND=1 67 + 68 + #---------------------------------------------------------------------- 69 + # Whether the config and paths are looked up relative to the 70 + # installation 71 + #---------------------------------------------------------------------- 72 + RELATIVE_PATHS=0 73 + RELATIVE_OCAML_SITELIB=$$PREFIX/lib 74 + 75 + #---------------------------------------------------------------------- 76 + # Whether make install should update Makefile.packages just before 77 + # running 78 + #---------------------------------------------------------------------- 79 + CHECK_BEFORE_INSTALL=0
+11
vendor/opam/ocamlfind/README.md
··· 1 + # Findlib 2 + 3 + - [Project page](http://projects.camlcity.org/projects/findlib.html) 4 + with links to download tarballs and documentation 5 + 6 + - [README.xml with changelog](doc/README.xml) 7 + 8 + - [Installation](INSTALL) 9 + 10 + - [License](LICENSE) 11 +
+14
vendor/opam/ocamlfind/REVISIONS
··· 1 + The following table shows which Subversion revision of the 2 + repository corresponds with which released version of 3 + findlib. 4 + 5 + Released versions up to 0.9 are checked in into CVS, and 6 + not Subversion. 7 + 8 + Released version = Subversion revision 9 + ---------------------------------------------------------------------- 10 + 1.0 54 11 + 1.0.1 57 12 + 1.0.2 63 13 + 1.0.3 69 14 + 1.0.4 72
+6
vendor/opam/ocamlfind/TODO
··· 1 + Document archive(plugin) 2 + 3 + Suggestion (gasche): -show-command only outputs the constructed 4 + command, but does not run it. 5 + 6 + Get ready for -ppx
+849
vendor/opam/ocamlfind/configure
··· 1 + #! /bin/sh 2 + # $Id$ 3 + # ---------------------------------------------------------------------- 4 + # 5 + 6 + # Some functions 7 + 8 + #set -x 9 + 10 + version="$(sed -ne 's/^version: *"\(.*\)\.git".*/\1/p' opam)" 11 + 12 + if test -z "$version"; then 13 + echo "Internal error: failed to parse version number from opam file" 1>&2 14 + exit 1 15 + fi 16 + 17 + # Remember the old IFS value: 18 + oldifs="$IFS" 19 + 20 + 21 + in_path () { 22 + # Does $1 exist in $PATH? 23 + IFS=":" 24 + for d in $PATH; do 25 + if test -x "$d/$1"; then 26 + IFS="$oldifs" 27 + return 0 28 + fi 29 + done 30 + IFS="$oldifs" 31 + return 1 32 + #--- The following is not portable enough: 33 + # if test -x `type -p ls`; then 34 + # # type -p works! 35 + # type -p $1 >/dev/null 36 + # else 37 + # # use 'which' instead 38 + # p=`which $1` 39 + # test -x "$p" 40 + # fi 41 + } 42 + 43 + 44 + get_path () { 45 + IFS=":" 46 + for d in $PATH; do 47 + if test -x "$d/$1"; then 48 + IFS="$oldifs" 49 + echo "$d/$1" 50 + return 51 + fi 52 + done 53 + IFS="$oldifs" 54 + #--- The following is not portable enough: 55 + # if test -x `type -p ls`; then 56 + # # type -p works! 57 + # type -p $1 58 + # else 59 + # # use 'which' instead 60 + # p=`which $1` 61 + # test -x "$p" && echo $p 62 + # fi 63 + } 64 + 65 + 66 + get_stdlib () { 67 + # Older versions of ocamlc do not accept -where, so there is a fallback 68 + # method: 69 + ocamlc -where 2>/dev/null | tr -d '\r' || { 70 + ocamlc -v | sed -n -e "/Standard library directory/s/.*: \(.*\)/\1/p"; } 71 + } 72 + 73 + 74 + get_lib () { 75 + # $1: name of a library to search for 76 + # $2...: places to test 77 + libname="$1" 78 + while [ "$#" != "0" ]; do 79 + if [ -f "$1/lib${libname}.so" ] || [ -f "$1/lib${libname}.a" ]; then 80 + echo "$1" 81 + return 0 82 + fi 83 + shift 84 + done 85 + return 1 86 + } 87 + 88 + 89 + get_lib_file () { 90 + # $1: name of library without "lib" and suffix 91 + # $2: directory 92 + # returns full path of library 93 + if [ -f "$2/lib$1.so" ]; then 94 + echo "$2/lib$1.so" 95 + elif [ -f "$2/lib$1.a" ]; then 96 + echo "$2/lib$1.a" 97 + else 98 + echo "" 99 + fi 100 + } 101 + 102 + 103 + cygpath_to_unix () { 104 + v=$1 105 + eval "p=\"\$$v\"" 106 + p="$(cygpath -w -s "$p")" 107 + p="$(cygpath -u "$p")" 108 + eval "$v=\"$p\"" 109 + } 110 + 111 + 112 + ###################################################################### 113 + # Here the main program begins: 114 + 115 + ###################################################################### 116 + # Interpret the command line 117 + 118 + ocamlfind_bin="" 119 + ocamlfind_man="" 120 + ocaml_sitelib="" 121 + ocamlfind_config="" 122 + with_toolbox=0 123 + with_topfind=1 124 + with_camlp4=1 125 + with_relative_paths=0 126 + custom=-custom 127 + system="" 128 + sh="" 129 + 130 + while [ "$#" != "0" ]; do 131 + case "$1" in 132 + -bindir) ocamlfind_bin=$2 133 + shift 2 134 + ;; 135 + -mandir) ocamlfind_man=$2 136 + shift 2 137 + ;; 138 + -sitelib) ocaml_sitelib=$2 139 + shift 2 140 + ;; 141 + -config) ocamlfind_config=$2 142 + with_relative_paths=0 143 + shift 2 144 + ;; 145 + -no-custom) custom= 146 + shift 147 + ;; 148 + -cygpath) system=mingw 149 + shift 150 + ;; 151 + -system) system=$2 152 + shift 2 153 + ;; 154 + -with-toolbox) with_toolbox=1 155 + shift 156 + ;; 157 + -with-relative-paths-at) with_relative_paths=1 158 + ocaml_prefix=$2 159 + shift 2 160 + ;; 161 + -no-topfind) with_topfind=0 162 + shift 163 + ;; 164 + -no-camlp4) with_camlp4=0 165 + shift 166 + ;; 167 + -version) 168 + echo "$version" 169 + exit 0 170 + ;; 171 + -h|-help|--help) echo "usage: configure [options]" 1>&2 172 + echo " -bindir path where binaries are installed" 1>&2 173 + echo " -mandir path where manual pages are installed" 1>&2 174 + echo " -sitelib path set the location of the site-specific packages" 1>&2 175 + echo " -config path set the location of the configuration file" 1>&2 176 + echo " -no-custom don't link in custom runtime mode" 1>&2 177 + echo " -system <systype> override system type (esp. mingw and win32)" 1>&2 178 + echo " -with-toolbox also build the toolbox" 1>&2 179 + echo " -with-relative-paths-at path load configuration relative to the installation path" 1>&2 180 + echo " -no-topfind don't install topfind script into stdlib directory" 1>&2 181 + echo " -no-camlp4 don't install the camlp4 META file" 1>&2 182 + exit 183 + ;; 184 + *) echo "configure: run 'configure -h' to get help" 1>&2 185 + exit 1 186 + ;; 187 + esac 188 + done 189 + 190 + echo "Welcome to findlib version $version" 191 + echo "Configuring core..." 192 + 193 + 194 + ####################################################################### 195 + # inspect the system 196 + 197 + # Some standard Unix tools must be available: 198 + 199 + for tool in sed ocaml ocamlc uname rm make cat dirname basename; do 200 + if in_path $tool; then true; else 201 + echo "configure: $tool not in PATH; this is required" 1>&2 202 + exit 1 203 + fi 204 + done 205 + 206 + lib_suffix=$(ocamlc -config 2>/dev/null | tr -d '\r' | sed -n -e 's/^ext_lib: //p') 207 + 208 + # Check for Cygwin: 209 + 210 + exec_suffix= 211 + pure_mingw="no" 212 + mingw_lib= 213 + case $(uname) in 214 + CYGWIN*) 215 + exec_suffix=.exe 216 + echo "Cygwin build environment found; using .exe as suffix for binaries" 217 + ;; 218 + MSYS_NT*) 219 + exec_suffix=.exe 220 + echo "MSYS_NT build environment found; using .exe as suffix for binaries" 221 + ;; 222 + MINGW*) 223 + exec_suffix=.exe 224 + pure_mingw="yes" 225 + echo "MinGW build environment found; using .exe as suffix for binaries" 226 + mingw_lib=$(get_path gcc) 227 + mingw_lib=$(dirname "$mingw_lib")/../lib 228 + ;; 229 + *) 230 + true ;; 231 + esac 232 + 233 + ###################################################################### 234 + # Is the target Win32? 235 + 236 + use_cygpath=0 237 + # Whether we have to translate Unix paths to/from Windows paths. 238 + 239 + if [ -z "$system" ]; then 240 + system=$(ocamlc -config 2>/dev/null | tr -d '\r' | sed -n -e 's/^system: //p') 241 + # This may be 242 + # - mingw or mingw64 243 + # - win32 244 + # - win64 245 + # - cygwin 246 + # - some other string means Unix 247 + # - empty means ocamlc does not support -config 248 + fi 249 + 250 + path_sep=':' 251 + case "$system" in 252 + mingw|mingw64) 253 + if [ "$pure_mingw" = "no" ]; then 254 + # CYGWIN 255 + use_cygpath=1 256 + fi 257 + ;; 258 + win32) use_cygpath=1;; 259 + win64) use_cygpath=1;; 260 + # A quirk of history means OCAMLPATH uses ; on Cygwin 261 + cygwin) path_sep=';';; 262 + esac 263 + 264 + ###################################################################### 265 + # check for presence of /bin/sh 266 + 267 + if [ ! -f /bin/sh ]; then 268 + sh="sh" 269 + fi 270 + 271 + ###################################################################### 272 + # Find out standard library location 273 + 274 + ocaml_core_stdlib=$(get_stdlib) 275 + ocaml_major="$(ocamlc -vnum 2>/dev/null | cut -f1 -d.)" 276 + if [ ! -d "$ocaml_core_stdlib" ]; then 277 + echo "configure: cannot determine ocaml's standard library directory" 1>&2 278 + exit 1 279 + fi 280 + if [ -z "$ocaml_major" ]; then ocaml_major=3; fi 281 + 282 + if [ ${use_cygpath} -gt 0 ]; then 283 + cygpath_to_unix ocaml_core_stdlib 284 + # This makes ocaml_core_stdlib a Unix-type path 285 + fi 286 + 287 + # Set site-lib directory: 288 + 289 + if [ -z "$ocaml_sitelib" ]; then 290 + case "$ocaml_core_stdlib" in 291 + /opt/*) ocaml_sitelib=$(dirname "${ocaml_core_stdlib}")/site-lib 292 + ;; 293 + *) ocaml_sitelib="${ocaml_core_stdlib}/site-lib" 294 + ;; 295 + esac 296 + fi 297 + 298 + ocamlpath="${ocaml_sitelib}" 299 + if [ ${use_cygpath} -gt 0 ]; then 300 + cygpath_to_unix ocamlpath 301 + fi 302 + if [ "$ocaml_major" -ge 5 ]; then 303 + # OCaml 5.0+ installs its own META files under the stdlib directory. 304 + # If findlib has been configured -sitelib $(ocamlc -where) then there's 305 + # nothing to do, but otherwise we need to put OCaml's Standard Library 306 + # into the path setting. 307 + if [ ! -e "${ocaml_sitelib}/stdlib.cmi" ]; then 308 + ocamlpath="${ocaml_core_stdlib}${path_sep}${ocamlpath}" 309 + fi 310 + fi 311 + 312 + # Find out the directory where ocamlc is: 313 + 314 + ocamlc=$(get_path ocamlc) 315 + ocaml_core_bin=$(dirname "${ocamlc}") 316 + 317 + # Set the directory of ocamlfind: 318 + 319 + test -n "$ocamlfind_bin" || ocamlfind_bin="$ocaml_core_bin" 320 + 321 + # Find the directory for the manual: 322 + 323 + # Fallback: 324 + ocaml_core_man=/usr/local/man 325 + 326 + d="$ocaml_core_bin" 327 + while [ "$d" != '/' ]; do 328 + f=0 329 + if [ -d "$d/man/man1" ]; then 330 + if [ -f "$d/man/man1/ocamlc.1" ] || 331 + [ -f "$d/man/man1/ocamlc.1.gz" ] || 332 + [ -f "$d/man/man1/ocamlc.1.Z" ]; then 333 + f=1 334 + fi 335 + else 336 + if [ -d "$d/man/mann" ]; then 337 + if [ -f "$d/man/mann/ocamlc.n" ] || 338 + [ -f "$d/man/mann/ocamlc.n.gz" ] || 339 + [ -f "$d/man/mann/ocamlc.n.Z" ]; then 340 + f=1 341 + fi 342 + fi 343 + fi 344 + if [ "$f" = "1" ]; then 345 + ocaml_core_man="$d/man" 346 + d="/" 347 + else 348 + d=$(dirname "$d") 349 + fi 350 + done 351 + 352 + # Set the directory for ocamlfind's manuals: 353 + 354 + test -n "$ocamlfind_man" || ocamlfind_man="$ocaml_core_man" 355 + 356 + # Guess the right directory for the configuration file: 357 + 358 + if [ -z "${ocamlfind_config}" ]; then 359 + d="$ocaml_core_bin" 360 + case "$d" in 361 + */bin) 362 + if [ -f "$(dirname "$d")/lib/findlib.conf" ]; then 363 + ocamlfind_config="$(dirname "$d")/lib/findlib.conf" 364 + else 365 + ocamlfind_config="$(dirname "$d")/etc/findlib.conf" 366 + fi 367 + ;; 368 + *) 369 + ocamlfind_config=/usr/local/etc/findlib.conf 370 + # Fallback value 371 + ;; 372 + esac 373 + fi 374 + 375 + ###################################################################### 376 + # do we have #remove_directory? 377 + 378 + echo "Checking for #remove_directory..." 379 + have_remdir=1 380 + ocaml itest-aux/remdir.ml >/dev/null 2>/dev/null || have_remdir=0 381 + 382 + ###################################################################### 383 + # Test the threading model 384 + 385 + echo "Testing threading model..." 386 + 387 + if ocamlc -vmthread >/dev/null 2>/dev/null; then 388 + ocaml_threads="vm" 389 + else 390 + ocaml_threads="none" 391 + fi 392 + 393 + if ocamlc -config >/dev/null 2>/dev/null; then 394 + # Good. ocamlc tells us the threading model. 395 + if ocamlc -config | grep 'systhread_supported: true'; then 396 + ocaml_threads="posix" 397 + fi 398 + else 399 + # Old ocamlc do not have -config. 400 + rm -f itest-aux/simple 401 + ocamlc -w a -custom -thread -o itest-aux/simple -I +unix unix.cma threads.cma itest-aux/simple_threads.ml \ 402 + >itest-aux/err.out 2>&1 403 + output=$(cat itest-aux/err.out) 404 + 405 + if [ -z "$output" ]; then 406 + ocaml_threads="posix" 407 + fi 408 + fi 409 + 410 + ###################################################################### 411 + # Does this version of OCaml support autolinking? 412 + 413 + # Works for OCaml >= 3.00 on. Because findlib can only be compiled 414 + # with these OCaml versions, we can safely assume that autolinking 415 + # is enabled. 416 + 417 + ocaml_autolink="true" 418 + 419 + ###################################################################### 420 + # Does this version of OCaml support DLLs? 421 + 422 + echo "Testing DLLs..." 423 + 424 + have_dlls="yes" 425 + 426 + ocaml -I +unix unix.cma itest-aux/simple.ml >/dev/null || have_dlls="no" 427 + 428 + ###################################################################### 429 + # Does this version of OCaml support extension points? 430 + 431 + echo "Testing whether ppxopt can be supported..." 432 + 433 + with_ppxopt=1 434 + enable_topfind_ppxopt=true 435 + 436 + ocaml -I +compiler-libs itest-aux/ppx.ml >/dev/null || { 437 + with_ppxopt=0 438 + enable_topfind_ppxopt=false 439 + } 440 + 441 + ###################################################################### 442 + # Check for -opaque 443 + 444 + echo "Checking for ocamlc -opaque..." 445 + 446 + opaque="-opaque" 447 + ocamlc -opaque -version >/dev/null 2>/dev/null || opaque="" 448 + 449 + ###################################################################### 450 + # Check for ocamlopt -g 451 + 452 + echo "Checking for ocamlopt -g..." 453 + 454 + native_debugging_info="-g" 455 + ocamlopt -g -version >/dev/null 2>/dev/null || native_debugging_info="" 456 + 457 + ###################################################################### 458 + # Configure libraries 459 + 460 + check_before_install=0 461 + findlib_installed_meta='' 462 + if [ -d "${ocaml_sitelib}" ] && [ "${ocaml_major}" -lt 5 ]; then 463 + previous_config="${ocaml_sitelib}/findlib/Makefile.packages" 464 + if [ -f "${previous_config}" ]; then 465 + echo "Querying installation: found list of findlib-generated META files" 466 + eval "$(sed -ne 's/ /,/g' -e 's/^SITELIB_META,*=,*\([^,].*[^,]\),*/findlib_installed_meta="\1"/p' "$previous_config")" 467 + echo "Installation has: $findlib_installed_meta" 468 + else 469 + previous_config='' 470 + check_before_install=1 471 + echo "Querying installation: META list not found" 472 + echo "make install will double-check installed META files" 473 + fi 474 + else 475 + previous_config='' 476 + fi 477 + 478 + echo "Configuring libraries..." 479 + 480 + # Only succeeds if ${ocaml_sitelib}/$1/META exists and we're **certain** 481 + # it wasn't installed by a previous findlib installation. 482 + is_third_party_META () { 483 + if [ $check_before_install -eq 0 ]; then 484 + if [ -f "${ocaml_sitelib}/$1/META" ]; then 485 + case ",$findlib_installed_meta," in 486 + *,$1,*) 487 + return 1;; 488 + *) 489 + return 0;; 490 + esac 491 + else 492 + return 1 493 + fi 494 + else 495 + return 1 496 + fi 497 + } 498 + 499 + check_library () { 500 + if is_third_party_META "$1"; then 501 + echo "$1: package already present" 502 + # Library is present - exit code is 0 because the library is found 503 + # (e.g. detection for Unix) but we don't actually add it to the 504 + # generated_META list. 505 + package_dir="${ocaml_sitelib}/$1" 506 + package_subdir="$1" 507 + package_key="$(echo "$1" | tr - _)" 508 + eval "${package_key}_dir=\"${package_dir}\"" 509 + eval "${package_key}_subdir=\"${package_subdir}\"" 510 + return 0 511 + fi 512 + 513 + if [ -z "$3" ]; then 514 + check_library "$1" "$2" "$1.cmi" 515 + return $? 516 + fi 517 + 518 + package="$1" 519 + if [ -z "$2" ]; then 520 + msg='' 521 + else 522 + msg=" ($2)" 523 + fi 524 + 525 + shift 2 526 + for file; do 527 + if [ -e "${ocaml_core_stdlib}/${file}" ]; then 528 + package_dir="$(dirname "${file}")" 529 + if [ "${package_dir}" = '.' ]; then 530 + echo "${package}: found" 531 + package_subdir='.' 532 + package_dir='^' 533 + else 534 + package_subdir="${package_dir}" 535 + package_dir="+${package_dir}" 536 + echo "${package}: found (in ${package_dir})" 537 + fi 538 + package_key="$(echo "${package}" | tr - _)" 539 + eval "${package_key}_dir=\"${package_dir}\"" 540 + eval "${package_key}_subdir=\"${package_subdir}\"" 541 + if [ "${ocaml_major}" -ge 5 ]; then 542 + return 0 543 + fi 544 + if [ "$package" = 'num' ]; then 545 + generated_META="${generated_META} num num-top" 546 + numtop='num-top' 547 + else 548 + generated_META="${generated_META} ${package}" 549 + fi 550 + return 0 551 + fi 552 + done 553 + 554 + echo "$package: not present${msg}" 555 + return 1 556 + } 557 + 558 + if [ "${ocaml_major}" -ge 5 ]; then 559 + generated_META='' 560 + else 561 + generated_META='stdlib' 562 + fi 563 + numtop='' 564 + 565 + if ! check_library unix 'possible since 4.08' unix/unix.cmi unix.cmi; then 566 + echo "configure: ocamlfind requires OCaml's Unix library" 1>&2 567 + exit 1 568 + fi 569 + 570 + check_library dynlink '' dynlink/dynlink.cmi dynlink.cmi 571 + check_library bigarray 'possible since 4.08' 572 + check_library compiler-libs '' 'compiler-libs' 573 + check_library dbm 'normal since 4.00' 574 + check_library graphics 'normal since 4.09' 575 + check_library num 'normal since 4.06' 576 + check_library ocamlbuild 'normal since 4.03' ocamlbuild/ocamlbuildlib.cma 577 + check_library ocamldoc '' ocamldoc/odoc.cmi 578 + check_library raw_spacetime 'normal since 4.12' raw_spacetime_lib.cmxa 579 + check_library threads '' threads/thread.cmi vmthreads/thread.cmi; 580 + 581 + # Need to know if str and labltk are available for the toolbox 582 + if check_library str 'possible since 4.08' str/str.cmi str.cmi; then 583 + have_str=1 584 + else 585 + have_str=0 586 + fi 587 + 588 + if check_library labltk 'normal since 4.02' labltk/labltk.cma; then 589 + have_labltk=1 590 + else 591 + have_labltk=0 592 + fi 593 + 594 + # Dynlink check. 595 + 596 + have_natdynlink=0 597 + natdynlink="" 598 + camlp4_dynlink="" 599 + if [ -f "${ocaml_core_stdlib}/${dynlink_subdir:?}/dynlink.cmxa" ]; then 600 + have_natdynlink=1 601 + natdynlink="archive(native) = \"dynlink.cmxa\"" 602 + camlp4_dynlink="dynlink" 603 + echo "native dynlink: found" 604 + else 605 + natdynlink="archive(native) = \"\"" 606 + echo "native dynlink: not found" 607 + fi 608 + 609 + # Check on camlp4: 610 + 611 + if [ $with_camlp4 -eq 0 ]; then 612 + echo "camlp4: disabled" 613 + else 614 + if in_path camlp4; then 615 + if is_third_party_META camlp4; then 616 + echo "camlp4: third-party" 617 + fi 618 + camlp4_dir=$(camlp4 -where | tr -d '\r') 619 + if [ ${use_cygpath} -gt 0 ]; then 620 + camlp4_dir=$(echo x | env USE_CYGPATH=1 tools/patch x "$camlp4_dir") 621 + # This makes camlp4_dir a windows path 622 + elif [ "${pure_mingw}" = "yes" ]; then 623 + # Must double the backslahes 624 + camlp4_dir="$(echo "${camlp4_dir}" | sed -e 's;\\;\\\\;g')" 625 + fi 626 + camlp4_version=$(camlp4 -v 2>&1) 627 + if [ "$have_dlls" = "yes" ]; then 628 + camlp4_cmd="camlp4" 629 + else 630 + camlp4_cmd="safe_camlp4" 631 + fi 632 + # Check whether 3.09 or 3.10 style: 633 + if camlp4 -loaded-modules >/dev/null 2>/dev/null; then 634 + camlp4style=310 635 + else 636 + camlp4style=309 637 + fi 638 + generated_META="${generated_META} camlp4" 639 + rm -rf "site-lib-src/camlp4" 640 + mkdir "site-lib-src/camlp4" 641 + cp "site-lib-src/camlp4.$camlp4style/META.in" "site-lib-src/camlp4/" 642 + echo "camlp4: using $camlp4_cmd, style $camlp4style" 643 + else 644 + with_camlp4=0 645 + echo "camlp4: not present (normal since OCaml-4.02)" 646 + fi 647 + fi 648 + 649 + # bytes? 650 + # (NB. This is always ours, and it doesn't go into generated_META) 651 + 652 + req_bytes="" 653 + if [ -f "${ocaml_core_stdlib}/bytes.cmi" ] || 654 + [ -f "${ocaml_core_stdlib}/stdlib__bytes.cmi" ] || 655 + [ -f "${ocaml_core_stdlib}/stdlib__Bytes.cmi" ]; then 656 + echo "bytes: found, installing fake library" 657 + lbytes="bytes" 658 + cbytes=0 659 + else 660 + echo "bytes: not found, installing compat library" 661 + lbytes="" 662 + req_bytes="bytes" 663 + cbytes=1 664 + fi 665 + 666 + 667 + if [ $with_toolbox -gt 0 ]; then 668 + if [ $have_str -eq 0 ] || [ $have_labltk -eq 0 ]; then 669 + echo "Sorry, toolbox requires str and labltk - omitting toolbox." 670 + with_toolbox=0 671 + fi 672 + fi 673 + 674 + # Generate the META files now. 675 + 676 + for dir in site-lib-src/*; do 677 + # We do not really know if $dir is a directory. 678 + rm -f "$dir"/META 679 + done 680 + 681 + for lib in $generated_META $lbytes; do 682 + if="" 683 + if [ -f site-lib-src/"$lib"/interfaces.out ]; then 684 + if=$(cat site-lib-src/"$lib"/interfaces.out) 685 + fi 686 + sed \ 687 + -e "s|%%type_of_threads%%|${ocaml_threads}|g" \ 688 + -e "s|%%camlp4_dir%%|${camlp4_dir}|g" \ 689 + -e "s|%%camlp4_version%%|${camlp4_version}|g" \ 690 + -e "s|%%camlp4_cmd%%|${camlp4_cmd}|g" \ 691 + -e "s|%%camlp4_dynlink%%|${camlp4_dynlink}|g" \ 692 + -e "s|%%interfaces%%|${if}|g" \ 693 + -e "s|%%findlib_version%%|${version}|g" \ 694 + -e "s|%%natdynlink%%|${natdynlink}|g" \ 695 + -e "s|%%dynlink_dir%%|${dynlink_dir:?}|g" \ 696 + -e "s|%%unix_dir%%|${unix_dir:?}|g" \ 697 + -e "s|%%str_dir%%|${str_dir:?}|g" \ 698 + site-lib-src/"$lib"/META.in > site-lib-src/"$lib"/META 699 + 700 + echo "Configuration for $lib written to site-lib-src/$lib/META" 701 + done 702 + 703 + # create META from META.in in POSIX-compatible & safe way 704 + # see: https://www.shellcheck.net/wiki/SC2044 705 + meta_subst="sed -e 's/@VERSION@/$version/g' \ 706 + -e 's/@REQUIRES@/${req_bytes}/g' \ 707 + \"\$1\" > \"\${1%.in}\"" 708 + find src -name 'META.in' -type f -exec sh -c "$meta_subst" sh {} \; 709 + 710 + ###################################################################### 711 + 712 + printf "Detecting compiler arguments: " 713 + 714 + if make -C tools/extract_args >ocargs.log 2>&1; then 715 + printf "(extractor built) " 716 + # ocamlbrowser does not work! 717 + 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 718 + echo "ok" 719 + else 720 + echo "FAILED (see the file ocargs.log for details)" 721 + exit 1 722 + fi 723 + else 724 + echo "FAILED (see the file ocargs.log for details)" 725 + exit 1 726 + fi 727 + 728 + ###################################################################### 729 + # Write Makefile.config 730 + 731 + parts="findlib" 732 + ocamlfind_ocamlflags="-I +unix -I +dynlink" 733 + ocamlfind_archives="findlib.cma unix.cma" 734 + if [ $with_toolbox -gt 0 ]; then 735 + parts="$parts findlib-toolbox" 736 + fi 737 + if [ $cbytes -gt 0 ]; then 738 + # bytes first, because findlib needs it 739 + parts="bytes $parts" 740 + ocamlfind_ocamlflags="${ocamlfind_ocamlflags} -I ../bytes" 741 + ocamlfind_archives="bytes.cma ${ocamlfind_archives}" 742 + fi 743 + 744 + relative_site_lib=$(echo "${ocaml_sitelib}" | sed -e "s#^${ocaml_prefix}#\$PREFIX#") 745 + 746 + if [ $with_relative_paths -gt 0 ]; then 747 + # if configured with relative paths we add the relative path to the search path 748 + relative_paths="true" 749 + ocamlpath="${relative_site_lib}${path_sep}${ocamlpath}" 750 + else 751 + relative_paths="false" 752 + fi 753 + 754 + { 755 + echo "# Makefile.config written by configure" 756 + echo "OCAML_CORE_STDLIB=${ocaml_core_stdlib}" 757 + echo "OCAML_CORE_BIN=${ocaml_core_bin}" 758 + echo "OCAML_CORE_MAN=${ocaml_core_man}" 759 + echo "OCAML_SITELIB=${ocaml_sitelib}" 760 + echo "FINDLIB_PATH=${ocamlpath}" 761 + echo "OCAML_THREADS=${ocaml_threads}" 762 + echo "OCAMLFIND_BIN=${ocamlfind_bin}" 763 + echo "OCAMLFIND_MAN=${ocamlfind_man}" 764 + echo "OCAMLFIND_CONF=${ocamlfind_config}" 765 + echo "OCAMLFIND_OCAMLFLAGS=${ocamlfind_ocamlflags}" 766 + echo "OCAMLFIND_ARCHIVES=${ocamlfind_archives}" 767 + echo "OCAML_AUTOLINK=${ocaml_autolink}" 768 + echo "OCAML_REMOVE_DIRECTORY=${have_remdir}" 769 + echo "EXEC_SUFFIX=${exec_suffix}" 770 + echo "LIB_SUFFIX=${lib_suffix}" 771 + echo "CUSTOM=${custom}" 772 + echo "PARTS=${parts}" 773 + echo "INSTALL_TOPFIND=${with_topfind}" 774 + echo "RELATIVE_PATHS=${relative_paths}" 775 + echo "RELATIVE_OCAML_SITELIB=${relative_site_lib}" | sed -e "s/\\\$/\$\$/" 776 + echo "USE_CYGPATH=${use_cygpath}" 777 + echo "HAVE_NATDYNLINK=${have_natdynlink}" 778 + echo "VERSION=${version}" 779 + echo "ENABLE_TOPFIND_PPXOPT=${enable_topfind_ppxopt}" 780 + echo "SYSTEM=${system}" 781 + echo "NUMTOP=${numtop}" 782 + echo "SH=${sh}" 783 + if [ "$mingw_lib" != "" ]; then 784 + echo "OCAMLC_FLAGS=-I \"${mingw_lib}\"" 785 + echo "OCAMLOPT_FLAGS=-I \"${mingw_lib}\"" 786 + fi 787 + echo "OPAQUE=${opaque}" 788 + echo "OCAMLOPT_G=${native_debugging_info}" 789 + echo "CHECK_BEFORE_INSTALL=${check_before_install}" 790 + echo "CP = cp" 791 + echo "INSTALLDIR = install -d" 792 + echo "# change to INSTALLDIR = mkdir -p when BSD install is unavavailable" 793 + echo "INSTALLFILE = install -c" 794 + echo "# change to INSTALLFILE = cp when BSD install is unavailable" 795 + } > Makefile.config 796 + 797 + echo "SITELIB_META=${generated_META}" >Makefile.packages 798 + 799 + # All OK 800 + 801 + echo 802 + echo "About the OCAML core installation:" 803 + echo " Standard library: ${ocaml_core_stdlib}" 804 + echo " Binaries: ${ocaml_core_bin}" 805 + echo " Manual pages: ${ocaml_core_man}" 806 + echo " Multi-threading type: ${ocaml_threads}" 807 + echo "The directory of site-specific packages will be" 808 + echo " site-lib: ${ocaml_sitelib}" 809 + echo "The configuration file is written to:" 810 + echo " findlib config file: ${ocamlfind_config}" 811 + echo "Software will be installed:" 812 + echo " Libraries: in <site-lib>/findlib" 813 + echo " Binaries: ${ocamlfind_bin}" 814 + echo " Manual pages: ${ocamlfind_man}" 815 + if [ $with_topfind -gt 0 ]; then 816 + echo " topfind script: ${ocaml_core_stdlib}" 817 + else 818 + echo " topfind script: omitted" 819 + fi 820 + 821 + if [ $with_ppxopt -gt 0 ]; then 822 + echo "Topfind ppxopt support: yes" 823 + else 824 + echo "Topfind ppxopt support: no" 825 + fi 826 + 827 + if [ $with_toolbox -gt 0 ]; then 828 + echo "Toolbox: yes" 829 + else 830 + echo "Toolbox: no" 831 + fi 832 + 833 + if [ -z "$custom" ]; then 834 + echo "Link custom runtime: no" 835 + else 836 + echo "Link custom runtime: yes" 837 + fi 838 + 839 + if [ $cbytes -gt 0 ]; then 840 + echo "Need bytes compatibility: yes" 841 + else 842 + echo "Need bytes compatibility: no" 843 + fi 844 + 845 + echo 846 + echo "Configuration has been written to Makefile.config" 847 + echo 848 + echo "You can now do 'make all', and optionally 'make opt', to build ocamlfind." 849 +
+15
vendor/opam/ocamlfind/doc/DOCINFO
··· 1 + To build the html and manual pages from the SGML sources, you need the 2 + following tools: 3 + 4 + - The DocBook DTD 5 + (http://www.davenport.com) 6 + - James Clark's SGML tools (jade, sx suffice) 7 + (http://www.jclark.com) 8 + - Normal Walsh's DSSSL stylesheets to make the HTML pages 9 + (http://nwalsh.com/docbook/dsssl) 10 + - My db2man tool to make the manual pages 11 + (http://www.ocaml-programming.de/packages) 12 + 13 + The latter also requires Christian Lindig's XML parser 14 + (//http://www.cs.tu-bs.de/softech/people/lindig/software/tony.html). 15 +
+73
vendor/opam/ocamlfind/doc/Makefile
··· 1 + DOCBOOK_HTML = /usr/share/sgml/docbook/stylesheet/dsssl/modular/html 2 + DOCBOOK_PRINT = /usr/share/sgml/docbook/stylesheet/dsssl/modular/print 3 + SRC = $(PWD)/src 4 + 5 + EXPORTED = findlib.mli fl_package_base.mli fl_metascanner.mli \ 6 + fl_dynload.mli topfind.mli 7 + 8 + .PHONY: guide-html ref-html ref-man 9 + 10 + default: guide-html ref-html ref-man README QUICKSTART 11 + 12 + guide-html: guide-html/TIMESTAMP 13 + ref-html: ref-html/TIMESTAMP 14 + ref-man: ref-man/TIMESTAMP 15 + 16 + guide-html/TIMESTAMP: src/*.sgml src/*.mod QUICKSTART.xml common.xml config.xml 17 + mkdir -p guide-html 18 + cd guide-html; \ 19 + rm -f *.htm*; \ 20 + openjade -t sgml -D$(DOCBOOK_HTML) -D$(SRC) findlib.sgml; \ 21 + true 22 + readme -html QUICKSTART.xml >guide-html/quickstart.html 23 + touch guide-html/TIMESTAMP 24 + 25 + ref-html/TIMESTAMP: src/*.sgml src/*.mod common.xml config.xml $(EXPORTED:%=../src/findlib/%) 26 + mkdir -p ref-html 27 + cd ref-html; \ 28 + rm -f *.htm*; \ 29 + openjade -t sgml -D$(DOCBOOK_HTML) -D$(SRC) findlib_ref.sgml; \ 30 + true 31 + mkdir -p ref-html/lib 32 + cd ../src/findlib && \ 33 + ocamldoc -html -d $(PWD)/ref-html/lib -stars -t "The Findlib Library" $(EXPORTED) 34 + touch ref-html/TIMESTAMP 35 + 36 + src/findlib_reference.xml: src/*.sgml src/*.mod 37 + osx -D$(DOCBOOK_HTML) -D$(SRC) \ 38 + findlib_reference.sgml >src/findlib_reference.xml ; \ 39 + true 40 + 41 + ref-man/TIMESTAMP: src/findlib_reference.xml 42 + mkdir -p ref-man 43 + cd ref-man; \ 44 + rm -f *.[0-9] TIMESTAMP; \ 45 + db2man <../src/findlib_reference.xml 46 + touch ref-man/TIMESTAMP 47 + 48 + # Unfortunately, output of ocamldoc -man is too bad to be useful. 49 + # cd ../src/findlib && \ 50 + # ocamldoc -man -man-mini -d $(PWD)/ref-man -man-suffix 3 -stars -t "The Findlib Library" $(EXPORTED) 51 + 52 + .SUFFIXES: .xml .sgml 53 + 54 + .sgml.xml: 55 + sx -xndata $< >$@; true 56 + 57 + 58 + 59 + clean: 60 + rm -rf guide-html guide-man ref-html/TIMESTAMP 61 + rm -f src/*.xml 62 + 63 + distclean: 64 + rm -f src/*.xml 65 + rm -f src/*~ 66 + rm -f *~ 67 + 68 + QUICKSTART: QUICKSTART.xml 69 + readme -text QUICKSTART.xml >QUICKSTART 70 + 71 + README: README.xml 72 + readme -text README.xml >README 73 +
+288
vendor/opam/ocamlfind/doc/QUICKSTART.xml
··· 1 + <?xml version="1.0" encoding="ISO-8859-1"?> 2 + <!DOCTYPE readme SYSTEM "readme.dtd" [ 3 + 4 + <!ENTITY % common SYSTEM "common.xml"> 5 + %common; 6 + 7 + <!-- Special HTML config: --> 8 + <!ENTITY % readme:html:up '<a href="../..">up</a>'> 9 + 10 + <!ENTITY % config SYSTEM "config.xml"> 11 + %config; 12 + 13 + ]> 14 + 15 + <readme title="QUICKSTART - The most important ways to use findlib"> 16 + <sect1> 17 + <title>Intro</title> 18 + <p>See the file INSTALL for instructions how to build and install 19 + findlib.</p> 20 + </sect1> 21 + 22 + <sect1> 23 + <title>Findlib and the toploop</title> 24 + 25 + <p>For a number of platforms, OCaml can load bytecode-compiled 26 + libraries dynamically. For these platforms, findlib is very simple to 27 + use as explained in the following. For other platforms, see the paragraph 28 + below about "custom toploops".</p> 29 + 30 + <p>After the toploop has been started, it is possible to load the special 31 + findlib support:<footnote>In previous versions, #use "findlib" loaded the 32 + library. However, this caused a name conflict for a certain type of 33 + installation. Because of this, the name of the loader script has been changed 34 + to "topfind", but "findlib", and "ocamlfind" (Debian) are also available 35 + for backwards compatibility.</footnote> 36 + 37 + <code> 38 + $ ocaml 39 + Objective Caml version 3.07 40 + 41 + # #use "topfind";; 42 + Findlib has been successfully loaded. Additional directives: 43 + #require "package";; to load a package 44 + #list;; to list the available packages 45 + #camlp4o;; to load camlp4 (standard syntax) 46 + #camlp4r;; to load camlp4 (revised syntax) 47 + #predicates "p,q,...";; to set these predicates 48 + Topfind.reset();; to force that packages will be reloaded 49 + #thread;; to enable threads 50 + 51 + - : unit = () 52 + </code> 53 + 54 + You can now list the available packages: 55 + 56 + <code> 57 + # #list;; 58 + bigarray (version: [distributed with Ocaml]) 59 + camlp4 (version: Camlp4 version 3.03 ALPHA) 60 + dbm (version: [distributed with Ocaml]) 61 + dynlink (version: [distributed with Ocaml]) 62 + findlib (version: 0.6) 63 + graphics (version: [distributed with Ocaml]) 64 + labltk (version: [distributed with Ocaml]) 65 + netstring (version: 0.10) 66 + num (version: [distributed with Ocaml]) 67 + stdlib (version: [distributed with Ocaml]) 68 + str (version: [distributed with Ocaml]) 69 + threads (version: [distributed with Ocaml]) 70 + unix (version: [distributed with Ocaml]) 71 + xstrp4 (version: 1.1) 72 + </code> 73 + 74 + and load packages by simply typing: 75 + 76 + <code> 77 + # #require "netstring";; 78 + Loading /opt/ocaml/lib/unix.cma 79 + Loading /opt/ocaml/lib/str.cma 80 + Loading /opt/ocaml/site-lib/netstring/netstring.cma 81 + Loading /opt/ocaml/site-lib/netstring/netstring_top.cmo 82 + </code> 83 + 84 + Findlib takes care to load packages that are required by loaded packages 85 + first. For example, "netstring" uses "unix" and "str" internally, but you 86 + do not need to load them because findlib does it for you. In this example 87 + you can also see that findlib loads netstring_top.cmo containing printers 88 + for the toploop.</p> 89 + 90 + <p>You can also enable the Camlp4 parsers by simply typing 91 + 92 + <code> 93 + # #camlp4o;; 94 + Loading /opt/ocaml-3.03a/lib/camlp4/camlp4o.cma 95 + Camlp4 Parsing version 3.03 ALPHA 96 + </code> 97 + 98 + for the standard syntax or 99 + 100 + <code> 101 + # #camlp4r;; 102 + Loading /opt/ocaml-3.03a/lib/camlp4/camlp4r.cma 103 + Camlp4 Parsing version 3.03 ALPHA 104 + </code> 105 + 106 + for the revised syntax. (But you cannot switch between the syntaxes.) 107 + </p> 108 + </sect1> 109 + 110 + <sect1> 111 + <title>Custom Toploops</title> 112 + 113 + <p>For some platforms, OCaml does not implement loading external 114 + libraries (e.g. Cygwin). One has to create a so-called custom toploop 115 + that statically links with these libraries. Example: 116 + 117 + <code> 118 + $ ocamlfind ocamlmktop -o mytop -package findlib,unix -linkpkg 119 + $ ./mytop 120 + Objective Caml version 3.07 121 + 122 + # #use "topfind";; 123 + Findlib has been successfully loaded. Additional directives: 124 + #require "package";; to load a package 125 + #list;; to list the available packages 126 + #camlp4o;; to load camlp4 (standard syntax) 127 + #camlp4r;; to load camlp4 (revised syntax) 128 + #predicates "p,q,...";; to set these predicates 129 + Topfind.reset();; to force that packages will be reloaded 130 + #thread;; to enable threads 131 + 132 + - : unit = () 133 + </code> 134 + 135 + Now "#require" works for all libraries referring to the special "unix" 136 + functions. 137 + </p> 138 + </sect1> 139 + 140 + <sect1> 141 + <title>Findlib and scripts</title> 142 + 143 + <p>The #require directive can also be used in scripts. Example: 144 + 145 + <code> 146 + #use "topfind";; 147 + #require "netstring";; 148 + 149 + open Cgi;; 150 + ... 151 + </code> 152 + 153 + This makes it possible to write scripts that do not contain #directory 154 + directives that are specific for certain installations.</p> 155 + 156 + <p>For Unix environments, you can start scripts directly if you 157 + apply the following trick: 158 + 159 + <code> 160 + #! /bin/sh 161 + # (* 162 + exec ocaml "$0" "$@" 163 + *) use "topfind";; 164 + #require "netstring";; 165 + 166 + open Cgi;; 167 + ... 168 + </code> 169 + 170 + This works wherever OCaml is installed.</p> 171 + </sect1> 172 + 173 + <sect1> 174 + <title>Compiling programs</title> 175 + 176 + <p>Assumed you want to compile a program that uses the Netstring package. 177 + Do it the following way: 178 + 179 + <code> 180 + $ ocamlfind ocamlc -package netstring -c myprogram.ml 181 + </code> 182 + 183 + This way you do not need to add "-I" options to locate Netstring.</p> 184 + 185 + <p>If you want to create an executable, do not forget to add the 186 + -linkpkg switch: 187 + 188 + <code> 189 + $ ocamlfind ocamlc -o myprogram -package netstring -linkpkg myprogram.cmo 190 + </code> 191 + 192 + This switch causes that the mentioned packages are added to the resulting 193 + executable.</p> 194 + 195 + <p>If you want to include several packages, you can either add several 196 + "-package" options, or you can enumerate the packages separated by commas: 197 + -package netstring,labltk.</p> 198 + </sect1> 199 + 200 + <sect1> 201 + <title>Camlp4</title> 202 + 203 + <p>If you add a -syntax option, the compiler will be told to parse the 204 + source file using camlp4: 205 + 206 + <code> 207 + $ ocamlfind ocamlc -package netstring -syntax camlp4o -c myprogram.ml 208 + </code> 209 + 210 + Use -syntax camlp4o for the standard syntax or -syntax camlp4r for the 211 + revised syntax.</p> 212 + 213 + <p>Additionally, you can mention packages that add new syntax features. 214 + The package xstrp4 is an example of this: 215 + 216 + <code> 217 + $ ocamlfind ocamlc -package xstrp4,netstring -syntax camlp4o -c myprogram.ml 218 + </code> 219 + 220 + Now you can use the $ notation that is implemented by xstrp4 in the 221 + source file myprogram.ml.</p> 222 + 223 + <p>Note that you can also invoke ocamldep from ocamlfind: 224 + 225 + <code> 226 + $ ocamlfind ocamldep -package xstrp4 -syntax camlp4o *.ml *.mli &gt;.depend 227 + </code> 228 + 229 + This enables the syntax extensions, too.</p> 230 + </sect1> 231 + 232 + <sect1> 233 + <title>ocamlbrowser</title> 234 + <p>Since findlib-0.7, it is also possible to start ocamlbrowser from 235 + ocamlfind. For example, 236 + 237 + <code> 238 + $ ocamlfind browser -package xstrp4 239 + </code> 240 + 241 + adds the correct path specification such that the modules contained in the 242 + package xstrp4 are also displayed. With 243 + 244 + <code> 245 + $ ocamlfind browser -all 246 + </code> 247 + 248 + all package are added to the path spec. 249 + </p> 250 + </sect1> 251 + 252 + <sect1> 253 + <title>The Makefile wizard</title> 254 + <p>There is a wizard that makes it very easy to write Makefiles. Call the 255 + wizard by 256 + <code> 257 + $ ocamlfind findlib/make_wizard 258 + </code> 259 + (the wizard requires that the labltk library is available). A new window 260 + pops up, and by very few clicks you can describe your own library. Finally, 261 + a Makefile is written. 262 + </p> 263 + </sect1> 264 + 265 + <sect1> 266 + <title>There is no magic!</title> 267 + 268 + <p>Findlib is neither a patch of OCaml nor uses it internal features of 269 + the OCaml programming environment. It is only a convention to install 270 + software components in filesystem hierarchies, a library interpreting 271 + this convention, and some frontend applications making the library usable for 272 + you.</p> 273 + 274 + <p>One important consequence is that you can only refer to those 275 + software components that have previously been installed in a way findlib 276 + understands. This convention is beyond the scope of this QUICKSTART guide, 277 + see the reference manual for details. You can always check whether findlib 278 + accepts a component as "findlib package" by the command 279 + 280 + <code> 281 + $ ocamlfind list 282 + </code> 283 + 284 + (this is the same as the #list directive in the toploop). If the package 285 + occurs in the list, it is found, otherwise not.</p> 286 + </sect1> 287 + </readme> 288 +
+714
vendor/opam/ocamlfind/doc/README.xml
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <!DOCTYPE readme SYSTEM "readme.dtd" [ 3 + 4 + <!ENTITY % common SYSTEM "common.xml"> 5 + %common; 6 + 7 + <!-- Special HTML config: --> 8 + <!ENTITY % readme:html:up '<a href="../..">up</a>'> 9 + 10 + <!ENTITY % config SYSTEM "config.xml"> 11 + %config; 12 + 13 + ]> 14 + 15 + <readme title="README - The findlib library manager"> 16 + <sect1> 17 + <title>Introduction</title> 18 + 19 + <p>The "findlib" software provides a scheme to manage reusable software 20 + components in the form of libraries, and includes tools that support 21 + this scheme. A library installed as a findlib component is also called 22 + a package. The point is that the findlib scheme allows it to store 23 + metainformation about the library, especially how it can be used in 24 + programs. The packages are kept in the filesystem hierarchy, but the 25 + directory structure is defined by findlib, and there is no way to 26 + deviate from this standard. The library contains functions to look the 27 + directory up that stores a package, to query metainformation about a 28 + package, and to retrieve dependency information about multiple 29 + packages. There is also a tool that allows the user to enter queries 30 + on the command-line. In order to simplify compilation and linkage, 31 + there are new frontends of the various OCaml compilers that can 32 + directly deal with packages. 33 + </p> 34 + 35 + <p>It is important to understand that findlib is <em>not</em> a 36 + general-purpose package manager (like rpm for Linux), and does <em>not</em> 37 + support the management of arbitrary files, but only OCaml libraries. 38 + However, there are lots of special functions for libraries. findlib 39 + is more comparable with Gnome's pkg-config and Perl's MakeMaker, but 40 + of course there are language-specific differences.</p> 41 + 42 + <p>The metainformation includes:</p> 43 + 44 + <ul> 45 + <li><p>The necessary command-line arguments to use a library.</p> 46 + </li> 47 + <li><p>Dependencies on other packages.</p> 48 + </li> 49 + <li><p>Version strings.</p> 50 + </li> 51 + </ul> 52 + 53 + <p>These data can be conditional. Possible conditions are certain 54 + environmental settings, such as whether the bytecode or the native code 55 + compiler is used, or whether the application is multi-threaded. It is 56 + also possible that a package behaves differently when a certain other 57 + package is selected.</p> 58 + 59 + <p>There is special support for scripts. It is possible to load 60 + libraries into toploops, including all dependent libraries, with only 61 + one command.</p> 62 + 63 + <p>Findlib has been developed since March 1999, and has matured 64 + for more than four years until the release of version 1.0. One of the 65 + important questions during this long period of development was which 66 + features are necessary and which not. The result is a utility that 67 + follows still simple concepts, but is flexible enough to allow even 68 + the description of complex libraries and complex interdependencies. 69 + </p> 70 + </sect1> 71 + 72 + <sect1> 73 + <title>Documentation</title> 74 + 75 + <p>See the file QUICKSTART for the most important findlib commands.</p> 76 + 77 + <p>There is a User's Guide introducing into the concepts of findlib, 78 + especially explaining how to create packages.</p> 79 + 80 + <p>The Reference Manual describes commands, directory structure, 81 + configuration files, and library routines in detail.</p> 82 + </sect1> 83 + 84 + <sect1> 85 + <title>Installation</title> 86 + 87 + <p>See the file INSTALL.</p> 88 + </sect1> 89 + 90 + <sect1> 91 + <title>Download</title> 92 + <p> 93 + The current version is announced in the 94 + <a href="&url.linkdb;">Objective Caml Link Database</a>. 95 + </p> 96 + </sect1> 97 + 98 + <sect1> 99 + <title>Copyright and License Conditions</title> 100 + <p> 101 + Findlib is copyright 1999-2012 by Gerd Stolpmann. See the file LICENSE 102 + for the MIT/X11 style license conditions. 103 + 104 + Contact me at gerd@gerd-stolpmann.de in case of questions. 105 + </p> 106 + </sect1> 107 + 108 + <sect1> 109 + <title>List of Changes</title> 110 + <ul> 111 + 112 + <li> 113 + <p><em>1.9.8:</em>: A few build-related fixes.</p> 114 + </li> 115 + 116 + <li> 117 + <p><em>1.9.7:</em>: Allow overriding low-level module loader 118 + in `Fl_dynload.load_packages`. This is very useful in JSOO 119 + where we may want to implement a `.cma` -> `.js` cache instead 120 + of calling `Dynlink.loadfile` dynamically. (Emilio J. Gallego 121 + Arias).</p> 122 + <p>Fix auto-detection of -opaque (Stephen Dolan)</p> 123 + <p>Fix linking of threads.cmxa in OCaml-5.2 (David Allsopp)</p> 124 + <p>Improved scripts (shellcheck) (Marek Kubica)</p> 125 + <p>Support for relocatable installations (Marek Kubica)</p> 126 + <p>Support OCAMLOPT_SHARED (Chen Qi)</p> 127 + <p>Avoid exception for PATH containing "." (Dmetry Bely)</p> 128 + <p>Fixes for Windows (David Allsopp)</p> 129 + <p>Typos in documentation (Antonin Décimo)</p> 130 + <p>Upgrade ocamlfind for OCaml-5 (David Allsopp)</p> 131 + </li> 132 + 133 + <li> 134 + <p><em>1.9.6:</em>: Support for OCaml-5 (as far as foreseeable) 135 + (David Allsopp).</p> 136 + <p>Again buildable since OCaml-3.08 (David Allsopp).</p> 137 + <p>Fix an install problem when building with a system-provided 138 + OCaml compiler (Louis Gesbert).</p> 139 + </li> 140 + 141 + <li> 142 + <p><em>1.9.5:</em>: fixes a bug in the scripting that 143 + slipped into 1.9.4</p> 144 + </li> 145 + 146 + <li> 147 + <p><em>1.9.4:</em> Also finds the libraries str.cm(x)a, unix.cm(x)a, 148 + and dynlink.cm(x)a in subdirectories of the OCaml standard library, 149 + as needed for OCaml-4.14 (David Allsopp).</p> 150 + <p>Support for runtime_events (Patrick Ferris)</p> 151 + <p>Fix spelling of "OCaml" everywhere (Marek Kubica)</p> 152 + <p>Work around the deprecation of a POSIX shell feature 153 + (Issam Maghni)</p> 154 + <p>Support DESTDIR, and favor the "install" command for installation 155 + (Gerd Stolpmann on suggestion of Thomas Klausner)</p> 156 + </li> 157 + 158 + <li><p><em>1.9.3:</em> Fixes another build problem regarding OCaml-5.00</p></li> 159 + 160 + <li><p><em>1.9.2:</em> Fixes a build problem regarding OCaml-5.00</p></li> 161 + 162 + <li><p><em>1.9.1:</em> Fixes a few install-related issues, like missing files.</p></li> 163 + 164 + <li> 165 + <p><em>1.9:</em> Overhaul how separately installed packages (e.g. num) 166 + are handled (by David Allsopp).</p> 167 + <p>Switch to opam-2.0 file format (by David Allsopp).</p> 168 + <p>Fix an incomaptibility with ocaml-4.13 (by David Allsopp).</p> 169 + <p>Expose the native toplevel (by Louis Gesbert).</p> 170 + <p>Fix an incompatibility with "Jane Street Style" (by Mark Laws).</p> 171 + <p>Switch from m4 to sed (by kit-ty-kate).</p> 172 + </li> 173 + 174 + <li> 175 + <p><em>1.8.1:</em> Adapted to upcoming ocaml-4.09.</p> 176 + <p>New API Findlib.list_packages' can specify a package prefix.</p> 177 + </li> 178 + 179 + <li> 180 + <p><em>1.8.0:</em> Fix reinstallation of "num" for OCaml-4.06. 181 + </p> 182 + <p>Fix build with OCaml-4.07.</p> 183 + <p>The installation of graphics/META is now optional.</p> 184 + <p>Fix "ocamlfind query -d".</p> 185 + <p>The environment variable OCAMLFIND_IGNORE_DUPS_IN is now interpreted 186 + as a list of directories.</p> 187 + <p>Packages for "ocamlfind query" may now be separated by commas, too.</p> 188 + <p>New "warning" property for packages.</p> 189 + <p>Forgetting to pass -thread/-vmthread only prints a warning now, 190 + but doesn't stop the build.</p> 191 + <p>For dealing with case-sensitive filesystems it is now only tried to 192 + match ASCII characters, but not encoding-dependent characters.</p> 193 + </li> 194 + 195 + <li> 196 + <p><em>1.7.3:</em> Fix regarding num-top: this library is now also 197 + optional, as num.</p> 198 + </li> 199 + 200 + <li> 201 + <p><em>1.7.2:</em> Trying to protect against failures when 202 + several package installs are done in parallel.</p> 203 + 204 + <p>New subpackage "findlib.top" for the toploop (Jeremie Dimino).</p> 205 + 206 + <p>The "num" library is now optional.</p> 207 + 208 + <p>Shell scripts are started via "sh" command when there is no 209 + /bin/sh (ygrek)</p> 210 + </li> 211 + 212 + <li> 213 + <p><em>1.7.1:</em> added missing file to tarball</p> 214 + </li> 215 + 216 + <li> 217 + <p><em>1.7.0:</em> New command "ocamlfind printppx" that outputs 218 + how the ppx preprocessor would be called (Hendrik Tews).</p> 219 + <p>Support for the raw_spacetime library that comes with 220 + OCaml 4.04 (Gerd Stolpmann with help from Mark Shinwell).</p> 221 + <p>Require that ocamlc and ocamlc.opt are installed to the 222 + same directory for emitting the "opt" setting in the generated 223 + config file - same for ocamlopt.opt, ocamldep.opt, ocamldoc.opt.</p> 224 + </li> 225 + 226 + <li> 227 + <p><em>1.6.3:</em>Fix: "ocamlfind printconf" respects the 228 + environment variable OCAMLFIND_CONF (reported by Andre)</p> 229 + <p>Build with -opaque (reported by hhugo)</p> 230 + <p>Preliminary support for native toplevel so far the toplevel 231 + is implemented symmetrically to the bytecode case (this is not 232 + correct in vanilla ocaml)</p> 233 + <p>New options: ocamlfind query -qe -qo</p> 234 + </li> 235 + 236 + <li> 237 + <p><em>1.6.2:</em>Uninstalling findlib no longer uninstalls the 238 + ocamlbuild library by accident (Gabriel Scherer, Edwin Török)</p> 239 + <p>Adding an "ocamldoc" library, providing the cmi's for ocamldoc 240 + plugins (suggested by Armaël Guéneau)</p> 241 + <p>Support for OCaml-4.03: recognize that the new -color option 242 + has an argument (reported by Guillaume Bury)</p> 243 + </li> 244 + 245 + <li> 246 + <p><em>1.6.1:</em> Just an important doc fix.</p> 247 + </li> 248 + 249 + <li> 250 + <p><em>1.6.0:</em> Adding support for dynamically loading 251 + packages (François Bobot): new "plugin" variable, new 252 + Fl_dynload module.</p> 253 + <p>New command "ocamlfind lint" for checking META files 254 + (François Bobot).</p> 255 + <p>Also support MSYS_NT on Windows. Permit spaces in install 256 + paths (Christophe Troestler).</p> 257 + <p>Allow to query the location of the META file of a package: 258 + "ocamlfind query -format '%m'" (Gerd Stolpmann).</p> 259 + <p>Get the install path for the META file of packages: 260 + "ocamlfind printconf metapath" (Gerd Stolpmann).</p> 261 + </li> 262 + 263 + <li> 264 + <p><em>1.5.6:</em> for MSVC build fixing bad filename suffix 265 + (Dmitry Bely).</p> 266 + <p>The switch -only-show did not work as described. 267 + (Error report from Bob Atkey.)</p> 268 + <p>Also support mingw64 as system type (Matthieu Dubuget).</p> 269 + </li> 270 + 271 + <li> 272 + <p><em>1.5.5:</em> fixes a build problem for BSD systems</p> 273 + </li> 274 + 275 + <li> 276 + <p><em>1.5.4:</em> New ppxopt META variables (Peter Zotov).</p> 277 + <p>Support for OCAMLFIND_TOOLCHAIN environment variable (Peter Zotov). 278 + </p> 279 + </li> 280 + 281 + <li> 282 + <p><em>1.5.3:</em> The installation of "bytes" respects now $prefix and 283 + the configured destination.</p> 284 + <p>New option -pp for "ocamlfind query", to get preprocessor packages.</p> 285 + <p>Updated the compatibility Bytes module to support extend, init, mapi, 286 + blit_string (Gabriel Scherer).</p> 287 + </li> 288 + 289 + <li> 290 + <p><em>1.5.2:</em> support for the query formats "%+a" and "%+A".</p> 291 + <p>Fix: the "ppx" property is now also path-expanded when interpreted 292 + in a toploop.</p> 293 + <p>Fix: implicit "ppx" is not path-expanded anymore.</p> 294 + <p>Fix: Build bytes.cmxs only if natdynlink is enabled (Andy Ray).</p> 295 + </li> 296 + <li> 297 + <p><em>1.5.1:</em> includes a file that was missing in 1.5</p> 298 + </li> 299 + <li> 300 + <p><em>1.5:</em> Including the "bytes" package that is either 301 + a compat package for ocaml &lt; 4.02 or a fake package for ocaml &gt;= 4.02. 302 + The package aims at helping to support the transition to the new 303 + "bytes" type for mutable strings.</p> 304 + <p>Also installing findlib.cmxs if OCaml supports it.</p> 305 + <p>Allowing to disable camlp4 (in prep for OCaml-4.02).</p> 306 + <p>The "ppx" package property can be specified for constructing 307 + ppx-type preprocessors (patches from Peter Zotov).</p> 308 + </li> 309 + 310 + <li> 311 + <p><em>1.4.1:</em>ocamldoc: The order of -ppopt arguments was 312 + changed by ocamlfind, which is not correct. (Sylvain Le Gall and 313 + Jérémie Dimino.)</p> 314 + </li> 315 + 316 + <li> 317 + <p><em>1.4:</em> Fixed performance bug when many arguments 318 + need to be processed (Jérôme Vouillon).</p> 319 + <p>Auto-configuring ocamldoc.opt if it is found (Christopher 320 + Zimmermann).</p> 321 + <p>New config switch -no-custom to prevent that "ocamlfind" 322 + is linked in custom-runtime mode (bytecode only) (Christopher 323 + Zimmermann).</p> 324 + <p>The library dbm is no longer part of OCaml, and now 325 + optional in findlib (Ashish Argawal).</p> 326 + <p>Support for ocamloptp.</p> 327 + <p>New function Topfind.log for controlling the verbosity 328 + (Jeremie Dimino).</p> 329 + <p>Rewritten Fl_metascanner without camlp4 (patch from 330 + Gabriel Scherer)</p> 331 + </li> 332 + 333 + <li> 334 + <p><em>1.3.3:</em> OCaml-4: using the new #remove_directory directive 335 + if present.</p> 336 + <p>Better compatibility with the OCaml version from Homebrew.</p> 337 + </li> 338 + 339 + <li> 340 + <p><em>1.3.2:</em> Handling of empty arguments (Wojciech Meyer).</p> 341 + <p>Added entry for camlp4.fulllib.</p> 342 + <p>New switch -add for "ocamlfind install" (Hans Ole Rafaelsen).</p> 343 + <p>Further fixes for ocaml-4.00.</p> 344 + <p>Fixing the recognition of double .cmi interface files.</p> 345 + <p>Fixing -dontlink (it is now deeply interpreted).</p> 346 + </li> 347 + 348 + <li> 349 + <p><em>1.3.1:</em> Fixing a bug with ocamlmklib that slipped through 350 + in 1.3.0</p> 351 + </li> 352 + 353 + <li> 354 + <p><em>1.3.0:</em> Fixes for ocaml-4.00 (especially topfind).</p> 355 + <p>Emitting an error if the configuration file does not exist.</p> 356 + <p>Emitting a warning if the selected toolchain does not exist.</p> 357 + <p>camlp4 is referenced by "+camlp4" in META.</p> 358 + <p>Including the sources for the documentation in the tarball.</p> 359 + <p>License change (simplification) for num_top_printers.mli.</p> 360 + <p>Fix ocamlmklib wrapper: processing contracted args (like -L/dir) correctly.</p> 361 + <p>Many wrappers get a new option -passrest instructing to pass all 362 + remaining options on the command-line unchanged to the invoked tool.</p> 363 + <p>Prettified -help output.</p> 364 + </li> 365 + 366 + <li> 367 + <p><em>1.2.8:</em> 368 + Adding support for ocamlmklib (B. Meurer's patches)</p> 369 + <p>Fix for win32 in the configure script.</p> 370 + </li> 371 + <li> 372 + <p><em>1.2.7:</em> 373 + Fix: if a META file defines several packages, and one of the packages 374 + has a broken dependency, ocamlfind used to report all errors even if 375 + the broken packages were not used. This is now changed - broken 376 + subpackages are ignored when they are not needed, in the same way as 377 + broken top-level packages are ignored when not needed. (Thanks to 378 + Sylvain Le Gall for reporting the problem.)</p> 379 + <p>Added -thread and -vmthread switches to "ocamlfind ocamldoc". 380 + These actually only add the right predicates. (Thanks to Vladimir 381 + Ivanov for pointing this problem out.)</p> 382 + <p>Package warnings can be emitted by "ocamlfind ocamldoc".</p> 383 + </li> 384 + <li> 385 + <p><em>1.2.6:</em> adding META for ocamlbuild.</p> 386 + <p>Fixes for MinGW/MSYS platform.</p> 387 + <p>Improved messages.</p> 388 + </li> 389 + <li> 390 + <p><em>1.2.5:</em> Fix: Again CR deletion... Turns out some OS do not 391 + understand '\r' but only '\015' (thanks to Isaiah Weiner).</p> 392 + <p>Support for Win64 (untested; thanks to David Allsopp).</p> 393 + <p>ocamlfind no longer emits auto-generated -ccopt options. These 394 + tend to accumulate, and it is possible that for large projects 395 + the maximum command line length is exceeded. Current versions of 396 + the OCaml compilers do not need these extra -ccopt anyway, so 397 + this code is completely dropped.</p> 398 + </li> 399 + 400 + <li> 401 + <p><em>1.2.4:</em> Fix: Bigarray needs unix (Thanks to Markus Mottl).</p> 402 + <p>Fix: In the version of camlp4 provided by OCaml 3.11 various 403 + libraries do not contain dynlink anymore. Because of this, dynlink 404 + becomes a prerequisite of camlp4. (Thanks to Martin Jambon).</p> 405 + <p>Attempt: Fixing the space issue for paths (Win32). It is unclear 406 + whether it is solved. (Thanks to Christophe Troestler).</p> 407 + </li> 408 + 409 + <li> 410 + <p><em>1.2.3:</em> Solving the CR deletion differently, to 411 + make OS X happy.</p> 412 + </li> 413 + 414 + <li> 415 + <p><em>1.2.2:</em> Fix: Problem with CR character (Cygwin) 416 + (Thanks to David Allsopp). 417 + </p> 418 + <p>Fix: Case-insensitive filesystems (partially solved) 419 + (Thanks to David Allsopp). 420 + </p> 421 + <p>Fix: File name with backslashes at the end (Win32; 422 + thanks to Dmitry Grebeniuk).</p> 423 + </li> 424 + 425 + <li> 426 + <p><em>1.2.1:</em> Fix: Camlp4 rules now activate the 427 + stream parser extension</p> 428 + </li> 429 + 430 + <li> 431 + <p><em>1.2:</em> Fix in build scripts: Prepending $(prefix) 432 + when installing safe_camlp4 (thanks to Daniel Janus)</p> 433 + <p>Non-existing -I directories are ignored 434 + (thanks to Nicolas Pouillard)</p> 435 + <p>A script to create a MacOS X package (thanks to 436 + Pietro Abate)</p> 437 + <p>Better support for Windows (with help from Robert 438 + Roessler and David Allsopp)</p> 439 + <p>Support for camlp4 on OCaml 3.10</p> 440 + <p>Fix: "ocamlfind install" with "-patch" option writes 441 + now correct META file for the case that subpackages occur</p> 442 + <p>Adding environment variable OCAMLFIND_IGNORE_DUPS_IN 443 + to reduce the number of warnings ocamlfind emits</p> 444 + </li> 445 + 446 + <li> 447 + <p><em>1.1.2:</em> Bugfix in the META parser: Backslashes are now 448 + correctly parsed. (Thanks to Martin Jambon for finding this problem.)</p> 449 + <p>Fixes for platforms that do not support dynamic loading of 450 + DLLs.</p> 451 + <p>Fixed extraction of camlp4 parameters from packages.</p> 452 + </li> 453 + 454 + <li> 455 + <p><em>1.1.1:</em> Bugfixes only: Fixed detection of threading model 456 + for OCaml 3.09. Fixed alternate configuration files.</p> 457 + </li> 458 + 459 + <li> 460 + <p><em>1.1:</em> Automatic detection of standard compiler options.</p> 461 + 462 + <p>Liberated the checks whether a package is already installed.</p> 463 + 464 + <p>The .opt compilers are entered into findlib.conf if available.</p> 465 + 466 + <p>New: "install" has -optional switch for optional files.</p> 467 + 468 + <p>New: "install" has -patch-version to patch the version into 469 + the installed META file.</p> 470 + 471 + <p>New: "install" has -patch-rmpkg to remove subpackages from 472 + the installed META file.</p> 473 + 474 + <p>New: "install" has -patch-archives which removes non-existing 475 + files from "archive" variables. This is experimental.</p> 476 + 477 + <p>New: subpackages can be disabled by exists_if.</p> 478 + 479 + <p>New: Support for toolchains.</p> 480 + 481 + <p>Fix for "remove": -destdir works again.</p> 482 + 483 + <p>Fix for "call": CTRL-C works when calling interactive commands.</p> 484 + 485 + <p>Fix for preprocessor packages: Dependencies on normal packages 486 + are resolved.</p> 487 + 488 + </li> 489 + 490 + <li><p><em>1.0.4:</em> Fix: In previous versions, "ocamlmktop" 491 + set the "toploop" predicate. It turned out, however, that the toploops 492 + generated in this way did not work properly. For this reason, 493 + "ocamlmktop" does not set "toploop" any more for link time, but 494 + instead a new predicate "create_toploop". When the toploop is 495 + executed, the predicate "toploop" is again added.</p> 496 + </li> 497 + 498 + <li><p><em>1.0.3:</em> Fix: The relative position of "-cclib -l" 499 + options on the command line is preserved. In previous versions, 500 + these options were moved to the beginning of the argument list. This 501 + did not work for static link editing; dynamic link editing was not 502 + affected.</p> 503 + <p>Fix: The automatic fixup of "threads" dependencies 504 + works again. In the previous version, this was broken.</p> 505 + <p>Addition: -format '%(name)' for ocamlfind query.</p> 506 + <p>Some minor improvements of the documentation.</p> 507 + </li> 508 + 509 + <li><p><em>1.0.2:</em> Fix: The alternate package layout did 510 + not fully work. This is repaired now, and there are some clarifications 511 + about relative directory paths in the documentation.</p> 512 + </li> 513 + 514 + <li><p><em>1.0.1:</em> Fix: Forgot to install some .cmi 515 + files</p> 516 + </li> 517 + 518 + <li><p><em>1.0:</em> It is now possible to divide the 519 + description of a package into subpackages (but there is still only one 520 + META file, but with enhanced syntax). This allows it to describe 521 + intra-package dependencies.</p> 522 + 523 + <p>Predicates in META files can be negated.</p> 524 + 525 + <p>The "error" variable allows you to detect conditions under which 526 + the library would not work, and to generate error messages.</p> 527 + 528 + <p>It is possible to refer to archive files installed in other 529 + packages.</p> 530 + 531 + <p>The set of predicates is extended by "package predicates" 532 + after the dependency analysis, making conditions expressible that 533 + depend on whether other packages are selected.</p> 534 + 535 + <p>The "+=" operator in META files adds words to variables rather 536 + than setting them.</p> 537 + 538 + <p>The "#thread" directive enables multi-threading in toploops and 539 + scripts, if possible.</p> 540 + 541 + <p>The "#predicates" directive simplifies the addition of predicates. 542 + </p> 543 + 544 + <p>Queries: The format specifier %D prints the description of 545 + the package. -long-format includes the description. Short options 546 + -r, -l, -d.</p> 547 + 548 + <p>ocamlfind list -describe prints package descriptions.</p> 549 + 550 + <p>Support for "ocamlfind ocamldoc". However, the implementation is 551 + quite sloppy.</p> 552 + 553 + <p>The configuration file is called "findlib.conf" by default, 554 + not "ocamlfind.conf".</p> 555 + 556 + <p>Removal of "ocamlfind guess".</p> 557 + 558 + <p>Support for #use "findlib" and #use "ocamlfind" has been 559 + removed. The only remaining way to load findlib is by #use "topfind".</p> 560 + 561 + <p>There is no longer a thread-safe version of findlib. The user 562 + has to ensure that only one thread uses findlib (which is usually trivial 563 + to achieve).</p> 564 + 565 + <p>ocamlmktop: Directories are no longer automatically added 566 + to the search path. This did not work anyway, and this change forces 567 + scripts to always invoke "#require" to load/enable libraries, for 568 + better uniformity.</p> 569 + 570 + <p>Fixes: num-top works. "ocamlfind ocamlopt -thread" generates 571 + a better error message on non-POSIX systems. "ocamlfind query -descendants" 572 + takes predicates into account (it did not do that in previous versions of 573 + findlib).</p> 574 + </li> 575 + 576 + <li><p><em>0.9:</em> Changes for OCaml 3.07 (-thread, 577 + -vmthread). Includes Zack's toploop printers for bigints.</p> 578 + </li> 579 + 580 + <li><p><em>0.8 - 0.8.1:</em> Renamed a lot of modules to avoid name 581 + clashes with OCaml core modules. Cygwin: Additional option 582 + -cygpath for "configure". The man pages have a NAME 583 + section. Bugfix in Makefile wizard.</p> 584 + </li> 585 + 586 + <li><p><em>0.7 - 0.7.2:</em> DLLs: There are now two styles of 587 + installation: DLLs can be installed in the package 588 + directories (like before), or in a shared directory 589 + "stublibs". For the first style, there is now an option 590 + "ldconf" that determines whether the ld.conf file is to be 591 + updated, and if so, which file. The latter style is enabled 592 + by simply creating a directory "stublibs" in the site-lib 593 + directory. (In the first version the directory was called 594 + "libexec". By user request, the name of the DLL directory 595 + has been changed to "stublibs".)</p> 596 + 597 + <p>"ocamlfind install" preserves now the mtime of the files.</p> 598 + 599 + <p>"ocamlfind printconf" is more flexible, and easier to call 600 + from scripts.</p> 601 + 602 + <p>"ocamlfind browser" calls ocamlbrowser with the right -I 603 + options.</p> 604 + 605 + <p>"ocamlfind query": -descendants implies now -recursive.</p> 606 + 607 + <p>"ocamlfind ocamldep": -native-filter and -bytecode-filter for more 608 + exact dependency generation.</p> 609 + 610 + <p>There may be now postinstall and postremove scripts.</p> 611 + 612 + <p>"ocamlfind pkg/cmd": This syntax can be used to call the program cmd 613 + that is installed in the package directory for pkg. Intended to 614 + simplify the invocation of programs that are installed in package 615 + directories and not in XXX/bin, which may be useful for package- 616 + related tools.</p> 617 + 618 + <p>Findlib has now a toolbox containing helpful programs besides 619 + ocamlfind. For the beginning, there is a Makefile wizard that 620 + can be called by "ocamlfind findlib/make_wizard".</p> 621 + 622 + <p>#use "topfind" instead of #use "findlib" to avoid name clashes 623 + in a certain configuration. #use "findlib" and #use "ocamlfind" 624 + are still supported for backward compatibility if the name clash 625 + does not occur.</p> 626 + 627 + <p>Fix: bytecode threads work again. (The wrong unix library was 628 + linked for recent OCaml versions.)</p> 629 + 630 + <p>Many smaller improvements; the docs have been updated.</p> 631 + </li> 632 + 633 + <li><p><em>0.6 - 0.6.2:</em> Minor changes for Ocaml-3.03-alpha 634 + (and later for 3.04). New #list directive. New: #use 635 + "findlib" loads the findlib directives into every toploop 636 + (Ocaml-3.03-alpha).</p> 637 + 638 + <p>The file ld.conf is automatically updated when DLLs are 639 + installed or removed.</p> 640 + 641 + <p>Fix: /tmp/findlib_initf* no longer overflows. The thread 642 + library is now always the first linked library.</p> 643 + </li> 644 + 645 + <li><p><em>0.5 - 0.5.4:</em> Findlib has now a configuration 646 + file (see documentation under findlib.conf). Much more 647 + environment variables. The location of the standard library is 648 + now configurable at runtime. 649 + </p> 650 + 651 + <p>The package search path can now be selected independently 652 + of the package installation directory.</p> 653 + 654 + <p>New commands: ocamlfind list, ocamlfind printconf, ocamlfind guess 655 + (See documentation under ocamlfind)</p> 656 + 657 + <p>Optional alternate directory layout: All META files go into 658 + a separate directory (see documentation under site-lib).</p> 659 + 660 + <p>Findlib works now only for OCaml 3; support for OCaml 2 has been 661 + dropped. As a consequence, the "configure" script could be 662 + simplified; it is no longer necessary to figure out the 663 + linker options.</p> 664 + 665 + <p>Improved support for camlp4: New directives #camlp4o and 666 + #camlp4r for the toploop.</p> 667 + 668 + <p>ocamlfind now detects whether two selected packages have 669 + equally named toplevel modules, and prints a warning in this case.</p> 670 + 671 + <p>There is a downstripped version ocamlfind-mini (see directory 672 + "mini"). This is a one-file script that can be easily 673 + distributed with any software. ocamlfind-mini has reduced 674 + functionality, but it is sufficient to compile and install a 675 + library. (But it does not support using a library.)</p> 676 + 677 + <p>Support for the Cygwin port of OCaml.</p> 678 + 679 + <p>Installation of packages: The file permissions are 680 + preserved when files are installed. However, the umask is 681 + applied. The "install" and "remove" subcommands have better 682 + diagnostics.</p> 683 + 684 + <p>ocamlfind ocamlmktop: Generates now initialization code for the 685 + include path. You don't need to call your toploop with -I 686 + options any more. Furthermore, this fixes some problems with 687 + packages that add printers to the toploop.</p> 688 + 689 + <p>New: ocamlfind ocamldep. ocamlfind is now prepared for the new 690 + -pp option of ocamldep (upcoming Ocaml 3.03).</p> 691 + 692 + <p>Installation of findlib: New PREFIX variable in Makefile to 693 + install locally.</p> 694 + 695 + <p>Fixes: itest. ocamlfind query -descendants works again.</p> 696 + </li> 697 + 698 + <li><p><em>0.4:</em> Experimental support for camlp4 (see FAQ 699 + section in the manual). New environment variable 700 + OCAMLFIND_COMMANDS (see ocamlfind(1)). 701 + </p> 702 + </li> 703 + 704 + <li><p><em>0.3 - 0.3.1:</em> Necessary updates for OCaml 705 + 3. Bugfix: Findlib did not work for bytecode threads. The reason was 706 + that findlib added the directory of the stdlib to the search 707 + path. Works now. 708 + </p> 709 + </li> 710 + 711 + </ul> 712 + <p>Older changes are no longer documented.</p> 713 + </sect1> 714 + </readme>
+353
vendor/opam/ocamlfind/doc/common.xml
··· 1 + <?xml encoding="ISO-8859-1"?> 2 + 3 + <!-- ************************************************************ --> 4 + <!-- EXTERNAL URLs --> 5 + <!-- ************************************************************ --> 6 + 7 + <!ENTITY url.ocaml 8 + "http://caml.inria.fr/"> 9 + 10 + <!ENTITY url.ocaml.org 11 + "http://www.ocaml.org/"> 12 + 13 + <!ENTITY url.ocaml.list 14 + "http://caml.inria.fr/caml-list-eng.html"> 15 + 16 + <!ENTITY url.ocaml.download 17 + "ftp://ftp.inria.fr/lang/caml-light/"> 18 + 19 + <!ENTITY url.ocaml.camlp4 20 + "http://caml.inria.fr/camlp4/"> 21 + 22 + <!ENTITY url.ocaml.hump 23 + "http://caml.inria.fr/humps/"> 24 + 25 + <!ENTITY url.ocaml.mottl 26 + "http://www.ai.univie.ac.at/~markus/home/ocaml_sources.html"> 27 + 28 + <!ENTITY url.ocaml.mottl.pcre 29 + "http://www.ai.univie.ac.at/~markus/home/ocaml_sources.html#toc11"> 30 + 31 + <!ENTITY url.ocaml.lindig 32 + "http://www.gaertner.de/~lindig/software/"> 33 + 34 + <!-- 35 + <!ENTITY url.ocaml.lindig.ocmarkup 36 + "http://www.cs.tu-bs.de/softech/people/lindig/software/ocmarkup.html"> 37 + --> 38 + 39 + <!ENTITY url.ocaml.lindig.tony 40 + "http://www.gaertner.de/~lindig/software/tony.html"> 41 + 42 + <!ENTITY url.ocaml.filliatre 43 + "http://www.lri.fr/~filliatr/software.en.html"> 44 + 45 + <!ENTITY url.ocaml.filliatre.cgi 46 + "http://www.lri.fr/~filliatr/ftp/ocaml/cgi/"> 47 + 48 + <!ENTITY url.ocaml.frisch 49 + "http://www.eleves.ens.fr:8080/home/frisch/soft"> 50 + 51 + <!ENTITY url.ocaml.guesdon.ocamlodbc 52 + "http://pauillac.inria.fr/~guesdon/Tools/ocamlodbc/ocamlodbc.html"> 53 + 54 + <!ENTITY url.xml-spec 55 + "http://www.w3.org/TR/1998/REC-xml-19980210.html"> 56 + 57 + <!ENTITY url.xml.oasis 58 + "http://www.oasis-open.org/cover/"> 59 + 60 + <!ENTITY url.xml.w3c 61 + "http://www.w3c.org/XML/"> 62 + 63 + <!ENTITY url.jclark-xmltdata 64 + "ftp://ftp.jclark.com/pub/xml/xmltest.zip"> 65 + 66 + <!ENTITY urlprefix.ietf.rfc 67 + "http://www.ietf.org/rfc"> 68 + <!-- Ohne "/" am Ende! --> 69 + 70 + <!ENTITY url.apache 71 + "http://www.apache.org/"> 72 + 73 + <!ENTITY url.apache.cgi-howto 74 + "http://httpd.apache.org/docs/howto/cgi.html"> 75 + 76 + <!ENTITY url.apache.suexec 77 + "http://httpd.apache.org/docs/suexec.html"> 78 + 79 + <!ENTITY url.apache.jserv 80 + "http://java.apache.org/"> 81 + 82 + <!ENTITY url.apache.jakarta 83 + "http://jakarta.apache.org/"> 84 + 85 + <!ENTITY url.unixodbc 86 + "http://www.unixodbc.org"> 87 + 88 + <!-- ************************************************************ --> 89 + <!-- MY URLs --> 90 + <!-- ************************************************************ --> 91 + 92 + <!ENTITY url.linkdb 93 + "http://links.camlcity.org"> 94 + 95 + <!ENTITY url.svn 96 + "https://godirepo.camlcity.org/"> 97 + 98 + <!ENTITY url.mailman 99 + "https://godirepo.camlcity.org/mailman"> 100 + 101 + <!ENTITY url.pipermail 102 + "https://godirepo.camlcity.org/pipermail"> 103 + 104 + <!ENTITY mail.godi-list 105 + "godi-list@ocaml-programming.de"> 106 + 107 + <!ENTITY url.godi-list-info 108 + "&url.mailman;/listinfo/godi-list"> 109 + 110 + <!ENTITY url.godi-list-archives 111 + "&url.pipermail;/godi-list"> 112 + 113 + <!-- ************************************************************ --> 114 + <!-- HOMEPAGE URLs --> 115 + <!-- ************************************************************ --> 116 + 117 + <!-- GENERIC --> 118 + 119 + <!ENTITY url.gps-ocaml-download 120 + "http://download.camlcity.org/download"> 121 + 122 + <!ENTITY url.gps-ocaml-download-byte 123 + "/download/bytecode"> 124 + 125 + <!ENTITY url.gps-old-download 126 + "http://www.gerd-stolpmann.de/download"> 127 + 128 + <!ENTITY url.gps-prog 129 + "/archive/programming"> 130 + 131 + <!-- SPECIFIC --> 132 + 133 + <!ENTITY url.portal-img 134 + "/files"> 135 + 136 + 137 + <!ENTITY release.javacaml 138 + "1998"> 139 + 140 + <!ENTITY url.javacaml-download 141 + "/archive/javacaml/download/"> 142 + 143 + <!ENTITY url.javacaml-project 144 + "/archive/javacaml/"> 145 + 146 + 147 + 148 + <!ENTITY release.ocamldb 149 + "0.2"> 150 + 151 + <!ENTITY url.ocamldb-download 152 + "&url.gps-ocaml-download;/ocamldb.tgz"> 153 + 154 + <!ENTITY url.ocamldb-project 155 + "&url.gps-ocaml-projects;/ocamldb/"> 156 + 157 + 158 + 159 + <!ENTITY release.findlib 160 + "1.5"> 161 + 162 + <!ENTITY url.findlib-download 163 + "&url.gps-ocaml-download;/findlib-&release.findlib;.tar.gz"> 164 + 165 + <!ENTITY url.findlib-project 166 + "/projects/findlib.html"> 167 + 168 + <!ENTITY url.findlib-readme 169 + "/projects/dl/findlib-&release.findlib;/doc/README"> 170 + 171 + <!ENTITY url.findlib-intro 172 + "/projects/findlib.html"> 173 + 174 + <!ENTITY url.findlib-manual 175 + "/projects/dl/findlib-&release.findlib;/doc/guide-html/index.html"> 176 + 177 + <!ENTITY url.findlib-quickstart 178 + "/projects/dl/findlib-&release.findlib;/doc/QUICKSTART"> 179 + 180 + 181 + 182 + <!ENTITY release.findlib-browser 183 + "0.2.2"> 184 + 185 + <!ENTITY url.findlib-browser-download 186 + "&url.gps-ocaml-download;/findlib-browser-&release.findlib-browser;.tar.gz"> 187 + 188 + <!ENTITY url.findlib-browser-project 189 + "/projects/findlib-browser.html"> 190 + 191 + 192 + 193 + <!ENTITY release.cryptgps 194 + "0.2.1"> 195 + 196 + <!ENTITY url.cryptgps-download 197 + "&url.gps-ocaml-download;/cryptgps-&release.cryptgps;.tar.gz"> 198 + 199 + <!ENTITY url.cryptgps-project 200 + "/projects/cryptgps.html"> 201 + 202 + 203 + 204 + <!ENTITY release.db2man 205 + "0.1"> 206 + 207 + <!ENTITY url.db2man-download 208 + "&url.gps-ocaml-download;/db2man-&release.db2man;.tar.gz"> 209 + 210 + <!ENTITY url.db2man-project 211 + "/projects/db2man.html"> 212 + 213 + 214 + 215 + <!ENTITY release.xstr 216 + "0.2.1"> 217 + 218 + <!ENTITY url.xstr-download 219 + "&url.gps-ocaml-download;/xstr-&release.xstr;.tar.gz"> 220 + 221 + <!ENTITY url.xstr-project 222 + "/projects/xstr.html"> 223 + 224 + 225 + 226 + <!ENTITY release.xstrp4 227 + "1.7"> 228 + 229 + <!ENTITY url.xstrp4-download 230 + "&url.gps-ocaml-download;/xstrp4-&release.xstrp4;.tar.gz"> 231 + 232 + <!ENTITY url.xstrp4-project 233 + "/projects/xstrp4.html"> 234 + 235 + 236 + <!ENTITY url.markup-tamara 237 + "http://www.ocaml-programming.de/markup/"> 238 + 239 + 240 + 241 + <!ENTITY release.pxp 242 + "1.1.6"> 243 + 244 + <!ENTITY release.pxp-dev 245 + "1.2.0test2"> 246 + 247 + <!ENTITY url.pxp-download 248 + "&url.gps-ocaml-download;/pxp-&release.pxp;.tar.gz"> 249 + 250 + <!ENTITY url.pxp-download-dev 251 + "&url.gps-ocaml-download;/pxp-&release.pxp-dev;.tar.gz"> 252 + 253 + <!ENTITY url.pxp-project 254 + "/projects/pxp.html"> 255 + 256 + <!ENTITY url.pxp-project-dev 257 + "/projects/pxp.html"> 258 + 259 + <!ENTITY url.pxp-intro 260 + "/projects/pxp.html"> 261 + 262 + <!ENTITY url.pxp-manual 263 + "/projects/dl/pxp-1.1.6/doc/manual/html/index.html"> 264 + 265 + <!ENTITY url.pxp-relnotes 266 + "/projects/dl/pxp-1.1.6/doc/RELEASE-NOTES"> 267 + 268 + <!ENTITY url.pxp-list 269 + "http://www.orcaware.com/mailman/listinfo/ocaml-pxp-users"> 270 + 271 + 272 + 273 + <!ENTITY release.ocamlnet 274 + "2.2.9"> 275 + 276 + <!ENTITY url.ocamlnet-download 277 + "&url.gps-ocaml-download;/ocamlnet-&release.ocamlnet;.tar.gz"> 278 + 279 + <!ENTITY url.ocamlnet-home 280 + "/projects/ocamlnet.html"> 281 + 282 + <!ENTITY url.ocamlnet-project 283 + "/projects/ocamlnet.html"> 284 + 285 + <!ENTITY url.ocamlnet-intro 286 + "/projects/ocamlnet.html"> 287 + 288 + <!ENTITY url.ocamlnet-manual 289 + "/projects/dl/ocamlnet-2.2.9/doc/html-main/index.html"> 290 + 291 + <!ENTITY url.ocamlnet-refmanual 292 + "&url.ocamlnet-manual;"> 293 + 294 + <!ENTITY url.netstring-project 295 + "&url.ocamlnet-project;"> 296 + 297 + 298 + 299 + <!ENTITY release.wtimer 300 + "1.0"> 301 + <!ENTITY url.wtimer-download 302 + "&url.gps-ocaml-download;/wtimer-&release.wtimer;.tar.gz"> 303 + <!ENTITY url.wtimer-project 304 + "/projects/wtimer.html"> 305 + 306 + 307 + <!ENTITY url.wdialog-project 308 + "/projects/wdialog.html"> 309 + 310 + <!ENTITY url.wdialog-intro 311 + "/projects/wdialog.html"> 312 + 313 + 314 + <!ENTITY url.godi-home 315 + "/godi"> 316 + <!ENTITY release.godi 317 + "20061228"> 318 + <!ENTITY url.godi-download 319 + "&url.gps-ocaml-download;/godi-bootstrap-&release.godi;.tar.gz"> 320 + <!ENTITY url.godi-intro 321 + "/godi"> 322 + 323 + <!ENTITY url.godi-build 324 + "http://www.ocaml-programming.de/godi-build/"> 325 + 326 + <!ENTITY url.dev-server 327 + "https://gps.dynxs.de/"> 328 + 329 + 330 + <!ENTITY release.godi-tools 331 + "1.5.3"> 332 + <!ENTITY url.godi-tools-download 333 + "&url.gps-ocaml-download;/godi-tools-&release.godi-tools;.tar.gz"> 334 + 335 + 336 + <!-- Smaller things (patches etc.) --> 337 + 338 + <!ENTITY url.str-patch-download 339 + "&url.gps-ocaml-download;/str-2.04.patch"> 340 + 341 + 342 + <!ENTITY url.linkdb-download 343 + "&url.gps-ocaml-download;/linkdb-2001-07-10.tar.gz"> 344 + 345 + 346 + <!-- ************************************************************ --> 347 + <!-- MAIL URLs --> 348 + <!-- ************************************************************ --> 349 + 350 + <!ENTITY person.gps '<a href="mailto:&person.gps.mail;">Gerd Stolpmann</a>'> 351 + 352 + <!ENTITY person.gps.mail 353 + "gerd@gerd-stolpmann.de">
+22
vendor/opam/ocamlfind/doc/config.xml
··· 1 + <?xml version="1.0" encoding="ISO-8859-1"?> 2 + 3 + <!ENTITY % readme:html:previous '&nbsp;'> 4 + <!ENTITY % readme:html:up '&nbsp;'> 5 + <!ENTITY % readme:html:next '&nbsp;'> 6 + 7 + <!ENTITY % bar 8 + '<table bgcolor="lightgrey" width="100&#37;" 9 + cellspacing="0" border="0" cellpadding="10"> 10 + <tr><td align="left">%readme:html:previous;</td> 11 + <td align="center">%readme:html:up;</td> 12 + <td align="right">%readme:html:next;</td> 13 + </tr></table>'> 14 + 15 + <!ENTITY % readme:html:header 16 + "%bar;<hr>"> 17 + 18 + <!ENTITY % readme:html:trailer 19 + "<hr>%bar;"> 20 + 21 + 22 + <!ENTITY % readme:html:textcolor "black">
+38
vendor/opam/ocamlfind/doc/readme.dtd
··· 1 + <!-- $Id --> 2 + 3 + <!ENTITY % p.like "p|ul"> 4 + <!ENTITY % text "br|code|em|footnote|a"> 5 + 6 + <!ELEMENT readme (sect1+)> 7 + <!ATTLIST readme 8 + title CDATA #REQUIRED> 9 + 10 + <!ELEMENT sect1 (title,(sect2|%p.like;)+)> 11 + 12 + <!ELEMENT sect2 (title,(sect3|%p.like;)+)> 13 + 14 + <!ELEMENT sect3 (title,(%p.like;)+)> 15 + 16 + <!ELEMENT title (#PCDATA|br)*> 17 + 18 + <!ELEMENT p (#PCDATA|%text;)*> 19 + 20 + <!ELEMENT br EMPTY> 21 + 22 + <!ELEMENT code (#PCDATA)> 23 + 24 + <!ELEMENT em (#PCDATA|%text;)*> 25 + 26 + <!ELEMENT ul (li+)> 27 + 28 + <!ELEMENT li (%p.like;)*> 29 + 30 + <!ELEMENT footnote (#PCDATA|%text;)*> 31 + 32 + <!ELEMENT a (#PCDATA)*> 33 + <!ATTLIST a 34 + href CDATA #IMPLIED 35 + readmeref CDATA #IMPLIED 36 + > 37 + 38 +
+24
vendor/opam/ocamlfind/doc/src/findlib.dsl
··· 1 + <!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [ 2 + <!ENTITY dbstyle SYSTEM "docbook.dsl" CDATA DSSSL> 3 + ]> 4 + 5 + <style-sheet> 6 + <style-specification use="docbook"> 7 + <style-specification-body> 8 + 9 + (define %footnotes-at-end% 10 + ;; Should footnotes appear at the end of HTML pages? 11 + #t) 12 + 13 + (define %html-ext% 14 + ;; Default extension for HTML output files 15 + ".html") 16 + 17 + (define %root-filename% 18 + ;; Name for the root HTML document 19 + "index") 20 + 21 + </style-specification-body> 22 + </style-specification> 23 + <external-specification id="docbook" document="dbstyle"> 24 + </style-sheet>
+2476
vendor/opam/ocamlfind/doc/src/findlib.sgml
··· 1 + <!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ 2 + <!ENTITY findlibmeta SYSTEM "findlib_meta.mod"> 3 + <!ENTITY findlibsitelib SYSTEM "findlib_sitelib.mod"> 4 + <!ENTITY findlibmli SYSTEM "findlib_mli.mod"> 5 + <!ENTITY findlibtopfind SYSTEM "findlib_topfind.mod"> 6 + <!ENTITY findlibocamlfind SYSTEM "findlib_ocamlfind.mod"> 7 + <!ENTITY findlibconf SYSTEM "findlib_conf.mod"> 8 + <!ENTITY % gps.common SYSTEM "../common.xml"> 9 + %gps.common; 10 + ]> 11 + 12 + <book> 13 + 14 + <title>The findlib User's Guide</title> 15 + <bookinfo> 16 + <!-- <bookbiblio> --> 17 + <authorgroup> 18 + <author> 19 + <firstname>Gerd</firstname> 20 + <surname>Stolpmann</surname> 21 + <authorblurb> 22 + <para> 23 + <address> 24 + <email>gerd@gerd-stolpmann.de</email> 25 + </address> 26 + </para> 27 + </authorblurb> 28 + </author> 29 + </authorgroup> 30 + 31 + <copyright> 32 + <year>1999-2014</year><holder>Gerd Stolpmann</holder> 33 + </copyright> 34 + <!-- </bookbiblio> --> 35 + 36 + <abstract> 37 + <para> 38 + The "findlib" library provides a scheme to manage reusable software 39 + components (packages), and includes tools that support this 40 + scheme. Packages are collections of OCaml modules for which 41 + metainformation can be stored. The packages are kept in the filesystem 42 + hierarchy, but with strict directory structure. The library contains 43 + functions to look the directory up that stores a package, to query 44 + metainformation about a package, and to retrieve dependency 45 + information about multiple packages. There is also a tool that allows 46 + the user to enter queries on the command-line. In order to simplify 47 + compilation and linkage, there are new frontends of the various OCaml 48 + compilers that can directly deal with packages. 49 + </para> 50 + 51 + <para> 52 + Together with the packages metainformation is stored. This includes a 53 + version string, the archives the package consists of, and additional 54 + linker options. Packages can also be dependent on other 55 + packages. There is a query which finds out all predecessors of a list 56 + of packages and sorts them topologically. The new compiler frontends 57 + do this implicitly. 58 + </para> 59 + 60 + <para> 61 + Metainformation can be conditional, i.e. depend on a set of 62 + predicates. This is mainly used to be able to react on certain 63 + properties of the environment, such as if the bytecode or the native 64 + compiler is invoked, if the application is multi-threaded, and a few 65 + more. If the new compiler frontends are used, most predicates are 66 + found out automatically. 67 + </para> 68 + 69 + <para> 70 + There is special support for scripts. A new directive, "#require", 71 + loads packages into scripts. 72 + </para> 73 + 74 + <formalpara> 75 + <title>Download findlib</title> 76 + <para> 77 + This manual describes version &release.findlib; of the software 78 + package. It can be downloaded at 79 + <ulink URL="&url.gps-ocaml-download;"> 80 + &url.gps-ocaml-download; 81 + </ulink>. The user's guide and the reference manual are included. 82 + Newest releases of "findlib" will be announced in 83 + <ulink URL="&url.linkdb;">The OCaml Link 84 + Database</ulink>. 85 + </para> 86 + </formalpara> 87 + 88 + <formalpara> 89 + <title>Quickstart</title> 90 + <para> 91 + See also the <ulink URL="&url.findlib-quickstart;">Quickstart page</ulink> 92 + for instructions for the most common 93 + cases.</para> 94 + </formalpara> 95 + </abstract> 96 + 97 + <legalnotice> 98 + <title>License</title> 99 + <para> 100 + This document, and the described software, "findlib", are copyright by 101 + Gerd Stolpmann. 102 + </para> 103 + 104 + <para> 105 + Permission is hereby granted, free of charge, to any person obtaining 106 + a copy of this document and the "findlib" software (the 107 + "Software"), to deal in the Software without restriction, including 108 + without limitation the rights to use, copy, modify, merge, publish, 109 + distribute, sublicense, and/or sell copies of the Software, and to 110 + permit persons to whom the Software is furnished to do so, subject to 111 + the following conditions: 112 + </para> 113 + 114 + <para> 115 + The above copyright notice and this permission notice shall be included 116 + in all copies or substantial portions of the Software. 117 + </para> 118 + 119 + <para> 120 + The Software is provided ``as is'', without warranty of any kind, express 121 + or implied, including but not limited to the warranties of 122 + merchantability, fitness for a particular purpose and noninfringement. 123 + In no event shall Gerd Stolpmann be liable for any claim, damages or 124 + other liability, whether in an action of contract, tort or otherwise, 125 + arising from, out of or in connection with the Software or the use or 126 + other dealings in the software. 127 + </para> 128 + </legalnotice> 129 + 130 + </bookinfo> 131 + 132 + 133 + 134 + <!-- ********************************************************************** --> 135 + 136 + 137 + 138 + <part> 139 + <title>User's Guide</title> 140 + 141 + <chapter> 142 + <title>Libraries and Packages</title> 143 + 144 + <para> Reusability is one of the keywords in software engineering 145 + today. It simply means to have source code that can be shared by 146 + several programs. Usually, modules are combined to libraries, and the 147 + library archive files can be linked into programs. As the idea might 148 + be simple, its practical implementation is complex because sharing of 149 + source code has an impact on all steps and phases in software 150 + production. This document only addresses the following administrative 151 + problems: 152 + </para> 153 + 154 + <itemizedlist mark="bullet" spacing="compact"> 155 + <listitem> 156 + <para> 157 + Storing the libraries in file hierarchies 158 + </para> 159 + </listitem> 160 + 161 + <listitem> 162 + <para> 163 + Compiling and linking programs using such libraries 164 + </para> 165 + </listitem> 166 + 167 + <listitem> 168 + <para> 169 + Managing dependencies between libraries 170 + </para> 171 + </listitem> 172 + </itemizedlist> 173 + 174 + <para> 175 + Objective Caml has a variety of language means to support 176 + reusability. Most important, polymorphic functions can be written 177 + which generalize the types of input arguments and the 178 + type of the result value. There are many examples in the core library 179 + such that I assume that the reader is familiar with this 180 + feature. Second, modules and functors must be mentioned which not only 181 + generalize types of values, but can even generalize structures, 182 + i.e. types with associated operations. Third, the class construct 183 + allows us to adopt the object-oriented techniques of abstraction such 184 + as inheritance and dynamic method lookup. 185 + </para> 186 + 187 + <para> 188 + In the following, we are only analyzing the problem of making and 189 + using libraries from a purely software-technical point of view. This 190 + means, we ignore how to make functions polymorphic, and how to create 191 + functors and classes. Instead, we only look at how to invoke the 192 + OCaml compiler to create, manage, and use libraries. Especially, we 193 + are interested in the administration of systems of libraries that 194 + have dependencies.</para> 195 + 196 + <para> 197 + One of the complex operations on such a system is the replacement of 198 + a library by a newer version. Because of the strict compatibility 199 + checks of OCaml, it is usually necessary to rebuild and reinstall 200 + all dependent libraries as well. With the help of findlib, one can 201 + find out which are the dependent libraries. (However, findlib does 202 + not provide a framework to rebuild them. For example, the GODI 203 + system includes such a framework.) 204 + </para> 205 + 206 + <para> 207 + The library is also called a "package" when it is seen as a removable 208 + and replaceable set of files. Findlib requires that there is a 209 + certain directory structure; it is not possible to install the files 210 + at arbitrary places (findlib does not even maintain a file list). 211 + For simplicity, every library is usually stored into its own 212 + directory, i.e. the library archive files and the interface files. 213 + </para> 214 + 215 + <para>From the perspective of the compiler, the library is made 216 + accessible by adding the package directory to the search path 217 + of the compiler. By doing so, the modules of the library are 218 + added to the namespace universe, and thus can be opened by 219 + modules using them. This means that the approach "one package 220 + = one directory" can be naturally translated into language 221 + operations modifying the namespace scope.</para> 222 + 223 + <para> 224 + When linking a program, it must be specified which link operation is 225 + necessary to use a certain library. Often, only a single archive file 226 + needs to be linked in, but sometimes additional archives or system 227 + libraries must be linked, too. Furthermore, the link operations 228 + often depends on certain conditions, e.g. whether a single- or 229 + multi-threaded program is being created. 230 + </para> 231 + 232 + <para> 233 + The <emphasis>findlib</emphasis> library is my suggestion for a 234 + package manager suitable for Objective Caml. It is a library (stored 235 + as a package itself) which can answer the following questions: 236 + </para> 237 + 238 + <itemizedlist mark="bullet" spacing="compact"> 239 + <listitem> 240 + <para>If I want to use a package, which is the directory containing 241 + the compiled interfaces and implementations? - The package directory 242 + may vary from system to system, and this feature makes it easier to 243 + write Makefiles that run everywhere. Furthermore, OCaml can load 244 + modules dynamically, and it is not a good practice to compile in the 245 + location of such modules. The better way is to ask findlib where the 246 + module resides today. 247 + </para> 248 + </listitem> 249 + 250 + <listitem> 251 + <para>Which other packages must be linked in, too, if I want to use a 252 + certain package? 253 + </para> 254 + </listitem> 255 + 256 + <listitem> 257 + <para>Which archives need to be linked in, and which compiler options 258 + are necessary? 259 + </para> 260 + </listitem> 261 + 262 + <listitem> 263 + <para>If there is a version of the archive with additional properties, 264 + which file should I use? - Additional properties are at least: 265 + Thread-safety, using POSIX threads, and being gprof-enabled. It is 266 + simple to add more criterions. 267 + </para> 268 + </listitem> 269 + </itemizedlist> 270 + 271 + 272 + <para> 273 + Furthermore, there is a frontend for this library called 274 + <emphasis>ocamlfind</emphasis>. It is a command-line interface for the 275 + library, but has also some additional abilities: 276 + </para> 277 + 278 + 279 + <itemizedlist mark="bullet" spacing="compact"> 280 + <listitem> 281 + <para>It can invoke ocamlc, ocamlopt, ocamlmktop, and ocamlcp such 282 + that compiler arguments necessary to use a package or link it in are 283 + automatically added. 284 + </para> 285 + </listitem> 286 + 287 + <listitem> 288 + <para>It can install and uninstall packages. 289 + </para> 290 + </listitem> 291 + 292 + <listitem> 293 + <para>It can find out dependent packages. 294 + </para> 295 + </listitem> 296 + </itemizedlist> 297 + 298 + <para> 299 + As you'll see in the following chapters, the usage of this library is 300 + really simple. If you want only to link in packages written by other 301 + people, you must only change the command that invokes the compiler, 302 + e.g. instead of calling "ocamlc program.ml" invoke "ocamlfind ocamlc 303 + -package name_of_package_to_use -linkpkg program.ml", and you can 304 + refer to the named package within program.ml. If you want to turn your 305 + collection of modules into a package, you need only to write one 306 + administrative file (META) containing all extra information such as 307 + required other packages. 308 + </para> 309 + 310 + 311 + </chapter> 312 + 313 + <!-- ********************************************************************** --> 314 + 315 + <chapter> 316 + <title>Using packages</title> 317 + 318 + <sect1> 319 + <title>Listing the installed packages</title> 320 + 321 + <para> 322 + You can list which packages are installed by executing 323 + 324 + <programlisting> 325 + ocamlfind list 326 + </programlisting> 327 + 328 + You will get a list of names and version numbers. You can get a bit 329 + more information by passing the -describe option: 330 + 331 + <programlisting> 332 + ocamlfind list -describe 333 + </programlisting> 334 + </para> 335 + </sect1> 336 + 337 + 338 + <sect1> 339 + <title>Looking up package directories</title> 340 + 341 + <para> 342 + The package manager knows the preferred location for packages (this 343 + location is compiled in), which is usually 344 + /usr/local/lib/ocaml/site-lib. You can ask the package manager where 345 + package p is stored by simply typing 346 + </para> 347 + 348 + <programlisting> 349 + ocamlfind query p 350 + </programlisting> 351 + 352 + <para> 353 + and it will answer something like 354 + </para> 355 + 356 + <programlisting> 357 + /usr/local/lib/ocaml/site-lib/p 358 + </programlisting> 359 + 360 + <para> 361 + There is an environment variable OCAMLPATH which can specify further 362 + directories where packages are stored. (The search order is: first 363 + the directories in OCAMLPATH in turn, then the default path 364 + set in ocamlfind.conf) 365 + </para> 366 + 367 + <para> 368 + Historically, this kind of query was the first and only way of using 369 + ocamlfind, and because of the similarity to the Unix find command it 370 + got its name. Finding out package locations is a basic but 371 + nethertheless important feature because it hides the details of the 372 + filesystem hierarchy. It is sufficient only to know the name of the 373 + package, and if needed, you can use the lookup mechanism implemented 374 + in ocamlfind to get the concrete directory. 375 + </para> 376 + </sect1> 377 + 378 + 379 + <sect1> 380 + <title>How a package directory looks like</title> 381 + 382 + <para> 383 + Let us assume that the package p implements the modules M1 and M2. If 384 + you compile m1.mli and m2.mli you get the corresponding binary files 385 + m1.cmi and m2.cmi describing the interfaces of the modules. Of course, 386 + these cmi files must go into the package directory. It is recommended 387 + to put the source mli files into the directory, too, as they document 388 + the interface. 389 + </para> 390 + 391 + <para> 392 + Another product of the compilation are two cmo files, m1.cmo and 393 + m2.cmo (we assume the bytecode compiler, the native compiler would 394 + create m1.cmx and m2.cmx). It is possible to put these files directly 395 + into the directory, but there is a better way. As it makes only sense 396 + to use both modules (a very common assumption), they should first be 397 + archived by doing 398 + </para> 399 + 400 + <programlisting> 401 + ocamlc -a -o p.cma m1.cmo m2.cmo 402 + </programlisting> 403 + 404 + <para> 405 + The archive p.cma contains both cmo files, and preserves the order of 406 + the files. Assumed that in M2 there is a reference to an entity in M1, 407 + M2 depends on M1 and when linking a program using these modules, M1 408 + must be mentioned first (e.g. ocamlc m1.cmo m2.cmo 409 + program.ml)<footnote><para>Note that C linkers usually require the reverse 410 + order, but only for archive elements, i.e. files with suffix 411 + .a.</para></footnote>. If you create the archive p.cma it contains already 412 + this dependency, and you need not to remember it when linking in the 413 + p.cma. 414 + </para> 415 + 416 + <para> 417 + So far the files m1.cmi, m2.cmi, and p.cma are needed, and m1.mli and 418 + m2.mli are recommended. Usually there is another file in the 419 + directory, META, containing additional information about the package. 420 + In our example, META looks like 421 + </para> 422 + 423 + <programlisting> 424 + description = "Our super-duper package" 425 + requires = "" 426 + version = "1" 427 + archive(byte) = "p.cma" 428 + </programlisting> 429 + 430 + <para>The variable "requires" contains a list of packages that are 431 + required by this package (the names may be separated by commas or 432 + spaces). As our package, p, does not depend on any other package, this 433 + list is empty. I'll explain what happens with non-empty lists below. 434 + </para> 435 + 436 + <para> 437 + The variable "version" is simply a version string, and "description" 438 + is a short comment on the package. 439 + </para> 440 + 441 + <para>The variable "archive" denotes the files that have to be 442 + actually linked in if the package is used. This is again a list of 443 + (file) names. In contrast to the other variables, "archive" has a 444 + condition, written in parentheses. This value of "archive" will only 445 + be used if the predicate "byte" is true; this predicate is usually 446 + given if the program is compiled to bytecode. If you have a native 447 + archive, p.cmxa, of the two modules M1 and M2, you can add another 448 + line to META: 449 + </para> 450 + 451 + <programlisting> 452 + archive(native) = "p.cmxa" 453 + </programlisting> 454 + 455 + <para> 456 + The correct value for the "archive" variable is selected upon the 457 + given set of predicates. 458 + </para> 459 + 460 + <para>Many packages can also be loaded at runtime with the 461 + <literal>Fl_dynload</literal> module. In this case, though, the 462 + variable "plugin" is used instead of "archive", e.g.</para> 463 + 464 + <programlisting> 465 + plugin(byte) = "p.cma" 466 + plugin(native) = "p.cmxs" 467 + </programlisting> 468 + 469 + <para>(You can create p.cmxs from p.cmxa with 470 + "ocamlopt -shared -linkall -o p.cmxs p.cmxa".) Note that "plugin" is entirely optional. 471 + </sect1> 472 + 473 + 474 + <sect1> 475 + <title>Querying information stored in META files</title> 476 + 477 + <para> 478 + By setting some options of ocamlfind you can query the variables from 479 + the META files. For example, -long-format (or short -l) selects all 480 + interesting variables: 481 + </para> 482 + 483 + <programlisting> 484 + ocamlfind query -long-format p 485 + </programlisting> 486 + 487 + <para> 488 + This would answer something like: 489 + </para> 490 + 491 + <programlisting> 492 + package: p 493 + description: Our super-duper package 494 + version: 1 495 + archive(s): 496 + linkopts: 497 + location: /usr/local/lib/ocaml/site-lib/p 498 + </programlisting> 499 + 500 + <para> 501 + The values of the "archive" variable are missing because no predicate 502 + has been set, without further options "ocamlfind query" operates with 503 + an empty set of predicates. To get the bytecode archive, run: 504 + </para> 505 + 506 + <programlisting> 507 + ocamlfind query -long-format -predicates byte p 508 + </programlisting> 509 + 510 + <para> 511 + You can set more than one predicate. It usually does not make sense, but 512 + you could for example select both bytecode and native archives by: 513 + </para> 514 + 515 + <programlisting> 516 + ocamlfind query -long-format -predicates byte,native p 517 + </programlisting> 518 + 519 + <para> 520 + As both settings for "archive" are now equally like, the extraction 521 + mechanism chooses simply the first. The general rule is that the first 522 + most special value is selected. 523 + </para> 524 + </sect1> 525 + 526 + 527 + <sect1> 528 + <title>How to compile and link a program that uses a package</title> 529 + 530 + <para> 531 + Now suppose you want to compile a program which calls functions of 532 + your new package p. If prog1.ml, prog2.ml, and prog3.ml are the three 533 + source files the program consists of, compile them with the commands 534 + </para> 535 + 536 + <programlisting> 537 + ocamlfind ocamlc -package p -c prog1.ml 538 + ocamlfind ocamlc -package p -c prog2.ml 539 + ocamlfind ocamlc -package p -c prog3.ml 540 + </programlisting> 541 + 542 + <para> 543 + The "ocamlfind ocamlc" invocation is a frontend to "ocamlc". Most 544 + arguments are directly passed to "ocamlc", but there are a few new 545 + options, and often some new options are implicitly added. Here, the 546 + new -package option is used, which adds search paths such that the 547 + modules of package p are found. Effectively, the following direct 548 + ocamlc invocations would be equivalent 549 + <footnote><para>If you specify the -verbose option, the constructed 550 + command is printed to the terminal. Actually, there are some more 551 + implicitly added options, especially -ccopt -I&lt;dir&gt; for every 552 + package directory &lt;dir&gt;. This means that you can compile C 553 + programs accessing header files stored in the package directory. 554 + </para></footnote>: 555 + </para> 556 + 557 + <programlisting> 558 + ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog1.ml 559 + ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog2.ml 560 + ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog3.ml 561 + </programlisting> 562 + 563 + <para> 564 + The -I option has the effect that the named directory is also searched 565 + when looking up cmi files. Because of this you can refer directly to 566 + the modules M1 and M2 in the program sources. 567 + </para> 568 + 569 + <para> 570 + In order to link the program use the following command: 571 + </para> 572 + 573 + <programlisting> 574 + ocamlfind ocamlc -o program -package p -linkpkg prog1.cmo prog2.cmo prog3.cmo 575 + </programlisting> 576 + 577 + <para> 578 + The -linkpkg option causes some more arguments to be added to the 579 + constructed ocamlc command. Especially, the name of the archive of p 580 + is extracted from the META file, and automatically inserted before the 581 + prog1.cmo argument. The resulting command looks like<footnote> 582 + <para>Again, the actual command contains even some more arguments... 583 + </para></footnote>: 584 + </para> 585 + 586 + <programlisting> 587 + ocamlc -o program -I /usr/local/lib/ocaml/site-lib/p p.cma prog1.cmo prog2.cmo prog3.cmo 588 + </programlisting> 589 + 590 + <para> 591 + Please note that the bytecode archive p.cma has been selected, and not 592 + the native archive p.cmxa. As it is known that the bytecode compiler 593 + is used, the predicate "byte" is automatically set. 594 + </para> 595 + 596 + </sect1> 597 + 598 + 599 + <sect1> 600 + <title>Dependencies</title> 601 + 602 + <para> 603 + Often packages use other packages themselves. Let q be another package 604 + consisting of the single module M3 which contains references to M1 and 605 + M2. At the first glance, we can ignore this when describing the 606 + package, as we could always add "-package p" and "-package q" options 607 + when compiling programs using q. This solution is not optimal, as the 608 + user of a package must have knowledge about details of the package that 609 + should normally be hidden. When we introduced the notion of packages, 610 + one of the most important properties was that we can replace packages 611 + by improved versions. Imagine that q is replaced by q', but q' uses 612 + not only p but also r. Every program that used q and is now forced to 613 + use q' must be changed (at least in the Makefile) in order to link r, 614 + too. This is clearly not what is intended by packages. 615 + </para> 616 + 617 + <para> 618 + The far better solution is to store dependency information in the META 619 + files. The "requires" variable can list names of packages that are 620 + direct ancestors, i.e. referred directly. (Do not put indirect 621 + ancestors into this variable, for example further packages required by 622 + r when describing q - these are found out automatically.) The META 623 + file of q looks like: 624 + </para> 625 + 626 + <programlisting> 627 + description = "Something that needs p" 628 + requires = "p" 629 + version = "1" 630 + archive(byte) = q.cma 631 + archive(native) = q.cmxa 632 + </programlisting> 633 + 634 + <para> 635 + If you want to put several package names into "requires", separate 636 + them with commas or spaces. 637 + </para> 638 + 639 + <para> 640 + The "ocamlfind query" command ignores the "requires" value by default, 641 + you must add the -recursive option. In this case, all direct or 642 + indirect ancestors of the packages given on the command line are 643 + selected, too, and printed in topological order. For example, the 644 + command 645 + </para> 646 + 647 + <programlisting> 648 + ocamlfind query -recursive -long-format -predicate byte q 649 + </programlisting> 650 + 651 + <para> 652 + prints two records: 653 + </para> 654 + 655 + <programlisting> 656 + package: p 657 + description: Our super-duper package 658 + version: 1 659 + archive(s): p.cma 660 + linkopts: 661 + location: /usr/local/lib/ocaml/site-lib/p 662 + 663 + package: q 664 + description: Something that needs p 665 + version: 1 666 + archive(s): q.cma 667 + linkopts: 668 + location: /usr/local/lib/ocaml/site-lib/p 669 + </programlisting> 670 + 671 + <para> 672 + Without -recursive, only q would have been printed. 673 + </para> 674 + 675 + <para> 676 + The compiler frontend provided with ocamlfind always works 677 + recursively. In order to compile and link another.ml that uses q, the 678 + following command is sufficient: 679 + </para> 680 + 681 + <programlisting> 682 + ocamlfind ocamlc -o another -package q -linkpkg another.ml 683 + </programlisting> 684 + 685 + <para> 686 + It is not necessary to specify -package p in this statement as the 687 + dependency relation is always used to find out the actually meant 688 + set of packages. 689 + </para> 690 + 691 + </sect1> 692 + 693 + 694 + <sect1> 695 + <title>Linker options</title> 696 + 697 + <para> 698 + <emphasis> 699 + Beginning with OCaml 3.00, the compiler itself has an interesting feature 700 + called "automatic linking" that makes the following mechanism superfluous in 701 + most cases. Automatic linking means that it is possible to store the linker 702 + options into the cma or cmxa file such that the compiler itself knows which 703 + options are necessary. Of course, the following mechanism still works, and it 704 + is still helpful when conditional linking is required. 705 + </emphasis> 706 + </para> 707 + 708 + <para> 709 + OCaml has a C interface which means that C libraries can be linked in 710 + and C functions can be declared as new language primitives. Using such 711 + libraries requires special linker options. Some of the core libraries 712 + distributed with OCaml are partly implemented in C and thus additional 713 + libraries must be specified in the linking phase of the program. 714 + </para> 715 + 716 + <para> 717 + For example, the "str" library providing regular expressions requires 718 + to be linked as follows: 719 + </para> 720 + 721 + <programlisting> 722 + ocamlc -o prog str.cma my_file1.cmo my_file2.cmo -cclib -lstr 723 + </programlisting> 724 + 725 + <para> 726 + The -cclib option passes the following argument directly to the 727 + underlying C linker which has the effect that libstr.a is linked in, 728 + too. The "-cclib -lstr" is directly associated with str.cma as the 729 + latter simply cannot be used without the former. Assume you would 730 + write a META file describing str. That "str.cma" should be linked in 731 + as archive is clear; the "-cclib -lstr" can be specified in another 732 + variable called "linkopts". The META file would look like: 733 + </para> 734 + 735 + <programlisting> 736 + requires = "" 737 + version = "str from ocaml 2.02" 738 + archive(byte) = "str.cma" 739 + archive(native) = "str.cmxa" 740 + linkopts = "-cclib -lstr" 741 + </programlisting> 742 + 743 + <para> 744 + This has the effect that specifying -linkpkg in one of the compiler 745 + frontends not only chooses one of the archive files, but also extracts 746 + the necessary linker options from the META file. The above example can 747 + also be compiled with: 748 + </para> 749 + 750 + <programlisting> 751 + ocamlfind ocamlc -o prog -package str -linkpkg my_file1.cmo my_file2.cmo 752 + </programlisting> 753 + 754 + <para> 755 + Most people will never write META files with "linkopts" settings. But 756 + this feature is very useful at least for the core libraries such as 757 + str. Because of this, the "findlib" distribution comes with META files 758 + for the core libraries in order to hide the linker options. This 759 + means that you can already use the packages "str", "dbm", "dynlink", 760 + "graphics", "num", "threads", "unix", and "camltk", and that the 761 + appropriate archives and linker options are automatically extracted. 762 + </para> 763 + 764 + </sect1> 765 + 766 + </chapter> 767 + 768 + <!-- ********************************************************************** --> 769 + 770 + <chapter> 771 + <title>Dependency analysis of packages</title> 772 + 773 + <sect1> 774 + <title>Querying ancestors</title> 775 + 776 + <para> 777 + Every package denotes in its META file only the list of direct 778 + ancestors. The theoretical model of the dependency relation is a 779 + directed acyclic graph (DAG), with the packages as vertices and edges 780 + from packages to their direct ancestors. The graph must be acyclic 781 + because OCaml does not allow cyclic dependencies between modules. 782 + </para> 783 + 784 + <para> 785 + What happens if you query something like 786 + </para> 787 + 788 + <programlisting> 789 + ocamlfind query -recursive p1 p2 ... pN 790 + </programlisting> 791 + 792 + <para> 793 + is that the named packages p1 to pN are marked in the graph, and that 794 + repeatedly all direct ancestors of marked packages are marked, too, 795 + until there is not any marked package remaining with an unmarked 796 + ancestor. All marked packages are then printed in topological 797 + order. This simply means that for the printed packages p1 to pM holds 798 + that if pI is printed before pJ then pI is a (possibly indirect) 799 + ancestor of pJ. 800 + </para> 801 + 802 + <para> 803 + The topological order plays a role when the link command is 804 + constructed by "ocamlfind ocamlc", as Ocaml requires that archives 805 + must be linked in topological order. For example, the link statement 806 + </para> 807 + 808 + <programlisting> 809 + ocamlfind ocamlc -o another -package q -linkpkg another.ml 810 + </programlisting> 811 + 812 + <para> 813 + must be turned into the effective command 814 + </para> 815 + 816 + <programlisting> 817 + ocamlc -o another [...more options...] p.cma q.cma another.ml 818 + </programlisting> 819 + 820 + <para> 821 + and <emphasis>not</emphasis> 822 + </para> 823 + 824 + <programlisting> 825 + ocamlc -o another [...more options...] q.cma p.cma another.ml 826 + </programlisting> 827 + 828 + <para> 829 + because there are references from q.cma to p.cma. 830 + </para> 831 + 832 + <para> 833 + In C, there is a similar requirement when linking static archives. The 834 + linker backend ld wants the archives in <emphasis>reversed</emphasis> 835 + topological order, i.e. the deepest ancestor must come last in the 836 + list of linked archives. Because of this, the additional linker 837 + options specified in the "linkopts" variable are passed in reversed 838 + order to the underlying linker. This means that you can refer to C 839 + libraries of ancestor packages of p in C libraries provided in p. 840 + </para> 841 + 842 + <para> 843 + Note that most operating systems do not require any specific order for 844 + dynamically linked C libraries (the exception is, surprise!, AIX). 845 + </para> 846 + 847 + </sect1> 848 + 849 + 850 + <sect1> 851 + <title>Querying descendants</title> 852 + 853 + <para> 854 + It is often useful to find out the descendants of a package, i.e. all 855 + direct or indirect users of the package. There is another "ocamlfind" 856 + subcommand that allows us to query descendants. For example, to get 857 + the direct and indirect users of p, type in 858 + </para> 859 + 860 + <programlisting> 861 + ocamlfind query -descendants p 862 + </programlisting> 863 + 864 + <para> 865 + The set of packages that are possible descendants is determined as 866 + follows: 867 + 868 + <itemizedlist mark="bullet" spacing="compact"> 869 + <listitem> 870 + <para> 871 + All packages located in directories mentioned in the environment 872 + variable OCAMLPATH are candidates. Note that only package directories 873 + containing META files are taken. 874 + </para> 875 + </listitem> 876 + 877 + <listitem> 878 + <para> 879 + The packages in the default package directory are candidates, too. 880 + </para> 881 + </listitem> 882 + 883 + <listitem> 884 + <para> 885 + If there are two packages with the same name, only the first 886 + counts, i.e. the first in OCAMLPATH, then the one in the default directory. 887 + </para> 888 + </listitem> 889 + </itemizedlist> 890 + 891 + After this set has been determined, the complete dependency graph is 892 + constructed on it. As the descendants are queried, the dependencies 893 + are read in the inverse way compared with queries of the ancestors. 894 + </para> 895 + 896 + </sect1> 897 + 898 + 899 + </chapter> 900 + 901 + <!-- ********************************************************************** --> 902 + 903 + <chapter> 904 + <title>A new frontend for ocamlc</title> 905 + 906 + <sect1> 907 + <title>Compiling and linking</title> 908 + 909 + <para> 910 + There are compiler frontends for the four compilers ocamlc, ocamlopt, 911 + ocamlmktop, and ocamlcp. They are simply called by specifying the name 912 + of the compiler as first argument to ocamlfind, i.e. 913 + </para> 914 + 915 + <programlisting> 916 + ocamlfind ocamlc ...arguments... 917 + ocamlfind ocamlopt ...arguments... 918 + ocamlfind ocamlmktop ...arguments... 919 + ocamlfind ocamlcp ...arguments... 920 + </programlisting> 921 + 922 + <para> 923 + In addition to the compiler options handled by the compilers 924 + themselves, the following options are available: 925 + </para> 926 + 927 + <itemizedlist mark="bullet" spacing="compact"> 928 + <listitem> 929 + <para> 930 + -package &lt;name&gt;: Causes that the package &lt;name&gt is added to 931 + the package list, and that -I options are added for every package, and 932 + all direct or indirect ancestors. 933 + </para> 934 + </listitem> 935 + 936 + <listitem> 937 + <para> 938 + -linkpkg: Causes that the archives of the packages in the package list 939 + and all their direct or indirect ancestors are added in topological 940 + order to the command line before the first file to compile or to 941 + link. Packages specified by -dontlink are not linked in, though. 942 + Furthermore, the linker options of these packages are added in 943 + reverse topological order at the end of the command line. 944 + </para> 945 + </listitem> 946 + 947 + <listitem> 948 + <para> 949 + -predicates &lt;predicate-list&gt;: The named predicates are included 950 + in the list of predicates. Note that there are some predicates set by 951 + default, see below. 952 + </para> 953 + </listitem> 954 + 955 + <listitem> 956 + <para> 957 + -dontlink &lt;name&gt;: Specifies that the package &lt;name&gt; and 958 + all its direct or indirect ancestors should not be linked in. 959 + </para> 960 + </listitem> 961 + 962 + 963 + <listitem> 964 + <para> 965 + -passopt &lt;opt&gt;: The option &lt;opt&gt; is passed directly to the 966 + underlying compiler. This is especially needed to pass undocumented 967 + options to the compiler. 968 + </para> 969 + </listitem> 970 + </itemizedlist> 971 + 972 + <para> 973 + If you only want to compile, i.e. the -c option is in effect, you 974 + normally only need the -package option. 975 + </para> 976 + 977 + <para> 978 + Depending on the compiler and on the given options, some predicates 979 + are set by default: 980 + </para> 981 + 982 + <itemizedlist mark="bullet" spacing="compact"> 983 + <listitem> 984 + <para> 985 + byte: The predicate "byte" is set when ocamlc, ocamlcp, or ocamlmktop 986 + is used to compile or link. 987 + </para> 988 + </listitem> 989 + 990 + <listitem> 991 + <para> 992 + native: The predicate "native" is set when ocamlopt is used to compile 993 + or to link. 994 + </para> 995 + </listitem> 996 + 997 + <listitem> 998 + <para> 999 + toploop: The predicate "toploop" is set when a toploop is being executed 1000 + </para> 1001 + </listitem> 1002 + 1003 + <listitem> 1004 + <para> 1005 + create_toploop: The predicate "toploop" is set when ocamlmktop is used to 1006 + compile or to link a toploop 1007 + </para> 1008 + </listitem> 1009 + 1010 + 1011 + <listitem> 1012 + <para> 1013 + gprof: The predicate "gprof" is set when ocamlopt with -p option is 1014 + invoked. 1015 + </para> 1016 + </listitem> 1017 + 1018 + <listitem> 1019 + <para> 1020 + mt: The predicate "mt" is set when the -thread or the -vmthread option is in effect. 1021 + </para> 1022 + </listitem> 1023 + 1024 + <listitem> 1025 + <para> 1026 + mt_posix: The predicate "mt_posix" is set together with "mt" if the 1027 + POSIX thread implementation is selected. 1028 + </para> 1029 + </listitem> 1030 + 1031 + <listitem> 1032 + <para> 1033 + mt_vm: The predicate "mt_vm" is set together with "mt" if the bytecode 1034 + thread implementation is selected. 1035 + </para> 1036 + </listitem> 1037 + 1038 + <listitem> 1039 + <para> 1040 + autolink: The predicate "autolink" is set if the OCaml compiler can perform 1041 + automatic linking. This predicate is never set if the -noautolink option is 1042 + in effect. 1043 + </para> 1044 + </listitem> 1045 + 1046 + </itemizedlist> 1047 + 1048 + </sect1> 1049 + 1050 + 1051 + <sect1> 1052 + <title>Toploops and runtime systems</title> 1053 + 1054 + <sect2> 1055 + <title>Dynamic toploops</title> 1056 + 1057 + <para> 1058 + Recent versions of OCaml support dynamic loading of stub libraries 1059 + (but only for the more widely used operating systems). This means 1060 + that one can start a toploop by running 1061 + 1062 + <programlisting> 1063 + $ ocaml 1064 + Objective Caml version 3.07+2 1065 + 1066 + # _ 1067 + </programlisting> 1068 + 1069 + and that it is now possible to load .cma archive files referring to 1070 + shared C libraries ("DLLs"). In older versions of OCaml this was 1071 + not possible and one had to create a so-called custom toploop 1072 + with the ocamlmktop command. This method is still supported and 1073 + explained below; however, nowadays it is often not necessary to 1074 + do so. For the modern way, findlib includes a small script called 1075 + "topfind" (i.e. "ocamlfind for the toploop") that can be directly 1076 + loaded into the toploop: 1077 + 1078 + <programlisting> 1079 + # #use "topfind";; 1080 + - : unit = () 1081 + Findlib has been successfully loaded. Additional directives: 1082 + #require "package";; to load a package 1083 + #list;; to list the available packages 1084 + #camlp4o;; to load camlp4 (standard syntax) 1085 + #camlp4r;; to load camlp4 (revised syntax) 1086 + #predicates "p,q,...";; to set these predicates 1087 + Topfind.reset();; to force that packages will be reloaded 1088 + #thread;; to enable threads 1089 + 1090 + - : unit = () 1091 + # _ 1092 + </programlisting> 1093 + </para> 1094 + 1095 + <para> 1096 + A number of additional directives are now available. The "#require" 1097 + directive loads additional packages (with all dependencies): 1098 + </para> 1099 + 1100 + <programlisting> 1101 + # #require "q1,q2,...,qM";; 1102 + </programlisting> 1103 + 1104 + <para> 1105 + "#require" loads the listed packages and all their ancestors in the 1106 + right order, but leaves packages out that have already been loaded. 1107 + Scripts can now simply load and document which packages are used by a 1108 + "#require" directive right at the beginning of the script. 1109 + </para> 1110 + 1111 + <para> 1112 + The #list directive lists the available packages as "ocamlfind list" 1113 + would do it.</para> 1114 + 1115 + <para> 1116 + If you need additional predicates, you can set them with #predicates. 1117 + Note that this should be done before the first package is loaded in 1118 + order to ensure a consistent library system.</para> 1119 + 1120 + <para> 1121 + The #thread directive enables multi-threading if possible. Note that 1122 + this is only supported for installations basing on the POSIX thread 1123 + library. (However, if you have only have VM threads, you can still 1124 + create a custom toploop supporting threads. See below.) Furthermore, 1125 + the #thread directive should be executed before any packages are 1126 + loaded. 1127 + </para> 1128 + 1129 + <para> 1130 + The #camlp4o and #camlp4r directives load the camlp4 syntax parsers 1131 + for the standard and the revised syntax, respectively. 1132 + </para> 1133 + 1134 + <para> 1135 + Especially when developing packages, it is sometimes necessary to 1136 + reload all dynamically loaded packages in the toploop. This can be 1137 + forced by 1138 + </para> 1139 + 1140 + <programlisting> 1141 + Topfind.reset();; 1142 + </programlisting> 1143 + 1144 + <para> 1145 + which causes the "#require" directive to load all packages again. The 1146 + Topfind module implements all the mentioned directives. 1147 + </para> 1148 + </sect2> 1149 + 1150 + <sect2> 1151 + <title>Custom toploops</title> 1152 + 1153 + <para> 1154 + It is very simple to create toploops. In order to make a toploop 1155 + executable that includes directly the packages p1,p2,..,pN simply 1156 + execute the command 1157 + </para> 1158 + 1159 + <programlisting> 1160 + ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib -linkpkg 1161 + </programlisting> 1162 + 1163 + <para> 1164 + (Maybe you have to add the -custom switch.) Note that one of the 1165 + packages should be "findlib" itself, because this adds the 1166 + additional directives mentioned above, i.e. you can directly use 1167 + these directives without #use "topfind" (but running "topfind" 1168 + is harmless). 1169 + </para> 1170 + 1171 + <para> 1172 + Note that such a toploop includes the code of the packages given 1173 + on the command line, but that it does not automatically add the 1174 + package directories to the search path (in previous versions of 1175 + findlib this was tried, but it never really worked). To do so, 1176 + you still have to #require the packages. 1177 + </para> 1178 + 1179 + <para> 1180 + In order to create a toploop supporting VM-style threads, use the 1181 + command 1182 + 1183 + <programlisting> 1184 + ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib,threads -vmthread -linkpkg 1185 + </programlisting> 1186 + 1187 + Now the #thread directive will work and enable the access to the 1188 + multi-threading modules. 1189 + </para> 1190 + </sect2> 1191 + 1192 + <sect2> 1193 + <title>Runtime systems</title> 1194 + 1195 + <para> 1196 + Building of runtime systems is supported, too. For example, you can run 1197 + </para> 1198 + 1199 + <programlisting> 1200 + ocamlfind ocamlc -o runtime -make-runtime -package p1,p2,...,pN -linkpkg 1201 + </programlisting> 1202 + 1203 + <para> 1204 + but the problem is which options to specify when a program is linked 1205 + for this runtime system. If you executed 1206 + </para> 1207 + 1208 + <programlisting> 1209 + ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\ 1210 + -linkpkg m1.cmo ... mM.cmo 1211 + </programlisting> 1212 + 1213 + <para> 1214 + it would be tried to link the archives from the packages again into 1215 + the bytecode binary. Because of this, it is necessary to suppress 1216 + linking in packages of the runtime system when linking binaries for a 1217 + runtime system. The -dontlink option can be used for this: 1218 + </para> 1219 + 1220 + <programlisting> 1221 + ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\ 1222 + -dontlink p1,p2,...,pN -linkpkg m1.cmo ... mM.cmo 1223 + </programlisting> 1224 + 1225 + <para> 1226 + Note that the -package option can enumerate more packages than 1227 + -dontlink, and in this case the additional packages are actually 1228 + linked in as they are not contained in the runtime system. 1229 + </para> 1230 + </sect2> 1231 + 1232 + </sect1> 1233 + 1234 + 1235 + <sect1> 1236 + <title>Multi-threaded applications</title> 1237 + 1238 + <para> 1239 + If an already existing package is planned to be used in a 1240 + multi-threaded environment, some language constructs must be replaced 1241 + by different ones. For example, global variables must be protected by 1242 + locks (mutexes). Because of 1243 + this it is common practice to provide two versions of such packages, 1244 + one for single-, one for multi-threaded applications (or, another 1245 + technique, there is a special add-on module that initializes a 1246 + library for multi-threaded usage). 1247 + </para> 1248 + 1249 + <para> 1250 + The predicate "mt" should be used to recognize multi-threaded 1251 + applications. For example, a package could consist of two archives, 1252 + p.cma, and p_mt.cma, where the latter archive is designed for 1253 + multi-threaded execution. The META file would contain the following 1254 + lines causing that always the appropriate archive is linked: 1255 + </para> 1256 + 1257 + <programlisting> 1258 + archive(byte) = "p.cma" 1259 + archive(byte,mt) = "p_mt.cma" 1260 + </programlisting> 1261 + 1262 + <para> 1263 + When querying the package database the option "-predicates mt" must be 1264 + included in the commands in order to select the appropriate entries. 1265 + </para> 1266 + 1267 + <para> 1268 + When compiling or linking it is necessary to specify either the 1269 + "-thread" or the "-vmthread" option anyway. The compiler frontends 1270 + detects these options, and automatically set the "mt" 1271 + predicate. The following command is an example for this; note that the 1272 + "threads" package means the standard library of Ocaml providing thread 1273 + support: 1274 + </para> 1275 + 1276 + <programlisting> 1277 + ocamlfind ocamlc -thread -package threads,p,q -c x.ml 1278 + </programlisting> 1279 + 1280 + <para> 1281 + For some operating systems, Ocaml supports the native multithreading 1282 + libraries conforming to the POSIX interface. As the linker options are 1283 + generally different, another predicate must be set to get these 1284 + libraries linked in. The predicate "mt_posix" indicates POSIX 1285 + threads while "mt_vm" indicates bytecode (virtual machine) threads. 1286 + </para> 1287 + 1288 + </sect1> 1289 + 1290 + 1291 + <sect1> 1292 + <title>Support for gprof-enabled modules</title> 1293 + 1294 + <para> 1295 + When a program is compiled and linked with ocamlopt, gprof-style 1296 + profiling can be enabled by selecting the -p option. This means that 1297 + the resulting archives are different, and that it would be useful if 1298 + there were another predicate in order to select such archives. 1299 + </para> 1300 + 1301 + <para> 1302 + The predicate "gprof" can be used for this. It is automatically set if 1303 + the -p option turns on the gprof-mode in an ocamlopt invocation. 1304 + </para> 1305 + 1306 + </sect1> 1307 + 1308 + </chapter> 1309 + 1310 + <!-- ********************************************************************** --> 1311 + 1312 + <chapter> 1313 + <title>Complex packages</title> 1314 + 1315 + <sect1> 1316 + <title>The standard predicates</title> 1317 + 1318 + <para> 1319 + Settings in the META file have usually the form: 1320 + </para> 1321 + 1322 + <programlisting> 1323 + varname ( predname1, predname2, ... ) = "value" 1324 + </programlisting> 1325 + 1326 + <para> 1327 + The names in the parentheses are called <emphasis>formal 1328 + predicates</emphasis> and express a condition which must hold such 1329 + that the value on the right side is selected. When querying 1330 + information you can specify a set of <emphasis> actual 1331 + predicates</emphasis> that are assumed to be true. There are the 1332 + following standard predicates: 1333 + </para> 1334 + 1335 + <itemizedlist mark="bullet" spacing="compact"> 1336 + <listitem> 1337 + <para> 1338 + The "byte" predicate means that the bytecode compiler is used. 1339 + </para> 1340 + </listitem> 1341 + 1342 + <listitem> 1343 + <para> 1344 + The "native" predicate means that the native compiler is used. 1345 + </para> 1346 + </listitem> 1347 + 1348 + <listitem> 1349 + <para> 1350 + The "toploop" predicate means that the toploop is available in the 1351 + linked program. 1352 + </para> 1353 + </listitem> 1354 + 1355 + <listitem> 1356 + <para> 1357 + The "mt" predicate means that the program is multi-threaded. 1358 + </para> 1359 + </listitem> 1360 + 1361 + <listitem> 1362 + <para> 1363 + The "mt_posix" predicate means that in the case "mt" is set, too, the 1364 + POSIX libraries are used to implement threads. 1365 + </para> 1366 + </listitem> 1367 + 1368 + <listitem> 1369 + <para> 1370 + The "mt_vm" predicate means that in the case "mt" is set, too, the 1371 + VM-based libraries are used to implement threads. 1372 + </para> 1373 + </listitem> 1374 + 1375 + <listitem> 1376 + <para> 1377 + The "gprof" predicate means that in the case "native" is set, too, the 1378 + program is compiled for profiling 1379 + </para> 1380 + </listitem> 1381 + 1382 + <listitem> 1383 + <para> 1384 + The "autolink" predicate indicates that ocamlc is able to perform 1385 + automatic linking. 1386 + </para> 1387 + </listitem> 1388 + 1389 + 1390 + </itemizedlist> 1391 + 1392 + <para> 1393 + It is possible to have more predicates indicating different 1394 + environments; just use them, it is not necessary to declare them 1395 + anywhere. 1396 + </para> 1397 + 1398 + <para> 1399 + The value which is selected for a variable depends on the set of 1400 + assumed predicates. In order to get selected, all formal predicates 1401 + must be included in the set of actual predicates; if still 1402 + multiple values fulfill this condition, the value with the maximum 1403 + number of formal predicates is used; and if still in doubt, the first 1404 + of these in the META file is taken. 1405 + </para> 1406 + 1407 + <para> 1408 + It is possible to negate a formal predicate: Just prepend a minus 1409 + sign to it, e.g. var(p,-q). In this case, it is required that the 1410 + negated predicates are false (not contained in the set of actual predicates). 1411 + </para> 1412 + 1413 + <para> 1414 + For all variables that are evaluated after the dependency analysis, 1415 + findlib adds the so-called package predicates to the set of actual 1416 + predicates. For every selected package p the predicate pkg_p 1417 + (with the fixed prefix "pkg_") is added. One application of this 1418 + are compatibility checks: The special <literal>error</literal> variable 1419 + is evaluated after dependency analysis, but before anything else 1420 + is done. For example, to state that package p is incompatible with 1421 + package q one can add to the META file of p: 1422 + 1423 + <programlisting> 1424 + error(pkg_q) = "Package p is incompatible with q" 1425 + </programlisting> 1426 + 1427 + The value of <literal>error</literal> is printed as message in the 1428 + case the condition is true.</para> 1429 + 1430 + </sect1> 1431 + 1432 + 1433 + <sect1> 1434 + <title>Defining additional predicates</title> 1435 + 1436 + <para> 1437 + Additional predicates can be simply used without any declaration, 1438 + i.e. you can freely invent new predicates. One application of them 1439 + is to express conditional linkage. For example, one may provide archives 1440 + for various conditions, such as a production archive, and a 1441 + development archive. A single new predicate, "development", would be 1442 + sufficient to express this: 1443 + </para> 1444 + 1445 + <programlisting> 1446 + archive(byte) = "p_production.cma" 1447 + archive(byte,development) = "p_development.cma" 1448 + </programlisting> 1449 + 1450 + <para> 1451 + When linking, include a "-predicates development" argument in the 1452 + compiler command to select the development archive, otherwise the 1453 + production archive is taken. 1454 + </para> 1455 + 1456 + <para> 1457 + Predicates could also be used to select among several implementations 1458 + of the same module. Define simply one predicate per implementation, 1459 + e.g. "p_impl1", "p_impl2", and "p_impl3", and specify the archives for 1460 + every implementation separately: 1461 + </para> 1462 + 1463 + <programlisting> 1464 + archive(byte,p_impl1) = "p_impl1.cma" 1465 + archive(byte,p_impl2) = "p_impl2.cma" 1466 + archive(byte,p_impl3) = "p_impl3.cma" 1467 + </programlisting> 1468 + 1469 + <para> 1470 + In the case that the implementations have different dependencies, 1471 + simply provide multiple "requires" variables: 1472 + </para> 1473 + 1474 + <programlisting> 1475 + requires(p_impl1) = "q" 1476 + requires(p_impl2) = "q,r" 1477 + requires(p_impl3) = "r,s" 1478 + </programlisting> 1479 + 1480 + <para> 1481 + Sometimes, the implementations require different linker options. In 1482 + this case, define several versions of the "linkopts" variable just 1483 + like in the "requires" example. 1484 + </para> 1485 + 1486 + <para> 1487 + Note that predicates are global identifiers that can be potentially 1488 + applied to every selected package. In the case that a predicate is 1489 + only meaningful for a single package, it is common practice to 1490 + choose the package name as prefix of the predicate name (e.g. 1491 + "netstring_minimum" is a predicate usually only applied to the "netstring" 1492 + package). 1493 + <para> 1494 + 1495 + <para> 1496 + Predicates could be used to select which features of a library are 1497 + linked. For example, 1498 + 1499 + <programlisting> 1500 + archive(byte) = "p_basic.cma" 1501 + archive(byte,p_extension) = "p_basic.cma p_ext.cma" 1502 + </programlisting> 1503 + 1504 + would add the p_ext.cma archive only if the p_extension predicate 1505 + were set. <emphasis>It is considered as bad practice to select 1506 + extensions of libraries by predicates. Findlib provides the construct 1507 + of subpackages for this purpose.</emphasis> 1508 + </para> 1509 + </sect1> 1510 + 1511 + 1512 + <sect1> 1513 + <title>Appending to variables</title> 1514 + 1515 + <para>The syntax 1516 + 1517 + <programlisting> 1518 + varname ( predname1, predname2, ... ) += "value" 1519 + </programlisting> 1520 + 1521 + (note the "+=" operator) can be used to append values to variables 1522 + depending on whether predicates are true. The "+=" lines in the META 1523 + file are evaluated one after the other, and <emphasis>every</emphasis> 1524 + line is selected for which the formal predicates are satisfied, 1525 + and these lines are added to the current value of the variable. This is 1526 + different from the "=" operator where only the most specific 1527 + assignment is taken. 1528 + </para> 1529 + 1530 + <para>The values are considered as space-separated words when they 1531 + are appended, i.e. the new words are added to the list of current 1532 + words.</para> 1533 + 1534 + <para>For example, in the hypothetic META file 1535 + 1536 + <programlisting> 1537 + var(p) += "a" 1538 + var(p,q) += "b" 1539 + </programlisting> 1540 + 1541 + the value of var is "a b" if both p and q are true, and the value is 1542 + only "a" is only p is true (and the value is empty otherwise). If 1543 + the operator "=" had been used, the value would have been only "b" 1544 + when both p and q are true.</para> 1545 + 1546 + <para>In the case that there both "=" and "+=" settings for 1547 + the same variable, a special algorithm is used: First the most specific 1548 + "=" setting is determined, and second all matching "+=" settings are 1549 + appended in the order they appear in the file.</para> 1550 + 1551 + <para>Finally, here is a real-world example. Imagine you have an 1552 + archive p.cma and a special extension for the toploop, p_top.cma. 1553 + Furthermore, there is a special debugging version p_dev.cma that 1554 + replaces p.cma during development. You can now simply write 1555 + 1556 + <programlisting> 1557 + archive(byte) = "p.cma" 1558 + archive(byte,development) = "p_dev.cma" 1559 + archive(byte,toploop) += "p_top.cma" 1560 + </programlisting> 1561 + 1562 + to select <emphasis>either</emphasis> p.cma or p_dev.cma, and append 1563 + p_top.cma for toploops to whatever was selected in the first step.</para> 1564 + </sect1> 1565 + 1566 + 1567 + 1568 + <sect1> 1569 + <title>Subpackages</title> 1570 + 1571 + <para> 1572 + Sometimes a package consists of several archive files that are closely 1573 + related. It is now possible to express dependencies between these 1574 + archives by splitting the package into several parts called subpackages. 1575 + For example, package p consists of a base archive p_base.cma, and two 1576 + extensions p_ext1.cma and p_ext2.cma that both require the base archive 1577 + but are independent of each other. This META file expresses this 1578 + dependency directly: 1579 + 1580 + <programlisting> 1581 + # META file of package p: 1582 + requires = "p.base" 1583 + 1584 + package "base" ( 1585 + archive(byte) = "p_base.cma" 1586 + ) 1587 + 1588 + package "ext1" ( 1589 + requires = "p.base" 1590 + archive(byte) = "p_ext1.cma" 1591 + ) 1592 + 1593 + package "ext2" ( 1594 + requires = "p.base" 1595 + archive(byte) = "p_ext2.cma" 1596 + ) 1597 + </programlisting> 1598 + 1599 + If installed as package "p", this definition actually defines four 1600 + logical packages: "p" (the main package), "p.base", "p.ext1", and 1601 + "p.ext2" (the subpackages). These four entities only share the META 1602 + file in which they are declared, and the directory where the archive 1603 + files are stored, but all other properties can be individually set 1604 + for each package. This also means that all package dependencies 1605 + must explicitly added by "requires" variables, as there are no 1606 + implied dependencies. In this example, the main package and "p.ext1" 1607 + and "p.ext2" are all dependent on "p.base". 1608 + </para> 1609 + 1610 + <para> 1611 + The users of this installation can refer to all four packages. This 1612 + means that 1613 + 1614 + <programlisting> 1615 + ocamlfind ocamlc -package p -linkpkg ... 1616 + </programlisting> 1617 + 1618 + links only p_base.cma into the final program, while 1619 + 1620 + <programlisting> 1621 + ocamlfind ocamlc -package p.ext1 -linkpkg ... 1622 + </programlisting> 1623 + 1624 + selects both p_base.cma and p_ext1.cma. 1625 + </sect1> 1626 + 1627 + 1628 + 1629 + <sect1> 1630 + <title>Glue code</title> 1631 + 1632 + <para>Imagine we have two packages p and q that are normally 1633 + independent, i.e. one can link p without q, and q without p. However, 1634 + when both p and q are used in the same program, it is expected that 1635 + they cooperate with each other. Of course, this situation can be 1636 + modeled with the help of subpackages (a real-world example of this are 1637 + p=lablgtk and q=lablgl).</para> 1638 + 1639 + <para>The idea is as follows: p has a subpackage p.for_q that contains 1640 + code with special features for q, and q has a subpackage q.use_p that 1641 + depends on p, p.for_q, and q, and that contains the code using the 1642 + special features of p. Expressed in META files, p would define 1643 + 1644 + <programlisting> 1645 + # META file for p: 1646 + requires = "..." 1647 + archive = "..." 1648 + 1649 + package "for_q" ( 1650 + requires = "p" 1651 + archive = "..." 1652 + ) 1653 + </programlisting> 1654 + 1655 + and q would define 1656 + 1657 + <programlisting> 1658 + # META file for q: 1659 + requires = "..." 1660 + archive = "..." 1661 + 1662 + package "use_p" ( 1663 + requires = "q,p.for_q" 1664 + archive = "..." 1665 + ) 1666 + </programlisting> 1667 + 1668 + Of course, the program using both libraries must explicitly enable 1669 + the subpackages by mentioning "q.use_p" on the ocamlfind command line, 1670 + otherwise the glue code would be omitted. 1671 + </para> 1672 + 1673 + <para> 1674 + Unfortunately, it is not possible to use the package predicates 1675 + pkg_p and pkg_q to add archives depending on whether the other 1676 + package is also selected. The problem is that the order cannot 1677 + be specified, i.e. whether p must be linked first or q. 1678 + </para> 1679 + </sect1> 1680 + 1681 + 1682 + 1683 + <sect1> 1684 + <title>Plugins</title> 1685 + 1686 + <para><emphasis>(Since findlib-1.6.)</emphasis></para> 1687 + 1688 + <para> 1689 + Plugins are packages that can be loaded at runtime. Plugins are 1690 + intended as a mechanism for loading add-on code into 1691 + executables. Technically, there is some overlap with the concept of a 1692 + "shared library". Note, however, that there is no universal support 1693 + for plugins, as it is unimplemented on some platforms, and only 1694 + poorly on some others (including x86 in the 32 bit case). Also, there 1695 + must always be an explicit "load" statement in the loading executable. 1696 + You cannot link an executable directly against plugins. 1697 + </para> 1698 + 1699 + <sect2><title>Preparing a plugin</title> 1700 + <para> 1701 + For bytecode there is no problem to load cma files at runtime. 1702 + For native-code, though, you need to convert cmxa files into cmxs 1703 + files first:</para> 1704 + 1705 + <programlisting> 1706 + ocamlopt -shared -linkall -o m.cmxs m.cmxa 1707 + </programlisting> 1708 + 1709 + <para>As mentioned, be prepared that this command fails on platforms where 1710 + plugins are unavailable.</para> 1711 + 1712 + <para>The cmxs files can then be referenced from META. We don't use 1713 + the "archive" variable in this case but "plugin":</para> 1714 + 1715 + <programlisting> 1716 + plugin(byte) = "m.cma" 1717 + plugin(native) = "m.cmxs" 1718 + </programlisting> 1719 + 1720 + <para>Before findlib-1.6, there was some half-official convention using the 1721 + "plugin" predicate. This is still supported, but deprecated:</para> 1722 + 1723 + <programlisting> 1724 + archive(byte) = "m.cma" 1725 + archive(native,plugin) = "m.cmxs" 1726 + </programlisting> 1727 + </sect2> 1728 + 1729 + <sect2><title>Load-time dependencies</title> 1730 + <para>Plugins can be, of course, be dependent on other 1731 + plugins. You run into a problem, though, when you make a plugin dependent 1732 + on a package that doesn't qualify as plugin (i.e. lacks the "plugin" 1733 + definition). In this case, the loader simply skips the dependency, 1734 + and you cannot load the plugin.</para> 1735 + 1736 + <para>Because of this dependency issue, it is recommended to add the 1737 + "plugin" variable to all packages that are installed on a system, 1738 + because this does not only allow it to load all packages at runtime, but 1739 + also to use these packages as dependency of the actual plugin code.</para> 1740 + 1741 + <para>That said, you just need to add a "requires" directive, e.g. 1742 + 1743 + <programlisting> 1744 + requires = "pkg1" 1745 + plugin(byte) = "m.cma" 1746 + plugin(native) = "m.cmxs" 1747 + </programlisting> 1748 + </para> 1749 + </sect2> 1750 + 1751 + <sect2><title>How to load a plugin</title> 1752 + <para>Linking an executable that can load a plugin: An executable 1753 + must link the package "findlib.dynload". This does not only add 1754 + the loader, but also special initialization code to the executable:</para> 1755 + 1756 + <programlisting> 1757 + ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg ... 1758 + </programlisting> 1759 + 1760 + <para>In particular, this records the packages that are already included 1761 + into the executable (in-core packages). If a plugin is now dependent 1762 + on such a package, this is recognized, and the package is not loaded 1763 + (which would not work anyway).</para> 1764 + 1765 + <para>Now, you can load a plugin "foo" with:</para> 1766 + 1767 + <programlisting> 1768 + Fl_dynload.load_packages ["foo"] 1769 + </programlisting> 1770 + 1771 + <para>This loads the cma or cmxs files, and runs the initialization code 1772 + of all top-level definitions of the included modules.</para> 1773 + 1774 + <para>Of course, you can also call <literal>load_packages</literal> from 1775 + a library if "findlib.dynload" is a required package of the library 1776 + package.</para> 1777 + </sect2> 1778 + 1779 + <sect2><title>Fat plugins</title> 1780 + <para>Sometimes it is handy to create plugins that already include all 1781 + the required packages. The plugin acts more like a dynamically loadable 1782 + executable that already includes whatever it needs. You can create such 1783 + a "fat" plugin with: 1784 + 1785 + <programlisting> 1786 + ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 m.cmxa 1787 + </programlisting> 1788 + 1789 + In this case, the "requires" line in the META file should remain empty. 1790 + </para> 1791 + 1792 + <para> 1793 + Note, however, that you cannot handle packages this way that are already 1794 + linked into the main program, because it is invalid to load a module that 1795 + is already part of the main executable. Let's assume that the executable 1796 + links in q1, q2, and q3. Then, you need to exclude these packages from the 1797 + plugin. The -dont-link option comes handy in this case: 1798 + 1799 + <programlisting> 1800 + ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 -dont-link q1,q2,q3 m.cmxa 1801 + </programlisting> 1802 + 1803 + This excludes q1,q2,q3 even if these packages occur as dependencies of 1804 + p1,p2,p3. In this case, though, you need to put q1,q2,q3 into the "requires" 1805 + field of META. 1806 + </para> 1807 + </sect2> 1808 + </sect1> 1809 + 1810 + 1811 + 1812 + <sect1> 1813 + <title>Lint</title> 1814 + 1815 + <para><emphasis>(Since findlib-1.6.)</emphasis></para> 1816 + 1817 + <para> 1818 + As it has become more and more complicated to write correct META files 1819 + there is now some support for recognizing typical problems. Just use 1820 + 1821 + <programlisting> 1822 + ocamlfind lint META 1823 + </programlisting> 1824 + 1825 + to check the file META in the current directory. The tool reports problematic 1826 + lines in META, e.g. 1827 + 1828 + <programlisting> 1829 + archive(byte,plugin) = "oUnit.cma" 1830 + This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable. 1831 + 1832 + archive(native,plugin) = "oUnit.cmxs" 1833 + This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable. 1834 + </programlisting> 1835 + 1836 + </para> 1837 + </sect1> 1838 + </chapter> 1839 + 1840 + 1841 + <!-- ********************************************************************** --> 1842 + 1843 + <chapter> 1844 + <title>How to create your own packages</title> 1845 + 1846 + <sect1> 1847 + <title>Installing and removing packages</title> 1848 + 1849 + <para> 1850 + The ocamlfind command can install and remove packages. For example, 1851 + to install a package p containing the files META, m1.cmi, m2.cmi, p.cma, 1852 + run 1853 + 1854 + <programlisting> 1855 + ocamlfind install p META m1.cmi m2.cmi p.cma 1856 + </programlisting> 1857 + 1858 + This installs the files into the default location for new packages 1859 + (set in ocamlfind.conf). If you have files that are not always built, 1860 + add these after the -optional switch: 1861 + 1862 + <programlisting> 1863 + ocamlfind install p META m1.cmi m2.cmi p.cma -optional p.cmxa p.cmxs 1864 + </programlisting> 1865 + 1866 + To remove the package, run 1867 + 1868 + <programlisting> 1869 + ocamlfind remove p 1870 + </programlisting> 1871 + 1872 + Note that every package must have a META file, it is not possible to 1873 + omit it. 1874 + </para> 1875 + </sect1> 1876 + 1877 + 1878 + <sect1> 1879 + <title>Change your Makefile</title> 1880 + 1881 + <para> 1882 + Here is a commented version of a Makefile that may be used to compile 1883 + and link a package. It describes the frequent case that the package 1884 + simply consists of a bundle of modules that are dependent on other 1885 + packages. 1886 + </para> 1887 + 1888 + <para> 1889 + First, some general definitions. NAME is the name of the package. The 1890 + OBJECTS variable enumerates the bytecode objects, whereas XOBJECTS 1891 + names the native objects. The same naming convention is used for 1892 + ARCHIVE and XARCHIVE, specifying the resulting bytecode, resp. native 1893 + archive file. The REQUIRES variable lists the names of the packages 1894 + that are needed for this package. If you need additional predicates, 1895 + put them into the PREDICATES variable. 1896 + </para> 1897 + 1898 + <programlisting> 1899 + NAME = p 1900 + 1901 + OCAMLC = ocamlfind ocamlc 1902 + OCAMLOPT = ocamlfind ocamlopt 1903 + OCAMLDEP = ocamldep 1904 + 1905 + OBJECTS = p1.cmo p2.cmo 1906 + XOBJECTS = p1.cmx p2.cmx 1907 + 1908 + ARCHIVE = $(NAME).cma 1909 + XARCHIVE = $(NAME).cmxa 1910 + SARCHIVE = $(NAME).cmxs 1911 + 1912 + REQUIRES = unix str q r s 1913 + PREDICATES = 1914 + </programlisting> 1915 + 1916 + <para> 1917 + The default goal is "all", causing the bytecode archive to be 1918 + created. In order to get a native archive, choose "opt" as second goal. 1919 + (The ".PHONY" line is a declaration meaningful for GNU-make; "all" and 1920 + "opt" are only virtual goals as there no files "all", or "opt" which 1921 + is indicated by making them dependents of ".PHONY".) 1922 + </para> 1923 + 1924 + <programlisting> 1925 + .PHONY: all opt 1926 + all: $(ARCHIVE) 1927 + opt: $(XARCHIVE) $(SARCHIVE) 1928 + </programlisting> 1929 + 1930 + <para> 1931 + The following two rules create the bytecode resp. native archive from 1932 + the objects. 1933 + </para> 1934 + 1935 + <programlisting> 1936 + $(ARCHIVE): $(OBJECTS) 1937 + $(OCAMLC) -a -o $(ARCHIVE) -package "$(REQUIRES)" -linkpkg \ 1938 + -predicates "$(PREDICATES)" $(OBJECTS) 1939 + $(XARCHIVE): $(XOBJECTS) 1940 + $(OCAMLOPT) -a -o $(XARCHIVE) -package "$(REQUIRES)" -linkpkg \ 1941 + -predicates "$(PREDICATES)" $(XOBJECTS) 1942 + 1943 + $(SARCHIVE): $(XARCHIVE) 1944 + $(OCAMLOPT) -shared -o $(SARCHIVE) $(XARCHIVE) || true 1945 + </programlisting> 1946 + 1947 + <para> 1948 + Note that the cmxs archive is optional: we just ignore the error 1949 + when it cannot be built. 1950 + </para> 1951 + 1952 + <para> 1953 + These rules compile the modules independently. The lines similar to 1954 + ".ml.cmo" must be read: "How to transform files with suffix .ml into 1955 + files with suffix .cmo". The corresponding command can refer to the 1956 + input file as "$&lt;" and to the output file(s) as "$@". 1957 + </para> 1958 + 1959 + <programlisting> 1960 + .SUFFIXES: .cmo .cmi .cmx .ml .mli 1961 + 1962 + .ml.cmo: 1963 + $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \ 1964 + -c $&lt; 1965 + .mli.cmi: 1966 + $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \ 1967 + -c $&lt; 1968 + .ml.cmx: 1969 + $(OCAMLOPT) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \ 1970 + -c $&lt; 1971 + </programlisting> 1972 + 1973 + <para> 1974 + The "depend" goal is the file describing the dependencies within the 1975 + package; it is created by ocamldep. 1976 + </para> 1977 + 1978 + <programlisting> 1979 + depend: *.ml *.mli 1980 + $(OCAMLDEP) *.ml *.mli &gt;depend 1981 + include depend 1982 + </programlisting> 1983 + 1984 + <para> 1985 + The "install" rule is a bit tricky. First it is tested if there is a 1986 + native archive to install, and if so, the variable "extra" contains 1987 + the corresponding files. The "ocamlfind install" command creates a new 1988 + package directory and puts the given files into it. 1989 + </para> 1990 + 1991 + <programlisting> 1992 + .PHONY: install uninstall 1993 + install: all 1994 + ocamlfind install $(NAME) *.mli *.cmi $(ARCHIVE) META \ 1995 + -optional $(XARCHIVE) $(SARCHIVE) 1996 + 1997 + uninstall: 1998 + ocamlfind remove $(NAME) 1999 + </programlisting> 2000 + 2001 + <para> 2002 + Last but not least a cleanup rule: 2003 + </para> 2004 + 2005 + <programlisting> 2006 + .PHONY: clean 2007 + rm -f *.cmi *.cmo *.cmx *.cma *.cmxa *.a 2008 + </programlisting> 2009 + </sect1> 2010 + 2011 + 2012 + <sect1> 2013 + <title>Using the Makefile wizard</title> 2014 + 2015 + <para> 2016 + Especially for beginners, the findlib distribution includes a GUI to 2017 + create Makefiles. As this is an optional feature, it must have been 2018 + selected when findlib was built (option -with-toolbox). To invoke the 2019 + GUI, run the command 2020 + 2021 + <programlisting> 2022 + $ ocamlfind findlib/make_wizard 2023 + </programlisting> 2024 + 2025 + (Btw, this is the general syntax to run executables installed in 2026 + package directories.) The wizard starts, and allows you to describe 2027 + your project. When you save the result, not only a "Makefile" is 2028 + created, but also the file ".make-wizard" containing the state. 2029 + If you later start the wizard again, this file will be automatically 2030 + loaded, and you can modify your definition.</para> 2031 + 2032 + <para>The wizard consists of seven (hopefully self-explanatory) pages 2033 + you can fill out. The basic idea is that the .ml, .mli, .mly, and .mll 2034 + files in the current directory are compiled to a .cma or .cmxa 2035 + archive, and that optionally executables are created from this archive 2036 + and from additional modules (main programs). This scheme can be both 2037 + used for libraries and application programs.</para> 2038 + 2039 + <para>You can choose packages you want to use in your library or 2040 + program by clicking at them in a selection box. The camlp4 syntax 2041 + parsers can be optionally enabled. The modules to be compiled can 2042 + be picked from the current directory, they must be selected in the 2043 + right order, however.</para> 2044 + 2045 + <para>The generated "Makefile" defines a number of logical targets 2046 + (like "all", "opt", etc) that are explained at the beginning of the 2047 + file. The file is fully commented, and not very difficult to understand. 2048 + Only traditional Makefile syntax is used, so it is expected that it 2049 + works for every version of the "make" utility. 2050 + </para> 2051 + 2052 + <para>When you build the project, the META file is created 2053 + dynamically. If you do not like this, set the variable MAKE_META to 2054 + the empty string. (It is a good idea to put such setting into a 2055 + second file, and enter the name of this file into the box "Local 2056 + extensions in" of the wizard, so you can generate the "Makefile" again 2057 + without overwriting your own modifications. This second file can 2058 + override the setting in the generated "Makefile".) 2059 + </para> 2060 + 2061 + </sect1> 2062 + 2063 + </chapter> 2064 + 2065 + 2066 + <!-- ********************************************************************** --> 2067 + 2068 + <chapter> 2069 + <title>FAQs</title> 2070 + 2071 + <sect1> 2072 + <title>Does findlib support the autolink feature of OCaml 3?</title> 2073 + 2074 + <para> 2075 + <emphasis>Short answer:</emphasis> Findlib is compatible with autolink 2076 + </para> 2077 + 2078 + <para> 2079 + The new archive format introduced with OCaml 3 can store the linker options 2080 + that are necessary to link an archive. For example: 2081 + 2082 + <programlisting> 2083 + ocamlc -a -o myarchive.cma mymodule.cmo -cclib -lmylibrary 2084 + </programlisting> 2085 + 2086 + This command does not only create the new archive 2087 + <literal>myarchive.cma</literal>, but it also writes into a special section of 2088 + that file that the linker option <literal>-cclib -lmylibrary</literal> is 2089 + necessary to link this archive. 2090 + </para> 2091 + 2092 + <para> 2093 + This means for findlib that most of the "linkopts" attributes in META files 2094 + have become superfluous: The compiler itself already knows the linker options, 2095 + we do not need to tell the compiler the options. We could simply leave all 2096 + "linkopts" attributes out. 2097 + </para> 2098 + 2099 + <para> 2100 + Of course, the "linkopts" feature of findlib still works. This is necessary 2101 + because findlib should keep the compatibility with older software, and because 2102 + "linkopts" is more powerful (you can have conditional linker options). 2103 + </para> 2104 + 2105 + <para> 2106 + If you have software that must run in both OCaml 2 and OCaml 3 environments, 2107 + you can make your "linkopts" attribute dependent on the "autolink" 2108 + predicate. For example: 2109 + 2110 + <programlisting> 2111 + linkopts = "-cclib -lmylibrary" 2112 + linkopts(autolink) = "" 2113 + </programlisting> 2114 + 2115 + The findlib installation for OCaml 3 will take the second line which is 2116 + reasonable because ocamlc already knows how to link; the installation for 2117 + OCaml 2 never sets the "autolink" predicate and therefore uses the first line. 2118 + </para> 2119 + </sect1> 2120 + 2121 + 2122 + 2123 + <sect1> 2124 + <title>Why does findlib not automatically include the -custom option if 2125 + linked with C code?</title> 2126 + 2127 + <para><emphasis>Short answer:</emphasis> 2128 + Because there are several ways of linking, and findlib is not the 2129 + right instance to find out the right way</para> 2130 + 2131 + <para>Recent versions of OCaml support DLLs, at least for some 2132 + platforms. Here, the option -custom is not necessary at all, because the 2133 + C libraries can be looked up and loaded at runtime. The option -custom 2134 + would have the effect of forcing static linking.</para> 2135 + 2136 + <para>But even for platforms without DLL support, there are two 2137 + alternatives. One possibility is to use -custom, and the other is to 2138 + create runtime systems with -make-runtime, and reference them with 2139 + -use-runtime. Fortunately, recent versions of OCaml select now themselves 2140 + -custom automatically if -make-runtime is omitted, so findlib needs not to 2141 + bother with it. 2142 + </para> 2143 + </sect1> 2144 + 2145 + 2146 + 2147 + <sect1> 2148 + <title>Does findlib support linking of applications as well as 2149 + packages?</title> 2150 + 2151 + <para> 2152 + <emphasis>Short answer:</emphasis> Yes, but it is not very obvious</para> 2153 + 2154 + <para> 2155 + Applications also depend on other components, they have predicates, sometimes 2156 + they need linker options; there seems to be only little difference between 2157 + applications (stand-alone programs) and packages. If you want to use the 2158 + findlib mechanisms for applications, too, the following trick helps. 2159 + </para> 2160 + 2161 + <para> 2162 + The environment variable <literal>OCAMLPATH</literal> may contain a 2163 + colon-separated path of possible sitelib locations. It is allowed to include 2164 + "." into the path (Shell commands follow): 2165 + 2166 + <programlisting> 2167 + OCAMLPATH=. 2168 + export OCAMLPATH 2169 + </programlisting> 2170 + 2171 + This makes ".", i.e. your current directory, another sitelib location. You may 2172 + now put the components of your applications into subdirectories together with 2173 + META files; the hierarchy might look as follows: 2174 + 2175 + <programlisting> 2176 + ./Makefile global Makefile 2177 + ./localpkg1/META first local package directory: Contains META 2178 + ./localpkg1/... ... and more 2179 + ./localpkg2/META second local package dir: Contains META 2180 + ./localpkg2/... ... and more 2181 + ... 2182 + </programlisting> 2183 + 2184 + From findlib's point of view, these directories are now package directories, 2185 + and you can refer to them on the command line: 2186 + 2187 + <programlisting> 2188 + ocamlfind ocamlc -o ... -linkpkg -package localpkg1,localpkg2,... 2189 + </programlisting> 2190 + 2191 + If you do not want subdirectories, you can also refer to the META file in the 2192 + same directory by the name ".", e.g.: 2193 + 2194 + <programlisting> 2195 + ocamlfind ocamlc -o ... -linkpkg -package . 2196 + </programlisting> 2197 + 2198 + In this case, the linking information will be taken from 2199 + <literal>./META</literal>. 2200 + </para> 2201 + </sect1> 2202 + 2203 + 2204 + <sect1> 2205 + <title> 2206 + Does Findlib support camlp4? 2207 + </title> 2208 + 2209 + <para> 2210 + <emphasis>Short answer:</emphasis> Yes, but there is only little 2211 + documentation.</para> 2212 + 2213 + <para> 2214 + Since Findlib-0.4, there is some experimental camlp4 support. For 2215 + example, the following compiler invocation chooses the revised syntax: 2216 + 2217 + <programlisting> 2218 + ocamlfind ocamlc -syntax camlp4r -package camlp4 -c file.ml 2219 + </programlisting> 2220 + 2221 + As you can see, camlp4 must be included as package, and the 2222 + -syntax option must specify which syntax is selected (either 2223 + <literal>camlp4o</literal> or <literal>camlp4r</literal>).</para> 2224 + 2225 + <para> 2226 + If you want to pass additional options to the preprocessor, 2227 + you can use the <literal>-ppopt</literal> option: 2228 + 2229 + <programlisting> 2230 + ocamlfind ocamlc -syntax camlp4r -package camlp4 -ppopt pa_ifdef.cmo -c file.ml 2231 + </programlisting> 2232 + </para> 2233 + 2234 + <para> 2235 + From the toploop, the following commands work: 2236 + 2237 + <programlisting> 2238 + $ ocaml 2239 + Objective Caml version 3.07+2 2240 + 2241 + # #use "./topfind";; 2242 + - : unit = () 2243 + Findlib has been successfully loaded. Additional directives: 2244 + #require "package";; to load a package 2245 + #list;; to list the available packages 2246 + #camlp4o;; to load camlp4 (standard syntax) 2247 + #camlp4r;; to load camlp4 (revised syntax) 2248 + #predicates "p,q,...";; to set these predicates 2249 + Topfind.reset();; to force that packages will be reloaded 2250 + #thread;; to enable threads 2251 + 2252 + - : unit = () 2253 + # #camlp4o;; (* or camlp4r *) 2254 + /opt/godi/lib/ocaml/std-lib/camlp4: added to search path 2255 + /opt/godi/lib/ocaml/std-lib/camlp4/camlp4o.cma: loaded 2256 + Camlp4 Parsing version 3.07+2 2257 + 2258 + # _ 2259 + </programlisting> 2260 + 2261 + <sect2> 2262 + <title>The concept</title> 2263 + <para> 2264 + If you have a <literal>-syntax</literal> option on the command line, 2265 + ocamlfind will generate a <literal>-pp</literal> parameter and pass it to the 2266 + invoked compiler. This is performed as follows: The specified packages are 2267 + inspected under a certain set of predicates, the <emphasis>syntax 2268 + predicates</emphasis>. The syntax predicates are <literal>syntax</literal>, 2269 + <literal>preprocessor</literal>, and the predicates following 2270 + <literal>-syntax</literal>. The predicate <literal>syntax</literal> simply 2271 + means that the <literal>-syntax</literal> option has been specified. 2272 + The predicate <literal>preprocessor</literal> means that the preprocessor 2273 + command is being constructed. The predicates added by 2274 + <literal>-syntax</literal> may be used to distinguish between syntax variants 2275 + (currently <literal>camlp4o</literal> and <literal>camlp4r</literal>). 2276 + </para> 2277 + 2278 + <para>The packages are searched for a variable <literal>preprocessor</literal>; 2279 + normally the <literal>camlp4</literal> package defines it as (see its META 2280 + file): 2281 + 2282 + <programlisting> 2283 + preprocessor = "camlp4 -nolib" 2284 + </programlisting> 2285 + 2286 + Now that the name of the preprocessor command is known, the arguments of the 2287 + command are looked up. The META files are evaluated under the syntax 2288 + predicates, and all <literal>archive</literal> variables are collected and 2289 + passed as arguments to the preprocessor. For example, the camlp4 package 2290 + defines: 2291 + 2292 + <programlisting> 2293 + archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo" 2294 + archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo" 2295 + </programlisting> 2296 + 2297 + Note that the predicate <literal>preprocessor</literal> prevents ocamlfind from 2298 + including these archives into the regular list of archives to link. 2299 + </para> 2300 + </sect2> 2301 + <sect2> 2302 + <title>How to write a META file for your own syntax extension</title> 2303 + <para> 2304 + Suppose you have two archives: <literal>pa_myext.cma</literal> contains the 2305 + extension code of camlp4, and <literal>run_myext.cma</literal> contains runtime 2306 + material that must be present in programs compiled with your extensions. Your 2307 + META file should look as follows: 2308 + 2309 + <programlisting> 2310 + requires = "camlp4" 2311 + archive(syntax,toploop) = "pa_myext.cma run_myext.cma" 2312 + archive(syntax,preprocessor) = "pa_myext.cma" 2313 + archive(syntax,byte) = "run_myext.cma" 2314 + archive(syntax,native) = "run_myext.cmxa" 2315 + </programlisting> 2316 + 2317 + You may add dependencies on <literal>camlp4o</literal> or 2318 + <literal>camlp4r</literal> if you have archives only working for one of the two 2319 + syntax variants. 2320 + </para> 2321 + 2322 + <para>To compile a program using your syntax extension package, one should use: 2323 + 2324 + <programlisting> 2325 + ocamlfind ocamlc -package yourname -syntax variant ... 2326 + </programlisting> 2327 + </para> 2328 + </sect2> 2329 + 2330 + <sect2> 2331 + <title>Example</title> 2332 + 2333 + <para>The package <literal>xstrp4</literal> defines a syntax extension allowing 2334 + $-substitutions in OCaml strings. Version 1.0 of this package takes advantage 2335 + from the new camlp4 support of findlib; you may have a look at it for an 2336 + example.</para> 2337 + 2338 + <para>You can find <literal>xstrp4</literal> 2339 + <ulink URL="&url.xstrp4-project;">here</ulink>.</para> 2340 + </sect2> 2341 + </sect1> 2342 + 2343 + 2344 + <sect1> 2345 + <title> 2346 + Does Findlib support ppx-style preprocessors? 2347 + </title> 2348 + 2349 + <para> 2350 + <emphasis>Short answer:</emphasis> Yes, but there is only little 2351 + documentation.</para> 2352 + 2353 + <para>Since findlib-1.5, ppx-style preprocessors are supported 2354 + to some extent. A package can now define a "ppx" property which is simply 2355 + a command to run as preprocessor (the command gets the marshalled AST 2356 + as input, and must generate the transformed AST in its output; see the 2357 + -ppx option of ocamlc/ocamlopt). A META file can simply look like: 2358 + 2359 + <programlisting> 2360 + ppx = "./command" 2361 + </programlisting> 2362 + 2363 + when "command" is installed in the package directory (but you can also 2364 + omit "./" to search it, and you can prefix it with "@name/" if the command 2365 + is taken from another package "name"). 2366 + </para> 2367 + 2368 + <para>For more complex scenarios, additional options or 2369 + arguments for the ppx preprocessor can be specified in descendant 2370 + packages with the "ppxopt" property. Package "A" might provide a 2371 + generic ppx preprocessor with a META file containing 2372 + 2373 + <programlisting> 2374 + ppx = "./generic_ppx" 2375 + </programlisting> 2376 + 2377 + Package B might instantiate that preprocessor with 2378 + 2379 + <programlisting> 2380 + requires = "A" 2381 + ppxopt = "A,ppx_b.cmo" 2382 + </programlisting> 2383 + 2384 + In this case "ocamlfind ocamlc -package B" would 2385 + add <literal>-ppx "path_to_A/genric_ppx ppx_b.cmo"</literal> to 2386 + the ocamlc invocation. The format of the "ppxopt" property is 2387 + specified in the findlib reference manual. 2388 + </para> 2389 + 2390 + 2391 + <para>This feature is still a bit experimental.</para> 2392 + 2393 + </sect1> 2394 + 2395 + 2396 + <sect1> 2397 + <title>Why do some people install the .cmx files?</title> 2398 + 2399 + <para>In principle, it is not necessary to install the .cmx 2400 + files created by the ocamlopt compiler, as the .a and .cmxa files 2401 + already contain the assembly code and all needed auxiliary information. 2402 + However, it may be sensible to install the .cmx files, too. They 2403 + contain the intermediate code of small functions that are candidates 2404 + for inlining, and installing them allows the compiler to do inlining 2405 + even across library boundaries. Note that only very small functions 2406 + can be inlined at all, and that there are language elements that 2407 + prevent inlining (e.g. raising an exception with an argument), so 2408 + it makes only sense when the library actually has such functions 2409 + and really profits from inlining.</para> 2410 + 2411 + <para>Inlining has also disadvantages: The library can no 2412 + longer be replaced by a different version even if the interface 2413 + remains exactly the same, because code using the library may have 2414 + inlined code of the old version.</para> 2415 + </sect1> 2416 + 2417 + 2418 + <sect1> 2419 + <title>How do I express conflicts?</title> 2420 + 2421 + <para>A conflict means that a certain combination of packages 2422 + and package features will not work. A number of conflict conditions 2423 + can be expressed:</para> 2424 + 2425 + <itemizedlist> 2426 + <listitem> 2427 + <para>To state that a package will not work if a certain 2428 + predicate is set, use the <literal>error</literal> variable. For example, 2429 + when package p does not work for multi-threaded programs: 2430 + 2431 + <programlisting> 2432 + error(mt) = "Package p is incompatible with multi-threaded programs" 2433 + </programlisting> 2434 + 2435 + This works for other standard predicates, too.</para> 2436 + </listitem> 2437 + 2438 + <listitem> 2439 + <para>To state that a package will not work together with 2440 + another package, it is possible to make <literal>error</literal> dependent 2441 + on package predicates. For example, when package p does not work 2442 + together with q: 2443 + 2444 + <programlisting> 2445 + error(pkg_q) = "Package p is incompatible with package q" 2446 + </programlisting> 2447 + 2448 + This also works with subpackages (e.g. <literal>pkg_q.q_sub</literal>). 2449 + </para> 2450 + </listitem> 2451 + 2452 + <listitem> 2453 + <para>If an error is too much, it might be a good idea to 2454 + just inform the user about possible problems. In this case 2455 + you can emit a warning instead: 2456 + </para> 2457 + 2458 + <programlisting> 2459 + warning(pkg_q) = "Using package p and q together is a really bad idea" 2460 + </programlisting> 2461 + 2462 + </itemizedlist> 2463 + 2464 + <para>Note that such error conditions should only be added if there is 2465 + absolutely no chance to get the combination of packages and features running. 2466 + For example, in the case of multi-threaded programs it is often possible 2467 + to add wrappers around unsafe libraries to fix the incompatibility. 2468 + </para> 2469 + 2470 + <para>It is not possible to express incompatibilities between package 2471 + versions. Such incompatibilities should be detected when software is 2472 + installed, not when it is used.</para> 2473 + </sect1> 2474 + </chapter> 2475 + </part> 2476 + </book>
+427
vendor/opam/ocamlfind/doc/src/findlib_conf.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>findlib.conf</refentrytitle> 5 + <manvolnum>5</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="findlib.conf"> 10 + <refname>findlib.conf</refname> 11 + <refpurpose>[Configuration of findlib/ocamlfind]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsect1> 16 + <title>GENERAL</title> 17 + 18 + <para> 19 + There are three possibilities to configure the findlib library: 20 + 21 + <variablelist> 22 + <varlistentry> 23 + <term>Build time:</term> 24 + <listitem><para> 25 + Before findlib is compiled, a "configure" script is invoked to figure 26 + out the settings that are most likely to work on the system. Most 27 + settings are simply entered into text files and can easily be changed 28 + after installation. The following properties cannot be changed later 29 + because they are compiled into the resulting binaries: 30 + 31 + <itemizedlist> 32 + <listitem> 33 + <para> 34 + The default location of the configuration file findlib.conf. However, 35 + you can set a different location by the environment variable 36 + <literal>OCAMLFIND_CONF</literal>. 37 + </para> 38 + </listitem> 39 + 40 + <listitem> 41 + <para> 42 + Whether the installed OCaml version supports autolinking or not. 43 + </para> 44 + </listitem> 45 + 46 + </itemizedlist> 47 + </para> 48 + </listitem> 49 + </varlistentry> 50 + 51 + <varlistentry> 52 + <term>Configuration file findlib.conf:</term> 53 + <listitem><para> 54 + An initial version of this file is generated by the configure script, 55 + but you are free to modify it later. Most important, this file 56 + contains the system-wide search path used to look up packages, and the 57 + default location where to install new packages. 58 + </para> 59 + <para> 60 + All files with the suffix ".conf" found in the directory 61 + findlib.conf.d are also scanned for parameters. 62 + </para> 63 + </listitem> 64 + </varlistentry> 65 + 66 + <varlistentry> 67 + <term>Environment variables:</term> 68 + <listitem><para> 69 + The settings of findlib.conf can be overridden by environment variables. 70 + </para> 71 + </listitem> 72 + </varlistentry> 73 + </variablelist> 74 + 75 + Last but not least, several settings can also be passed as 76 + command-line options, or by invoking the function 77 + <literal>Findlib.init</literal>. 78 + </para> 79 + </refsect1> 80 + 81 + 82 + <!-- ********************************************************************** --> 83 + 84 + 85 + <refsect1> 86 + <title>findlib.conf</title> 87 + 88 + <para> 89 + The directory containing findlib.conf is determined at build time (by 90 + running the configure script), the fallback default is 91 + <literal>/usr/local/etc</literal>. You can set a different location by 92 + changing the environment variable <literal>OCAMLFIND_CONF</literal> 93 + which must contain the absolute path of findlib.conf. 94 + </para> 95 + 96 + <para> 97 + The file has the same syntax as <link 98 + linkend="META"><literal>META</literal></link>, i.e. it consists of a 99 + number of lines with the format 100 + 101 + <programlisting> 102 + <replaceable>variable</replaceable> = "<replaceable>value</replaceable>" 103 + </programlisting> 104 + </para> 105 + 106 + <para>Here is the list of allowed variables: 107 + 108 + <variablelist> 109 + <varlistentry> 110 + <term><literal>path</literal></term> 111 + <listitem><para> 112 + The search path for META files/package directories. The variable 113 + enumerates directories which are separated by colons (Windows: 114 + semicolons), and these directories are tried in turn to find a certain 115 + package. More exactly, if d is such a directory and p the searched 116 + package, the search algorithm will first check whether d/p/META 117 + exists. In this case, this META file is taken, and d/p is the package 118 + directory. Second, the algorithm tries d/META.p, but the package 119 + directory must be specified in this META.p file by a 120 + <literal>directory</literal> directive. 121 + </para> 122 + 123 + <para> 124 + Note that the first found META file is taken, so the order of the 125 + directories in the search path counts. 126 + </para> 127 + 128 + <para> 129 + This variable is required. 130 + </para> 131 + 132 + <para> 133 + Example: 134 + 135 + <programlisting> 136 + path = "/usr/local/lib/ocaml/site-lib:/usr/lib/ocaml/site-lib" 137 + </programlisting> 138 + </para> 139 + </listitem> 140 + </varlistentry> 141 + </variablelist> 142 + 143 + 144 + <variablelist> 145 + <varlistentry> 146 + <term><literal>destdir</literal></term> 147 + <listitem><para> 148 + This variable determines the location where <literal>ocamlfind 149 + install</literal> puts the packages by default: If d is this 150 + directory, and p the package to install, a new subdirectory d/p will 151 + be created containing all the files of the package. 152 + </para> 153 + 154 + <para>Example: 155 + <programlisting> 156 + destdir = "/usr/local/lib/ocaml/site-lib" 157 + </programlisting> 158 + </para> 159 + 160 + <para> 161 + This variable is required. 162 + </para> 163 + </listitem> 164 + </varlistentry> 165 + </variablelist> 166 + 167 + 168 + <variablelist> 169 + <varlistentry> 170 + <term><literal>metadir</literal></term> 171 + <listitem><para> 172 + If set, the command <literal>ocamlfind install</literal> will put the 173 + META files of packages into this directory (files are named META.p 174 + where p=package name); otherwise the META files are put into the 175 + package directories like any other file. 176 + </para> 177 + 178 + <para>Example: 179 + <programlisting> 180 + metadir = "/var/lib/findlib/metaregistry" 181 + </programlisting> 182 + </para> 183 + 184 + <para> 185 + This variable is optional. It is not used by default. 186 + </para> 187 + </listitem> 188 + </varlistentry> 189 + </variablelist> 190 + 191 + 192 + <variablelist> 193 + <varlistentry> 194 + <term><literal>ocamlc</literal>, 195 + <literal>ocamlopt</literal>, 196 + <literal>ocamlcp</literal>, 197 + <literal>ocamlmktop</literal>, 198 + <literal>ocamldoc</literal>, 199 + <literal>ocamldep</literal>, 200 + <literal>ocamlbrowser</literal> 201 + </term> 202 + <listitem><para> 203 + If you want to call other executables than "ocamlc", "ocamlopt", 204 + "ocamlcp", "ocamlmktop", "ocamldoc", "ocamldep", and 205 + "ocamlbrowser", you can 206 + set the names of 207 + the executables here. The command <literal>ocamlfind</literal> looks 208 + into these four variables to determine the names of the compilers to 209 + call. 210 + </para> 211 + 212 + <para>Example: 213 + <programlisting> 214 + ocamlc = "ocamlc.opt" 215 + ocamlopt = "ocamlopt.opt" 216 + ocamlcp = "ocamlcp.opt" 217 + ocamlmktop = "ocamlmktop.opt" 218 + </programlisting> 219 + </para> 220 + 221 + <para> 222 + This variable is optional. It is not used by default. 223 + </para> 224 + </listitem> 225 + </varlistentry> 226 + </variablelist> 227 + 228 + <variablelist> 229 + <varlistentry> 230 + <term><literal>stdlib</literal></term> 231 + <listitem><para> 232 + This variable determines the location of the standard library. This must 233 + be the same directory for which the OCaml compilers are configured. 234 + </para> 235 + 236 + <para> 237 + This variable is optional. It is not recommend to set this variable 238 + unless you know what you are doing! 239 + </para> 240 + </listitem> 241 + </varlistentry> 242 + </variablelist> 243 + 244 + <variablelist> 245 + <varlistentry> 246 + <term><literal>ldconf</literal></term> 247 + <listitem><para> 248 + This variable determines the location of the ld.conf file. This must 249 + be the same file the OCaml compilers read in; it is updated by 250 + ocamlfind when installing and removing packages. You can set this 251 + variable to the special value "<literal>ignore</literal>" to disable 252 + the automatic modification of the ld.conf file. 253 + </para> 254 + 255 + <para> 256 + If not set, the ld.conf file is assumed to reside in the OCaml 257 + standard library directory. 258 + </para> 259 + 260 + <para> 261 + This variable is optional. It is not recommended to set this variable 262 + unless you know what you are doing! 263 + </para> 264 + </listitem> 265 + </varlistentry> 266 + </variablelist> 267 + </para> 268 + 269 + <para> 270 + Toolchains: It is possible to have variants of the original configuration. 271 + These variants are called "toolchains" because they are intended to 272 + select different compilers, e.g. patched compilers. In order to 273 + set a variable for a certain toolchain, use the syntax 274 + 275 + <programlisting> 276 + <replaceable>variable</replaceable>(<replaceable>toolchain</replaceable>) = "<replaceable>value</replaceable>" 277 + </programlisting> 278 + 279 + For example: 280 + 281 + <programlisting> 282 + ocamlc(mypatch) = "ocamlc-mypatch" 283 + </programlisting> 284 + 285 + When the toolchain "mypatch" is selected, this compiler will be used instead 286 + of the standard one.</para> 287 + 288 + <para>In order to switch to a certain toolchain, use the -toolchain 289 + option of <link linkend="ocamlfind">ocamlfind</link>.</para> 290 + 291 + </refsect1> 292 + 293 + 294 + 295 + <!-- ********************************************************************** --> 296 + 297 + 298 + <refsect1> 299 + <title>Environment</title> 300 + 301 + <para> 302 + A number of environment variables modifies the behaviour of 303 + findlib/ocamlfind: 304 + 305 + <variablelist> 306 + <varlistentry> 307 + <term><literal>OCAMLFIND_CONF</literal></term> 308 + <listitem><para> 309 + This variable overrides the location of the configuration file 310 + findlib.conf. It must contain the absolute path name of this file. 311 + </para> 312 + </listitem> 313 + </varlistentry> 314 + </variablelist> 315 + 316 + <variablelist> 317 + <varlistentry> 318 + <term><literal>OCAMLFIND_TOOLCHAIN</literal></term> 319 + <listitem><para> 320 + This variable sets the currently selected toolchain when 321 + a <literal>-toolchain</literal> option is not passed 322 + on the command line. 323 + </para> 324 + </listitem> 325 + </varlistentry> 326 + </variablelist> 327 + 328 + <variablelist> 329 + <varlistentry> 330 + <term><literal>OCAMLPATH</literal></term> 331 + <listitem><para> 332 + This variable may contain an additional search path for package 333 + directories. It is treated as if the directories were prepended to 334 + the configuration variable <literal>path</literal>. 335 + </para> 336 + </listitem> 337 + </varlistentry> 338 + </variablelist> 339 + 340 + <variablelist> 341 + <varlistentry> 342 + <term><literal>OCAMLFIND_DESTDIR</literal></term> 343 + <listitem><para> 344 + This variable overrides the configuration variable 345 + <literal>destdir</literal>. 346 + </para> 347 + </listitem> 348 + </varlistentry> 349 + </variablelist> 350 + 351 + <variablelist> 352 + <varlistentry> 353 + <term><literal>OCAMLFIND_METADIR</literal></term> 354 + <listitem><para> 355 + This variable overrides the configuration variable 356 + <literal>metadir</literal>. 357 + </para> 358 + </listitem> 359 + </varlistentry> 360 + </variablelist> 361 + 362 + <variablelist> 363 + <varlistentry> 364 + <term><literal>OCAMLFIND_COMMANDS</literal></term> <listitem><para> 365 + This variable overrides the configuration variables 366 + <literal>ocamlc</literal>, <literal>ocamlopt</literal>, 367 + <literal>ocamlcp</literal>, <literal>ocamlmktop</literal>, 368 + <literal>ocamldoc</literal>, <literal>ocamldep</literal>, and/or 369 + <literal>ocamlbrowser</literal>. 370 + Its value must conform to the syntax 371 + 372 + <programlisting> 373 + 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> 374 + </programlisting> 375 + </para> 376 + 377 + <para>Example: 378 + <programlisting> 379 + ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00 ocamlcp=ocamlcp-3.00 ocamlmktop=ocamlmktop-3.00 380 + </programlisting> 381 + </para> 382 + 383 + </listitem> 384 + </varlistentry> 385 + </variablelist> 386 + 387 + <variablelist> 388 + <varlistentry> 389 + <term><literal>CAMLLIB</literal> or <literal>OCAMLLIB</literal></term> 390 + <listitem><para> 391 + This variable overrides the configuration variable 392 + <literal>stdlib</literal>. 393 + </para> 394 + </listitem> 395 + </varlistentry> 396 + </variablelist> 397 + 398 + <variablelist> 399 + <varlistentry> 400 + <term><literal>OCAMLFIND_LDCONF</literal></term> 401 + <listitem><para> 402 + This variable overrides the configuration variable 403 + <literal>ldconf</literal>. 404 + </para> 405 + </listitem> 406 + </varlistentry> 407 + </variablelist> 408 + 409 + <variablelist> 410 + <varlistentry> 411 + <term><literal>OCAMLFIND_IGNORE_DUPS_IN</literal></term> 412 + <listitem><para> 413 + This variable instructs findlib not to emit warnings that packages 414 + or module occur several times. The variable must be set to the 415 + directory where the packages reside that are to be ignored for this 416 + warning. 417 + </para> 418 + </listitem> 419 + </varlistentry> 420 + </variablelist> 421 + 422 + 423 + </para> 424 + </refsect1> 425 + 426 + 427 + </refentry>
+420
vendor/opam/ocamlfind/doc/src/findlib_meta.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>META</refentrytitle> 5 + <manvolnum>5</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="META"> 10 + <refname>META</refname> 11 + <refpurpose>[File that specifies metainformation of OCaml packages]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsynopsisdiv> 16 + <title>GRAMMAR</title> 17 + <synopsis> 18 + metafile ::= entry* 19 + entry ::= assignment | addition | subpackage 20 + subpackage ::= "package" pkgname '(' metafile ')' 21 + assignment ::= variable_name [ formal_predicates ] '=' value 22 + addition ::= variable_name [ formal_predicates ] '+=' value 23 + formal_predicates ::= '(' formal_predicate { ',' formal_predicate } ')' 24 + variable_name ::= name 25 + formal_predicate ::= name | '-' name 26 + name ::= [ 'A'-'Z' 'a'-'z' '0'-'9' '_' '.' ]+ 27 + pkgname ::= '"' (character but not '.')* '"' 28 + value ::= '"' character* '"' 29 + </synopsis> 30 + </refsynopsisdiv> 31 + 32 + <refsect1> 33 + <title>DESCRIPTION</title> 34 + <para> 35 + If a package directory contains a file with the fixed name "META" it 36 + is interpreted as described here. The file is a sequence of entries 37 + following the given grammar; every entry defines a variable under a 38 + certain condition given by the list of formal predicates, or it 39 + introduces a subpackage. 40 + </para> 41 + 42 + <para> 43 + There is a list of predefined variables and a list of standard 44 + predicates. These variables define: required packages, description, version 45 + information, directories, archive files, and linker options. The 46 + predicates denote circumstances of the application of the variables: 47 + whether the bytecode or the native compiler is used, if there is a 48 + toploop compiled in, details of multi-threading execution, details of 49 + profiling. 50 + </para> 51 + </refsect1> 52 + 53 + <refsect1> 54 + <title>DETAILS OF THE FILE FORMAT</title> 55 + <para> 56 + The file consists of a sequence of entries which must be formed as the 57 + grammar prescribes. The lexical tokens are names, values, and 58 + interpunctuation like '(', ',' and so on. Note that linefeeds do not 59 + play a special role, i.e. an entry definition may be given in more than 60 + one line, or several definitions may occur on a single line. There may 61 + be comments which begin with '#' and run until the end of the line. 62 + </para> 63 + 64 + <para> 65 + Names are sequences of the characters A-Z, a-z, 0-9, or _. Names 66 + containing capital letters and names beginning with digits are 67 + allowed but not recommended. 68 + </para> 69 + 70 + <para> 71 + Values are enclosed between double quotes. Values may contain any 72 + character. The characters " and \ must be preceded by backslashes. 73 + </para> 74 + 75 + <para> 76 + Package names must not contain the '.' character because it is used 77 + as delimiter of compound names. 78 + </para> 79 + 80 + </refsect1> 81 + 82 + <refsect1> 83 + <title>MAIN PACKAGES AND SUBPACKAGES</title> 84 + <para> 85 + The outermost variable assignments and additions belong to the main 86 + package. The name of the main package is not defined within META; 87 + it is either the name of the directory containing META or the suffix 88 + of the META file (if the name of the META file is formed like 89 + META.name).</para> 90 + 91 + <para>The keyword <literal>package</literal> starts the definition 92 + of a subpackage. There must not be two such definitions with the 93 + same name. Within the parentheses, the variable assignments and 94 + additions refer to the subpackage. It is allowed that a subpackage 95 + contains further subpackages.</para> 96 + 97 + <para>The package name following <literal>package</literal> 98 + is the local name relative to the main package, i.e. the 99 + name of the main package is not mentioned. At all other places, 100 + however, the subpackage must be prefixed by the name of the 101 + containing package, separated by a '.'.</para> 102 + 103 + <para>Subpackages are independent of the containing package, except 104 + that the subpackage points to the same installation directory as 105 + the containing package (i.e. the location of the installation directory 106 + is inherited from the containing package).</para> 107 + </refsect1> 108 + 109 + 110 + <refsect1> 111 + <title>SEMANTICS OF VARIABLE DEFINITIONS</title> 112 + 113 + <para> 114 + In order to determine the value of a variable, first all assignments 115 + are inspected, and the most specific assignment is taken (if there is 116 + none, the empty string will be taken as value). In a second step, 117 + all additions are gone through one after the other in the order 118 + they occur in the file, and the values of all matching additions are 119 + appended to the current value. In the following, it is further 120 + clarified which assignment is the most specific, which additions 121 + actually match, and how the details of the value addition look like.</para> 122 + 123 + <para> The most specific assignment is selected upon a set of actual 124 + predicates, i.e. the set of predicates that are assumed to be true. 125 + The predicates occurring in the definitions of assignments and 126 + additions are called formal predicates. They may be positive or 127 + negative; the latter are prepended by a '-' sign. In order to 128 + determine the value after the evaluation of the assignments, the 129 + following rules apply: </para> 130 + 131 + <itemizedlist mark="bullet" spacing="compact"> 132 + <listitem> 133 + <para> An assignment can only be used if all positive formal 134 + predicates are included in the set of actual predicates, and if all 135 + negative formal predicates are not included in the set of actual 136 + predicates. Such an assignment is called 137 + <emphasis>applicable</emphasis>. If there is no such assignment, the 138 + variable will have no value. 139 + </para> 140 + </listitem> 141 + 142 + <listitem> 143 + <para> 144 + If there is more than one applicable assignment, the definition with 145 + the biggest number of formal predicates is selected. 146 + </para> 147 + </listitem> 148 + 149 + <listitem> 150 + <para> 151 + If there is still more than one applicable assignment, both applicable 152 + and with a maximum number of formal predicates, the definition that is defined 153 + first is selected. 154 + </para> 155 + </listitem> 156 + </itemizedlist> 157 + 158 + <para>An addition is matching when all positive formal predicates are 159 + included in the set of actual predicates, and all negative formal 160 + predicates are not included.</para> 161 + 162 + <para>The value of an addition is appended to the current value with 163 + implicit white space as separator.</para> 164 + 165 + </refsect1> 166 + 167 + <refsect1> 168 + <title>VARIABLES</title> 169 + 170 + <para> 171 + There is a set of variables with predefined meaning: 172 + </para> 173 + 174 + <itemizedlist mark="bullet" spacing="compact"> <listitem> <para> The 175 + variable "directory" redefines the location of the package 176 + directory. Normally, the META file is the first file read in the 177 + package directory, and before any other file is read, the "directory" 178 + variable is evaluated in order to see if the package directory must be 179 + changed. The value of the "directory" variable is determined with an 180 + empty set of actual predicates. The value must be either: an absolute 181 + path name of the alternate directory, or a path name relative to the 182 + stdlib directory of OCaml (written "+path"), or a normal relative path 183 + name (without special syntax). In the latter case, the interpretation 184 + depends on whether it is contained in a main or sub package, and 185 + whether the standard repository layout or the alternate layout is in 186 + effect (see <link linkend="site-lib">site-lib</link> for these terms). 187 + For a main package in standard layout the base directory is the 188 + directory physically containing the META file, and the relative path 189 + is interpreted for this base directory. For a main package in 190 + alternate layout the base directory is the directory physically 191 + containing the META.pkg files. The base directory for subpackages is 192 + the package directory of the containing package. (In the case 193 + that a subpackage definition does not have a "directory" setting, 194 + the subpackage simply inherits the package directory of the containing 195 + package. By writing a "directory" directive one can change this 196 + location again.) 197 + </para> </listitem> 198 + 199 + <listitem> 200 + <para> 201 + The variable "requires" specifies the list of required packages. The 202 + names of the packages must be separated by white space and/or commas. 203 + The names must be fully qualified (i.e. when they refer to a subpackage, 204 + the names of all containing packages must be prepended, separated by 205 + '.'). 206 + </para> 207 + </listitem> 208 + 209 + <listitem> 210 + <para> 211 + The variable "description" may include a short description of the 212 + package (displayed by <literal>ocamlfind list</literal>). 213 + </para> 214 + </listitem> 215 + 216 + <listitem> 217 + <para> 218 + The variable "version" specifies the version string. 219 + </para> 220 + </listitem> 221 + 222 + <listitem> 223 + <para> 224 + The variable "archive" specifies the list of archive files. These 225 + files should be given either as (1) plain names without any directory 226 + information; they are only searched in the package directory. 227 + (2) Or they have the form "+path" in which case the files are looked up 228 + relative to the standard library. (3) Or they have the form "@name/file" 229 + in which case the files are looked up in the package directory 230 + of another package. (4) Or they are given as absolute paths. 231 + </para> 232 + 233 + <para>The 234 + names of the files must be separated by white space and/or commas. 235 + In the preprocessor stage, the archive files are passed as extensions 236 + to the preprocessor (camlp4) call. In the linker stage (-linkpkg), the archive 237 + files are linked. In the compiler stage, the archive files are ignored. 238 + </para> 239 + 240 + <para> 241 + Note that "archive" should only be used for archive files that are 242 + intended to be included in executables or loaded into toploops. For 243 + modules loaded at runtime there is the separate variable "plugin". 244 + </listitem> 245 + 246 + <listitem> 247 + <para> 248 + The variable "plugin" specifies the plugin archives of the package. 249 + These can be dynamically loaded with the <literal>Fl_dynload</literal> 250 + module. The plugin archives can have ".cmo", ".cma", or ".cmxs" suffix. 251 + </para> 252 + </listitem> 253 + 254 + <listitem> 255 + <para> 256 + The variable "linkopts" specifies additional linker options. 257 + </para> 258 + </listitem> 259 + 260 + <listitem> 261 + <para> 262 + The variable "error" can be used to signal error conditions. When 263 + this variable is applicable, the ocaml compilers are stopped, and 264 + an error message is printed. The message is the value of the variable. 265 + </para> 266 + </listitem> 267 + 268 + <listitem> 269 + <para> 270 + The variable "warning" can be used to signal warnings. When 271 + this variable is applicable, the warning is printed, but the 272 + compilation continues. The message is the value of the variable. 273 + </para> 274 + </listitem> 275 + 276 + <listitem> 277 + <para> 278 + The variable "exists_if" can be used to disable subpackages. The 279 + value of "exists_if" is a file; the subpackage is hidden if this 280 + file does not exist. You can also enumerate several files, and the 281 + subpackage is hidden if none of the files exist. 282 + </para> 283 + </listitem> 284 + 285 + <listitem> 286 + <para> 287 + The variable "ppx" is a command that is added to the compiler invocation 288 + via the -ppx option (available since OCaml-4.01). If the command is 289 + relative to the current directory (e.g. ./cmd), the command is expected 290 + in the package directory. The special forms as defined for "archive" 291 + are also available (e.g. @otherpkg/cmd). Additional arguments can be 292 + specified on the ocamlfind command line with the -ppxopt option 293 + or the "ppxopt" variable. 294 + </para> 295 + </listitem> 296 + 297 + <listitem> 298 + <para> 299 + The variable "ppxopt" is a set of options that are added to the ppx 300 + rewriter invocation. The contents of the variable consists of one or 301 + several whitespace-separated parts. Every part consists of several 302 + comma-separated subparts; the first subpart indicates the package 303 + that contains the ppx rewriter invocation, the rest contain the options 304 + to be appended. If the option is a path relative to the current directory 305 + (e.g. ./foo.cma), the path is expanded relative to the package directory. 306 + The special forms as defined for "archive" are also available 307 + (e.g. @otherpkg/foo.cma). 308 + </para> 309 + </listitem> 310 + 311 + </itemizedlist> 312 + 313 + <para> 314 + It is possible to define additional variables but there is currently 315 + no software interpreting them. 316 + </para> 317 + </refsect1> 318 + 319 + 320 + <refsect1> 321 + <title>PREDICATES</title> 322 + 323 + <para> 324 + There is a list of standard predicates: 325 + </para> 326 + 327 + <itemizedlist mark="bullet" spacing="compact"> 328 + <listitem> 329 + <para> 330 + The "byte" predicate means that the bytecode compiler is used. 331 + </para> 332 + </listitem> 333 + 334 + <listitem> 335 + <para> 336 + The "native" predicate means that the native compiler is used. 337 + </para> 338 + </listitem> 339 + 340 + <listitem> 341 + <para> 342 + The "toploop" predicate means that the toploop is available in the 343 + linked program. It is only set when the toploop is running, not when 344 + the toploop is generated. 345 + </para> 346 + </listitem> 347 + 348 + <listitem> 349 + <para> 350 + The "create_toploop" predicate means that a toploop is created (using 351 + ocamlmktop). 352 + </para> 353 + </listitem> 354 + 355 + <listitem> 356 + <para> 357 + The "mt" predicate means that the program is multi-threaded. 358 + </para> 359 + </listitem> 360 + 361 + <listitem> 362 + <para> 363 + The "mt_posix" predicate means that in the case "mt" is set, too, the 364 + POSIX libraries are used to implement threads. 365 + </para> 366 + </listitem> 367 + 368 + <listitem> 369 + <para> 370 + The "mt_vm" predicate means that in the case "mt" is set, too, the 371 + VM-based libraries are used to implement threads. 372 + </para> 373 + </listitem> 374 + 375 + <listitem> 376 + <para> 377 + The "gprof" predicate means that in the case "native" is set, too, the 378 + program is compiled for profiling 379 + </para> 380 + </listitem> 381 + 382 + <listitem> 383 + <para> 384 + The "autolink" predicate means that ocamlc can/will perform automatic linking. 385 + </para> 386 + </listitem> 387 + 388 + <listitem> 389 + <para> 390 + The "preprocessor" predicate means that the META variables are scanned for 391 + preprocessor options.</para> 392 + </listitem> 393 + 394 + <listitem> 395 + <para> 396 + The "syntax" predicate means that the -syntax option is present on the 397 + command line.</para> 398 + </listitem> 399 + 400 + <listitem> 401 + <para> 402 + Legacy: The "plugin" predicate could be used in some versions of findlib 403 + to select cmxs archives instead of cmxa archives. This use is still possible 404 + but discouraged. 405 + </para> 406 + </listitem> 407 + 408 + </itemizedlist> 409 + 410 + <para>In addition to these predicates, there are package predicates 411 + for every package that is finally selected. Of course, this kind of 412 + predicate must not be used to select "directory" and "requires" 413 + variables, but for the other variables they are perfectly valid. 414 + The package predicates have the form "pkg_" plus the name of the 415 + package (fully qualified).</para> 416 + 417 + 418 + </refsect1> 419 + 420 + </refentry>
+181
vendor/opam/ocamlfind/doc/src/findlib_mli.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>Findlib</refentrytitle> 5 + <manvolnum>3</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="Findlib"> 10 + <refname>Findlib</refname> 11 + <refpurpose>[Module for package management]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsynopsisdiv> 16 + <title>SIGNATURE</title> 17 + <synopsis> 18 + module Findlib : 19 + sig 20 + <link linkend="Findlib.package-directory" 21 + endterm="val.Findlib.package-directory"></link> 22 + <link linkend="Findlib.package-property" 23 + endterm="val.Findlib.package-property"></link> 24 + <link linkend="Findlib.package-ancestors" 25 + endterm="val.Findlib.package-ancestors"></link> 26 + <link linkend="Findlib.package-deep-ancestors" 27 + endterm="val.Findlib.package-deep-ancestors"></link> 28 + <link linkend="Findlib.default-location" 29 + endterm="val.Findlib.default-location"></link> 30 + 31 + (* Note: This signature is incomplete. See findlib.mli for the 32 + * full signature. 33 + *) 34 + 35 + end 36 + </synopsis> 37 + </refsynopsisdiv> 38 + 39 + 40 + <refsect1> 41 + <title>PACKAGING</title> 42 + 43 + <para> 44 + The Findlib module is part of the "findlib" package. In order to link 45 + it in, it is sufficient to link "findlib" in, e.g. 46 + </para> 47 + 48 + <programlisting> 49 + ocamlfind ocamlc <replaceable>options</replaceable> -package findlib -linkpkg <replaceable>options</replaceable> 50 + </programlisting> 51 + 52 + <para> 53 + There are archives for the bytecode compiler and for the native 54 + compiler; for single-threaded and for multi-threaded applications, and 55 + there is a special addition for toploops. 56 + </para> 57 + </refsect1> 58 + 59 + 60 + <refsect1> 61 + <title>DESCRIPTION</title> 62 + 63 + <para> 64 + The Findlib module is the primary interface of the findlib library. It 65 + contains functions to lookup packages, to interpret <xref 66 + linkend="META" endterm="META"> files, and to determine the ancestors of 67 + packages. 68 + </para> 69 + 70 + 71 + <refsect2> 72 + <title><anchor id="Findlib.package-directory"> 73 + Findlib.package_directory <replaceable>pkg</replaceable></title> 74 + <programlisting id="val.Findlib.package-directory"> 75 + val package_directory : string -&gt; string 76 + </programlisting> 77 + <para> 78 + Gets the absolute path of the directory where the package 79 + <replaceable>pkg</replaceable> is stored. The exception Not_found is 80 + raised if the package could not be found. 81 + Other exceptions may occur as file I/O is done. 82 + </para> 83 + </refsect2> 84 + 85 + 86 + 87 + <refsect2> 88 + <title><anchor id="Findlib.package-property"> 89 + Findlib.package_property <replaceable>predicates</replaceable> 90 + <replaceable>pkg</replaceable> <replaceable>variable</replaceable> 91 + </title> 92 + <programlisting id="val.Findlib.package-property"> 93 + val package_property : string list -&gt; string -&gt; string -&gt; string 94 + </programlisting> 95 + <para> 96 + Determines the value of the <replaceable>variable</replaceable> 97 + defined in the <xref linkend="META" endterm="META"> file of package 98 + <replaceable>pkg</replaceable> with the given set of 99 + <replaceable>predicates</replaceable>. The exception Not_found is 100 + raised if the package or the variable could not be found. Other 101 + exceptions may occur as file I/O is done. 102 + </para> 103 + <refsect3> 104 + <title>Examples</title> 105 + <para> 106 + Get the value of the "requires" variable of package "p" with an empty 107 + set of predicates: 108 + </para> 109 + <programlisting> 110 + Findlib.package_property [] "p" "requires" 111 + </programlisting> 112 + <para> 113 + Get the value of the "archive" variable of package "p" for 114 + multi-threaded bytecode applications: 115 + </para> 116 + <programlisting> 117 + Findlib.package_property [ "mt"; "byte" ] "p" "archive" 118 + </programlisting> 119 + </refsect3> 120 + </refsect2> 121 + 122 + 123 + 124 + <refsect2> 125 + <title><anchor id="Findlib.package-ancestors"> 126 + Findlib.package_ancestors <replaceable>predicates</replaceable> 127 + <replaceable>pkg</replaceable> 128 + </title> 129 + <programlisting id="val.Findlib.package-ancestors"> 130 + val package_ancestors : string list -&gt; string -&gt; string list 131 + </programlisting> 132 + <para> 133 + Determines the direct ancestors of package 134 + <replaceable>pkg</replaceable> for the set of 135 + <replaceable>predicates</replaceable>. The returned list has no 136 + specific order. The exception Not_found is raised if the package could 137 + not be found. The exception Failure is raised if one of the ancestors 138 + could not be found, or if a circular dependency has been 139 + detected. Other exceptions may occur as file I/O is done. 140 + </para> 141 + </refsect2> 142 + 143 + 144 + 145 + <refsect2> 146 + <title><anchor id="Findlib.package-deep-ancestors"> 147 + Findlib.package_deep_ancestors <replaceable>predicates</replaceable> 148 + <replaceable>pkglist</replaceable> 149 + </title> 150 + <programlisting id="val.Findlib.package-deep-ancestors"> 151 + val package_deep_ancestors : string list -&gt; string list -&gt; string list 152 + </programlisting> 153 + <para> 154 + Determines the list of direct or indirect ancestors of the packages in 155 + <replaceable>pkglist</replaceable> for the set of 156 + <replaceable>predicates</replaceable>. The returned list is 157 + topologically sorted. 158 + The exception Not_found is raised if the package could 159 + not be found. The exception Failure is raised if one of the ancestors 160 + could not be found, or if a circular dependency has been 161 + detected. Other exceptions may occur as file I/O is done. 162 + </para> 163 + </refsect2> 164 + 165 + 166 + 167 + <refsect2> 168 + <title><anchor id="Findlib.default-location"> 169 + Findlib.default_location ()</title> 170 + <programlisting id="val.Findlib.default-location"> 171 + val default_location : unit -&gt; string 172 + </programlisting> 173 + <para> 174 + Gets the default location where new packages will be installed. 175 + </para> 176 + </refsect2> 177 + 178 + </refsect1> 179 + 180 + </refentry> 181 +
+1436
vendor/opam/ocamlfind/doc/src/findlib_ocamlfind.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>ocamlfind</refentrytitle> 5 + <manvolnum>1</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="ocamlfind"> 10 + <refname>ocamlfind</refname> 11 + <refpurpose>[Command-line interface of the Package manager]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsynopsisdiv> 16 + <title>SYNOPSIS</title> 17 + <synopsis> 18 + <link linkend="ocamlfind.query">ocamlfind query [-help | other options] <replaceable>package_name</replaceable> ...</link> 19 + or: <link linkend="ocamlfind.ocamlc">ocamlfind ocamlc [-help | other options] <replaceable>file</replaceable> ...</link> 20 + or: <link linkend="ocamlfind.ocamlcp">ocamlfind ocamlcp [-help | other options] <replaceable>file</replaceable> ...</link> 21 + or: <link linkend="ocamlfind.ocamlmktop">ocamlfind ocamlmktop [-help | other options] <replaceable>file</replaceable> ...</link> 22 + or: <link linkend="ocamlfind.ocamlopt">ocamlfind ocamlopt [-help | other options] <replaceable>file</replaceable> ...</link> 23 + or: <link linkend="ocamlfind.ocamldoc">ocamlfind ocamldoc [-help | other options] <replaceable>file</replaceable> ...</link> 24 + or: <link linkend="ocamlfind.ocamldep">ocamlfind ocamldep [-help | other options] <replaceable>file</replaceable> ...</link> 25 + or: <link linkend="ocamlfind.ocamlmklib">ocamlfind ocamlmklib [-help | other options] <replaceable>file</replaceable> ...</link> 26 + or: <link linkend="ocamlfind.ocamlbrowser">ocamlfind ocamlbrowser [-help | other options]</link> 27 + or: <link linkend="ocamlfind.install">ocamlfind install [-help | other options] <replaceable>package_name</replaceable> <replaceable>file</replaceable> ...</link> 28 + or: <link linkend="ocamlfind.remove">ocamlfind remove [-help | other options] <replaceable>package_name</replaceable></link> 29 + or: <link linkend="ocamlfind.list">ocamlfind lint <replaceable>META</replaceable></link> 30 + or: <link linkend="ocamlfind.list">ocamlfind list [-describe]</link> 31 + or: <link linkend="ocamlfind.printppx">ocamlfind printppx [-help | other options] <replaceable>package_name</replaceable> ...</link> 32 + or: <link linkend="ocamlfind.printconf">ocamlfind printconf [ variable ]</link> 33 + or: <link linkend="ocamlfind.pkgcmd">ocamlfind <replaceable>package</replaceable>/<replaceable>command</replaceable> <replaceable>arg</replaceable> ...</link> 34 + 35 + Optional toolchain selection by: 36 + <link linkend="ocamlfind.toolchain">ocamlfind -toolchain <replaceable>name</replaceable> ...</link> 37 + </synopsis> 38 + </refsynopsisdiv> 39 + 40 + 41 + <!-- ********************************************************************** --> 42 + 43 + <refsect1> 44 + <title><anchor id="ocamlfind.query"> 45 + THE "query" SUBCOMMAND 46 + </title> 47 + 48 + <refsect2> 49 + <title>Synopsis</title> 50 + <programlisting> 51 + ocamlfind query [ -predicates <replaceable>p</replaceable> | 52 + -format <replaceable>f</replaceable> | 53 + -long-format | -l | 54 + -i-format | 55 + -l-format | 56 + -a-format | 57 + -o-format | 58 + -p-format | 59 + -prefix <replaceable>p</replaceable> | 60 + -separator <replaceable>s</replaceable> | 61 + -suffix <replaceable>s</replaceable> | 62 + -pp | 63 + -descendants | -d | 64 + -recursive | -r 65 + -qe | -qo] <replaceable>package</replaceable> ... 66 + </programlisting> 67 + </refsect2> 68 + 69 + <refsect2> <title>Description</title> 70 + 71 + <para> This command looks packages up, sorts them optionally, and 72 + prints attributes of them. If the option -recursive (short: -r) is not 73 + specified, exactly the packages given on the command line are looked 74 + up; if -recursive is present, the packages and all their ancestors, or 75 + if -descendants (short: -d) is present, too, all their descendants are printed. 76 + </para> 77 + 78 + <para> 79 + Package lookup and the selection of the attributes of the packages can 80 + be modified by specifying predicates; without a -predicates option the 81 + empty set of predicates is used. Note that even the lookup is 82 + influenced by the set of actual predicates as the "requires" variables 83 + may be conditional. 84 + </para> 85 + 86 + <para> 87 + What is printed about a package depends on the specified format; there 88 + are a number of options that modify the format. Some formats denote 89 + sets of values (such as -format %a), in which case multiple output 90 + records are printed for every package. (It is even possible to specify 91 + formats denoting the Cartesian product of sets, such as -format %a%o, 92 + but this does not make sense.) Before the first output record the 93 + prefix is printed, and the suffix after the last record. Between two 94 + records the separator is printed. 95 + </para> 96 + </refsect2> 97 + 98 + <refsect2> 99 + <title>Options</title> 100 + 101 + <variablelist> 102 + <varlistentry> 103 + <term>-predicates <replaceable>p</replaceable></term> 104 + <listitem><para>Sets the set of actual predicates. The argument 105 + <replaceable>p</replaceable> is a list of predicate names separated 106 + by commas and/or whitespace. If multiple -predicates options are 107 + given, the union of all specified sets is effectively used. 108 + </para></listitem> 109 + </varlistentry> 110 + <varlistentry> 111 + <term>-format <replaceable>f</replaceable></term> 112 + <listitem><para>Sets the format to the string 113 + <replaceable>f</replaceable>. Characters preceded by a percent sign 114 + are interpreted as placeholders; all other characters mean 115 + themselves. The defined placeholders are listed below. 116 + The default format is "%d". 117 + </para></listitem> 118 + </varlistentry> 119 + <varlistentry> 120 + <term>-long-format or -l</term> 121 + <listitem><para>Sets the format such that all relevant variables are printed. 122 + </para></listitem> 123 + </varlistentry> 124 + <varlistentry> 125 + <term>-i-format</term> 126 + <listitem><para>Same as -format "-I %d", i.e. directory options for ocamlc are printed. 127 + </para></listitem> 128 + </varlistentry> 129 + <varlistentry> 130 + <term>-l-format</term> 131 + <listitem><para>Same as -format "-ccopt -L%d", i.e. directory options for the 132 + linker backend are printed. 133 + </para></listitem> 134 + </varlistentry> 135 + <varlistentry> 136 + <term>-a-format</term> 137 + <listitem><para>Same as -format "%+a", i.e. archive file names are printed. 138 + </para></listitem> 139 + </varlistentry> 140 + <varlistentry> 141 + <term>-o-format</term> 142 + <listitem><para>Same as -format "%o", i.e. linker options are printed. 143 + </para></listitem> 144 + </varlistentry> 145 + <varlistentry> 146 + <term>-p-format</term> 147 + <listitem><para>Same as -format "%p", i.e. package names are printed. 148 + </para></listitem> 149 + </varlistentry> 150 + <varlistentry> 151 + <term>-prefix <replaceable>p</replaceable></term> 152 + <listitem><para>Sets the prefix that is printed before the first output record 153 + to the given string. The default prefix is the empty string. 154 + </para></listitem> 155 + </varlistentry> 156 + <varlistentry> 157 + <term>-suffix <replaceable>s</replaceable></term> 158 + <listitem><para>Sets the suffix that is printed after the last output record 159 + to the given string. The default suffix is the empty string. 160 + </para></listitem> 161 + </varlistentry> 162 + <varlistentry> 163 + <term>-separator <replaceable>s</replaceable></term> 164 + <listitem><para>Sets the separator that is printed between output records to 165 + the given string. The default separator is a linefeed character. 166 + </para></listitem> 167 + </varlistentry> 168 + <varlistentry> 169 + <term>-recursive or -r</term> 170 + <listitem><para>Not only the packages given on the command line are queried 171 + but also all ancestors or descendants. If the option -descendants is 172 + specified, too, the descendants are printed, otherwise the 173 + ancestors. The packages are topologically sorted. 174 + </para></listitem> 175 + </varlistentry> 176 + <varlistentry> 177 + <term>-descendants -d</term> 178 + <listitem><para>Instead of the ancestors the descendants of the 179 + given packages are queried. This option implies <literal>-recursive</literal>. 180 + </para></listitem> 181 + </varlistentry> 182 + <varlistentry> 183 + <term>-pp</term> 184 + <listitem><para>Query preprocessor packages (camlp4 syntax extensions). Normally 185 + it is not needed to set -predicates, except you need the archives (then add 186 + -predicates byte). This option implies <literal>-recursive</literal>. 187 + </para></listitem> 188 + </varlistentry> 189 + <varlistentry> 190 + <term>-qe</term> 191 + <listitem><para>Do not print most errors to stderr, just set the exit code 192 + </para></listitem> 193 + </varlistentry> 194 + <varlistentry> 195 + <term>-qo</term> 196 + <listitem><para>Do not print the regular output. 197 + </para></listitem> 198 + </varlistentry> 199 + 200 + </variablelist> 201 + </refsect2> 202 + 203 + <refsect2> 204 + <title>Placeholders meaningful in the -format option</title> 205 + 206 + <variablelist> 207 + <varlistentry> 208 + <term>%%</term> 209 + <listitem><para>Replaced by a single percent sign</para></listitem> 210 + </varlistentry> 211 + <varlistentry> 212 + <term>%p</term> 213 + <listitem><para>Replaced by the package name</para></listitem> 214 + </varlistentry> 215 + <varlistentry> 216 + <term>%d</term> 217 + <listitem><para>Replaced by the package directory</para></listitem> 218 + </varlistentry> 219 + <varlistentry> 220 + <term>%m</term> 221 + <listitem><para>Replaced by the path to the META file (new since findlib-1.6) 222 + </para></listitem> 223 + </varlistentry> 224 + <varlistentry> 225 + <term>%D</term> 226 + <listitem><para>Replaced by the package description</para></listitem> 227 + </varlistentry> 228 + <varlistentry> 229 + <term>%v</term> 230 + <listitem><para>Replaced by the version string</para></listitem> 231 + </varlistentry> 232 + <varlistentry> 233 + <term>%a</term> 234 + <listitem><para>Replaced by the archive filename. If there is more 235 + than one archive, a separate output record is printed for every archive. 236 + </para></listitem> 237 + </varlistentry> 238 + <varlistentry> 239 + <term>%+a</term> 240 + <listitem><para>Like %a, but the filenames are converted to absolute 241 + paths ("+" and "@" notations are resolved) 242 + </para></listitem> 243 + </varlistentry> 244 + <varlistentry> 245 + <term>%A</term> 246 + <listitem><para>Replaced by the list of archive filenames.</para></listitem> 247 + </varlistentry> 248 + <varlistentry> 249 + <term>%+A</term> 250 + <listitem><para>Like %A, but the filenames are converted to absolute 251 + paths ("+" and "@" notations are resolved) 252 + </para></listitem> 253 + <varlistentry> 254 + <term>%o</term> 255 + <listitem><para>Replaced by one linker option. If there is more than 256 + one option, a separate output record is printed for every option. 257 + </para></listitem> 258 + </varlistentry> 259 + <varlistentry> 260 + <term>%O</term> 261 + <listitem><para>Replaced by the list of linker options.</para></listitem> 262 + </varlistentry> 263 + <varlistentry> 264 + <term>%(<replaceable>property</replaceable>)</term> 265 + <listitem><para>Replaced by the value of the property named in parentheses, 266 + or the empty string if not defined.</para></listitem> 267 + </varlistentry> 268 + </variablelist> 269 + </refsect2> 270 + 271 + </refsect1> 272 + 273 + 274 + <!-- ********************************************************************** --> 275 + 276 + <refsect1> 277 + <title><anchor id="ocamlfind.ocamlc"> 278 + <anchor id="ocamlfind.ocamlcp"> 279 + <anchor id="ocamlfind.ocamlopt"> 280 + <anchor id="ocamlfind.ocamlmktop"> 281 + THE SUBCOMMANDS "ocamlc", "ocamlcp", "ocamlopt", and "ocamlmktop" 282 + </title> 283 + 284 + <refsect2> 285 + <title>Synopsis</title> 286 + <programlisting> 287 + ocamlfind ( ocamlc | ocamlcp | ocamlopt | ocamlmktop ) 288 + [ -package <replaceable>package-name-list</replaceable> | 289 + -linkpkg | 290 + -predicates <replaceable>pred-name-list</replaceable> | 291 + -dontlink <replaceable>package-name-list</replaceable> | 292 + -syntax <replaceable>pred-name-list</replaceable> | 293 + -ppopt <replaceable>camlp4-arg</replaceable> | 294 + -ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable> | 295 + -dllpath-pkg <replaceable>package-name-list</replaceable> | 296 + -dllpath-all | 297 + -passopt <replaceable>arg</replaceable> | 298 + -passrest <replaceable>arg...</replaceable> | 299 + -only-show | 300 + <replaceable>standard-option</replaceable> ] 301 + <replaceable>file</replaceable> ... 302 + </programlisting> 303 + </refsect2> 304 + 305 + <refsect2> 306 + <title>Description</title> 307 + 308 + <para> 309 + These subcommands are drivers for the compilers with the same names, 310 + i.e. "ocamlfind ocamlc" is a driver for "ocamlc", and so on. The 311 + subcommands understand all documented options of the compilers (here 312 + called <replaceable>standard-options</replaceable>), but also a few 313 + more options. If these subcommands are invoked only with standard 314 + options, they behave as if the underlying compiler had been called 315 + directly. The extra options modify this. 316 + </para> 317 + 318 + <para> 319 + Internally, these subcommands transform the given list of options and 320 + file arguments into an invocation of the driven compiler. This 321 + transformation only adds options and files, and the relative order of 322 + the options and files passed directly is unchanged. 323 + </para> 324 + 325 + <para> 326 + If there are -package options, additional directory search specifiers 327 + will be included ("-I", and "-ccopt -I"), such that files of all named 328 + packages and all ancestors can be found. 329 + </para> 330 + 331 + <para> 332 + The -linkpkg option causes that the packages listed in the -package 333 + options and all necessary ancestors are linked in. This means that the 334 + archive files implementing the packages are inserted into the list of 335 + file arguments. 336 + </para> 337 + 338 + <para> 339 + As the package database is queried a set of predicates is needed. Most 340 + predicates are set automatically, see below, but additional predicates 341 + can be given by a -predicates option. 342 + </para> 343 + 344 + <para> 345 + If there is a <literal>-syntax</literal> option, the drivers assume that 346 + a preprocessor is to be used. In this case, the preprocessor command 347 + is built first in a preprocessor stage, and this command is passed to the 348 + compiler using the <literal>-pp</literal> option. The set of predicates 349 + in the preprocessor stage is different from the set in the compiler/linker 350 + stage.</para> 351 + 352 + </refsect2> 353 + 354 + <refsect2> 355 + <title>Options for compiling and linking</title> 356 + 357 + <para> 358 + Here, only the additional options not interpreted by the compiler but 359 + by the driver itself, and options with additional effects are explained. 360 + Some options are only meaningful for the preprocessor call, and are 361 + explained below. 362 + </para> 363 + 364 + <variablelist> 365 + <varlistentry> 366 + <term>-package <replaceable>package-name-list</replaceable></term> 367 + <listitem><para>Adds the listed package names to the set of included 368 + packages. The package names may be separated by commas and/or 369 + whitespace. In the transformed command, for every package of the set 370 + of included packages and for any ancestor a directory search option 371 + is inserted after the already given options. This means that 372 + "-I" and "-ccopt -I" options are added for every package directory. 373 + </para></listitem> 374 + </varlistentry> 375 + <varlistentry> 376 + <term>-linkpkg</term> 377 + <listitem><para>Causes that in the transformed command all archives 378 + of the packages specified by -packages and all their ancestors are 379 + added to the file arguments. More precisely, these archives are 380 + inserted before the first given file argument. Furthermore, "-ccopt 381 + -L" options for all package directories, and the linker options of 382 + the selected packages are added, too. Note that the archives are 383 + inserted in topological order while the linker options are added in 384 + reverse toplogical order. 385 + </para></listitem> 386 + </varlistentry> 387 + <varlistentry> 388 + <term>-predicates <replaceable>pred-name-list</replaceable></term> 389 + <listitem><para>Adds the given predicates to the set of actual 390 + predicates. The predicates must be separated by commas and/or 391 + whitespace. 392 + </para></listitem> 393 + </varlistentry> 394 + <varlistentry> 395 + <term>-dontlink <replaceable>package-name-list</replaceable></term> 396 + <listitem><para>This option modifies the behaviour of 397 + -linkpkg. Packages specified here and all ancestors are not linked 398 + in. Again the packages are separated by commas and/or whitespace. 399 + </para></listitem> 400 + </varlistentry> 401 + <varlistentry> 402 + <term>-dllpath-pkg <replaceable>package-name-list</replaceable></term> 403 + <listitem><para>For these packages <literal>-dllpath</literal> options 404 + are added to the compiler command. This may be useful when the ld.conf 405 + file is not properly configured.</para></listitem> 406 + </varlistentry> 407 + <varlistentry> 408 + <term>-dllpath-all</term> 409 + <listitem><para>For all linked packages <literal>-dllpath</literal> options 410 + are added to the compiler command. This may be useful when the ld.conf 411 + file is not properly configured.</para></listitem> 412 + </varlistentry> 413 + <varlistentry> 414 + <term>-passopt <replaceable>arg</replaceable></term> 415 + <listitem><para>The argument <replaceable>arg</replaceable> is 416 + passed directly to the underlying compiler. This is needed to 417 + specify undocumented compiler options. 418 + </para></listitem> 419 + </varlistentry> 420 + <varlistentry> 421 + <term>-passrest <replaceable>arg...</replaceable></term> 422 + <listitem><para>All following arguments <replaceable>arg...</replaceable> are 423 + passed directly to the underlying compiler. This is needed to 424 + specify undocumented compiler options. 425 + </para></listitem> 426 + <varlistentry> 427 + <term>-only-show</term> 428 + <listitem><para>Only prints the constructed command (ocamlc/ocamlopt) to 429 + stdout, but does not execute the command. (This is for the unlikely event 430 + that you need a wrapper around ocamlfind.) 431 + </para></listitem> 432 + </varlistentry> 433 + 434 + <varlistentry> 435 + <term>-verbose</term> 436 + <listitem><para>This standard option is interpreted by the driver, too. 437 + </para></listitem> 438 + </varlistentry> 439 + <varlistentry> 440 + <term>-thread</term> 441 + <listitem><para>This standard option causes that the predicate "mt" 442 + is added to the set of actual predicates. If POSIX threads are available, 443 + the predicate "mt_posix" is selected, too. If only VM threads are 444 + available, the predicate "mt_vm" is included into the set, and the 445 + compiler switch is changed into -vmthread. 446 + </para> 447 + <para>Note that the presence of the "mt" predicate triggers special 448 + fixup of the dependency graph (see below).</para> 449 + </listitem> 450 + </varlistentry> 451 + <varlistentry> 452 + <term>-vmthread</term> 453 + <listitem><para>This standard option causes that the predicates "mt" 454 + and "mt_vm" are added to the set of actual predicates. 455 + </para> 456 + <para>Note that the presence of the "mt" predicate triggers special 457 + fixup of the dependency graph (see below).</para> 458 + </listitem> 459 + </varlistentry> 460 + <varlistentry> 461 + <term>-p</term> 462 + <listitem><para>This standard option of "ocamlopt" causes that the 463 + predicate "gprof" is added to the set of actual predicates. 464 + </para></listitem> 465 + </varlistentry> 466 + 467 + </variablelist> 468 + 469 + </refsect2> 470 + 471 + <refsect2> 472 + <title>Options for preprocessing</title> 473 + 474 + <para> 475 + The options relevant for the preprocessor are the following: 476 + </para> 477 + 478 + <variablelist> 479 + <varlistentry> 480 + <term>-package <replaceable>package-name-list</replaceable></term> 481 + <listitem><para>These packages are considered while looking up the 482 + preprocessor arguments. (It does not cause problems that the same 483 + -package option is used for this purpose, because the set of predicates 484 + is different.) It is recommended to mention at least <literal>camlp4</literal> 485 + here if the preprocessor is going to be used. 486 + </para></listitem> 487 + </varlistentry> 488 + <varlistentry> 489 + <term>-syntax <replaceable>pred-name-list</replaceable></term> 490 + <listitem><para>These predicates are assumed to be true in addition 491 + to the standard preprocessor predicates. See below for a list. 492 + </para></listitem> 493 + </varlistentry> 494 + <varlistentry> 495 + <term>-ppopt <replaceable>camlp4-arg</replaceable></term> 496 + <listitem><para>This argument is passed to the camlp4 call. 497 + </para></listitem> 498 + </varlistentry> 499 + <varlistentry> 500 + <term>-ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable></term> 501 + <listitem><para>Add <replaceable>arg</replaceable> to the ppx 502 + preprocessor invocation specified via the "ppx" property in 503 + the META file of <replaceable>package</replaceable>. 504 + </para></listitem> 505 + </varlistentry> 506 + </variablelist> 507 + </refsect2> 508 + 509 + <refsect2> 510 + <title>Predicates for compiling and linking</title> 511 + 512 + <variablelist> 513 + <varlistentry> 514 + <term>byte</term> 515 + <listitem> 516 + <para> 517 + The "byte" predicate means that one of the bytecode compilers is 518 + used. It is automatically included into the predicate set if the 519 + "ocamlc", "ocamlcp", or "ocamlmktop" compiler is used. 520 + </para> 521 + </listitem> 522 + </varlistentry> 523 + 524 + <varlistentry> 525 + <term>native</term> 526 + <listitem> 527 + <para> 528 + The "native" predicate means that the native compiler is used. It is 529 + automatically included into the predicate set if the "ocamlopt" 530 + compiler is used. 531 + </para> 532 + </listitem> 533 + </varlistentry> 534 + 535 + <varlistentry> 536 + <term>toploop</term> 537 + <listitem> 538 + <para> 539 + The "toploop" predicate means that the toploop is available in the 540 + linked program. This predicate is only set when the toploop is actually 541 + being executed, not when the toploop is created (this changed in version 542 + 1.0.4 of findlib). 543 + </para> 544 + </listitem> 545 + </varlistentry> 546 + 547 + <varlistentry> 548 + <term>create_toploop</term> 549 + <listitem> 550 + <para> 551 + This predicate means that a toploop is being created (using 552 + ocamlmktop). 553 + </para> 554 + </listitem> 555 + </varlistentry> 556 + 557 + <varlistentry> 558 + <term>mt</term> 559 + <listitem> 560 + <para> 561 + The "mt" predicate means that the program is multi-threaded. It is 562 + automatically included into the predicate set if the -thread option is 563 + given. 564 + </para> 565 + </listitem> 566 + </varlistentry> 567 + 568 + <varlistentry> 569 + <term>mt_posix</term> 570 + <listitem> 571 + <para> 572 + The "mt_posix" predicate means that in the case "mt" is set, too, the 573 + POSIX libraries are used to implement threads. "mt_posix" is automatically 574 + included into the predicate set if the variable "type_of_threads" in the 575 + META description of the "threads" package has the value "posix". This 576 + is normally the case if "findlib" is configured for POSIX threads. 577 + </para> 578 + </listitem> 579 + </varlistentry> 580 + 581 + <varlistentry> 582 + <term>mt_vm</term> 583 + <listitem> 584 + <para> 585 + The "mt_vm" predicate means that in the case "mt" is set, too, the 586 + VM thread emulation is used to implement multi-threading. 587 + </para> 588 + </listitem> 589 + </varlistentry> 590 + 591 + <varlistentry> 592 + <term>gprof</term> 593 + <listitem> 594 + <para> 595 + The "gprof" predicate means that in the case "native" is set, too, the 596 + program is compiled for profiling. It is automatically included into 597 + the predicate set if "ocamlopt" is used and the -p option is in 598 + effect. 599 + </para> 600 + </listitem> 601 + </varlistentry> 602 + 603 + <varlistentry> 604 + <term>autolink</term> 605 + <listitem> 606 + <para> 607 + The "autolink" predicate means that ocamlc is able to perform automatic 608 + linking. It is automatically included into the predicate set if ocamlc 609 + knows automatic linking (from version 3.00), but it is not set if the 610 + -noautolink option is set. 611 + </para> 612 + </listitem> 613 + </varlistentry> 614 + 615 + <varlistentry> 616 + <term>syntax</term> 617 + <listitem><para>This predicate is set if there is a <literal>-syntax</literal> 618 + option. It is set both for the preprocessor and the compiler/linker stage, 619 + and it can be used to find out whether the preprocessor is enabled or not. 620 + </para></listitem> 621 + </varlistentry> 622 + 623 + </variablelist> 624 + 625 + </refsect2> 626 + 627 + <refsect2> 628 + <title>Predicates for preprocessing</title> 629 + 630 + <variablelist> 631 + <varlistentry> 632 + <term>preprocessor</term> 633 + <listitem><para>This predicate is always set while looking up the 634 + preprocessor arguments. It can be used to distinguish between the 635 + preprocessor stage and the compiler/linker stage.</para></listitem> 636 + </varlistentry> 637 + <varlistentry> 638 + <term>syntax</term> 639 + <listitem><para>This predicate is set if there is a <literal>-syntax</literal> 640 + option. It is set both for the preprocessor and the compiler/linker stage, 641 + and it can be used to find out whether the preprocessor is enabled or not. 642 + </para></listitem> 643 + </varlistentry> 644 + <varlistentry> 645 + <term>camlp4o</term> 646 + <listitem><para>This is the reserved predicate for the standard OCaml syntax. 647 + It can be used in the <literal>-syntax</literal> predicate list. 648 + </para></listitem> 649 + </varlistentry> 650 + <varlistentry> 651 + <term>camlp4r</term> 652 + <listitem><para>This is the reserved predicate for the revised OCaml syntax. 653 + It can be used in the <literal>-syntax</literal> predicate list. 654 + </para></listitem> 655 + </varlistentry> 656 + </variablelist> 657 + </refsect2> 658 + 659 + 660 + <refsect2> 661 + <title>Special behaviour of "ocamlmktop"</title> 662 + 663 + <para> As there is a special module <literal>Topfind</literal> that 664 + supports loading of packages in scripts, the "ocamlmktop" subcommand 665 + can add initialization code for this module. This extra code is 666 + linked into the executable if "findlib" is in the set of effectively 667 + linked packages. 668 + </para> 669 + 670 + </refsect2> 671 + 672 + 673 + <refsect2> 674 + <title>Fixup of the dependency graph for multi-threading</title> 675 + <para>For a number of reasons the presence of the "mt" predicate triggers 676 + that (1) the package "threads" is added to the list of required packages 677 + and (2) the package "threads" becomes prerequisite of all other packages 678 + (except of itself and a few hardcoded exceptions). The effect is that 679 + the options -thread and -vmthread automatically select the "threads" 680 + package, and that "threads" is inserted at the right position in the 681 + package list.</para> 682 + </refsect2> 683 + 684 + 685 + <refsect2> 686 + <title>Extended file naming</title> 687 + <para>At a number of places one can not only refer to files by absolute 688 + or relative path names, but also by extended names. These have two 689 + major forms: "+<replaceable>name</replaceable>" 690 + refers to the subdirectory <replaceable>name</replaceable> of the 691 + standard library directory, and "@<replaceable>name</replaceable>" 692 + refers to the package directory of the package <replaceable>name</replaceable>. 693 + Both forms can be continued by a path, e.g. "@netstring/netstring_top.cma". 694 + </para> 695 + 696 + <para> 697 + You can use extended names: (1) With <literal>-I</literal> options, 698 + (2) as normal file arguments of the compiler, (3) in the 699 + "archive" property of packages. 700 + </para> 701 + </refsect2> 702 + 703 + 704 + <refsect2> 705 + <title>How to set the names of the compiler executables</title> 706 + 707 + <para> Normally, the OCaml bytecode compiler can be called under the name 708 + <literal>ocamlc</literal>. However, this is not always true; sometimes a 709 + different name is chosen.</para> 710 + 711 + <para> You can instruct ocamlfind to call executables with other names than 712 + <literal>ocamlc</literal>, <literal>ocamlopt</literal>, 713 + <literal>ocamlmktop</literal>, and <literal>ocamlcp</literal>. If present, 714 + the environment variable <literal>OCAMLFIND_COMMANDS</literal> is interpreted 715 + as a mapping from the standard names to the actual names of the executables. It 716 + must have the following format: 717 + 718 + <programlisting> 719 + <replaceable>standardname1</replaceable>=<replaceable>actualname1</replaceable> <replaceable>standardname2</replaceable>=<replaceable>actualname2</replaceable> ... 720 + </programlisting> 721 + </para> 722 + 723 + <para>Example: You may set <literal>OCAMLFIND_COMMANDS</literal> as follows: 724 + 725 + <programlisting> 726 + OCAMLFIND_COMMANDS='ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00' 727 + export OCAMLFIND_COMMANDS 728 + </programlisting> 729 + </para> 730 + 731 + <para>Alternatively, you can change the configuration file 732 + <link linkend="findlib.conf">findlib.conf</link>.</para> 733 + </refsect2> 734 + 735 + </refsect1> 736 + 737 + <!-- ********************************************************************** --> 738 + 739 + <refsect1> 740 + <title><anchor id="ocamlfind.ocamlmklib"> 741 + THE SUBCOMMAND "ocamlmklib" 742 + </title> 743 + 744 + <refsect2> 745 + <title>Synopsis</title> 746 + <programlisting> 747 + ocamlfind ocamlmklib 748 + [ -package <replaceable>package-name-list</replaceable> | 749 + -predicates <replaceable>pred-name-list</replaceable> | 750 + -dllpath-pkg <replaceable>package-name-list</replaceable> | 751 + -dllpath-all | 752 + -passopt <replaceable>arg</replaceable> | 753 + -passrest <replaceable>arg...</replaceable> | 754 + <replaceable>standard-option</replaceable> ] 755 + <replaceable>file</replaceable> ... 756 + </programlisting> 757 + </refsect2> 758 + 759 + <refsect2> 760 + <title>Description</title> 761 + 762 + <para> 763 + This is a wrapper around ocamlmklib, and creates library archives and 764 + DLLs. In addition to the standard options, one can use -package to 765 + add the search path of packages. Note that no predicates are set by default - 766 + the wrapper does not know whether this is about byte or native code linking. 767 + </para> 768 + 769 + <para> 770 + This wrapper is mostly provided for completeness. 771 + </para> 772 + </refsect2> 773 + 774 + </refsect1> 775 + 776 + 777 + 778 + <!-- ********************************************************************** --> 779 + 780 + <refsect1> 781 + <title><anchor id="ocamlfind.ocamldep"> 782 + THE "ocamldep" SUBCOMMAND 783 + </title> 784 + 785 + <refsect2> 786 + <title>Synopsis</title> 787 + <programlisting> 788 + ocamlfind ocamldep [-package <replaceable>package-name-list</replaceable> | 789 + -syntax <replaceable>pred-name-list</replaceable> | 790 + -ppopt <replaceable>camlp4-arg</replaceable> | 791 + -passopt <replaceable>arg</replaceable> | 792 + -passrest <replaceable>arg...</replaceable> | 793 + -verbose | 794 + <replaceable>standard-option</replaceable>] <replaceable>file</replaceable> ... 795 + </programlisting> 796 + </refsect2> 797 + 798 + <refsect2><title>Description</title> 799 + <para> 800 + This command is a driver for the tool <literal>ocamldep</literal> of the 801 + OCaml distribution. This driver is only useful in conjunction with 802 + the preprocessor camlp4; otherwise it does not provide more functions 803 + than <literal>ocamldep</literal> itself. 804 + </para> 805 + </refsect2> 806 + 807 + <refsect2> 808 + <title>Options</title> 809 + 810 + <para> 811 + Here, only the additional options not interpreted by <literal>ocamldep</literal> 812 + but 813 + by the driver itself, and options with additional effects are explained. 814 + </para> 815 + 816 + <variablelist> 817 + <varlistentry> 818 + <term>-package <replaceable>package-name-list</replaceable></term> 819 + <listitem><para>The packages named here are only used to look up the 820 + preprocessor options. The package <literal>camlp4</literal> should be 821 + specified anyway, but further packages that add capabilities to the 822 + preprocessor can also be passed.</para></listitem> 823 + </varlistentry> 824 + 825 + <varlistentry> 826 + <term>-syntax <replaceable>pred-name-list</replaceable></term> 827 + <listitem><para>The predicates that are in effect during the look-up 828 + of the preprocessor options. At least, either <literal>camlp4o</literal> 829 + (selecting the normal syntax), or <literal>camlp4r</literal> (selecting 830 + the revised syntax) should be specified.</para></listitem> 831 + </varlistentry> 832 + 833 + <varlistentry> 834 + <term>-ppopt <replaceable>camlp4-arg</replaceable></term> 835 + <listitem><para>An option that is passed through to the camlp4 call.</para> 836 + </listitem> 837 + </varlistentry> 838 + 839 + <varlistentry> 840 + <term>-passopt <replaceable>arg</replaceable></term> 841 + <listitem><para>An option that is passed through to the ocamldep call.</para> 842 + </listitem> 843 + </varlistentry> 844 + 845 + <varlistentry> 846 + <term>-passrest <replaceable>arg...</replaceable></term> 847 + <listitem><para>All further arguments are passed down to ocamldep 848 + unprocessed</para> 849 + </listitem> 850 + </varlistentry> 851 + 852 + <varlistentry> 853 + <term>-verbose</term> 854 + <listitem><para>Displays the resulting ocamldep command (for debugging) 855 + </para></listitem> 856 + </varlistentry> 857 + </variablelist> 858 + 859 + </refsect2> 860 + 861 + <refsect2> 862 + <title>Example</title> 863 + 864 + <para>A typical way of using this driver: 865 + 866 + <programlisting> 867 + ocamlfind ocamldep -package camlp4,xstrp4 -syntax camlp4r file1.ml file2.ml 868 + </programlisting> 869 + 870 + This command outputs the dependencies of <literal>file1.ml</literal> and 871 + <literal>file2.ml</literal>, although these modules make use of the 872 + syntax extensions provided by <literal>xstrp4</literal> and are written 873 + in revised syntax. 874 + </para> 875 + </refsect2> 876 + 877 + </refsect1> 878 + 879 + 880 + <!-- ********************************************************************** --> 881 + 882 + <refsect1> 883 + <title><anchor id="ocamlfind.ocamlbrowser"> 884 + THE "ocamlbrowser" SUBCOMMAND 885 + </title> 886 + 887 + <refsect2> 888 + <title>Synopsis</title> 889 + <programlisting> 890 + ocamlfind ocamlbrowser [-package <replaceable>package-name-list</replaceable> | 891 + -all | 892 + -passopt <replaceable>arg</replaceable> 893 + -passrest ] 894 + </programlisting> 895 + </refsect2> 896 + 897 + <refsect2><title>Description</title> 898 + <para> 899 + This driver calls the <literal>ocamlbrowser</literal> with package options. 900 + With <literal>-package</literal>, the specified packages are included into 901 + the search path of the browser, and the modules of these packages become 902 + visible (in addition to the standard library). The option <literal>-all</literal> causes that all packages are selected that are managed by findlib.</para> 903 + 904 + <para> 905 + As for other drivers, the options <literal>-passopt</literal> and 906 + <literal>-passrest</literal> can be used 907 + to pass arguments directly to the <literal>ocamlbrowser</literal> program. 908 + </para> 909 + </refsect2> 910 + </refsect1> 911 + 912 + <!-- ********************************************************************** --> 913 + 914 + <refsect1> 915 + <title><anchor id="ocamlfind.ocamldoc"> 916 + THE SUBCOMMAND "ocamldoc" 917 + </title> 918 + 919 + <refsect2> 920 + <title>Synopsis</title> 921 + <programlisting> 922 + ocamlfind ocamldoc 923 + [ -package <replaceable>package-name-list</replaceable> | 924 + -predicates <replaceable>pred-name-list</replaceable> | 925 + -syntax <replaceable>pred-name-list</replaceable> | 926 + -ppopt <replaceable>camlp4-arg</replaceable> | 927 + <replaceable>standard-option</replaceable> ] 928 + <replaceable>file</replaceable> ... 929 + </programlisting> 930 + </refsect2> 931 + 932 + <refsect2> 933 + <title>Description</title> 934 + 935 + <para> 936 + This subcommand is a driver for ocamldoc. It undestands all options 937 + ocamldoc supports plus the mentioned findlib options. Basically, 938 + the -package options are translated into -I options, and the selected 939 + syntax options are translated into camlp4 options. 940 + </para> 941 + </refsect2> 942 + 943 + <refsect2> 944 + <title>Options</title> 945 + 946 + <para> 947 + Here, only the additional options not interpreted by <literal>ocamldep</literal> 948 + but 949 + by the driver itself, and options with additional effects are explained. 950 + </para> 951 + 952 + <variablelist> 953 + <varlistentry> 954 + <term>-package <replaceable>package-name-list</replaceable></term> 955 + <listitem><para>Adds the listed package names to the set of included 956 + packages. The package names may be separated by commas and/or 957 + whitespace. In the transformed command, for every package of the set 958 + of included packages and for any ancestor a directory search option 959 + is inserted after the already given options. This means that 960 + "-I" options are added for every package directory. 961 + </para></listitem> 962 + </varlistentry> 963 + 964 + <varlistentry> 965 + <term>-predicates <replaceable>pred-name-list</replaceable></term> 966 + <listitem><para>Adds the given predicates to the set of actual 967 + predicates. The predicates must be separated by commas and/or 968 + whitespace. 969 + </para></listitem> 970 + </varlistentry> 971 + 972 + <varlistentry> 973 + <term>-syntax <replaceable>pred-name-list</replaceable></term> 974 + <listitem><para>The predicates that are in effect during the look-up 975 + of the preprocessor options. At least, either <literal>camlp4o</literal> 976 + (selecting the normal syntax), or <literal>camlp4r</literal> (selecting 977 + the revised syntax) should be specified.</para></listitem> 978 + </varlistentry> 979 + 980 + <varlistentry> 981 + <term>-ppopt <replaceable>camlp4-arg</replaceable></term> 982 + <listitem><para>An option that is passed through to the camlp4 call.</para> 983 + </listitem> 984 + </varlistentry> 985 + </variablelist> 986 + </refsect2> 987 + </refsect1> 988 + 989 + 990 + <!-- ********************************************************************** --> 991 + 992 + <!-- 993 + 994 + <refsect1> 995 + <title><anchor id="ocamlfind.use"> 996 + THE "use" SUBCOMMAND 997 + </title> 998 + 999 + <refsect2> 1000 + <title>Synopsis</title> 1001 + <programlisting> 1002 + ocamlfind use [-p <replaceable>prefix</replaceable>] <replaceable>package_name</replaceable> ... 1003 + </programlisting> 1004 + </refsect2> 1005 + 1006 + <refsect2> 1007 + <title>Description</title> 1008 + 1009 + <para> 1010 + This subcommand should not be used any longer. It is equivalent to the 1011 + "query" subcommand with -i-format and -separator " ". 1012 + </para> 1013 + </refsect2> 1014 + </refsect1> 1015 + 1016 + --> 1017 + 1018 + <!-- ********************************************************************** --> 1019 + 1020 + <refsect1> 1021 + <title><anchor id="ocamlfind.install"> 1022 + THE "install" SUBCOMMAND 1023 + </title> 1024 + 1025 + <refsect2> 1026 + <title>Synopsis</title> 1027 + <programlisting> 1028 + ocamlfind install [ -destdir <replaceable>directory</replaceable> ] 1029 + [ -metadir <replaceable>directory</replaceable> ] 1030 + [ -ldconf <replaceable>path</replaceable> ] 1031 + [ -dont-add-directory-directive ] 1032 + [ -patch-version <replaceable>string</replaceable> ] 1033 + [ -patch-rmpkg <replaceable>name</replaceable> ] 1034 + [ -patch-archives ] 1035 + [ -dll ] [ -nodll ] [ -optional ] [ -add ] 1036 + <replaceable>package_name</replaceable> <replaceable>file</replaceable> ... 1037 + </programlisting> 1038 + </refsect2> 1039 + 1040 + <refsect2> 1041 + <title>Description</title> 1042 + <para> 1043 + This subcommand installs a new package either at the default location 1044 + (see the variable <literal>destdir</literal> of 1045 + <link linkend="findlib.conf">findlib.conf</link>), or in the directory 1046 + specified by the -destdir option. This 1047 + means that a new package directory is created and that the files on 1048 + the command line are copied to this directory. It is required that a 1049 + <literal>META</literal> file is one of the files copied to the target 1050 + directory. 1051 + </para> 1052 + 1053 + <para> 1054 + Note that package directories should be flat (no 1055 + subdirectories). Existing packages are never overwritten. 1056 + </para> 1057 + 1058 + <para> 1059 + It is possible to have a separate directory for all the META files. If 1060 + you want that, you have either to set the variable 1061 + <literal>metadir</literal> of 1062 + <link linkend="findlib.conf">findlib.conf</link>, or to specify the 1063 + -metadir option. In this case, the file called META is copied to the 1064 + specified directory and renamed to META.p (where p is the package 1065 + name), while all the other files are copied to the package 1066 + directory as usual. Furthermore, the META file is modified such that the 1067 + <literal>directory</literal> variable contains the path of the package 1068 + directory. 1069 + </para> 1070 + 1071 + <para> 1072 + The option -dont-add-directory-directive prevents the installer from 1073 + adding a <literal>directory</literal> variable. 1074 + </para> 1075 + 1076 + <para> 1077 + If there are files ending in the suffixes <literal>.so</literal> or 1078 + <literal>.dll</literal>, the package directory will be added to the 1079 + DLL configuration file <literal>ld.conf</literal>, such that the dynamic 1080 + loader can find the DLL. The location of this file can be overridden by 1081 + the -ldconf option. To turn this feature off, use "-ldconf ignore"; 1082 + this causes that the ld.conf file is not modified. 1083 + </para> 1084 + 1085 + <para> 1086 + However, if there is a stublibs directory in site-lib, the DLLs are not 1087 + installed in the package directory, but in this directory that is 1088 + shared by all packages that are installed at the same location. 1089 + In this case, the configuration file <literal>ld.conf</literal> is 1090 + not modified, so you do not need to say "-ldconf ignore" if you 1091 + prefer this style of installation. 1092 + </para> 1093 + 1094 + <para> 1095 + The options -dll and -nodll can be used to control exactly which files 1096 + are considered as DLLs and which not. By default, the mentioned 1097 + suffix rule is in effect: files ending in ".so" (Unix) or ".dll" 1098 + (Windows) are DLLs. The switch -dll changes this, and all following 1099 + files are considered as DLLs, regardless of their suffix. The switch 1100 + -nodll expresses that the following files are not DLLs, even if they 1101 + have a DLL-like suffix. For example, in the following call the files 1102 + f1 and f2 are handled by the suffix rule; f3 and f4 are DLLs anyway; 1103 + and f5 and f6 are not DLLs: 1104 + 1105 + <programlisting> 1106 + ocamlfind install p f1 f2 -dll f3 f4 -nodll f5 f6 1107 + </programlisting> 1108 + </para> 1109 + 1110 + <para> 1111 + The switch -optional declares that all following files are optional, 1112 + i.e. the command will not fail if files do not exist. 1113 + </para> 1114 + 1115 + <para> 1116 + The -patch options may be used to change the contents of the META files 1117 + while it is being installed. The option -patch-version changes the 1118 + contents of the top-level "version" variable. The option -patch-rmpkg 1119 + removes the given subpackage. The option -patch-archives is experimental, 1120 + in particular it removes all non-existing files from "archive" variables, 1121 + and even whole subpackages if the archives are missing. 1122 + </para> 1123 + 1124 + <para> 1125 + The effect of -add is to add further files to an already installed 1126 + packages. 1127 + </para> 1128 + 1129 + </refsect2> 1130 + 1131 + </refsect1> 1132 + 1133 + 1134 + <!-- ********************************************************************** --> 1135 + 1136 + <refsect1> 1137 + <title><anchor id="ocamlfind.remove"> 1138 + THE "remove" SUBCOMMAND 1139 + </title> 1140 + 1141 + <refsect2> 1142 + <title>Synopsis</title> 1143 + <programlisting> 1144 + ocamlfind remove [ -destdir <replaceable>directory</replaceable> ] 1145 + [ -metadir <replaceable>directory</replaceable> ] 1146 + [ -ldconf <replaceable>path</replaceable> ] 1147 + <replaceable>package_name</replaceable> 1148 + </programlisting> 1149 + </refsect2> 1150 + 1151 + <refsect2> 1152 + <title>Description</title> 1153 + <para> 1154 + The package will removed if it is installed at the default location 1155 + (see the variable <literal>destdir</literal> of 1156 + <link linkend="findlib.conf">findlib.conf</link>). If the package 1157 + resides at a different location, it will not be removed by default; 1158 + however, you can pass an alternate directory for packages by the 1159 + -destdir option. (This must be the same directory as specified at 1160 + installation time.) 1161 + </para> 1162 + 1163 + <para> 1164 + Note that package directories should be flat (no subdirectories); this 1165 + subcommand cannot remove deep package directories. 1166 + </para> 1167 + 1168 + <para> 1169 + If you have a separate directory for META files, you must either 1170 + configure this directory by the <literal>metadir</literal> variable 1171 + of <link linkend="findlib.conf">findlib.conf</link>, or by specifying 1172 + the -metadir option. 1173 + </para> 1174 + 1175 + <para> 1176 + The command does not fail if the package and/or the META 1177 + file cannot be located. You will get a warning only in this case. 1178 + </para> 1179 + 1180 + <para> 1181 + If the package directory is mentioned in the <literal>ld.conf</literal> 1182 + configuration file for DLLs, it will be tried to remove this entry 1183 + from the file. The location of this file can be overridden by 1184 + the -ldconf option. To turn this feature off, use "-ldconf ignore"; 1185 + this causes that the ld.conf file is not modified. 1186 + </para> 1187 + 1188 + <para> 1189 + If there is a stublibs directory, it is checked whether the package 1190 + owns any of the files in this directory, and the owned files will 1191 + be deleted. 1192 + </para> 1193 + 1194 + </refsect2> 1195 + </refsect1> 1196 + 1197 + 1198 + <!-- ********************************************************************** --> 1199 + 1200 + <refsect1> 1201 + <title><anchor id="ocamlfind.list"> 1202 + THE "list" SUBCOMMAND 1203 + </title> 1204 + 1205 + <refsect2> 1206 + <title>Synopsis</title> 1207 + <programlisting> 1208 + ocamlfind list [-describe] 1209 + </programlisting> 1210 + </refsect2> 1211 + 1212 + <refsect2> 1213 + <title>Description</title> 1214 + <para> 1215 + This command lists all packages in the search path. The option -describe 1216 + outputs the package descriptions, too. 1217 + </para> 1218 + </refsect2> 1219 + </refsect1> 1220 + 1221 + <!-- ********************************************************************** --> 1222 + 1223 + <refsect1> 1224 + <title><anchor id="ocamlfind.printppx"> 1225 + THE "printppx" SUBCOMMAND 1226 + </title> 1227 + 1228 + <refsect2> 1229 + <title>Synopsis</title> 1230 + <programlisting> 1231 + ocamlfind printppx 1232 + [ -predicates <replaceable>pred-name-list</replaceable> ] 1233 + [ -ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable> ] 1234 + <replaceable>package</replaceable> ... 1235 + </programlisting> 1236 + </refsect2> 1237 + 1238 + <refsect2> 1239 + <title>Description</title> 1240 + <para> 1241 + This command prints the ppx preprocessor options as they would 1242 + occur in an OCaml compiler invocation for the packages listed in 1243 + the command. The output includes one "-ppx" option for each 1244 + preprocessor. The possible options have the same meaning as for 1245 + "ocamlfind ocamlc". The option "-predicates" adds assumed 1246 + predicates and 1247 + "-ppxopt <replaceable>package</replaceable>,<replaceable>arg</replaceable>" 1248 + adds "<replaceable>arg</replaceable>" to the ppx invocation of 1249 + package <replaceable>package</replaceable>. 1250 + </para> 1251 + 1252 + <para> 1253 + The output of "ocamlfind printppx" will contain quotes 1254 + "<literal>"</literal>" for ppx commands that contain 1255 + space-separated arguments. In this case <literal>$(ocamlfind 1256 + printppx ...)</literal> won't work as naively expected, because 1257 + many shells (including bash and dash) perform field splitting on 1258 + the result of command substitutions without honoring quotes. 1259 + </para> 1260 + </refsect2> 1261 + </refsect1> 1262 + 1263 + <!-- ********************************************************************** --> 1264 + 1265 + <refsect1> 1266 + <title><anchor id="ocamlfind.lint"> 1267 + THE "lint" SUBCOMMAND 1268 + </title> 1269 + 1270 + <refsect2> 1271 + <title>Synopsis</title> 1272 + <programlisting> 1273 + ocamlfind lint <replaceable>file</replaceable> 1274 + </programlisting> 1275 + </refsect2> 1276 + 1277 + <refsect2> 1278 + <title>Description</title> 1279 + <para> 1280 + Checks the META file, and reports possible problems. 1281 + </para> 1282 + </refsect2> 1283 + </refsect1> 1284 + 1285 + <!-- ********************************************************************** --> 1286 + 1287 + <refsect1> 1288 + <title><anchor id="ocamlfind.printconf"> 1289 + THE "printconf" SUBCOMMAND 1290 + </title> 1291 + 1292 + <refsect2> 1293 + <title>Synopsis</title> 1294 + <programlisting> 1295 + ocamlfind printconf [ conf | path | destdir | metadir | metapath | stdlib | ldconf ] 1296 + </programlisting> 1297 + </refsect2> 1298 + 1299 + <refsect2> 1300 + <title>Description</title> 1301 + <para> 1302 + This command prints the effective configuration after reading the 1303 + configuration file, and after applying the various environment 1304 + variables overriding settings. When called without arguments, the command 1305 + prints all configuration options in a human-readable form. When called 1306 + with an argument, only the value of the requested option is printed without 1307 + explaining texts: 1308 + </para> 1309 + 1310 + <variablelist> 1311 + <varlistentry> 1312 + <term><literal>conf</literal></term> 1313 + <listitem><para>Prints the location of the configuration file findlib.conf 1314 + </para></listitem> 1315 + </varlistentry> 1316 + <varlistentry> 1317 + <term><literal>path</literal></term> 1318 + <listitem><para>Prints the search path for packages. The members of the 1319 + path are separated by linefeeds.</para></listitem> 1320 + </varlistentry> 1321 + <varlistentry> 1322 + <term><literal>destdir</literal></term> 1323 + <listitem><para>Prints the location where package are installed and 1324 + removed by default.</para></listitem> 1325 + </varlistentry> 1326 + <varlistentry> 1327 + <term><literal>metadir</literal></term> 1328 + <listitem><para>Prints the location where META files are installed and 1329 + removed (if the alternative layout is used).</para></listitem> 1330 + </varlistentry> 1331 + <varlistentry> 1332 + <term><literal>metapath</literal></term> 1333 + <listitem><para>Prints the path where the META file is installed for 1334 + a fictive package. The name of the package is marked with '%s' in the 1335 + path. For instance, this command could output "/some/path/%s/META" or 1336 + "/some/path/META.%s", depending on the layout.</para></listitem> 1337 + </varlistentry> 1338 + <varlistentry> 1339 + <term><literal>stdlib</literal></term> 1340 + <listitem><para>Prints the location of the standard library. 1341 + </para></listitem> 1342 + </varlistentry> 1343 + <varlistentry> 1344 + <term><literal>ldconf</literal></term> 1345 + <listitem><para>Prints the location of the ld.conf file 1346 + </para></listitem> 1347 + </varlistentry> 1348 + </variablelist> 1349 + 1350 + </refsect2> 1351 + </refsect1> 1352 + 1353 + 1354 + <!-- ********************************************************************** --> 1355 + 1356 + <refsect1> 1357 + <title><anchor id="ocamlfind.pkgcmd"> 1358 + THE SUBCOMMAND CALLING PACKAGE PROGRAMS 1359 + </title> 1360 + 1361 + <refsect2> 1362 + <title>Synopsis</title> 1363 + <programlisting> 1364 + ocamlfind <replaceable>pkg</replaceable>/<replaceable>cmd</replaceable> <replaceable>argument</replaceable> ... 1365 + </programlisting> 1366 + </refsect2> 1367 + 1368 + <refsect2> 1369 + <title>Description</title> 1370 + <para>This subcommand is useful to call programs that are installed in 1371 + package directories. It looks up the directory for 1372 + <replaceable>pkg</replaceable> and calls the command named 1373 + <replaceable>cmd</replaceable> in this directory. The remaining arguments 1374 + are passed to this command.</para> 1375 + 1376 + <para>argv(0) contains the absolute path to the command, and argv(1) and 1377 + the following argv entries contain the arguments. The working directory 1378 + is not changed.</para> 1379 + 1380 + <para>Example: To call the program "x" that is installed in package "p", 1381 + with arguments "y" and "z", run:</para> 1382 + 1383 + <programlisting> 1384 + ocamlfind p/x y z 1385 + </programlisting> 1386 + 1387 + </refsect2> 1388 + </refsect1> 1389 + 1390 + 1391 + <refsect1> 1392 + <title> 1393 + CONFIGURATION FILE, ENVIRONMENT VARIABLES 1394 + </title> 1395 + 1396 + <para> The configuration file and environment variables are documented 1397 + in the manual page for 1398 + <link linkend="findlib.conf">findlib.conf</link>. 1399 + </para> 1400 + </refsect1> 1401 + 1402 + <!-- ********************************************************************** --> 1403 + 1404 + <refsect1> 1405 + <title><anchor id="ocamlfind.toolchain"> 1406 + HOW TO SET THE TOOLCHAIN 1407 + </title> 1408 + 1409 + <refsect2> 1410 + <title>Synopsis</title> 1411 + <programlisting> 1412 + ocamlfind -toolchain <replaceable>name</replaceable> ... 1413 + </programlisting> 1414 + </refsect2> 1415 + 1416 + <refsect2> 1417 + <title>Description</title> 1418 + <para>The -toolchain option can be given before any other command, 1419 + e.g. 1420 + <programlisting> 1421 + ocamlfind -toolchain foo ocamlc -c file.ml 1422 + </programlisting> 1423 + compiles file.ml with toolchain "foo". By selecting toolchains one 1424 + can switch to different command sets. For instance, the toolchain 1425 + "foo" may consist of a patched ocamlc compiler. 1426 + See <link linkend="findlib.conf">findlib.conf</link> how to 1427 + configure toolchains. 1428 + </para> 1429 + </refsect2> 1430 + </refsect1> 1431 + 1432 + </refentry> 1433 + 1434 + 1435 + 1436 +
+24
vendor/opam/ocamlfind/doc/src/findlib_ref.dsl
··· 1 + <!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [ 2 + <!ENTITY dbstyle SYSTEM "docbook.dsl" CDATA DSSSL> 3 + ]> 4 + 5 + <style-sheet> 6 + <style-specification use="docbook"> 7 + <style-specification-body> 8 + 9 + (define %footnotes-at-end% 10 + ;; Should footnotes appear at the end of HTML pages? 11 + #t) 12 + 13 + (define %html-ext% 14 + ;; Default extension for HTML output files 15 + ".html") 16 + 17 + (define %root-filename% 18 + ;; Name for the root HTML document 19 + "index") 20 + 21 + </style-specification-body> 22 + </style-specification> 23 + <external-specification id="docbook" document="dbstyle"> 24 + </style-sheet>
+61
vendor/opam/ocamlfind/doc/src/findlib_ref.sgml
··· 1 + <!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ 2 + <!ENTITY findlibmeta SYSTEM "findlib_meta.mod"> 3 + <!ENTITY findlibsitelib SYSTEM "findlib_sitelib.mod"> 4 + <!ENTITY findlibmli SYSTEM "findlib_mli.mod"> 5 + <!ENTITY findlibtopfind SYSTEM "findlib_topfind.mod"> 6 + <!ENTITY findlibocamlfind SYSTEM "findlib_ocamlfind.mod"> 7 + <!ENTITY findlibconf SYSTEM "findlib_conf.mod"> 8 + <!ENTITY % gps.common SYSTEM "../common.xml"> 9 + %gps.common; 10 + ]> 11 + 12 + <book> 13 + 14 + <title>The findlib Reference Manual</title> 15 + <bookinfo> 16 + <!-- <bookbiblio> --> 17 + <authorgroup> 18 + <author> 19 + <firstname>Gerd</firstname> 20 + <surname>Stolpmann</surname> 21 + <authorblurb> 22 + <para> 23 + <address> 24 + <email>gerd@gerd-stolpmann.de</email> 25 + </address> 26 + </para> 27 + </authorblurb> 28 + </author> 29 + </authorgroup> 30 + 31 + <copyright> 32 + <year>1999-2003</year><holder>Gerd Stolpmann</holder> 33 + </copyright> 34 + <!-- </bookbiblio> --> 35 + </bookinfo> 36 + 37 + <part> 38 + <title>Commands</title> 39 + &findlibocamlfind; 40 + </part> 41 + 42 + <part> 43 + <title>Files</title> 44 + &findlibmeta; 45 + 46 + &findlibconf; 47 + 48 + &findlibsitelib; 49 + </part> 50 + 51 + <part> 52 + <title>Library</title> 53 + <chapter> 54 + <title>The findlib library</title> 55 + <para> 56 + <ulink url="lib/index.html">The findlib library</ulink> 57 + </para> 58 + </chapter> 59 + </part> 60 + 61 + </book>
+17
vendor/opam/ocamlfind/doc/src/findlib_reference.sgml
··· 1 + <!DOCTYPE reference PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ 2 + <!ENTITY findlibmeta SYSTEM "findlib_meta.mod"> 3 + <!ENTITY findlibsitelib SYSTEM "findlib_sitelib.mod"> 4 + <!ENTITY findlibmli SYSTEM "findlib_mli.mod"> 5 + <!ENTITY findlibtopfind SYSTEM "findlib_topfind.mod"> 6 + <!ENTITY findlibocamlfind SYSTEM "findlib_ocamlfind.mod"> 7 + <!ENTITY findlibconf SYSTEM "findlib_conf.mod"> 8 + ]> 9 + 10 + <reference> 11 + <title>Reference</title> 12 + &findlibocamlfind; 13 + &findlibmeta; 14 + &findlibconf; 15 + &findlibsitelib; 16 + </reference> 17 +
+165
vendor/opam/ocamlfind/doc/src/findlib_sitelib.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>site-lib</refentrytitle> 5 + <manvolnum>5</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="site-lib"> 10 + <refname>site-lib</refname> 11 + <refpurpose>[Location of package directories]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsynopsisdiv> 16 + <title>STANDARD LAYOUT</title> 17 + <synopsis> 18 + ...somewhere in the filesystem hierarchy... 19 + | 20 + \ 21 + site-lib 22 + | 23 + +- (optional) stublibs 24 + +- (optional) postinstall 25 + +- (optional) postremove 26 + | 27 + +- <replaceable>package1</replaceable> 28 + | | 29 + | +- META 30 + | +- <replaceable>archive files</replaceable> 31 + | +- <replaceable>interface definitions</replaceable> 32 + | 33 + +- <replaceable>package2</replaceable> 34 + + 35 + : 36 + : 37 + \ 38 + <replaceable>packageN</replaceable> 39 + </synopsis> 40 + </refsynopsisdiv> 41 + 42 + <refsect1> 43 + <title>DESCRIPTION</title> 44 + <para> 45 + Every installation of "findlib" has a default location for package 46 + directories, which is normally a directory called "site-lib". The 47 + location can be set by the configuration variables 48 + <literal>path</literal> (used to look up packages), and 49 + <literal>destdir</literal> (used to install new packages); 50 + see <link linkend="findlib.conf">findlib.conf</link>. 51 + </para> 52 + 53 + <para> 54 + The name of a package is the name of the package directory. For 55 + example, if <literal>destdir=/usr/local/lib/ocaml/site-lib</literal>, the 56 + package p will be installed in the subdirectory 57 + <literal>/usr/local/lib/ocaml/site-lib/p</literal>. This subdirectory 58 + must contain the META file and all other files belonging to the package. 59 + Package names must not contain the '.' character. 60 + </para> 61 + 62 + <para> 63 + The variable <literal>destdir</literal> specifies the directory for 64 + new packages. You can only have one such directory at a time; but of 65 + course you can change this directory in findlib.conf. The command 66 + <literal>ocamlfind install</literal> puts new packages into this 67 + directory; it is recommended to use this command for installation 68 + because it ensures that the directory layout is right. 69 + </para> 70 + 71 + <para> 72 + For searching packages, findlib uses (only) the variable 73 + <literal>path</literal> which may name several locations to look at. 74 + </para> 75 + 76 + <para> 77 + For systems with DLL support another directory may exist: stublibs. 78 + If present, findlib will install DLLs into this directory that is 79 + shared by all packages at the same site-lib location. Findlib remembers 80 + which DLL belongs to which package by special files with the suffix 81 + ".owner"; e.g. for the DLL "dllpcre.so" there is another file 82 + "dllpcre.so.owner" containing the string "pcre", so findlib knows 83 + that the package "pcre" owns this DLL. It is not possible that a DLL 84 + is owned by several packages. 85 + </para> 86 + 87 + <para> 88 + If the stublibs directory does not exist, DLLs are installed regularly 89 + in the package directories like any other file. 90 + </para> 91 + 92 + <para> 93 + For special needs, a postinstall and/or a postremove script may be 94 + installed in the site-lib directory. These scripts are invoked after 95 + installation or removal of a package, respectively. 96 + </para> 97 + 98 + </refsect1> 99 + 100 + 101 + <refsect1> 102 + <title>ALTERNATE LAYOUT</title> 103 + <para> 104 + 105 + <programlisting> 106 + ...somewhere in the filesystem hierarchy... 107 + | 108 + \ 109 + site-lib 110 + | 111 + +- (optional) stublibs 112 + +- (optional) postinstall 113 + +- (optional) postremove 114 + | 115 + +- <replaceable>package1</replaceable> 116 + | | 117 + | +- <replaceable>archive files</replaceable> 118 + | +- <replaceable>interface definitions</replaceable> 119 + | 120 + +- <replaceable>package2</replaceable> 121 + + 122 + : 123 + : 124 + \ 125 + : <replaceable>packageN</replaceable> 126 + | 127 + \ 128 + metaregistry 129 + | 130 + +- META.package1 131 + +- META.package2 132 + + 133 + : 134 + \ 135 + META.packageN 136 + </programlisting> 137 + </para> 138 + 139 + <para> 140 + This is an alternate directory layout collecting all META files in one 141 + directory. You can configure this layout by setting 142 + <literal>path</literal> to the absolute location of 143 + <literal>metaregistry</literal>. Findlib recognizes that there are 144 + META files in this directory and uses them; it is not necessary to 145 + include <literal>site-lib</literal> into the <literal>path</literal>. 146 + </para> 147 + 148 + <para> 149 + In order to work, the META files must contain a 150 + <literal>directory</literal> directive pointing to the corresponding 151 + package directory that resides below <literal>site-lib</literal>. 152 + </para> 153 + 154 + <para> 155 + The command <literal>ocamlfind install</literal> copes with this 156 + layout, too. The variable <literal>destdir</literal> must contain the 157 + absolute location of <literal>site-lib</literal>, and the variable 158 + <literal>metadir</literal> must contain the absolute location of 159 + <literal>metaregistry</literal>. Note that <literal>ocamlfind 160 + install</literal> automatically adds a <literal>directory</literal> 161 + directive to the META file, so you need not do it manually. 162 + </para> 163 + </refsect1> 164 + 165 + </refentry>
+333
vendor/opam/ocamlfind/doc/src/findlib_topfind.mod
··· 1 + <refentry> 2 + 3 + <refmeta> 4 + <refentrytitle>Topfind</refentrytitle> 5 + <manvolnum>3</manvolnum> 6 + <refmiscinfo>The findlib package manager for OCaml</refmiscinfo> 7 + </refmeta> 8 + 9 + <refnamediv id="Topfind"> 10 + <refname>Topfind</refname> 11 + <refpurpose>[Module to load packages into toploops]</refpurpose> 12 + </refnamediv> 13 + 14 + 15 + <refsynopsisdiv> 16 + <title>SIGNATURE</title> 17 + <synopsis> 18 + module Topfind : 19 + sig 20 + <link linkend="Topfind.predicates" 21 + endterm="val.Topfind.predicates"></link> 22 + <link linkend="Topfind.add-predicates" 23 + endterm="val.Topfind.add-predicates"></link> 24 + <link linkend="Topfind.syntax" 25 + endterm="val.Topfind.syntax"></link> 26 + <link linkend="Topfind.standard-syntax" 27 + endterm="val.Topfind.standard-syntax"></link> 28 + <link linkend="Topfind.revised-syntax" 29 + endterm="val.Topfind.revised-syntax"></link> 30 + <link linkend="Topfind.dont-load" 31 + endterm="val.Topfind.dont-load"></link> 32 + <link linkend="Topfind.dont-load-deeply" 33 + endterm="val.Topfind.dont-load-deeply"></link> 34 + <link linkend="Topfind.load" 35 + endterm="val.Topfind.load"></link> 36 + <link linkend="Topfind.load-deeply" 37 + endterm="val.Topfind.load-deeply"></link> 38 + <link linkend="Topfind.reset" 39 + endterm="val.Topfind.reset"></link> 40 + end 41 + </synopsis> 42 + </refsynopsisdiv> 43 + 44 + 45 + <refsect1> 46 + <title>DIRECTIVES</title> 47 + <programlisting> 48 + <link linkend="Topfind.require" 49 + endterm="val.Topfind.require"></link> 50 + <link linkend="Topfind.camlp4o" 51 + endterm="val.Topfind.camlp4o"></link> 52 + <link linkend="Topfind.camlp4r" 53 + endterm="val.Topfind.camlp4r"></link> 54 + <link linkend="Topfind.list" 55 + endterm="val.Topfind.list"></link> 56 + </programlisting> 57 + </refsect1> 58 + 59 + 60 + <refsect1> 61 + <title>PACKAGING</title> 62 + 63 + <para> 64 + The Topfind module is part of the "findlib" package. The module 65 + depends on the presence of a toploop. When building a toploop, it is 66 + automatically linked in if "findlib" is linked in, e.g. 67 + </para> 68 + 69 + <programlisting> 70 + ocamlfind ocamlmktop <replaceable>options</replaceable> -package findlib -linkpkg <replaceable>options</replaceable> 71 + </programlisting> 72 + 73 + <para> 74 + When the platform supports DLLs, another possibility to get a toploop 75 + with findlib directives is to load the file "topfind" (normally installed 76 + in the standard library directory): 77 + </para> 78 + 79 + <programlisting> 80 + ~ > ocaml 81 + Objective Caml version 3.04 82 + 83 + # #use "topfind";; 84 + Findlib has been successfully loaded. Additional directives: 85 + #require "package";; to load a package 86 + #list;; to list the available packages 87 + #camlp4o;; to load camlp4 (standard syntax) 88 + #camlp4r;; to load camlp4 (revised syntax) 89 + Topfind.reset();; to force that packages will be reloaded 90 + 91 + - : unit = () 92 + # _ 93 + </programlisting> 94 + 95 + <para> 96 + This works even in scripts (but the startup message is suppressed in this 97 + case). 98 + </para> 99 + 100 + <para> 101 + The module is not thread-safe; if used in a multi-threaded script, all 102 + packgage loading must have happened before the first thread forks. 103 + </para> 104 + </refsect1> 105 + 106 + 107 + <refsect1> 108 + <title>DESCRIPTION</title> 109 + 110 + <para> 111 + The Topfind module contains some functions simplifying package loading 112 + in scripts. Most important, there is a new directive "#require" for 113 + the same purpose. 114 + </para> 115 + 116 + <para> 117 + The Topfind module needs some initialization, in particular the <link 118 + linkend="Topfind.predicates">predicates</link> variable needs to be 119 + set, and the packages already compiled into the toploop needs to be 120 + declared by the <link linkend="Topfind.dont-load">don't_load</link> 121 + function. If the toploop has been built by <xref 122 + linkend="ocamlfind" endterm="ocamlfind">, the necessary initialization is 123 + automatically compiled in. 124 + </para> 125 + 126 + 127 + <refsect2> 128 + <title><anchor id="Topfind.predicates"> 129 + The variable Topfind.predicates 130 + </title> 131 + <programlisting id="val.Topfind.predicates"> 132 + val predicates : string list ref 133 + </programlisting> 134 + <para> 135 + The variable contains the set of predicates that is assumed when 136 + packages are loaded. 137 + </para> 138 + </refsect2> 139 + 140 + 141 + <refsect2> 142 + <title><anchor id="Topfind.add-predicates"> 143 + Topfind.add_predicates <replaceable>predlist</replaceable> 144 + </title> 145 + <programlisting id="val.Topfind.add-predicates"> 146 + val add_predicates : string list -&gt; unit 147 + </programlisting> 148 + <para> 149 + This function adds the passed predicates <replaceable>predlist</replaceable> 150 + to the variable 151 + <literal>predicates</literal>. 152 + </para> 153 + </refsect2> 154 + 155 + 156 + <refsect2> 157 + <title><anchor id="Topfind.syntax"> 158 + Topfind.syntax <replaceable>variant</replaceable> 159 + </title> 160 + <programlisting id="val.Topfind.syntax"> 161 + val syntax : string -&gt; unit 162 + </programlisting> 163 + <para> 164 + This function emulates the <literal>-syntax</literal> command line 165 + switch of ocamlfind. 166 + </para> 167 + </refsect2> 168 + 169 + 170 + <refsect2> 171 + <title><anchor id="Topfind.standard-syntax"> 172 + Topfind.standard_syntax () 173 + </title> 174 + <programlisting id="val.Topfind.standard-syntax"> 175 + val standard_syntax : unit -&gt; unit 176 + </programlisting> 177 + <para> 178 + The same as <literal>syntax "camlp4o"</literal>. 179 + </para> 180 + </refsect2> 181 + 182 + 183 + <refsect2> 184 + <title><anchor id="Topfind.revised-syntax"> 185 + Topfind.revised_syntax () 186 + </title> 187 + <programlisting id="val.Topfind.revised-syntax"> 188 + val revised_syntax : unit -&gt; unit 189 + </programlisting> 190 + <para> 191 + The same as <literal>syntax "camlp4r"</literal>. 192 + </para> 193 + </refsect2> 194 + 195 + 196 + <refsect2> 197 + <title><anchor id="Topfind.dont-load"> 198 + Topfind.don't_load <replaceable>pkglist</replaceable> 199 + </title> 200 + <programlisting id="val.Topfind.dont-load"> 201 + val don't_load : string list -&gt; unit 202 + </programlisting> 203 + <para> 204 + Declares the packages enumerated in <replaceable>pkglist</replaceable> 205 + as being linked into the toploop. 206 + </para> 207 + </refsect2> 208 + 209 + 210 + <refsect2> 211 + <title><anchor id="Topfind.dont-load-deeply"> 212 + Topfind.don't_load_deeply <replaceable>pkglist</replaceable> 213 + </title> 214 + <programlisting id="val.Topfind.dont-load-deeply"> 215 + val don't_load_deeply : string list -&gt; unit 216 + </programlisting> 217 + <para> 218 + Declares the packages enumerated in <replaceable>pkglist</replaceable> 219 + and all direct and indirect ancestors as being linked into the toploop. 220 + </para> 221 + </refsect2> 222 + 223 + 224 + <refsect2> 225 + <title><anchor id="Topfind.load"> 226 + Topfind.load <replaceable>pkglist</replaceable> 227 + </title> 228 + <programlisting id="val.Topfind.load"> 229 + val load : string list -&gt; unit 230 + </programlisting> 231 + <para> 232 + The packages enumerated in <replaceable>pkglist</replaceable> are 233 + loaded in turn; packages that have already been loaded or that have 234 + been declared as linked in are skipped. 235 + </para> 236 + </refsect2> 237 + 238 + 239 + <refsect2> 240 + <title><anchor id="Topfind.load-deeply"> 241 + Topfind.load_deeply <replaceable>pkglist</replaceable> 242 + </title> 243 + <programlisting id="val.Topfind.load-deeply"> 244 + val load_deeply : string list -&gt; unit 245 + </programlisting> 246 + <para> 247 + The packages enumerated in <replaceable>pkglist</replaceable> and all 248 + direct or indirect ancestors are loaded in topological order; 249 + packages that have already been loaded or that have 250 + been declared as linked in are skipped. 251 + </para> 252 + </refsect2> 253 + 254 + 255 + <refsect2> 256 + <title><anchor id="Topfind.reset"> 257 + Topfind.reset () 258 + </title> 259 + <programlisting id="val.Topfind.reset"> 260 + val reset : unit -&gt; unit 261 + </programlisting> 262 + <para> 263 + This function causes that Topfind forgets that any package has already 264 + been loaded. Information about packages linked into the toploop remain 265 + intact. The effect of this function is that all dynamically loaded 266 + packages will be loaded again when <link 267 + linkend="Topfind.load">load</link>, <link 268 + linkend="Topfind.load-deeply">load_deeply</link> functions, or the 269 + <link linkend="Topfind.require">#require</link> directive are executed. 270 + </para> 271 + </refsect2> 272 + 273 + 274 + 275 + <refsect2> 276 + <title><anchor id="Topfind.require"> 277 + #require "<replaceable>package-name-list</replaceable>";; 278 + </title> 279 + <programlisting id="val.Topfind.require"> 280 + #require "<replaceable>package-name-list</replaceable>";; 281 + </programlisting> 282 + <para> 283 + The argument of the directive is a list of package names, separated by 284 + commas and/or whitespace. The directive has the same effect as <link 285 + linkend="Topfind.load-deeply">load_deeply</link>, i.e. the listed 286 + packages and all 287 + direct or indirect ancestors are loaded in topological order; 288 + packages that have already been loaded or that have 289 + been declared as linked in are skipped. 290 + </para> 291 + </refsect2> 292 + 293 + 294 + <refsect2> 295 + <title><anchor id="Topfind.camlp4o"> 296 + #camlp4o ;; 297 + </title> 298 + <programlisting id="val.Topfind.camlp4o"> 299 + #camlp4o ;; 300 + </programlisting> 301 + <para> 302 + Selects the standard syntax and loads the camlp4 preprocessor. 303 + </para> 304 + </refsect2> 305 + 306 + 307 + <refsect2> 308 + <title><anchor id="Topfind.camlp4r"> 309 + #camlp4r ;; 310 + </title> 311 + <programlisting id="val.Topfind.camlp4r"> 312 + #camlp4r ;; 313 + </programlisting> 314 + <para> 315 + Selects the revised syntax and loads the camlp4 preprocessor. 316 + </para> 317 + </refsect2> 318 + 319 + <refsect2> 320 + <title><anchor id="Topfind.list"> 321 + #list ;; 322 + </title> 323 + <programlisting id="val.Topfind.list"> 324 + #list ;; 325 + </programlisting> 326 + <para> 327 + Lists the packages that are in the search path. 328 + </para> 329 + </refsect2> 330 + 331 + </refsect1> 332 + 333 + </refentry>
+182
vendor/opam/ocamlfind/findlib-ppc.patch
··· 1 + diff -ur --unidirectional-new-file findlib-1.1.2pl1/Makefile findlib-1.1.2pl1.modify/Makefile 2 + --- findlib-1.1.2pl1/Makefile 2006-01-17 10:04:50.000000000 +1100 3 + +++ findlib-1.1.2pl1.modify/Makefile 2006-10-23 11:50:38.000000000 +1000 4 + @@ -17,12 +17,15 @@ 5 + for p in $(PARTS); do ( cd src/$$p; $(MAKE) opt ); done 6 + 7 + install: 8 + + mkdir -p $(prefix)$(OCAMLFIND_BIN) 9 + + mkdir -p $(prefix)$(OCAMLFIND_LIB) 10 + + mkdir -p $(prefix)$(OCAMLFIND_MAN) 11 + for p in $(PARTS); do ( cd src/$$p; $(MAKE) install ); done 12 + $(MAKE) install-doc 13 + $(MAKE) install-meta 14 + cd src/findlib; $(MAKE) install-num-top 15 + $(MAKE) install-config 16 + - cp tools/safe_camlp4 $(OCAMLFIND_BIN) 17 + + cp tools/safe_camlp4 $(prefix)$(OCAMLFIND_BIN) 18 + 19 + uninstall: 20 + $(MAKE) uninstall-doc 21 + @@ -30,12 +33,26 @@ 22 + for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) uninstall ); done 23 + $(MAKE) uninstall-config 24 + 25 + -clean: 26 + +clean: clean-macosx 27 + for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) clean ); done 28 + (cd itest-aux; $(MAKE) clean) 29 + (cd tools/extract_args; $(MAKE) clean) 30 + rm -f findlib.conf 31 + 32 + +# Make MacOS X package 33 + + 34 + +.PHONY: package-macosx 35 + + 36 + +package-macosx: all opt 37 + + mkdir -p package-macosx/root 38 + + export prefix=`pwd`/package-macosx/root && make install 39 + + export VERSION=1.1.2 && tools/make-package-macosx 40 + + #rm -rf package-macosx/root 41 + + 42 + +clean-macosx: 43 + + sudo rm -rf package-macosx 44 + + #rm -rf package-macosx/*.pkg package-macosx/*.dmg 45 + + 46 + .PHONY: release 47 + release: README 48 + ./release 49 + diff -ur --unidirectional-new-file findlib-1.1.2pl1/configure findlib-1.1.2pl1.modify/configure 50 + --- findlib-1.1.2pl1/configure 2006-01-17 10:04:49.000000000 +1100 51 + +++ findlib-1.1.2pl1.modify/configure 2006-10-23 11:50:43.000000000 +1000 52 + @@ -427,6 +427,7 @@ 53 + echo "EXEC_SUFFIX=${exec_suffix}" >>Makefile.config 54 + echo "PARTS=${parts}" >>Makefile.config 55 + echo "INSTALL_TOPFIND=${with_topfind}" >>Makefile.config 56 + +echo "VERSION=${version}" >> Makefile.config 57 + 58 + # All OK 59 + 60 + diff -ur --unidirectional-new-file findlib-1.1.2pl1/tools/make-package-macosx findlib-1.1.2pl1.modify/tools/make-package-macosx 61 + --- findlib-1.1.2pl1/tools/make-package-macosx 1970-01-01 10:00:00.000000000 +1000 62 + +++ findlib-1.1.2pl1.modify/tools/make-package-macosx 2006-10-23 11:50:52.000000000 +1000 63 + @@ -0,0 +1,119 @@ 64 + +#!/bin/sh 65 + + 66 + +######################################################################### 67 + +# # 68 + +# Objective Caml # 69 + +# # 70 + +# Damien Doligez, projet Moscova, INRIA Rocquencourt # 71 + +# # 72 + +# Copyright 2003 Institut National de Recherche en Informatique et # 73 + +# en Automatique. All rights reserved. This file is distributed # 74 + +# under the terms of the Q Public License version 1.0. # 75 + +# # 76 + +######################################################################### 77 + + 78 + +# $Id: make-package-macosx,v 1.10.2.2 2006/01/04 13:05:49 doligez Exp $ 79 + +# adapted to findlib by Pietro.Abate <pietro.abate@anu.edu.au> 80 + + 81 + +set -x 82 + + 83 + +cd package-macosx 84 + +rm -rf findlib.pkg findlib-rw.dmg 85 + +mkdir -p resources 86 + + 87 + +cat >Description.plist <<EOF 88 + + <?xml version="1.0" encoding="UTF-8"?> 89 + + <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 90 + + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 91 + + <plist version="1.0"> 92 + + <dict> 93 + + <key>IFPkgDescriptionDeleteWarning</key> 94 + + <string></string> 95 + + <key>IFPkgDescriptionDescription</key> 96 + + <string>The findlib library manager</string> 97 + + <key>IFPkgDescriptionTitle</key> 98 + + <string>Findlib</string> 99 + + <key>IFPkgDescriptionVersion</key> 100 + + <string>${VERSION}</string> 101 + + </dict> 102 + + </plist> 103 + +EOF 104 + + 105 + +cat >Info.plist <<EOF 106 + +<?xml version="1.0" encoding="UTF-8"?> 107 + +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 108 + + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 109 + +<plist version="1.0"> 110 + +<dict> 111 + + <key>CFBundleGetInfoString</key> 112 + + <string>The findlib library manager ${VERSION}</string> 113 + + <key>CFBundleIdentifier</key> 114 + + <string>http://www.ocaml-programming.de/packages/</string> 115 + + <key>CFBundleName</key> 116 + + <string>Findlib</string> 117 + + <key>CFBundleShortVersionString</key> 118 + + <string>${VERSION}</string> 119 + + <key>IFPkgFlagAllowBackRev</key> 120 + + <true/> 121 + + <key>IFPkgFlagAuthorizationAction</key> 122 + + <string>AdminAuthorization</string> 123 + + <key>IFPkgFlagDefaultLocation</key> 124 + + <string>/</string> 125 + + <key>IFPkgFlagInstallFat</key> 126 + + <false/> 127 + + <key>IFPkgFlagIsRequired</key> 128 + + <false/> 129 + + <key>IFPkgFlagRelocatable</key> 130 + + <false/> 131 + + <key>IFPkgFlagRestartAction</key> 132 + + <string>NoRestart</string> 133 + + <key>IFPkgFlagRootVolumeOnly</key> 134 + + <true/> 135 + + <key>IFPkgFlagUpdateInstalledLanguages</key> 136 + + <false/> 137 + + <key>IFPkgFormatVersion</key> 138 + + <real>0.10000000149011612</real> 139 + +</dict> 140 + +</plist> 141 + +EOF 142 + + 143 + +# stop here -> | 144 + +cat >resources/ReadMe.txt <<EOF 145 + +This package installs The findlib library manager ${VERSION}. 146 + +You need Mac OS X 10.4.x (Tiger). 147 + + 148 + +Files will be installed in the following directories: 149 + + 150 + +/usr/local/bin - command-line executables 151 + +/usr/local/lib/ocaml - library and support files 152 + +/usr/local/man - manual pages 153 + +EOF 154 + + 155 + +chmod -R g-w root 156 + +sudo chown -R root:admin root 157 + + 158 + +/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \ 159 + +-build -p "`pwd`/findlib.pkg" -f "`pwd`/root" -i "`pwd`/Info.plist" \ 160 + + -d "`pwd`/Description.plist" -r "`pwd`/resources" 161 + + 162 + +size=`du -s findlib.pkg | cut -f 1` 163 + +size=`expr $size + 8192` 164 + + 165 + +hdiutil create -sectors $size findlib-rw.dmg 166 + +name=`hdid -nomount findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1` 167 + +newfs_hfs -v 'Findlib' $name 168 + +hdiutil detach $name 169 + + 170 + +name=`hdid findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1` 171 + +if test -d '/Volumes/Findlib'; then 172 + + ditto -rsrcFork findlib.pkg "/Volumes/Findlib/findlib.pkg" 173 + + cp resources/ReadMe.txt "/Volumes/Findlib/" 174 + +else 175 + + echo 'Unable to mount the disk image as "/Volumes/Findlib"' >&2 176 + + exit 3 177 + +fi 178 + +open "/Volumes/Findlib" 179 + +hdiutil detach $name 180 + + 181 + +rm -rf "findlib-${VERSION}.dmg" 182 + +hdiutil convert findlib-rw.dmg -format UDZO -o "findlib-${VERSION}.dmg"
+2
vendor/opam/ocamlfind/findlib.conf.in
··· 1 + destdir="@SITELIB@" 2 + path="@FINDLIB_PATH@"
+171
vendor/opam/ocamlfind/findlib.files
··· 1 + # SYNTAX OF findlib.files: 2 + # 3 + # d DIRPATH 4 + # 5 + # include this subdirectory 6 + # 7 + # f FILEPATH 8 + # 9 + # include this file (or symlink) 10 + # 11 + # x FILEPATH 12 + # 13 + # exclude this file 14 + # 15 + # p DIRPATH/FILEPATTERN 16 + # 17 + # include all files of the directory that match the regular expression 18 + # FILEPATTERN (Str-type regexp) 19 + # 20 + # w DIRPATH/FILEPATTERN 21 + # 22 + # output a warning if one of the matching files matches 23 + # 24 + # Exclusions must be mentioned before inclusions. 25 + 26 + f configure 27 + f opam 28 + f ocamlfind.install 29 + f findlib.conf.in 30 + f INSTALL 31 + f LICENSE 32 + f Makefile 33 + f Makefile.config.pattern 34 + f itest 35 + f ocaml-stub 36 + 37 + d itest-aux 38 + f itest-aux/Makefile 39 + p itest-aux/.*\.ml 40 + 41 + d mini 42 + f mini/README 43 + f mini/ocamlfind-mini 44 + 45 + d tools 46 + f tools/collect_files 47 + f tools/file_exists 48 + d tools/extract_args 49 + f tools/extract_args/Makefile 50 + f tools/extract_args/extract_args.mll 51 + f tools/safe_camlp4 52 + f tools/make-package-macosx 53 + f tools/patch 54 + f tools/cmd_from_same_dir 55 + 56 + d site-lib-src 57 + d site-lib-src/bigarray 58 + f site-lib-src/bigarray/META.in 59 + f site-lib-src/bigarray/interfaces.in 60 + d site-lib-src/camlp4.309 61 + f site-lib-src/camlp4.309/META.in 62 + d site-lib-src/camlp4.310 63 + f site-lib-src/camlp4.310/META.in 64 + d site-lib-src/dbm 65 + f site-lib-src/dbm/META.in 66 + f site-lib-src/dbm/interfaces.in 67 + d site-lib-src/dynlink 68 + f site-lib-src/dynlink/META.in 69 + f site-lib-src/dynlink/interfaces.in 70 + d site-lib-src/graphics 71 + f site-lib-src/graphics/META.in 72 + f site-lib-src/graphics/interfaces.in 73 + d site-lib-src/labltk 74 + f site-lib-src/labltk/META.in 75 + f site-lib-src/labltk/interfaces.in 76 + d site-lib-src/num 77 + f site-lib-src/num/META.in 78 + f site-lib-src/num/interfaces.in 79 + d site-lib-src/num-top 80 + f site-lib-src/num-top/META.in 81 + d site-lib-src/stdlib 82 + f site-lib-src/stdlib/META.in 83 + f site-lib-src/stdlib/interfaces.in 84 + d site-lib-src/str 85 + f site-lib-src/str/META.in 86 + f site-lib-src/str/interfaces.in 87 + d site-lib-src/threads 88 + f site-lib-src/threads/META.in 89 + f site-lib-src/threads/interfaces.in 90 + d site-lib-src/unix 91 + f site-lib-src/unix/META.in 92 + f site-lib-src/unix/interfaces.in 93 + d site-lib-src/ocamlbuild 94 + f site-lib-src/ocamlbuild/META.in 95 + d site-lib-src/ocamldoc 96 + f site-lib-src/ocamldoc/META.in 97 + d site-lib-src/compiler-libs 98 + f site-lib-src/compiler-libs/META.in 99 + d site-lib-src/bytes 100 + f site-lib-src/bytes/META.in 101 + f site-lib-src/bytes/interfaces.in 102 + d site-lib-src/raw_spacetime 103 + f site-lib-src/raw_spacetime/interfaces.in 104 + f site-lib-src/raw_spacetime/META.in 105 + 106 + 107 + d src 108 + 109 + d src/findlib 110 + f src/findlib/Makefile 111 + f src/findlib/META.in 112 + f src/findlib/findlib_config.mlp 113 + f src/findlib/topfind.ml.in 114 + x src/findlib/fl_meta.ml 115 + x src/findlib/findlib_config.ml 116 + x src/findlib/ocaml_args.ml 117 + x src/findlib/topfind.ml 118 + f src/findlib/topfind.in 119 + p src/findlib/.*\.ml 120 + p src/findlib/.*\.mli 121 + p src/findlib/.*\.mll 122 + p src/findlib/.*\.src 123 + p src/findlib/.*\.p 124 + 125 + d src/findlib-toolbox 126 + f src/findlib-toolbox/Makefile 127 + f src/findlib-toolbox/make_wizard.ml 128 + f src/findlib-toolbox/make_wizard.pattern 129 + 130 + d src/bytes 131 + f src/bytes/Makefile 132 + f src/bytes/README 133 + f src/bytes/bytes.ml 134 + f src/bytes/META 135 + 136 + d doc 137 + f doc/DOCINFO 138 + f doc/QUICKSTART 139 + f doc/README 140 + p doc/.*\.xml 141 + p doc/.*\.dtd 142 + f doc/Makefile 143 + 144 + d doc/guide-html 145 + f doc/guide-html/index.html 146 + p doc/guide-html/.*\.html 147 + f doc/guide-html/TIMESTAMP 148 + 149 + d doc/ref-html 150 + d doc/ref-html/lib 151 + f doc/ref-html/index.html 152 + p doc/ref-html/.*\.html 153 + f doc/ref-html/TIMESTAMP 154 + f doc/ref-html/lib/index.html 155 + p doc/ref-html/lib/.*\.html 156 + p doc/ref-html/lib/.*\.css 157 + 158 + d doc/ref-man 159 + f doc/ref-man/ocamlfind.1 160 + f doc/ref-man/findlib.conf.5 161 + f doc/ref-man/META.5 162 + f doc/ref-man/site-lib.5 163 + f doc/ref-man/TIMESTAMP 164 + 165 + d doc/src 166 + p doc/src/.*\.dsl 167 + p doc/src/.*\.mod 168 + p doc/src/.*\.sgml 169 + p doc/src/.*\.xml 170 + 171 +
+101
vendor/opam/ocamlfind/itest
··· 1 + #! /bin/sh 2 + # $Id$ 3 + # ---------------------------------------------------------------------- 4 + # 5 + 6 + case `uname` in 7 + CYGWIN*) 8 + execsuffix=.exe ;; 9 + *) 10 + execsuffix= ;; 11 + esac 12 + ocamlfind="src/findlib/ocamlfind${execsuffix}" 13 + 14 + PATH="./tools:$PATH" 15 + export PATH 16 + 17 + check_linkage () { 18 + p=$1 19 + shift 20 + rm -f itest-aux/simple 21 + $ocamlfind ocamlc -linkall -linkpkg -custom "$@" -o itest-aux/simple itest-aux/simple_$p.ml >itest-aux/err.out 2>&1 22 + output=`cat itest-aux/err.out | sed -e '/WARNING.*/ d'` 23 + error=0 24 + if [ -n "$output" ]; then 25 + echo "* When trying to compile with" 26 + echo " $ocamlfind ocamlc -linkall -linkpkg -custom "$@" -o itest-aux/simple itest-aux/simple_$p.ml" 27 + echo " an error has occurred. The error error message has been written" 28 + echo " to itest-aux/err.out." 29 + error=1 30 + fi 31 + if [ "$error" = "0" ]; then 32 + result=`itest-aux/simple${execsuffix}` 33 + [ "x$result" = "xOK" ] 34 + else 35 + return $error 36 + fi 37 + } 38 + 39 + problems () { 40 + echo "* This test failed. Please check the settings in site-lib-src/$1/META," 41 + echo " especially the 'linkopts' variable, and try again. You can invoke" 42 + echo " this test directly by: ./itest $1" 43 + } 44 + 45 + 46 + do_test () { 47 + case "$1" in 48 + dbm|graphics|num|str|unix|bigarray|labltk) 49 + echo "* Checking linker options for $1 library" 50 + rm -f itest-aux/testdb* 51 + if check_linkage $1 -package $1; then 52 + echo "ok" 53 + else 54 + problems $1 55 + fi 56 + ;; 57 + threads) 58 + echo "* Checking linker options for threads library" 59 + if check_linkage $1 -package $1 -thread; then 60 + echo "ok" 61 + else 62 + problems $1 63 + fi 64 + ;; 65 + 66 + camlp4) 67 + echo "* Checking options for camlp4 preprocessor" 68 + if check_linkage $1 -package $1 -syntax camlp4r; then 69 + echo "ok" 70 + else 71 + problems $1 72 + fi 73 + ;; 74 + 75 + *) 76 + echo "unknown test: $1" 77 + ;; 78 + esac 79 + } 80 + 81 + 82 + OCAMLPATH="./site-lib-src" 83 + export OCAMLPATH 84 + 85 + if [ ! -f "$ocamlfind" ]; then 86 + echo "Sorry, you must first compile the library before you can invoke" 1>&2 87 + echo "the integration test." 1>&2 88 + exit 1 89 + fi 90 + 91 + if [ "$#" = "0" ]; then 92 + for t in unix str dbm graphics num threads bigarray labltk camlp4; do 93 + if [ -f "site-lib-src/$t/META" ]; then 94 + echo "------------------------------------------------------------------------------" 95 + do_test $t 96 + echo 97 + fi 98 + done 99 + else 100 + do_test $1 101 + fi
+7
vendor/opam/ocamlfind/itest-aux/Makefile
··· 1 + all: 2 + 3 + clean: 4 + rm -f simple simple.exe *.cmi *.cmo *.cma *.cmx *.o *.obj *.a *.lib 5 + rm -f err.out 6 + rm -f testdb* 7 +
+2
vendor/opam/ocamlfind/itest-aux/os_type.ml
··· 1 + print_endline Sys.os_type 2 + ;;
+1
vendor/opam/ocamlfind/itest-aux/ppx.ml
··· 1 + Toploop.preprocess_phrase;;
+2
vendor/opam/ocamlfind/itest-aux/remdir.ml
··· 1 + #remove_directory ".";; 2 +
+2
vendor/opam/ocamlfind/itest-aux/simple.ml
··· 1 + print_string "OK\n";; 2 +
+7
vendor/opam/ocamlfind/itest-aux/simple_bigarray.ml
··· 1 + open Bigarray.Array1;; 2 + let a = create Bigarray.int Bigarray.c_layout 4 in 3 + a.{0} <- 5 4 + ;; 5 + 6 + print_endline "OK";; 7 +
+5
vendor/opam/ocamlfind/itest-aux/simple_camlp4.ml
··· 1 + (* This is revised syntax: *) 2 + 3 + value x = 1; 4 + 5 + print_endline "OK";
+11
vendor/opam/ocamlfind/itest-aux/simple_camltk.ml
··· 1 + open Tk;; 2 + 3 + let top = openTk() in 4 + Frx_after.idle 5 + closeTk; 6 + mainLoop() 7 + ;; 8 + 9 + print_string "OK\n" 10 + ;; 11 +
+10
vendor/opam/ocamlfind/itest-aux/simple_dbm.ml
··· 1 + (try 2 + Sys.remove "itest-aux/testdb.db" 3 + with 4 + _ -> ()); 5 + 6 + let _ = 7 + Dbm.opendbm "itest-aux/testdb" [ Dbm.Dbm_rdwr; Dbm.Dbm_create ] 0o777 in 8 + 9 + print_string "OK\n";; 10 +
+4
vendor/opam/ocamlfind/itest-aux/simple_graphics.ml
··· 1 + Graphics.open_graph ""; 2 + 3 + print_string "OK\n";; 4 +
+10
vendor/opam/ocamlfind/itest-aux/simple_labltk.ml
··· 1 + open Tk;; 2 + 3 + let _ = openTk() in 4 + update(); 5 + closeTk() 6 + ;; 7 + 8 + print_string "OK\n" 9 + ;; 10 +
+4
vendor/opam/ocamlfind/itest-aux/simple_num.ml
··· 1 + let _ = Num.num_of_int 5 in 2 + 3 + print_string "OK\n";; 4 +
+4
vendor/opam/ocamlfind/itest-aux/simple_str.ml
··· 1 + let _ = Str.regexp ".*" in 2 + 3 + print_string "OK\n";; 4 +
+17
vendor/opam/ocamlfind/itest-aux/simple_threads.ml
··· 1 + let tl = 2 + List.map 3 + (fun _ -> 4 + Thread.create 5 + (fun () -> 6 + for i = 1 to 1000 do 7 + let _ = 1+1 in () 8 + done) 9 + ()) 10 + [ (); (); (); (); () ] 11 + in 12 + 13 + List.iter Thread.join tl 14 + ;; 15 + 16 + print_string "OK\n";; 17 +
+4
vendor/opam/ocamlfind/itest-aux/simple_unix.ml
··· 1 + let _ = Unix.getpid() in 2 + 3 + print_string "OK\n";; 4 +
+104
vendor/opam/ocamlfind/mini/README
··· 1 + ---------------------------------------------------------------------- 2 + ocamlfind-mini 3 + ---------------------------------------------------------------------- 4 + 5 + ocamlfind-mini is an OCaml script that implements a subset of the 6 + full functionality of ocamlfind. It consists only of one file, so it 7 + is easy to distribute it with any software. 8 + 9 + The subset is normally sufficient to compile a library and to 10 + install the library; but it is insufficient to link the library 11 + into an executable. 12 + 13 + ---------------------------------------------------------------------- 14 + SUPPORTED OPERATING SYSTEMS: 15 + ---------------------------------------------------------------------- 16 + 17 + For Unixes, the script runs out of the box. It uses the ocaml system 18 + found in the command path. 19 + 20 + I think the script also runs in Windows, but I have not yet checked that. 21 + Anyway, you cannot call it directly, but by doing 22 + ocaml ocamlfind-mini <args>... 23 + 24 + Macintosh is not supported; I don't have enough knowledge for a Mac port. 25 + 26 + ---------------------------------------------------------------------- 27 + FUNCTIONALITY: 28 + ---------------------------------------------------------------------- 29 + 30 + Overall: The configuration file ocamlfind.conf is ignored. However, 31 + some environment variables are respected (see below). 32 + 33 + A package directory is recognized by checking whether there is a META 34 + file in it. However, the contents of that file are ignored. 35 + 36 + The following subset has been implemented: 37 + 38 + - ocamlfind-mini [ocamlc|ocamlopt|ocamlcp|ocamlmktop] <args>... 39 + 40 + The -package option works, but you must set the environment variable 41 + OCAMLPATH (see below). 42 + 43 + The options -linkpkg, -predicates, -dontlink, -syntax, -ppopt are 44 + rejected. 45 + 46 + This normally means that you can compile modules as in: 47 + 48 + ocamlfind-mini ocamlc -c -package p1,p2,p3 my_module.ml 49 + 50 + However, you cannot create executables because -linkpkg is not 51 + supported. 52 + 53 + Note that ocamlfind-mini is unable to figure out the prerequisite 54 + packages, so the -package option must enumerate _all_ needed packages. 55 + 56 + Note that ocamlfind-mini does not support the alternate directory 57 + layout where all META files are collected in one directory. 58 + 59 + - ocamlfind-mini install <pkg> <file>... 60 + 61 + Installs the files in the package directory for <pkg>. You must help 62 + ocamlfind-mini by specifying the destination directory: 63 + 64 + * Setting the -destdir option: 65 + 66 + ocamlfind-mini install -destdir <dir> <pkg> <file> ... 67 + 68 + This command installs the new package into <dir>/<pkg>. 69 + 70 + * Setting the OCAMLFIND_DESTDIR variable: 71 + 72 + export OCAMLFIND_DESTDIR=<dir> 73 + ocamlfind-mini install <pkg> <file> ... 74 + 75 + This command installs the new package into <dir>/<pkg>, too. 76 + 77 + - ocamlfind-mini remove <pkg> 78 + 79 + Removes the package <pkg>. Again, you must specify the destination 80 + directory by either setting the -destdir option or by setting the 81 + OCAMLFIND_DESTDIR variable. 82 + 83 + ---------------------------------------------------------------------- 84 + ENVIRONMENT: 85 + ---------------------------------------------------------------------- 86 + 87 + The following variables are supported: 88 + 89 + - OCAMLPATH 90 + 91 + A colon (Win: semicolon)-separated list of directories: 92 + OCAMLPATH=<dir1>:<dir2>:... 93 + 94 + When ocamlfind-mini searches a package <pkg>, it checks whether 95 + <dirK>/<pkg>/META exists for K=1, 2, ... 96 + 97 + - OCAMLFIND_DESTDIR 98 + 99 + The destination directory for "install" and "remove". 100 + 101 + - OCAMLFIND_METADIR 102 + 103 + The destination directory for META files. It is not recommended to set 104 + this variable.
+851
vendor/opam/ocamlfind/mini/ocamlfind-mini
··· 1 + #! /bin/sh 2 + # (* 3 + exec ocaml "$0" "$@" 4 + *) directory ".";; 5 + 6 + (* $Id$ 7 + * ---------------------------------------------------------------------- 8 + * 9 + *) 10 + 11 + (**********************************************************************) 12 + 13 + (* Module split, rev. 1.2 *) 14 + 15 + module Split = struct 16 + let in_words s = 17 + (* splits s in words separated by commas and/or whitespace *) 18 + let l = String.length s in 19 + let rec split i j = 20 + if j < l then 21 + match s.[j] with 22 + (' '|'\t'|'\n'|'\r'|',') -> 23 + if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1)) 24 + else split (j+1) (j+1) 25 + | _ -> 26 + split i (j+1) 27 + else 28 + if i<j then [ String.sub s i (j-i) ] else [] 29 + in 30 + split 0 0 31 + ;; 32 + 33 + 34 + let in_words_ws s = 35 + (* splits s in words separated by whitespace *) 36 + let l = String.length s in 37 + let rec split i j = 38 + if j < l then 39 + match s.[j] with 40 + (' '|'\t'|'\n'|'\r') -> 41 + if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1)) 42 + else split (j+1) (j+1) 43 + | _ -> 44 + split i (j+1) 45 + else 46 + if i<j then [ String.sub s i (j-i) ] else [] 47 + in 48 + split 0 0 49 + ;; 50 + 51 + 52 + let path_separator = 53 + match Sys.os_type with 54 + "Unix" -> ':' 55 + | "Cygwin" -> ';' (* You might want to change this *) 56 + | "Win32" -> ';' 57 + | "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" 58 + | _ -> failwith "Findlib: unknown operating system" 59 + ;; 60 + 61 + 62 + let path str = 63 + (* split "str" into parts separated by "path_separator" *) 64 + let l = String.length str in 65 + let rec split_up j k = 66 + if k < l then begin 67 + let c = str.[k] in 68 + if c = path_separator then begin 69 + if k - j > 0 then 70 + String.sub str j (k-j) :: split_up (k+1) (k+1) 71 + else 72 + split_up (k+1) (k+1) 73 + end 74 + else 75 + split_up j (k+1) 76 + end 77 + else 78 + if k - j > 0 then 79 + [ String.sub str j (k-j) ] 80 + else 81 + [] 82 + in 83 + split_up 0 0 84 + ;; 85 + end;; 86 + 87 + (**********************************************************************) 88 + 89 + 90 + 91 + exception Usage;; 92 + 93 + type mode = 94 + M_use | M_query | M_install | M_remove | M_compiler of string 95 + | M_printconf | M_guess | M_list 96 + ;; 97 + 98 + 99 + let rec remove_dups l = 100 + match l with 101 + x :: l' -> 102 + if List.mem x l' then remove_dups l' else x::remove_dups l' 103 + | [] -> [] 104 + ;; 105 + 106 + 107 + let arg n = 108 + if n < Array.length Sys.argv then Sys.argv.(n) else raise Not_found 109 + ;; 110 + 111 + 112 + (**********************************************************************) 113 + 114 + let ocaml_stdlib_default = "/usr/local/lib/ocaml";; 115 + 116 + let ocaml_stdlib = 117 + begin 118 + (* Execute "ocamlc -v" and read the stdlib directory *) 119 + let filename = Filename.temp_file "ocamlfind." ".dat" in 120 + let command = "ocamlc -v >" ^ filename in (* SYS *) 121 + let n = Sys.command command in 122 + if n <> 0 then begin 123 + prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default"); 124 + ocaml_stdlib_default 125 + end 126 + else begin 127 + (* Search the line "Standard library directory: " *) 128 + let tag = "Standard library directory: " in 129 + let taglen = String.length tag in 130 + let f = open_in filename in 131 + let dir = ref ocaml_stdlib_default in 132 + try 133 + while true do 134 + let s = input_line f in 135 + if String.length s >= taglen && String.sub s 0 taglen = tag then begin 136 + dir := String.sub s taglen (String.length s - taglen); 137 + raise Exit; 138 + end 139 + done; 140 + assert false 141 + with 142 + Exit -> 143 + close_in f; 144 + (try Sys.remove filename with _ -> ()); 145 + !dir 146 + | End_of_file -> 147 + close_in f; 148 + prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default"); 149 + ocaml_stdlib_default 150 + end 151 + end 152 + ;; 153 + 154 + 155 + let ocamlpath = 156 + try 157 + Split.path (Sys.getenv "OCAMLPATH") 158 + with 159 + Not_found -> 160 + (* Use stdlib as default: *) 161 + [ ocaml_stdlib ] 162 + ;; 163 + 164 + 165 + let env_destdir = 166 + try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> "";; 167 + 168 + 169 + let env_metadir = 170 + try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> "";; 171 + 172 + 173 + let core_packages = 174 + [ "bigarray", ocaml_stdlib; 175 + "dbm", ocaml_stdlib; 176 + "dynlink", ocaml_stdlib; 177 + "graphics", ocaml_stdlib; 178 + "labltk", (Filename.concat ocaml_stdlib "labltk"); 179 + "num", ocaml_stdlib; 180 + "stdlib", ocaml_stdlib; 181 + "str", ocaml_stdlib; 182 + "threads", (Filename.concat ocaml_stdlib "threads"); 183 + "unix", ocaml_stdlib; 184 + ] 185 + ;; 186 + 187 + 188 + (**********************************************************************) 189 + 190 + let package_directory pkg = 191 + let rec lookup path = 192 + match path with 193 + | [] -> raise Not_found 194 + | dir :: path' -> 195 + let pkgdir = Filename.concat dir pkg in 196 + let meta = Filename.concat pkgdir "META" in 197 + if Sys.file_exists meta then 198 + pkgdir 199 + else 200 + lookup path' 201 + in 202 + 203 + try 204 + List.assoc pkg core_packages 205 + with 206 + Not_found -> 207 + lookup ocamlpath 208 + ;; 209 + 210 + 211 + (**********************************************************************) 212 + 213 + let use_package prefix pkgnames = 214 + let pdirs = 215 + List.map 216 + (fun pname -> 217 + try 218 + "-I " ^ package_directory pname 219 + with 220 + Not_found -> failwith ("Cannot find package " ^ pname ^ " (check environment variable OCAMLPATH)")) 221 + pkgnames 222 + in 223 + 224 + print_endline (prefix ^ String.concat " " pdirs) 225 + ;; 226 + 227 + 228 + (**************** OCAMLC/OCAMLMKTOP/OCAMLOPT subcommands ****************) 229 + 230 + type pass_file_t = 231 + Pass of string 232 + | Impl of string 233 + | Intf of string 234 + ;; 235 + 236 + 237 + let ocamlc which () = 238 + Arg.current := 1; 239 + 240 + let switches = ref [] in 241 + let pass_options = ref [] in 242 + let pass_files = ref [] in 243 + let incpath = ref [] in 244 + 245 + let packages = ref [] in 246 + 247 + let add_switch name = 248 + Arg.Unit (fun () -> 249 + switches := name :: !switches; 250 + pass_options := !pass_options @ [name]) in 251 + let add_spec_fn name s = 252 + pass_options := !pass_options @ [name; s] in 253 + let add_spec name = Arg.String (add_spec_fn name) in 254 + let add_pkg = 255 + Arg.String (fun s -> packages := !packages @ (Split.in_words s)) in 256 + 257 + 258 + Arg.parse 259 + (List.flatten 260 + [ [ 261 + "-package", add_pkg, 262 + " <name> Refer to package when compiling"; 263 + "-linkpkg", Arg.Unit(fun _ -> raise (Arg.Bad "Not supported: -linkpkg")), 264 + " Link the packages in (NOT SUPPORTED)"; 265 + "-predicates", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -predicates")), 266 + " <p> Add predicate <p> when resolving package properties (NOT SUPPORTED)"; 267 + "-dontlink", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -dontlink")), 268 + " <name> Do not link in package <name> and its ancestors (NOT SUPPORTED)"; 269 + "-syntax", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -syntax")), 270 + " <p> Use preprocessor with predicate <p> (NOT SUPPORTED)"; 271 + "-ppopt", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -ppopt")), 272 + " <opt> Append option <opt> to preprocessor invocation (NOT SUPPORTED)"; 273 + "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]), 274 + " <opt> Pass option <opt> directly to ocamlc/opt/mktop\nSTANDARD OPTIONS:"; 275 + 276 + "-a", add_switch "-a", 277 + " Build a library"; 278 + "-c", add_switch "-c", 279 + " Compile only (do not link)"; 280 + "-cc", add_spec "-cc", 281 + " <comp> Use <comp> as the C compiler and linker"; 282 + "-cclib", add_spec "-cclib", 283 + " <opt> Pass option <opt> to the C linker"; 284 + "-ccopt", add_spec "-ccopt", 285 + " <opt> Pass option <opt> to the C compiler and linker"; 286 + ]; 287 + if which = "ocamlopt" then [ 288 + "-compact", add_switch "-compact", 289 + " Optimize code size rather than speed" 290 + ] 291 + else []; 292 + if which <> "ocamlopt" then [ 293 + "-custom", add_switch "-custom", 294 + " Link in custom mode"; 295 + "-g", add_switch "-g", 296 + " Save debugging information"; 297 + ] else []; 298 + [ 299 + "-i", add_switch "-i", 300 + " Print the types"; 301 + "-I", (Arg.String 302 + (fun s -> 303 + incpath := s :: !incpath; 304 + add_spec_fn "-I" s)), 305 + " <dir> Add <dir> to the list of include directories"; 306 + "-impl", Arg.String (fun s -> pass_files := !pass_files @ [ Impl s ]), 307 + " <file> Compile <file> as a .ml file"; 308 + ] ; 309 + if which = "ocamlopt" then [ 310 + "-inline", add_spec "-inline", 311 + " <n> Set aggressiveness of inlining to <n>"; 312 + ] else []; 313 + [ 314 + "-intf", Arg.String (fun s -> pass_files := !pass_files @ [ Intf s ]), 315 + " <file> Compile <file> as a .mli file"; 316 + "-intf-suffix", add_spec "-intf-suffix", 317 + " <s> Suffix for interface file (default: .mli)"; 318 + "-intf_suffix", add_spec "-intf_suffix", 319 + " <s> same as -intf-suffix"; 320 + "-labels", add_switch "-labels", 321 + " Use commuting label mode"; 322 + "-linkall", add_switch "-linkall", 323 + " Link all modules, even unused ones"; 324 + ] ; 325 + if which <> "ocamlopt" then [ 326 + "-make-runtime", add_switch "-make-runtime", 327 + " Build a runtime system"; 328 + "-make_runtime", add_switch "-make_runtime", 329 + " same as -make-runtime"; 330 + ] else []; 331 + [ 332 + "-noautolink", add_switch "-noautolink", 333 + " Don't automatically link C libraries specif'd in .cma files"; 334 + "-noassert", add_switch "-noassert", 335 + " Do not compile assertion checks"; 336 + "-o", add_spec "-o", 337 + " <file> Set output file name to <file>"; 338 + "-output-obj", add_switch "-output-obj", 339 + " Output a C object file instead of an executable"; 340 + ]; 341 + if which = "ocamlopt" then [ 342 + "-p", add_switch "-p", 343 + " Compile/link with profiling support for \"gprof\" 344 + (implies -predicates gprof)"; 345 + ] else if which = "ocamlcp" then [ 346 + "-p", add_spec "-p", 347 + " [afilmt] Profile constructs specified by argument: 348 + a Everything 349 + f Function calls 350 + i if ... then ... else 351 + l while, for 352 + m match ... with 353 + t try ... with"; 354 + ] else []; 355 + [ 356 + "-pp", Arg.String (fun s -> add_spec_fn "-pp" s), 357 + " <command> Pipe sources through preprocessor <command>"; 358 + "-rectypes", add_switch "-rectypes", 359 + " Allow arbitrary recursive types"; 360 + ] ; 361 + if which = "ocamlopt" then [ 362 + "-S", add_switch "-S", 363 + " Keep intermediate assembly file"; 364 + ] else []; 365 + [ 366 + "-thread", add_switch "-thread", 367 + " Use thread-safe standard library (implies -predicate mt)"; 368 + "-unsafe", add_switch "-unsafe", 369 + " No bounds checking on array and string access"; 370 + ] ; 371 + if which <> "ocamlopt" then [ 372 + "-use-runtime", add_spec "-use-runtime", 373 + " <path> Generate bytecode for the given runtime system"; 374 + "-use_runtime", add_spec "-use_runtime", 375 + " same as -use-runtime"; 376 + ] else []; 377 + [ 378 + "-v", add_switch "-v", 379 + " Print compiler version number"; 380 + "-verbose", add_switch "-verbose", 381 + " Print calls to external commands"; 382 + "-w", add_spec "-w", 383 + " <flags> Enable or disable warnings according to <flags>: 384 + A/a enable/disable all warnings 385 + C/c enable/disable suspicious comment 386 + F/f enable/disable partially applied function 387 + M/m enable/disable overridden methods 388 + P/p enable/disable partial match 389 + S/s enable/disable non-unit statement 390 + U/u enable/disable unused match case 391 + V/v enable/disable hidden instance variables 392 + X/x enable/disable all other warnings 393 + default setting is A (all warnings enabled)"; 394 + "-warn-error", add_spec "-warn-error", 395 + " Turn these warnings into errors"; 396 + "-where", add_switch "-where", 397 + " Print standard library directory"; 398 + "-", Arg.String (fun s -> pass_files := !pass_files @ [ Pass s ]), 399 + " <file> Treat <file> as a file name (even if it starts with `-')"; 400 + ] 401 + ]) 402 + (fun s -> pass_files := !pass_files @ [ Pass s]) 403 + ("usage: ocamlfind-mini " ^ which ^ " [options] file ..."); 404 + 405 + begin match which with 406 + "ocamlc" 407 + | "ocamlcp" 408 + | "ocamlmktop" 409 + | "ocamlopt" -> () 410 + | _ -> failwith "unsupported backend" 411 + end; 412 + 413 + let verbose = List.mem "-verbose" !switches in 414 + 415 + (* check packages: *) 416 + List.iter 417 + (fun pkg -> 418 + try 419 + let _ = package_directory pkg in 420 + () 421 + with 422 + Not_found -> 423 + failwith ("package '" ^ pkg ^ "' not found (check environment variable OCAMLPATH)")) 424 + !packages; 425 + 426 + let eff_packages = !packages in 427 + 428 + let eff_packages_dl = 429 + remove_dups (List.map package_directory eff_packages) in 430 + 431 + let stdlibdir = 432 + (* normalized form of the stdlib directory *) 433 + let d = ocaml_stdlib in 434 + if d <> "" & d.[String.length d - 1] = '/' then 435 + String.sub d 0 (String.length d - 1) 436 + else 437 + d 438 + in 439 + let stdlibdirslash = stdlibdir ^ "/" in 440 + 441 + let i_options = 442 + List.flatten 443 + (List.map 444 + (fun pkgdir -> 445 + if pkgdir = stdlibdir or pkgdir = stdlibdirslash then 446 + [] 447 + else 448 + [ "-I"; pkgdir; 449 + "-ccopt"; "-I" ^ pkgdir; ]) 450 + eff_packages_dl) in 451 + 452 + let pass_files' = 453 + List.flatten 454 + (List.map 455 + (function 456 + Pass s -> 457 + if s.[0] = '-' 458 + then [ "-"; String.sub s 1 (String.length s - 1) ] 459 + else [ s ] 460 + | Impl s -> 461 + [ "-impl"; s ] 462 + | Intf s -> 463 + [ "-intf"; s ] 464 + ) 465 + !pass_files) 466 + in 467 + 468 + let arguments = 469 + !pass_options @ 470 + i_options @ 471 + pass_files' 472 + in 473 + 474 + let actual_command = which in 475 + 476 + if verbose then 477 + print_string ("+ " ^ actual_command ^ " " ^ 478 + String.concat " " arguments ^ "\n"); 479 + 480 + flush stdout; 481 + 482 + let argstring = 483 + String.concat " " 484 + (List.map Filename.quote arguments) 485 + in 486 + 487 + let status = Sys.command (actual_command ^ " " ^ argstring) in 488 + 489 + begin 490 + match status with 491 + 0 -> () 492 + | n -> 493 + if verbose then 494 + print_string (actual_command ^ " returned with exit code " ^ string_of_int n ^ "\n"); 495 + exit n 496 + end; 497 + ;; 498 + 499 + 500 + (************************************************************************) 501 + 502 + let make_directory dirname = 503 + (* Invoke the mkdir command *) 504 + let cmd = 505 + match Sys.os_type with 506 + "Unix" -> "mkdir" 507 + | "Cygwin" -> "mkdir" (* don't really know *) 508 + | "Win32" -> "md" 509 + | "MacOS" -> failwith "make_directory not implemented for MacOS" 510 + | _ -> failwith "Findlib: unknown operating system" 511 + in 512 + let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in 513 + if c <> 0 then 514 + failwith ("Cannot make directory " ^ dirname) 515 + ;; 516 + 517 + 518 + let remove_directory dirname = 519 + (* Invoke the rmdir command *) 520 + let cmd = 521 + match Sys.os_type with 522 + "Unix" -> "rmdir" 523 + | "Cygwin" -> "rmdir" (* don't really know *) 524 + | "Win32" -> "rd" 525 + | "MacOS" -> failwith "remove_directory not implemented for MacOS" 526 + | _ -> failwith "Findlib: unknown operating system" 527 + in 528 + let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in 529 + if c <> 0 then 530 + failwith ("Cannot remove directory " ^ dirname) 531 + ;; 532 + 533 + 534 + let list_dir dirname = 535 + let rec rd_dir f = 536 + try 537 + let s = input_line f in 538 + if s = "" then rd_dir f else s::rd_dir f 539 + with 540 + End_of_file -> 541 + close_in f; 542 + [] 543 + in 544 + 545 + (* Invoke the ls command *) 546 + let cmd = 547 + match Sys.os_type with 548 + "Unix" -> "ls -1" 549 + | "Cygwin" -> "ls -1" (* don't really know *) 550 + | "Win32" -> "dir /b" 551 + | "MacOS" -> failwith "list_dir not implemented for MacOS" 552 + | _ -> failwith "Findlib: unknown operating system" 553 + in 554 + let filename = Filename.temp_file "ocamlfind." ".dat" in 555 + let fullcmd = cmd ^ " " ^ Filename.quote dirname ^ " >" ^ filename in 556 + let n = Sys.command fullcmd in 557 + if n <> 0 then 558 + failwith ("Cannot execute: " ^ fullcmd); 559 + let f = open_in filename in 560 + let l = rd_dir f in 561 + close_in f; 562 + (try Sys.remove filename with _ -> ()); 563 + l 564 + ;; 565 + 566 + 567 + let copy_file ?(rename = (fun name -> name)) ?(append = "") src dstdir = 568 + (* A system-independent function to copy the file src to dstdir *) 569 + let outname = rename (Filename.basename src) in 570 + let ch_in = open_in_bin src in 571 + try 572 + let outpath = Filename.concat dstdir outname in 573 + if Sys.file_exists outpath then 574 + prerr_endline ("ocamlfind-mini: [WARNING] Overwriting file " ^ outpath); 575 + let ch_out = open_out_bin outpath in 576 + try 577 + let buflen = 4096 in 578 + let buf = Bytes.create buflen in 579 + let pos = ref 0 in 580 + let len = ref (input ch_in buf 0 buflen) in 581 + while !len > 0 do 582 + output ch_out buf !pos !len; 583 + len := input ch_in buf !pos buflen; 584 + done; 585 + output_string ch_out append; 586 + close_out ch_out; 587 + close_in ch_in; 588 + prerr_endline("Installed " ^ outpath); 589 + with 590 + exc -> close_out ch_out; raise exc 591 + with 592 + exc -> close_in ch_in; raise exc 593 + ;; 594 + 595 + 596 + let install_create_directory pkgname dstdir = 597 + if Sys.file_exists dstdir then 598 + failwith ("Package " ^ pkgname ^ " is already installed; please remove it first"); 599 + make_directory dstdir 600 + ;; 601 + 602 + 603 + exception Skip_file;; 604 + 605 + let install_package () = 606 + let destdir = ref (env_destdir) in 607 + let metadir = ref (env_metadir) in 608 + let don't_add_directory_directive = ref false in 609 + let pkgname = ref "" in 610 + let files = ref [] in 611 + 612 + let keywords = 613 + [ "-destdir", (Arg.String (fun s -> destdir := s)), 614 + "<path> Set the destination directory"; 615 + "-metadir", (Arg.String (fun s -> metadir := s)), 616 + "<path> Install the META file into this directory"; 617 + "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive), 618 + " never append directory='...' to META"; 619 + ] in 620 + let errmsg = "usage: ocamlfind-mini install [options] <package_name> <file> ..." in 621 + 622 + Arg.current := 1; 623 + Arg.parse 624 + keywords 625 + (fun s -> 626 + if !pkgname = "" 627 + then pkgname := s 628 + else files := s :: !files 629 + ) 630 + errmsg; 631 + if !pkgname = "" then (Arg.usage keywords errmsg; exit 1); 632 + 633 + (* Check destdir: *) 634 + if !destdir = "" then 635 + failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR"); 636 + if not (Sys.file_exists !destdir) then 637 + failwith ("The destination directory " ^ !destdir ^ " does not exist"); 638 + 639 + (* Check whether META exists: *) 640 + let meta_dot_pkg = "META." ^ !pkgname in 641 + let has_meta = 642 + List.exists 643 + (fun p -> 644 + let b = Filename.basename p in 645 + b = "META" || b = meta_dot_pkg) 646 + !files 647 + in 648 + if not has_meta then 649 + failwith "The META file is missing"; 650 + 651 + (* Check that there is no meta_dot_pkg: *) 652 + if Sys.file_exists (Filename.concat !metadir meta_dot_pkg) then 653 + failwith ("Package " ^ !pkgname ^ " is already installed; please remove it first"); 654 + 655 + (* Create the package directory: *) 656 + let pkgdir = Filename.concat !destdir !pkgname in 657 + install_create_directory !pkgname pkgdir; 658 + 659 + (* Now copy the files into the package directory: *) 660 + let has_metadir = !metadir <> "" in 661 + List.iter 662 + (fun p -> 663 + try 664 + copy_file 665 + ~rename: (fun f -> 666 + if has_metadir then begin 667 + if f = "META" || f = meta_dot_pkg 668 + then raise Skip_file 669 + else f 670 + end 671 + else 672 + if f = meta_dot_pkg then "META" else f) 673 + p 674 + pkgdir 675 + with 676 + Skip_file -> () 677 + ) 678 + !files; 679 + 680 + (* Finally copy META into metadir, if this has been requested *) 681 + if has_metadir then begin 682 + List.iter 683 + (fun p -> 684 + let b = Filename.basename p in 685 + if b = "META" || b = meta_dot_pkg then 686 + copy_file 687 + ~rename: (fun f -> 688 + if f = "META" then meta_dot_pkg else f) 689 + ~append: ("\ndirectory=\"" ^ pkgdir ^ "\" # auto-added by ocamlfind-mini\n") 690 + p 691 + !metadir 692 + ) 693 + !files 694 + end 695 + ;; 696 + 697 + 698 + let remove_package () = 699 + let destdir = ref (env_destdir) in 700 + let metadir = ref (env_metadir) in 701 + let pkgname = ref "" in 702 + 703 + let keywords = 704 + [ "-destdir", (Arg.String (fun s -> destdir := s)), 705 + "<path> Set the destination directory"; 706 + "-metadir", (Arg.String (fun s -> metadir := s)), 707 + "<path> Remove the META file from this directory"; 708 + ] in 709 + let errmsg = "usage: ocamlfind-mini remove [options] <package_name>" in 710 + 711 + Arg.current := 1; 712 + Arg.parse 713 + keywords 714 + (fun s -> 715 + if !pkgname = "" 716 + then pkgname := s 717 + else raise (Arg.Bad "too many arguments") 718 + ) 719 + errmsg; 720 + if !pkgname = "" then (Arg.usage keywords errmsg; exit 1); 721 + 722 + (* Check destdir: *) 723 + if !destdir = "" then 724 + failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR"); 725 + if not (Sys.file_exists !destdir) then 726 + failwith ("The destination directory " ^ !destdir ^ " does not exist"); 727 + 728 + let meta_dot_pkg = "META." ^ !pkgname in 729 + let has_metadir = !metadir <> "" in 730 + 731 + (* If there is a metadir, remove the META file from it: *) 732 + if has_metadir then begin 733 + let f = Filename.concat !metadir meta_dot_pkg in 734 + if Sys.file_exists f then begin 735 + Sys.remove f; 736 + prerr_endline ("Removed " ^ f); 737 + end 738 + else 739 + prerr_endline ("ocamlfind-mini: [WARNING] No such file: " ^ f) 740 + end; 741 + 742 + (* Remove the files from the package directory: *) 743 + let pkgdir = Filename.concat !destdir !pkgname in 744 + 745 + if Sys.file_exists pkgdir then begin 746 + let files = list_dir pkgdir in 747 + List.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files; 748 + remove_directory pkgdir; 749 + prerr_endline ("Removed " ^ pkgdir) 750 + end 751 + else 752 + prerr_endline("ocamlfind-mini: [WARNING] No such directory: " ^ pkgdir); 753 + ;; 754 + 755 + 756 + let select_mode() = 757 + let m_string = try arg 1 with Not_found -> raise Usage in 758 + let m = 759 + match m_string with 760 + ("use"|"-use") -> M_use 761 + | ("query"|"-query") -> M_query 762 + | ("install"|"-install") -> M_install 763 + | ("remove"|"-remove") -> M_remove 764 + | ("ocamlc"|"-ocamlc") -> M_compiler "ocamlc" 765 + | ("ocamlcp"|"-ocamlcp") -> M_compiler "ocamlcp" 766 + | ("ocamlmktop"|"-ocamlmktop") -> M_compiler "ocamlmktop" 767 + | ("ocamlopt"|"-ocamlopt") -> M_compiler "ocamlopt" 768 + | ("printconf"|"-printconf") -> M_printconf 769 + | ("guess"|"-guess") -> M_guess 770 + | ("list"|"-list") -> M_list 771 + | _ -> raise Usage 772 + in 773 + 774 + m 775 + ;; 776 + 777 + 778 + let sorry() = 779 + prerr_endline "ocamlfind-mini: sorry, this function is not implemented in the reduced version of ocamlfind"; 780 + exit 1 781 + ;; 782 + 783 + 784 + let main() = 785 + try 786 + let m = select_mode() in 787 + let l = Array.length Sys.argv in 788 + let rest = Array.sub Sys.argv 2 (l-2) in 789 + match m with 790 + M_use -> if rest = [| |] then raise Usage; 791 + if rest.(0) = "-p" then begin 792 + if l<4 then raise Usage; 793 + use_package rest.(1) 794 + (List.tl(List.tl(Array.to_list rest))) 795 + end 796 + else 797 + use_package "" (Array.to_list rest) 798 + | M_query -> sorry() 799 + | M_install -> install_package() 800 + | M_remove -> remove_package () 801 + | M_printconf -> sorry() 802 + | M_guess -> sorry() 803 + | M_list -> sorry() 804 + | M_compiler which -> ocamlc which () 805 + with 806 + Usage -> 807 + prerr_endline "usage: ocamlfind-mini ocamlc [-help | other options] <file> ..."; 808 + prerr_endline " or: ocamlfind-mini ocamlcp [-help | other options] <file> ..."; 809 + prerr_endline " or: ocamlfind-mini ocamlmktop [-help | other options] <file> ..."; 810 + prerr_endline " or: ocamlfind-mini ocamlopt [-help | other options] <file> ..."; 811 + prerr_endline " or: ocamlfind-mini install [-help | other options] <package_name> <file> ..."; 812 + prerr_endline " or: ocamlfind-mini remove [-help | other options] <package_name>"; 813 + exit 2 814 + | Failure f -> 815 + prerr_endline ("ocamlfind-mini: " ^ f); 816 + exit 2 817 + ;; 818 + 819 + 820 + try 821 + Sys.catch_break true; 822 + main() 823 + with 824 + any -> 825 + prerr_endline ("Uncaught exception: " ^ Printexc.to_string any); 826 + let raise_again = 827 + try ignore(Sys.getenv "OCAMLFIND_DEBUG"); true 828 + with Not_found -> false 829 + in 830 + if raise_again then raise any; 831 + exit 3 832 + ;; 833 + 834 + 835 + (* ====================================================================== 836 + * History: 837 + * 838 + * $Log: ocamlfind-mini,v $ 839 + * Revision 1.4 2001/03/10 08:15:24 gerd 840 + * -warn-error 841 + * 842 + * Revision 1.3 2001/03/06 20:18:03 gerd 843 + * Option -where. 844 + * 845 + * Revision 1.2 2001/03/04 19:03:56 gerd 846 + * list_dir: deletes the temp file after use 847 + * 848 + * Revision 1.1 2001/03/04 19:01:21 gerd 849 + * Initial revision. 850 + * 851 + *)
+4
vendor/opam/ocamlfind/ocaml-stub
··· 1 + #!/bin/sh 2 + 3 + BINDIR=$(dirname "$(command -v ocamlc)") 4 + "$BINDIR/ocaml" -I "$OCAML_TOPLEVEL_PATH" "$@"
+6
vendor/opam/ocamlfind/ocamlfind.install
··· 1 + bin: [ 2 + "src/findlib/ocamlfind" {"ocamlfind"} 3 + "?src/findlib/ocamlfind_opt" {"ocamlfind"} 4 + "?tools/safe_camlp4" 5 + ] 6 + toplevel: ["src/findlib/topfind"]
+39
vendor/opam/ocamlfind/opam
··· 1 + opam-version: "2.0" 2 + name: "ocamlfind" 3 + version: "1.9.8.git" 4 + license: "MIT" 5 + synopsis: "A library manager for OCaml" 6 + maintainer: "Thomas Gazagnaire <thomas@gazagnaire.org>" 7 + authors: "Gerd Stolpmann <gerd@gerd-stolpmann.de>" 8 + homepage: "http://projects.camlcity.org/projects/findlib.html" 9 + bug-reports: "https://github.com/ocaml/ocamlfind/issues" 10 + dev-repo: "git+https://github.com/ocaml/ocamlfind.git" 11 + description: """ 12 + Findlib is a library manager for OCaml. It provides a convention how 13 + to store libraries, and a file format ("META") to describe the 14 + properties of libraries. There is also a tool (ocamlfind) for 15 + interpreting the META files, so that it is very easy to use libraries 16 + in programs and scripts. 17 + """ 18 + build: [ 19 + [ 20 + "./configure" 21 + "-bindir" bin 22 + "-sitelib" lib 23 + "-mandir" man 24 + "-config" "%{lib}%/findlib.conf" 25 + "-no-custom" 26 + "-no-camlp4" {!ocaml:preinstalled & ocaml:version >= "4.02.0"} 27 + "-no-topfind" {ocaml:preinstalled} 28 + ] 29 + [make "all"] 30 + [make "opt"] {ocaml:native} 31 + ] 32 + install: [ 33 + [make "install"] 34 + ["install" "-m" "0755" "ocaml-stub" "%{bin}%/ocaml"] {ocaml:preinstalled} 35 + ] 36 + depends: [ 37 + "ocaml" {>= "3.08.0"} 38 + ] 39 + depopts: ["graphics"]
+73
vendor/opam/ocamlfind/patches/findlib-1.1-win32.diff
··· 1 + --- ./itest-aux/simple_dbm.ml.orig 2005-11-07 13:38:01.203976400 +0100 2 + +++ ./itest-aux/simple_dbm.ml 2005-11-07 13:38:11.498265600 +0100 3 + @@ -1,9 +1,9 @@ 4 + -(try 5 + +(try 6 + Sys.remove "itest-aux/testdb.db" 7 + -with 8 + +with 9 + _ -> ()); 10 + 11 + -let dbm = 12 + +let _dbm = 13 + Dbm.opendbm "itest-aux/testdb" [ Dbm.Dbm_rdwr; Dbm.Dbm_create ] 0o777 in 14 + 15 + print_string "OK\n";; 16 + --- ./itest-aux/simple_labltk.ml.orig 2005-11-07 13:39:25.931584300 +0100 17 + +++ ./itest-aux/simple_labltk.ml 2005-11-07 13:39:34.954108200 +0100 18 + @@ -1,6 +1,6 @@ 19 + open Tk;; 20 + 21 + -let top = openTk() in 22 + +let _top = openTk() in 23 + update(); 24 + closeTk() 25 + ;; 26 + --- ./itest-aux/simple_num.ml.orig 2005-11-07 13:39:00.956917700 +0100 27 + +++ ./itest-aux/simple_num.ml 2005-11-07 13:39:05.973881600 +0100 28 + @@ -1,4 +1,4 @@ 29 + -let n = Num.num_of_int 5 in 30 + +let _n = Num.num_of_int 5 in 31 + 32 + print_string "OK\n";; 33 + 34 + --- ./itest-aux/simple_str.ml.orig 2005-11-07 13:35:56.037998100 +0100 35 + +++ ./itest-aux/simple_str.ml 2005-11-07 13:35:58.661692300 +0100 36 + @@ -1,4 +1,4 @@ 37 + -let b = Str.regexp ".*" in 38 + +let _b = Str.regexp ".*" in 39 + 40 + print_string "OK\n";; 41 + 42 + --- ./itest-aux/simple_unix.ml.orig 2005-11-07 13:37:28.257845000 +0100 43 + +++ ./itest-aux/simple_unix.ml 2005-11-07 13:37:34.927235600 +0100 44 + @@ -1,4 +1,4 @@ 45 + -let p = Unix.getpid() in 46 + +let _p = Unix.getpid() in 47 + 48 + print_string "OK\n";; 49 + 50 + --- ./tools/extract_args/extract_args.ml.orig 2005-11-07 13:27:58.494279900 +0100 51 + +++ ./tools/extract_args/extract_args.ml 2005-11-07 13:32:33.393117500 +0100 52 + @@ -25,13 +25,17 @@ 53 + 54 + let get_help cmd = 55 + let temp_file = 56 + - Filename.temp_file "findlib" ".txt" in 57 + + Filename.temp_file "findlib" ".txt" 58 + + and quote s = 59 + + match Sys.os_type with 60 + + "Win32" -> s 61 + + | _ -> Filename.quote s in 62 + let help_out = 63 + try 64 + let code = 65 + - Sys.command (sprintf "%s -help >%s" 66 + - (Filename.quote cmd) 67 + - (Filename.quote temp_file)) in 68 + + Sys.command (sprintf "%s -help >%s" 69 + + (quote cmd) 70 + + (quote temp_file)) in 71 + if code <> 0 then 72 + raise Not_found; (* Assume command does not exist! *) 73 + let lines = read_lines temp_file in
+40
vendor/opam/ocamlfind/release
··· 1 + #! /bin/sh 2 + 3 + set -e 4 + 5 + version=`./configure -version 2>/dev/null` 6 + destdir="findlib-$version" 7 + 8 + mkdir -p packages 9 + rm -rf "packages/$destdir" 10 + makepkg -spec findlib.files -intree . -outtree "packages/$destdir" 11 + (cd packages; tar czf "$destdir.tar.gz" "$destdir") 12 + echo "Wrote packages/$destdir.tar.gz" 13 + 14 + # Checking git: 15 + 16 + master="$(git branch | grep '* master')" 17 + if [ -z "$master" ]; then 18 + echo "Error: not on master branch" 19 + exit 1 20 + fi 21 + 22 + status="$(git status -uno -s)" 23 + 24 + if [ -n "$status" ]; then 25 + echo "Error: git status not clean" 26 + exit 1 27 + else 28 + printf "Tag revision (y/n)? " 29 + read answer 30 + case "$answer" in 31 + y|Y|yes|YES) 32 + git tag -a -m "findlib-$version" findlib-$version 33 + git push --tags origin master 34 + echo "New tag: findlib-$version" 35 + ;; 36 + *) 37 + echo "Nothing tagged." 38 + ;; 39 + esac 40 + fi
+11
vendor/opam/ocamlfind/site-lib-src/bigarray/META.in
··· 1 + # Specifications for the "bigarray" library: 2 + requires = "unix" 3 + version = "[distributed with Ocaml]" 4 + description = "Large statically allocated arrays" 5 + directory = "^" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "bigarray.cma" 8 + archive(native) = "bigarray.cmxa" 9 + plugin(byte) = "bigarray.cma" 10 + plugin(native) = "bigarray.cmxs" 11 + linkopts = ""
+1
vendor/opam/ocamlfind/site-lib-src/bigarray/interfaces.in
··· 1 + bigarray.cma
+4
vendor/opam/ocamlfind/site-lib-src/bytes/META.in
··· 1 + name="bytes" 2 + version="[distributed with OCaml 4.02 or above]" 3 + description="dummy backward-compatibility package for mutable strings" 4 + requires=""
+8
vendor/opam/ocamlfind/site-lib-src/bytes/README
··· 1 + dummy forward-compatibility package for the standard Bytes module 2 + 3 + Starting from 4.02, the OCaml standard library splits String into two 4 + modules, String for now-immutable strings and Bytes for mutable byte 5 + sequences. A 'bytes' package is made available to older OCaml version 6 + that wish to use a Bytes module. This dummy 'bytes' package, intended 7 + to be installed on 4.02 and above, makes user-code depending on 8 + 'bytes' forward-compatible.
+2
vendor/opam/ocamlfind/site-lib-src/bytes/interfaces.in
··· 1 + bytes.cmo 2 +
+2
vendor/opam/ocamlfind/site-lib-src/bytes/interfaces.out
··· 1 + Bytes 2 +
+95
vendor/opam/ocamlfind/site-lib-src/camlp4.309/META.in
··· 1 + # Specifications for the "camlp4" preprocessor: 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "Base for Camlp4 syntax extensions" 5 + directory = "%%camlp4_dir%%" 6 + 7 + # For the toploop: 8 + archive(byte,toploop,camlp4o) = "camlp4o.cma" 9 + archive(byte,toploop,camlp4r) = "camlp4r.cma" 10 + 11 + # Scheme-like syntax: 12 + # Do #predicates "syntax,camlp4scheme", followed by #require "camlp4" 13 + archive(byte,toploop,camlp4scheme) = "camlp4sch.cma" 14 + 15 + # Standard ML-like syntax: 16 + # Do #predicates "syntax,camlp4sml", followed by #require "camlp4" 17 + archive(byte,toploop,camlp4sml) = "gramlib.cma camlp4_top.cma pa_sml.cmo" 18 + 19 + # Lisp-like syntax: 20 + # Do #predicates "syntax,camlp4lisp", followed by #require "camlp4" 21 + archive(byte,toploop,camlp4lisp) = "gramlib.cma camlp4_top.cma pa_lisp.cmo" 22 + 23 + # For the preprocessor itself: 24 + archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo" 25 + archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo" 26 + archive(syntax,preprocessor,camlp4sml) = "pa_sml.cmo pr_dump.cmo" 27 + archive(syntax,preprocessor,camlp4scheme) = "pa_scheme.cmo pr_dump.cmo" 28 + archive(syntax,preprocessor,camlp4lisp) = "pa_lisp.cmo pr_dump.cmo" 29 + preprocessor = "%%camlp4_cmd%% -nolib" 30 + 31 + package "gramlib" ( 32 + requires(toploop) = "camlp4" 33 + version = "[distributed with Ocaml]" 34 + description = "Grammar library to create syntax extensions" 35 + archive(byte) = "gramlib.cma" 36 + archive(byte,toploop) = "" # already contained in camlp4*.cma 37 + archive(native) = "gramlib.cmxa" 38 + ) 39 + 40 + package "quotations" ( 41 + requires = "camlp4" 42 + version = "[distributed with Ocaml]" 43 + description = "Syntax extension: Quotations to create AST nodes" 44 + archive(syntax,preprocessor) = "q_MLast.cmo" 45 + archive(syntax,toploop) = "q_MLast.cmo" 46 + ) 47 + 48 + package "phony_quotations" ( 49 + requires = "camlp4" 50 + version = "[distributed with Ocaml]" 51 + description = "Syntax extension: Phony quotations" 52 + archive(syntax,preprocessor) = "q_phony.cmo" 53 + archive(syntax,toploop) = "q_phony.cmo" 54 + ) 55 + 56 + package "extend" ( 57 + requires = "camlp4" 58 + version = "[distributed with Ocaml]" 59 + description = "Syntax extension: EXTEND the camlp4 grammar" 60 + archive(syntax,preprocessor) = "pa_extend.cmo" 61 + archive(syntax,toploop) = "pa_extend.cmo" 62 + ) 63 + 64 + package "extfun" ( 65 + requires = "camlp4" 66 + version = "[distributed with Ocaml]" 67 + description = "Syntax extension: Extensible functions" 68 + archive(syntax,preprocessor) = "pa_extfun.cmo" 69 + archive(syntax,toploop) = "pa_extfun.cmo" 70 + ) 71 + 72 + package "fstream" ( 73 + requires = "camlp4" 74 + version = "[distributed with Ocaml]" 75 + description = "Syntax extension: Functional stream parsers" 76 + archive(syntax,preprocessor) = "pa_fstream.cmo" 77 + archive(syntax,toploop) = "pa_fstream.cmo" 78 + ) 79 + 80 + package "macro" ( 81 + requires = "camlp4" 82 + version = "[distributed with Ocaml]" 83 + description = "Syntax extension: Conditional compilation" 84 + archive(syntax,preprocessor) = "pa_macro.cmo" 85 + archive(syntax,toploop) = "pa_macro.cmo" 86 + ) 87 + 88 + package "unit_constraints" ( 89 + requires = "camlp4" 90 + version = "[distributed with Ocaml]" 91 + description = "Syntax extension: Type constraints of type unit (revised syntax only)" 92 + archive(syntax,preprocessor,camlp4r) = "pa_ru.cmo" 93 + archive(syntax,toploop,camlp4r) = "pa_ru.cmo" 94 + error(syntax,-camlp4r) = "Not available" 95 + )
+147
vendor/opam/ocamlfind/site-lib-src/camlp4.310/META.in
··· 1 + # Specifications for the "camlp4" preprocessor: 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "Base for Camlp4 syntax extensions" 5 + directory = "+camlp4" 6 + 7 + # For the toploop: 8 + requires(byte,toploop) = "%%camlp4_dynlink%%" 9 + archive(byte,toploop,camlp4o) = "camlp4o.cma" 10 + archive(byte,toploop,camlp4r) = "camlp4r.cma" 11 + 12 + # For the preprocessor itself: 13 + archive(syntax,preprocessor,camlp4o) = "-parser o -parser op -printer p" 14 + archive(syntax,preprocessor,camlp4r) = "-parser r -parser rp -printer p" 15 + preprocessor = "%%camlp4_cmd%%" 16 + 17 + package "lib" ( 18 + requires = "camlp4 %%camlp4_dynlink%%" 19 + version = "[distributed with Ocaml]" 20 + description = "Camlp4 library" 21 + archive(byte) = "camlp4lib.cma" 22 + archive(byte,toploop) = "" # already contained in camlp4*.cma 23 + archive(native) = "camlp4lib.cmxa" 24 + ) 25 + 26 + package "gramlib" ( 27 + requires = "camlp4.lib" 28 + version = "[distributed with Ocaml]" 29 + description = "Compatibility name for camlp4.lib" 30 + ) 31 + 32 + # don't use camlp4.lib and camlp4.fulllib together 33 + package "fulllib" ( 34 + requires = "camlp4 %%camlp4_dynlink%%" 35 + version = "[distributed with Ocaml]" 36 + description = "Camlp4 library" 37 + error(pkg_camlp4.lib) = "camlp4.lib and camlp4.fulllib are incompatible" 38 + archive(byte) = "camlp4fulllib.cma" 39 + archive(byte,toploop) = "" # already contained in camlp4*.cma 40 + archive(native) = "camlp4fulllib.cmxa" 41 + ) 42 + 43 + package "quotations" ( 44 + version = "[distributed with Ocaml]" 45 + description = "Syntax extension: Quotations to create AST nodes" 46 + requires = "camlp4.quotations.r" # backward compat 47 + # We must have a non-empty archive, otherwise this pkg is ignored 48 + # for constructing the preprocessor command. We can pass -ignore arg 49 + # to camlp4 as dummy argument: 50 + archive(syntax,preprocessor) = "-ignore foo" 51 + package "o" ( 52 + requires = "camlp4" 53 + version = "[distributed with Ocaml]" 54 + description = "Syntax extension: Quotations to create AST nodes (original syntax)" 55 + archive(syntax,preprocessor) = "-parser Camlp4QuotationCommon -parser Camlp4OCamlOriginalQuotationExpander" 56 + archive(syntax,toploop) = "Camlp4Parsers/Camlp4QuotationCommon.cmo Camlp4Parsers/Camlp4OCamlOriginalQuotationExpander.cmo" 57 + ) 58 + package "r" ( 59 + requires = "camlp4" 60 + version = "[distributed with Ocaml]" 61 + description = "Syntax extension: Quotations to create AST nodes (revised syntax)" 62 + archive(syntax,preprocessor) = "-parser Camlp4QuotationCommon -parser Camlp4OCamlRevisedQuotationExpander" 63 + archive(syntax,toploop) = "Camlp4Parsers/Camlp4QuotationCommon.cmo Camlp4Parsers/Camlp4OCamlRevisedQuotationExpander.cmo" 64 + ) 65 + ) 66 + 67 + package "extend" ( 68 + requires = "camlp4" 69 + version = "[distributed with Ocaml]" 70 + description = "Syntax extension: EXTEND the camlp4 grammar" 71 + archive(syntax,preprocessor) = "-parser Camlp4GrammarParser" 72 + archive(syntax,toploop) = "Camlp4Parsers/Camlp4GrammarParser.cmo" 73 + ) 74 + 75 + package "listcomprehension" ( 76 + requires = "camlp4" 77 + version = "[distributed with Ocaml]" 78 + description = "Syntax extension for list comprehensions" 79 + archive(syntax,preprocessor) = "-parser Camlp4ListComprehension" 80 + archive(syntax,toploop) = "Camlp4Parsers/Camlp4ListComprehension.cmo" 81 + ) 82 + 83 + package "macro" ( 84 + requires = "camlp4" 85 + version = "[distributed with Ocaml]" 86 + description = "Syntax extension: Conditional compilation" 87 + archive(syntax,preprocessor) = "-parser Camlp4MacroParser" 88 + archive(syntax,toploop) = "Camlp4Parsers/Camlp4MacroParser.cmo" 89 + ) 90 + 91 + package "mapgenerator" ( 92 + requires = "camlp4" 93 + version = "[distributed with Ocaml]" 94 + description = "Syntax filter: Traverse data structure (map style)" 95 + archive(syntax,preprocessor) = "-filter Camlp4MapGenerator" 96 + archive(syntax,toploop) = "Camlp4Filters/Camlp4MapGenerator.cmo" 97 + ) 98 + 99 + package "foldgenerator" ( 100 + requires = "camlp4" 101 + version = "[distributed with Ocaml]" 102 + description = "Syntax filter: Traverse data structure (fold style)" 103 + archive(syntax,preprocessor) = "-filter Camlp4FoldGenerator" 104 + archive(syntax,toploop) = "Camlp4Filters/Camlp4FoldGenerator.cmo" 105 + ) 106 + 107 + package "metagenerator" ( 108 + requires = "camlp4" 109 + version = "[distributed with Ocaml]" 110 + description = "Syntax filter: Generate AST generator for data structure" 111 + archive(syntax,preprocessor) = "-filter Camlp4MetaGenerator" 112 + archive(syntax,toploop) = "Camlp4Filters/Camlp4MetaGenerator.cmo" 113 + ) 114 + 115 + package "locationstripper" ( 116 + requires = "camlp4" 117 + version = "[distributed with Ocaml]" 118 + description = "Syntax filter: Remove location info from AST" 119 + archive(syntax,preprocessor) = "-filter Camlp4LocationStripper" 120 + archive(syntax,toploop) = "Camlp4Filters/Camlp4LocationStripper.cmo" 121 + ) 122 + 123 + package "tracer" ( 124 + requires = "camlp4" 125 + version = "[distributed with Ocaml]" 126 + description = "Syntax filter: Trace execution" 127 + archive(syntax,preprocessor) = "-filter Camlp4Tracer" 128 + archive(syntax,toploop) = "Camlp4Filters/Camlp4Tracer.cmo" 129 + ) 130 + 131 + package "exceptiontracer" ( 132 + requires = "camlp4" 133 + version = "[distributed with Ocaml]" 134 + description = "Syntax filter: Trace exception execution" 135 + archive(syntax,preprocessor) = "-filter Camlp4ExceptionTracer" 136 + archive(syntax,toploop) = "Camlp4Filters/Camlp4ExceptionTracer.cmo" 137 + ) 138 + 139 + package "profiler" ( 140 + requires = "camlp4" 141 + version = "[distributed with Ocaml]" 142 + description = "Syntax filter: Count events during execution" 143 + archive(syntax,preprocessor) = "-filter Camlp4Profiler" 144 + archive(syntax,toploop) = "Camlp4Filters/Camlp4Profiler.cmo" 145 + archive(byte) = "camlp4prof.cmo" 146 + archive(native) = "camlp4prof.cmx" 147 + )
+45
vendor/opam/ocamlfind/site-lib-src/compiler-libs/META.in
··· 1 + # The compiler itself 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "compiler-libs support library" 5 + directory= "+compiler-libs" 6 + 7 + package "common" ( 8 + requires = "compiler-libs" 9 + version = "[distributed with Ocaml]" 10 + description = "Common compiler routines" 11 + archive(byte) = "ocamlcommon.cma" 12 + archive(native) = "ocamlcommon.cmxa" 13 + ) 14 + 15 + package "bytecomp" ( 16 + requires = "compiler-libs.common" 17 + version = "[distributed with Ocaml]" 18 + description = "Bytecode compiler" 19 + archive(byte) = "ocamlbytecomp.cma" 20 + archive(native) = "ocamlbytecomp.cmxa" 21 + ) 22 + 23 + package "optcomp" ( 24 + requires = "compiler-libs.common" 25 + version = "[distributed with Ocaml]" 26 + description = "Native-code compiler" 27 + archive(byte) = "ocamloptcomp.cma" 28 + archive(native) = "ocamloptcomp.cmxa" 29 + exists_if = "ocamloptcomp.cma" 30 + ) 31 + 32 + package "toplevel" ( 33 + requires = "compiler-libs.bytecomp" 34 + version = "[distributed with Ocaml]" 35 + description = "Toplevel interactions" 36 + archive(byte) = "ocamltoplevel.cma" 37 + ) 38 + 39 + package "native-toplevel" ( 40 + requires = "compiler-libs.optcomp dynlink" 41 + version = "[distributed with Ocaml]" 42 + description = "Toplevel interactions" 43 + archive(native) = "ocamltoplevel.cmxa" 44 + exists_if = "ocamltoplevel.cmxa" 45 + )
+10
vendor/opam/ocamlfind/site-lib-src/dbm/META.in
··· 1 + # Specification for the "dbm" library 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "Access to NDBM databases" 5 + directory = "^" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "dbm.cma" 8 + archive(native) = "dbm.cmxa" 9 + plugin(byte) = "dbm.cma" 10 + plugin(native) = "dbm.cmxs"
+1
vendor/opam/ocamlfind/site-lib-src/dbm/interfaces.in
··· 1 + dbm.cma
+8
vendor/opam/ocamlfind/site-lib-src/dynlink/META.in
··· 1 + # Specifications for the "dynlink" library: 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "Dynamic loading and linking of object files" 5 + directory = "%%dynlink_dir%%" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "dynlink.cma" 8 + %%natdynlink%%
+1
vendor/opam/ocamlfind/site-lib-src/dynlink/interfaces.in
··· 1 + dynlink.cma
+10
vendor/opam/ocamlfind/site-lib-src/graphics/META.in
··· 1 + # Specifications for the "graphics" library: 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "Portable drawing primitives" 5 + directory = "^" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "graphics.cma" 8 + archive(native) = "graphics.cmxa" 9 + plugin(byte) = "graphics.cma" 10 + plugin(native) = "graphics.cmxs"
+2
vendor/opam/ocamlfind/site-lib-src/graphics/interfaces.in
··· 1 + graphics.cma 2 +
+10
vendor/opam/ocamlfind/site-lib-src/labltk/META.in
··· 1 + # Specifications for the "labltk" library: 2 + requires = "" 3 + version = "[distributed with Ocaml]" 4 + description = "The Tk windowing toolkit" 5 + directory = "+labltk" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "labltk.cma" 8 + archive(native) = "labltk.cmxa" 9 + linkopts = "" 10 +
+2
vendor/opam/ocamlfind/site-lib-src/labltk/interfaces.in
··· 1 + labltk/*.cma 2 +
+6
vendor/opam/ocamlfind/site-lib-src/num-top/META.in
··· 1 + # Specification for the "num-top" library add-on: 2 + requires = "num.core" 3 + version = "%%findlib_version%%" 4 + description = "Add-on for num inside toploops" 5 + archive(byte,toploop) = "num_top.cma" 6 +
+14
vendor/opam/ocamlfind/site-lib-src/num/META.in
··· 1 + # Specification for the "num" library: 2 + requires = "num.core" 3 + requires(toploop) = "num.core,num-top" 4 + version = "[distributed with Ocaml]" 5 + description = "Arbitrary-precision rational arithmetic" 6 + package "core" ( 7 + directory = "^" 8 + version = "[internal]" 9 + browse_interfaces = "%%interfaces%%" 10 + archive(byte) = "nums.cma" 11 + archive(native) = "nums.cmxa" 12 + plugin(byte) = "nums.cma" 13 + plugin(native) = "nums.cmxs" 14 + )
+1
vendor/opam/ocamlfind/site-lib-src/num/interfaces.in
··· 1 + nums.cma
+8
vendor/opam/ocamlfind/site-lib-src/ocamlbuild/META.in
··· 1 + # Specification for the "ocamlbuild" library 2 + requires = "unix" 3 + version = "[distributed with Ocaml]" 4 + description = "ocamlbuild support library" 5 + directory= "^ocamlbuild" 6 + archive(byte) = "ocamlbuildlib.cma" 7 + archive(native) = "ocamlbuildlib.cmxa" 8 +
+5
vendor/opam/ocamlfind/site-lib-src/ocamldoc/META.in
··· 1 + # Specification for the "ocamldoc" library 2 + requires = "compiler-libs" 3 + version = "[distributed with Ocaml]" 4 + description = "ocamldoc plugin interface" 5 + directory= "^ocamldoc"
+11
vendor/opam/ocamlfind/site-lib-src/raw_spacetime/META.in
··· 1 + # Specifications for the "spacetime" library: 2 + requires = "" 3 + description = "Support library for the spacetime profiler" 4 + version = "[distributed with Ocaml]" 5 + directory = "^" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "raw_spacetime_lib.cma" 8 + archive(native) = "raw_spacetime_lib.cmxa" 9 + plugin(byte) = "raw_spacetime_lib.cma" 10 + plugin(native) = "raw_spacetime_lib.cmxs" 11 +
+1
vendor/opam/ocamlfind/site-lib-src/raw_spacetime/interfaces.in
··· 1 + raw_spacetime_lib.cma
+9
vendor/opam/ocamlfind/site-lib-src/stdlib/META.in
··· 1 + # Specifications for the standard library: 2 + # (Only included because of findlib-browser) 3 + requires = "" 4 + description = "Standard library" 5 + version = "[distributed with Ocaml]" 6 + directory = "^" 7 + browse_interfaces = "%%interfaces%%" 8 + 9 +
+1
vendor/opam/ocamlfind/site-lib-src/stdlib/interfaces.in
··· 1 + stdlib.cma
+12
vendor/opam/ocamlfind/site-lib-src/str/META.in
··· 1 + # Specifications for the "str" library: 2 + requires = "" 3 + description = "Regular expressions and string processing" 4 + version = "[distributed with Ocaml]" 5 + directory = "%%str_dir%%" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "str.cma" 8 + archive(native) = "str.cmxa" 9 + plugin(byte) = "str.cma" 10 + plugin(native) = "str.cmxs" 11 + 12 +
+1
vendor/opam/ocamlfind/site-lib-src/str/interfaces.in
··· 1 + str.cma
+37
vendor/opam/ocamlfind/site-lib-src/threads/META.in
··· 1 + # Specifications for the "threads" library: 2 + version = "[distributed with Ocaml]" 3 + description = "Multi-threading" 4 + requires(mt,mt_vm) = "threads.vm" 5 + requires(mt,mt_posix) = "threads.posix" 6 + directory = "^" 7 + type_of_threads = "%%type_of_threads%%" 8 + 9 + browse_interfaces = "%%interfaces%%" 10 + 11 + warning(-mt) = "Linking problems may arise because of the missing -thread or -vmthread switch" 12 + warning(-mt_vm,-mt_posix) = "Linking problems may arise because of the missing -thread or -vmthread switch" 13 + 14 + package "vm" ( 15 + # --- Bytecode-only threads: 16 + requires = "unix" 17 + directory = "+vmthreads" 18 + exists_if = "threads.cma" 19 + archive(byte,mt,mt_vm) = "threads.cma" 20 + version = "[internal]" 21 + ) 22 + 23 + package "posix" ( 24 + # --- POSIX-threads: 25 + requires = "unix" 26 + directory = "+threads" 27 + exists_if = "threads.cma" 28 + archive(byte,mt,mt_posix) = "threads.cma" 29 + archive(native,mt,mt_posix) = "threads.cmxa" 30 + version = "[internal]" 31 + ) 32 + 33 + package "none" ( 34 + error = "threading is not supported on this platform" 35 + version = "[internal]" 36 + ) 37 +
+2
vendor/opam/ocamlfind/site-lib-src/threads/interfaces.in
··· 1 + vmthreads/threads.cma 2 +
+13
vendor/opam/ocamlfind/site-lib-src/unix/META.in
··· 1 + # Specifications for the "unix" library: 2 + requires = "" 3 + description = "Unix system calls" 4 + version = "[distributed with Ocaml]" 5 + directory = "%%unix_dir%%" 6 + browse_interfaces = "%%interfaces%%" 7 + archive(byte) = "unix.cma" 8 + archive(native) = "unix.cmxa" 9 + archive(byte,mt_vm) = "vmthreads/unix.cma" 10 + plugin(byte) = "unix.cma" 11 + plugin(native) = "unix.cmxs" 12 + plugin(byte,mt_vm) = "vmthreads/unix.cma" 13 +
+1
vendor/opam/ocamlfind/site-lib-src/unix/interfaces.in
··· 1 + unix.cma
+9
vendor/opam/ocamlfind/src/bytes/META
··· 1 + name="bytes" 2 + version="[OCaml strictly before 4.02]" 3 + description="backward-compatibility package for mutable strings" 4 + requires="" 5 + browse_interfaces = "String" 6 + archive(byte)="bytes.cma" 7 + archive(native)="bytes.cmxa" 8 + plugin(byte)="bytes.cma" 9 + plugin(native)="bytes.cmxs"
+41
vendor/opam/ocamlfind/src/bytes/Makefile
··· 1 + BYTE_FILES=bytes.cmi bytes.cma 2 + NATIVE_FILES=bytes.cmx bytes$(LIB_SUFFIX) bytes.cmxa 3 + NATIVE_FILES_DYNLINK=bytes.cmxs 4 + 5 + TOP=../.. 6 + include $(TOP)/Makefile.config 7 + 8 + OCAMLC = ocamlc 9 + OCAMLOPT = ocamlopt $(OCAMLOPT_G) 10 + OCAMLOPT_SHARED = $(OCAMLOPT) 11 + 12 + build: all opt 13 + 14 + all: 15 + $(OCAMLC) -a -o bytes.cma bytes.ml 16 + 17 + opt: 18 + $(OCAMLOPT) -a -o bytes.cmxa bytes.ml 19 + if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \ 20 + $(OCAMLOPT_SHARED) -shared -o bytes.cmxs bytes.cmxa; \ 21 + fi 22 + 23 + install: all 24 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes" 25 + $(CP) META $(BYTE_FILES) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/" 26 + for f in $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK); do if [ -f "$$f" ]; then $(CP) $$f "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/"; fi; done 27 + 28 + uninstall: 29 + rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes" 30 + 31 + # install-self and uninstall-self use ocamlfind already. This is a bit 32 + # questionable here. 33 + 34 + install-self: all 35 + ocamlfind install bytes META $(BYTE_FILES) -optional $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK) 36 + 37 + uninstall-self: 38 + ocamlfind remove bytes 39 + 40 + clean: 41 + ocamlbuild -clean
+7
vendor/opam/ocamlfind/src/bytes/README
··· 1 + backward-compatibility package for the standard Bytes module of 4.02 2 + 3 + Starting from 4.02, the OCaml standard library splits String into two 4 + modules, String for now-immutable strings and Bytes for mutable byte 5 + sequences. This package exports a Bytes package mimicking the new 6 + interface to older OCaml version, letting you write code using Bytes 7 + that works with OCaml < 4.02.
+36
vendor/opam/ocamlfind/src/bytes/bytes.ml
··· 1 + include String 2 + 3 + let empty = "" 4 + let of_string = copy 5 + let to_string = copy 6 + 7 + let sub_string = sub 8 + let blit_string = blit 9 + 10 + let unsafe_to_string : t -> string = fun s -> s 11 + let unsafe_of_string : string -> t = fun s -> s 12 + 13 + let extend s left right = 14 + (* length of the final string *) 15 + let dstlen = left + length s + right in 16 + (* length of the included portion of the input string *) 17 + let srclen = min 0 left + length s + min 0 right in 18 + let t = create dstlen in 19 + if srclen > 0 then blit s (max 0 (-left)) t (max 0 left) srclen; 20 + t 21 + 22 + let init len f = 23 + let s = create len in 24 + for i = 0 to len - 1 do 25 + set s i (f i); 26 + done; 27 + s 28 + 29 + let mapi f input = 30 + let output = create (length input) in 31 + for i = 0 to length input - 1 do 32 + output.[i] <- f i input.[i]; 33 + done; 34 + output 35 + 36 + let cat = (^)
+37
vendor/opam/ocamlfind/src/findlib-toolbox/Makefile
··· 1 + TOP=../.. 2 + include $(TOP)/Makefile.config 3 + 4 + .PHONY: all opt install uninstall clean 5 + 6 + all: make_wizard$(EXEC_SUFFIX) 7 + 8 + opt: 9 + true 10 + 11 + make_wizard$(EXEC_SUFFIX): make_wizard.ml 12 + ocamlc -o make_wizard$(EXEC_SUFFIX) -I +unix -I +labltk -I ../findlib \ 13 + unix.cma str.cma labltk.cma findlib.cma make_wizard.ml 14 + 15 + install: 16 + $(INSTALLFILE) make_wizard$(EXEC_SUFFIX) make_wizard.pattern $(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib/ 17 + 18 + # uninstall: Nothing to do, because the removal of the findlib core also 19 + # deinstalls the make_wizard 20 + uninstall: 21 + true 22 + 23 + # ---------------------------------------------------------------------- 24 + 25 + tree: lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml test_tree.ml 26 + ocamlfind ocamlc -o tree -package labltk,unix,str -linkpkg \ 27 + lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml test_tree.ml 28 + 29 + tree_editor: lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml tree_editor.ml 30 + ocamlfind ocamlc -o tree_editor -package labltk,unix,str -linkpkg \ 31 + lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml tree_editor.ml 32 + 33 + # ---------------------------------------------------------------------- 34 + 35 + clean: 36 + rm -f *.cmi *.cmo 37 + rm -f make_wizard$(EXEC_SUFFIX) # tree tree_editor
+6
vendor/opam/ocamlfind/src/findlib-toolbox/directory.xpm
··· 1 + #define directory_width 16 2 + #define directory_height 16 3 + static unsigned char directory_bits[] = { 4 + 0xf8, 0x01, 0xfc, 0x03, 0xfe, 0x7f, 0x01, 0x80, 0x55, 0xd5, 0x01, 0x80, 5 + 0xab, 0xaa, 0x01, 0x80, 0x55, 0xd5, 0x01, 0x80, 0xab, 0xaa, 0x01, 0x80, 6 + 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+1559
vendor/opam/ocamlfind/src/findlib-toolbox/make_wizard.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + 7 + open Tk;; 8 + open Widget;; 9 + 10 + (**********************************************************************) 11 + (* GLOBAL VARIABLES *) 12 + (**********************************************************************) 13 + 14 + (* General *) 15 + 16 + let wiz_package_name = ref "";; 17 + let wiz_package_version = ref "";; 18 + let wiz_package_description = ref "";; 19 + 20 + (* Preprocessor *) 21 + 22 + let wiz_enable_camlp4 = ref false;; 23 + let wiz_camlp4_syntax = ref "camlp4o";; 24 + let wiz_camlp4_extensions = ref [];; (* list of package names *) 25 + let wiz_camlp4_selected = ref [];; (* subset of wiz_camlp4_extensions *) 26 + let wiz_camlp4_options = ref "";; 27 + 28 + (* Prerequisites *) 29 + 30 + let wiz_all_packages = ref [];; (* list of package names *) 31 + let wiz_required_packages = ref [];; (* subset of wiz_all_packages *) 32 + 33 + (* Build Library *) 34 + 35 + let wiz_available = ref [];; (* list of module names *) 36 + let wiz_byte_enable = ref true;; 37 + let wiz_nat_enable = ref true;; 38 + let wiz_objects = ref [];; (* subset of wiz_available *) 39 + let wiz_source_suffixes = ref ".ml .mli .mll .mly";; 40 + 41 + (* Build Executables *) 42 + 43 + let wiz_executables = ref [];; (* list of executable names *) 44 + let wiz_exec_objects = (ref [] : (string * (string list ref)) list ref);; 45 + (* an alist: for every executable, the corresponding list of modules is 46 + * stored. 47 + *) 48 + let wiz_exec_native = (ref [] : (string * bool ref) list ref);; 49 + (* an alist: for every executable, whether it is natively compiled or not *) 50 + 51 + (* Generate *) 52 + 53 + let wiz_makefile_name = ref "Makefile";; 54 + let wiz_local_makefile_name = ref "";; 55 + let wiz_make_default = ref "byte" ;; 56 + 57 + 58 + (**********************************************************************) 59 + (* AUXILIARY FUNCTIONS *) 60 + (**********************************************************************) 61 + 62 + let find_pos x l = 63 + let rec find k l = 64 + match l with 65 + h :: l' -> 66 + if x = h then k else find (k+1) l' 67 + | [] -> 68 + raise Not_found 69 + in 70 + find 0 l 71 + ;; 72 + 73 + 74 + let rec delete_at k l = 75 + match l with 76 + h :: l' -> if k <= 0 then l' else h :: (delete_at (k-1) l') 77 + | [] -> [] 78 + ;; 79 + 80 + 81 + let rec insert_at k x l = 82 + if k <= 0 then 83 + x :: l 84 + else 85 + match l with 86 + h :: l' -> h :: (insert_at (k-1) x l') 87 + | [] -> [] (* insert beyond end *) 88 + ;; 89 + 90 + 91 + let rec remove_dups l = 92 + (* Remove duplicate members in a sorted list *) 93 + match l with 94 + x :: (y :: l' as l1) when x = y -> 95 + remove_dups l1 96 + | x :: l' -> 97 + x :: remove_dups l' 98 + | [] -> 99 + [] 100 + ;; 101 + 102 + 103 + (**********************************************************************) 104 + (* SAVE/LOAD STATE *) 105 + (**********************************************************************) 106 + 107 + let save_var name printer out var = 108 + output_string out ("V" ^ name ^ "\n"); 109 + printer out var 110 + ;; 111 + 112 + let save_string out var = 113 + (* [var] must not contain linefeeds *) 114 + output_string out ("S" ^ var ^ "\n") 115 + ;; 116 + 117 + let save_bool out var = 118 + output_string out ("B" ^ string_of_bool var ^ "\n") 119 + ;; 120 + 121 + let save_list printer out var = 122 + output_string out ("L" ^ string_of_int (List.length var) ^ "\n"); 123 + List.iter (printer out) var 124 + ;; 125 + 126 + let save_pair lprinter rprinter out (lvar,rvar) = 127 + output_string out "P\n"; 128 + lprinter out lvar; 129 + rprinter out rvar 130 + ;; 131 + 132 + let save_ref printer out var = 133 + (* Actually doesn't save the reference! *) 134 + printer out !var 135 + ;; 136 + 137 + let save_state out = 138 + save_var "wiz_package_name" save_string out !wiz_package_name; 139 + save_var "wiz_package_version" save_string out !wiz_package_version; 140 + save_var "wiz_package_description" save_string out !wiz_package_description; 141 + save_var "wiz_enable_camlp4" save_bool out !wiz_enable_camlp4; 142 + save_var "wiz_camlp4_syntax" save_string out !wiz_camlp4_syntax; 143 + save_var "wiz_camlp4_extensions" (save_list save_string) out 144 + !wiz_camlp4_extensions; 145 + save_var "wiz_camlp4_selected" (save_list save_string) out 146 + !wiz_camlp4_selected; 147 + save_var "wiz_camlp4_options" save_string out !wiz_camlp4_options; 148 + save_var "wiz_all_packages" (save_list save_string) out 149 + !wiz_all_packages; 150 + save_var "wiz_required_packages" (save_list save_string) out 151 + !wiz_required_packages; 152 + save_var "wiz_available" (save_list save_string) out 153 + !wiz_available; 154 + save_var "wiz_byte_enable" save_bool out !wiz_byte_enable; 155 + save_var "wiz_nat_enable" save_bool out !wiz_nat_enable; 156 + save_var "wiz_objects" (save_list save_string) out 157 + !wiz_objects; 158 + save_var "wiz_source_suffixes" save_string out !wiz_source_suffixes; 159 + save_var "wiz_executables" (save_list save_string) out 160 + !wiz_executables; 161 + save_var "wiz_exec_objects" 162 + (save_list (save_pair save_string (save_ref (save_list save_string)))) 163 + out 164 + !wiz_exec_objects; 165 + save_var "wiz_exec_native" 166 + (save_list (save_pair save_string (save_ref save_bool))) 167 + out 168 + !wiz_exec_native; 169 + save_var "wiz_makefile_name" save_string out !wiz_makefile_name; 170 + save_var "wiz_local_makefile_name" save_string out !wiz_local_makefile_name; 171 + save_var "wiz_make_default" save_string out !wiz_make_default; 172 + ;; 173 + 174 + let save() = 175 + let f = open_out ".make-wizard" in 176 + save_state f; 177 + close_out f 178 + ;; 179 + 180 + let check_char inch c_expected = 181 + let c = input_char inch in 182 + if c <> c_expected then failwith "Cannot read .make-wizard" 183 + ;; 184 + 185 + let load_string inch = 186 + check_char inch 'S'; 187 + let line = input_line inch in 188 + (* prerr_endline ("String = " ^ line); *) 189 + line 190 + ;; 191 + 192 + let load_bool inch = 193 + check_char inch 'B'; 194 + bool_of_string(input_line inch) 195 + ;; 196 + 197 + let load_list parse inch = 198 + check_char inch 'L'; 199 + let n = int_of_string(input_line inch) in 200 + let l = ref [] in 201 + for i = 1 to n do 202 + l := parse inch :: !l; 203 + done; 204 + List.rev !l 205 + ;; 206 + 207 + let load_pair lparse rparse inch = 208 + check_char inch 'P'; 209 + ignore(input_line inch); 210 + let l = lparse inch in 211 + let r = rparse inch in 212 + (l,r) 213 + ;; 214 + 215 + let load_ref parse inch = 216 + ref(parse inch) 217 + ;; 218 + 219 + let load_var var parse inch = 220 + let value = parse inch in 221 + var := value 222 + ;; 223 + 224 + let load_variables spec inch = 225 + try 226 + while true do 227 + try 228 + check_char inch 'V'; 229 + let name = input_line inch in 230 + (* prerr_endline name;*) 231 + let loader = List.assoc name spec in (* or Not_found *) 232 + loader inch 233 + with 234 + Not_found -> 235 + () 236 + done; 237 + assert false 238 + with 239 + End_of_file -> 240 + () 241 + ;; 242 + 243 + let load_state inch = 244 + load_variables 245 + [ "wiz_package_name", 246 + (load_var wiz_package_name load_string); 247 + "wiz_package_version", 248 + (load_var wiz_package_version load_string); 249 + "wiz_package_description", 250 + (load_var wiz_package_description load_string); 251 + "wiz_enable_camlp4", 252 + (load_var wiz_enable_camlp4 load_bool); 253 + "wiz_camlp4_syntax", 254 + (load_var wiz_camlp4_syntax load_string); 255 + "wiz_camlp4_extensions", 256 + (load_var wiz_camlp4_extensions (load_list load_string)); 257 + "wiz_camlp4_selected", 258 + (load_var wiz_camlp4_selected (load_list load_string)); 259 + "wiz_camlp4_options", 260 + (load_var wiz_camlp4_options load_string); 261 + "wiz_all_packages", 262 + (load_var wiz_all_packages (load_list load_string)); 263 + "wiz_required_packages", 264 + (load_var wiz_required_packages (load_list load_string)); 265 + "wiz_available", 266 + (load_var wiz_available (load_list load_string)); 267 + "wiz_byte_enable", 268 + (load_var wiz_byte_enable load_bool); 269 + "wiz_nat_enable", 270 + (load_var wiz_nat_enable load_bool); 271 + "wiz_objects", 272 + (load_var wiz_objects (load_list load_string)); 273 + "wiz_source_suffixes", 274 + (load_var wiz_source_suffixes load_string); 275 + "wiz_executables", 276 + (load_var wiz_executables (load_list load_string)); 277 + "wiz_exec_objects", 278 + (load_var wiz_exec_objects (load_list 279 + (load_pair 280 + load_string 281 + (load_ref (load_list load_string))))); 282 + "wiz_exec_native", 283 + (load_var wiz_exec_native (load_list 284 + (load_pair 285 + load_string 286 + (load_ref load_bool)))); 287 + "wiz_makefile_name", 288 + (load_var wiz_makefile_name load_string); 289 + "wiz_local_makefile_name", 290 + (load_var wiz_local_makefile_name load_string); 291 + "wiz_make_default", 292 + (load_var wiz_make_default load_string); 293 + ] 294 + inch 295 + ;; 296 + 297 + 298 + let load() = 299 + let f = open_in ".make-wizard" in 300 + load_state f; 301 + close_in f 302 + ;; 303 + 304 + 305 + (**********************************************************************) 306 + (* PARSE PATTERN FILE *) 307 + (**********************************************************************) 308 + 309 + type sectiondata = 310 + Sect_const of string 311 + | Sect_var of string 312 + 313 + let section_re = Str.regexp "^\\[\\([A-Za-z_0-9-]+\\)\\]$" ;; 314 + let var_re = Str.regexp "\\[\\([A-Za-z_0-9-]+\\)\\]" ;; 315 + 316 + let parse_pattern inch = 317 + let rec parse_section name sect = 318 + try 319 + let line = input_line inch in 320 + if String.length line >= 2 && line.[0] = '#' && line.[1] = '#' then 321 + (* Comment line *) 322 + parse_section name sect 323 + else 324 + if Str.string_match section_re line 0 then 325 + (* New section begins *) 326 + let name' = Str.matched_group 1 line in 327 + (name, List.rev sect) :: parse_section name' [] 328 + else 329 + (* Normal data region *) 330 + let plist = Str.full_split var_re line in 331 + let slist = 332 + List.map 333 + (function 334 + Str.Text t -> Sect_const t 335 + | Str.Delim d -> Sect_var (String.sub d 1 (String.length d - 2)) 336 + ) 337 + plist @ [ Sect_const "\n" ] in 338 + parse_section name (List.rev slist @ sect) 339 + with 340 + End_of_file -> 341 + [ name, List.rev sect ] 342 + in 343 + 344 + parse_section "_preamble_" [] 345 + ;; 346 + 347 + let load_pattern() = 348 + let where = Filename.dirname (Sys.argv.(0)) in 349 + let name = Filename.concat where "make_wizard.pattern" in 350 + let f = open_in name in 351 + let p = parse_pattern f in 352 + close_in f; 353 + p 354 + ;; 355 + 356 + (**********************************************************************) 357 + (* MAKEFILE GENERATOR *) 358 + (**********************************************************************) 359 + 360 + let dollar_re = Str.regexp "\\$";; 361 + let meta_re = Str.regexp "[\\\\\\\"]";; 362 + 363 + let mkquote s = 364 + (* Quote "$" *) 365 + Str.global_replace dollar_re "$$" s 366 + ;; 367 + 368 + let metaquote s = 369 + (* Quote backslash and double quotes for META files *) 370 + Str.global_replace meta_re "\\\\0" s 371 + ;; 372 + 373 + let makemake() = 374 + let b = Buffer.create 1024 in 375 + let sections = load_pattern() in 376 + 377 + let write section vars = 378 + let sectlist = 379 + try List.assoc section sections 380 + with Not_found -> failwith ("Cannot find section: " ^ section) in 381 + List.iter 382 + (function 383 + Sect_const s -> 384 + Buffer.add_string b s 385 + | Sect_var v -> 386 + let s = 387 + try List.assoc v vars 388 + with Not_found -> failwith ("No such variable: " ^ v) in 389 + Buffer.add_string b s 390 + ) 391 + sectlist 392 + in 393 + 394 + let is_byte_exec execname = 395 + try not (!(List.assoc execname !wiz_exec_native)) 396 + with Not_found -> true 397 + in 398 + 399 + let byte_execs = 400 + List.map 401 + fst 402 + (List.filter 403 + (fun (execname,_) -> is_byte_exec execname) 404 + !wiz_exec_objects 405 + ) 406 + in 407 + 408 + let nat_execs = 409 + List.map 410 + fst 411 + (List.filter 412 + (fun (execname,_) -> not(is_byte_exec execname)) 413 + !wiz_exec_objects 414 + ) 415 + in 416 + 417 + let byte_exec_modules = 418 + remove_dups 419 + (List.sort compare 420 + (List.flatten 421 + (List.map 422 + (fun (_, l) -> !l) 423 + (List.filter 424 + (fun (execname, _) -> is_byte_exec execname) 425 + !wiz_exec_objects 426 + ) 427 + ) 428 + ) 429 + ) 430 + in 431 + 432 + let nat_exec_modules = 433 + remove_dups 434 + (List.sort compare 435 + (List.flatten 436 + (List.map 437 + (fun (_, l) -> !l) 438 + (List.filter 439 + (fun (execname, _) -> not(is_byte_exec execname)) 440 + !wiz_exec_objects 441 + ) 442 + ) 443 + ) 444 + ) 445 + in 446 + 447 + let required_packages = 448 + (* magically add "camlp4" if missing *) 449 + if !wiz_enable_camlp4 then ( 450 + ( if not (List.mem "camlp4" !wiz_required_packages) then 451 + [ "camlp4" ] 452 + else 453 + [] 454 + ) @ !wiz_camlp4_selected @ !wiz_required_packages 455 + ) 456 + else 457 + !wiz_required_packages 458 + in 459 + 460 + let variables = 461 + [ "name", 462 + mkquote !wiz_package_name; 463 + "makefile_name", 464 + mkquote !wiz_makefile_name; 465 + "version", 466 + mkquote(metaquote !wiz_package_version); 467 + "description", 468 + mkquote(metaquote !wiz_package_description); 469 + "byte_objects", 470 + String.concat " " (List.map 471 + (fun m -> String.uncapitalize m ^ ".cmo") 472 + !wiz_objects); 473 + "nat_objects", 474 + String.concat " " (List.map 475 + (fun m -> String.uncapitalize m ^ ".cmx") 476 + !wiz_objects); 477 + "byte_executables", 478 + String.concat " " byte_execs; 479 + "byte_exec_objects", 480 + String.concat " " (List.map 481 + (fun m -> String.uncapitalize m ^ ".cmo") 482 + byte_exec_modules); 483 + "nat_executables", 484 + String.concat " " nat_execs; 485 + "nat_exec_objects", 486 + String.concat " " (List.map 487 + (fun m -> String.uncapitalize m ^ ".cmx") 488 + nat_exec_modules); 489 + "prereqs", 490 + String.concat " " required_packages; 491 + "ppopts", 492 + if !wiz_enable_camlp4 then 493 + "-syntax " ^ !wiz_camlp4_syntax ^ 494 + (String.concat " " 495 + (List.map 496 + (fun opt -> " -ppopt " ^ mkquote(Filename.quote opt)) 497 + (Fl_split.in_words_ws !wiz_camlp4_options) 498 + )) 499 + else 500 + ""; 501 + "mtopts", 502 + if List.mem "threads" !wiz_required_packages then "-thread" else ""; 503 + "default_target", 504 + !wiz_make_default; 505 + ] in 506 + 507 + write "intro" variables; 508 + write "def_general" variables; 509 + if !wiz_byte_enable then write "def_byte_archive" variables; 510 + if !wiz_nat_enable then write "def_native_archive" variables; 511 + write "def_byte_exec" variables; 512 + write "def_nat_exec" variables; 513 + write "def_props" variables; 514 + write "def_tools" variables; 515 + write "rules" variables; 516 + write "default_target" variables; 517 + write "suffix_rules" variables; 518 + write "generate" variables; 519 + List.iter 520 + (fun (execname, modlist) -> 521 + let switches = 522 + if is_byte_exec execname then 523 + "-bytecode-filter" 524 + else 525 + "-native-filter" in 526 + let deptargets = 527 + String.concat " " (List.map 528 + (fun m -> 529 + let m' = String.uncapitalize m in 530 + m' ^ ".ml " ^ m' ^ ".mli") 531 + !modlist) in 532 + write "makemake_exec" ( [ "switches", switches; 533 + "execname", execname; 534 + "deptargets", deptargets ] @ variables ) 535 + ) 536 + !wiz_exec_objects; 537 + write "byte" variables; 538 + write "opt" variables; 539 + if !wiz_byte_enable then write "byte_archive" variables; 540 + if !wiz_nat_enable then write "native_archive" variables; 541 + List.iter 542 + (fun (execname, modlist) -> 543 + if is_byte_exec execname then begin 544 + let execobjs = 545 + String.concat " " (List.map 546 + (fun m -> String.uncapitalize m ^ ".cmo") 547 + !modlist) in 548 + write "byte_exec" ( ["execname", execname; 549 + "execobjs", execobjs ] @ variables ) 550 + end 551 + ) 552 + !wiz_exec_objects; 553 + List.iter 554 + (fun (execname, modlist) -> 555 + if not (is_byte_exec execname) then begin 556 + let execobjs = 557 + String.concat " " (List.map 558 + (fun m -> String.uncapitalize m ^ ".cmx") 559 + !modlist) in 560 + write "nat_exec" ( ["execname", execname; 561 + "execobjs", execobjs ] @ variables ) 562 + end 563 + ) 564 + !wiz_exec_objects; 565 + write "clean" variables; 566 + write "install" variables; 567 + 568 + if !wiz_local_makefile_name<> "" && 569 + Sys.file_exists !wiz_local_makefile_name then 570 + begin 571 + write "local" variables; 572 + let f = open_in !wiz_local_makefile_name in 573 + try 574 + while true do 575 + let s = input_line f in 576 + Buffer.add_string b s; 577 + Buffer.add_char b '\n'; 578 + done; 579 + assert false 580 + with 581 + End_of_file -> 582 + close_in f 583 + end; 584 + 585 + Buffer.contents b 586 + ;; 587 + 588 + (**********************************************************************) 589 + (* GUI *) 590 + (**********************************************************************) 591 + 592 + let headline_font = "-*-helvetica-bold-r-normal-*-*-140-*-*-*-*-iso8859-1" ;; 593 + let font = "-*-helvetica-medium-r-normal-*-*-120-*-*-*-*-iso8859-1" ;; 594 + 595 + (**********************************************************************) 596 + 597 + let top = ref Widget.default_toplevel;; 598 + let topframe = ref Widget.dummy;; 599 + let screens = ref [];; 600 + let current_screen = ref 0;; 601 + 602 + let ( !! ) = fun x -> !(!x);; 603 + 604 + let add_screen func = 605 + screens := !screens @ [ func ] 606 + ;; 607 + 608 + let add_headline frame text = 609 + let s1 = Frame.create ~height:15 frame in 610 + let w = Label.create ~text ~font:headline_font ~anchor:`W frame in 611 + let s2 = Frame.create ~height:10 frame in 612 + pack [ s1 ]; 613 + pack ~anchor:`W [ w ]; 614 + pack [ s2 ] 615 + ;; 616 + 617 + let add_para frame text = 618 + let s1 = Frame.create ~height:5 frame in 619 + let w = Message.create ~padx:0 ~text ~font ~anchor:`W ~width:(pixels (`Pt 400.0)) frame in 620 + let s2 = Frame.create ~height:5 frame in 621 + pack [ s1 ]; 622 + pack ~anchor:`W [ w ]; 623 + pack [ s2 ] 624 + ;; 625 + 626 + 627 + let dialog ~parent ~title ~message ~buttons ?(default = (-1)) () = 628 + (* Like Dialog.create, but our own style. *) 629 + let popup = Toplevel.create parent in 630 + Wm.title_set popup title; 631 + Wm.transient_set popup ~master:(Winfo.toplevel parent); 632 + add_headline popup title; 633 + add_para popup message; 634 + let f_buttons = Frame.create popup in 635 + let n = ref 0 in 636 + let r = ref (-1) in 637 + List.iter 638 + (fun text -> 639 + let k = !n in 640 + let b = 641 + Button.create ~font ~text ~command:(fun () -> r := k; destroy popup) 642 + f_buttons in 643 + (* --- Default buttons not yet supported because of deficiency in 644 + * labltk: 645 + if k = default then Button.configure ~default:`Active b; 646 + *) 647 + pack ~side:`Left [b]; 648 + incr n; 649 + ) 650 + buttons; 651 + pack [f_buttons]; 652 + Grab.set popup; 653 + Tkwait.window popup; 654 + !r 655 + ;; 656 + 657 + 658 + let ask_and_save frame = 659 + let reply = 660 + dialog ~parent:frame ~title:"Save .make-wizard?" 661 + ~message:"Do you want to save the current state in the file .make-wizard?" 662 + ~buttons:["Yes"; "No"; "Cancel"] 663 + ~default:0 664 + () 665 + in 666 + if reply = 0 then save(); 667 + reply < 2 668 + ;; 669 + 670 + 671 + let string_tv ?(onchange = fun () -> ()) frame v = 672 + let textvariable = Textvariable.create ~on:frame () in 673 + Textvariable.set textvariable !v; 674 + let rec set_handle() = 675 + Textvariable.handle textvariable 676 + ~callback:(fun () -> 677 + v := Textvariable.get textvariable; 678 + onchange(); 679 + set_handle()); 680 + in 681 + set_handle(); 682 + textvariable 683 + ;; 684 + 685 + 686 + let bool_tv ?(onchange = fun () -> ()) frame v = 687 + let textvariable = Textvariable.create ~on:frame () in 688 + Textvariable.set textvariable (if !v then "1" else "0"); 689 + let rec set_handle() = 690 + Textvariable.handle textvariable 691 + ~callback:(fun () -> 692 + v := Textvariable.get textvariable = "1"; 693 + onchange(); 694 + set_handle()); 695 + in 696 + set_handle(); 697 + textvariable 698 + ;; 699 + 700 + 701 + let label_box frame box = 702 + let sub = Frame.create frame in 703 + let row = ref 0 in 704 + List.iter 705 + (fun (l, v) -> 706 + let label = Label.create ~font ~text:l ~anchor:`E sub in 707 + let textvariable = string_tv frame v in 708 + let var = Entry.create ~font ~textvariable ~width:40 sub in 709 + grid ~row:!row ~column:0 ~sticky:"e" [ label ]; 710 + grid ~row:!row ~column:1 ~sticky:"w" [ var ]; 711 + incr row; 712 + ) 713 + box; 714 + pack ~anchor:`W [ sub ] 715 + ;; 716 + 717 + 718 + let scrolled_listbox ?(click = fun _ _ -> ()) ?(context = fun _ _ -> ()) 719 + ?(separator = true) ?(height = 8) frame = 720 + let f = Frame.create frame in 721 + let lb = Listbox.create ~selectmode:`Multiple ~width:20 ~height 722 + ~exportselection:false f in 723 + let sb = Scrollbar.create ~orient:`Vertical 724 + ~command:(Listbox.yview lb) 725 + f in 726 + Listbox.configure ~yscrollcommand:(Scrollbar.set sb) ~font lb; 727 + let sep = Frame.create ~width:30 f in 728 + pack ~side:`Left [ lb ]; 729 + pack ~side:`Left ~fill:`Y [ sb ]; 730 + if separator then pack ~side:`Left [ sep ]; 731 + 732 + bind ~events:[ `ButtonPressDetail 1 ] ~fields:[ `MouseY ] 733 + ~action:(fun einfo -> 734 + let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in 735 + Timer.set ~ms:0 ~callback:(fun () -> click lb row) 736 + ) 737 + lb; 738 + bind ~events:[ `ButtonPressDetail 3 ] ~fields:[ `MouseY ] 739 + ~action:(fun einfo -> 740 + let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in 741 + Timer.set ~ms:0 ~callback:(fun () -> context lb row) 742 + ) 743 + lb; 744 + 745 + (f, lb) 746 + ;; 747 + 748 + 749 + let listbox_select lb selection = 750 + Listbox.selection_clear lb ~first:(`Num 0) ~last:`End; 751 + for i = 0 to Listbox.size lb do 752 + let s = Listbox.get lb (`Num i) in 753 + if List.mem s selection then 754 + Listbox.selection_set lb ~first:(`Num i) ~last:(`Num i) 755 + done 756 + ;; 757 + 758 + 759 + let listbox_get_selection lb = 760 + List.map 761 + (fun index -> Listbox.get lb ~index) 762 + (Listbox.curselection lb) 763 + ;; 764 + 765 + 766 + let indented_cond_frame frame enablers = 767 + (* Returns a subframe of [frame] that is only mapped if the boolean 768 + * variable [!enable] is true. [enable_text] is the text for the 769 + * checkbox that toggles [!enable]. 770 + *) 771 + let onchange_enable = ref (fun () -> ()) in 772 + 773 + List.iter 774 + (fun (enable, enable_text) -> 775 + let enable_tv = bool_tv 776 + ~onchange:(fun () -> !onchange_enable()) 777 + frame enable in 778 + let cb = Checkbutton.create 779 + ~font ~text:enable_text ~variable:enable_tv frame in 780 + pack ~anchor:`W [cb]; 781 + ) 782 + enablers; 783 + 784 + let is_enabled() = 785 + let p = ref false in 786 + List.iter (fun (enable, _) -> p := !p || !enable) enablers; 787 + !p 788 + in 789 + 790 + let frame' = Frame.create frame in 791 + let indent = Frame.create ~width:30 frame' in 792 + let frame'' = Frame.create frame' in 793 + pack ~anchor:`W [frame']; 794 + 795 + let frame''_is_packed = ref false in 796 + let frame''_pack b = 797 + if b <> !frame''_is_packed then begin 798 + if b then 799 + pack ~side:`Left [indent; frame''] 800 + else 801 + Pack.forget [ frame'' ]; 802 + frame''_is_packed := b 803 + end 804 + in 805 + frame''_pack (is_enabled()); 806 + onchange_enable := (fun () -> frame''_pack (is_enabled())); 807 + frame'' 808 + ;; 809 + 810 + 811 + let double_listbox frame available objects scan = 812 + let boxes = Frame.create frame in 813 + let (f_left,lb_left) = scrolled_listbox boxes in 814 + let (f_right,lb_right) = scrolled_listbox ~separator:false boxes in 815 + let f_buttons = Frame.create boxes in 816 + let b_add = Button.create ~font ~text:"Add >>" f_buttons in 817 + let b_del = Button.create ~font ~text:"<< Del" f_buttons in 818 + let b_up = Button.create ~font ~text:"Up ^" f_buttons in 819 + let b_down= Button.create ~font ~text:"Down v" f_buttons in 820 + let b_scan= Button.create ~font ~text:"Rescan" f_buttons in 821 + let f_sep = Frame.create ~width:30 boxes in 822 + pack ~fill:`X [ b_add; b_del; b_up; b_down; b_scan ]; 823 + pack ~side:`Left [ coe f_left; coe f_buttons; coe f_sep; coe f_right ]; 824 + pack [ boxes ]; 825 + 826 + let update() = 827 + let still_available = (* available - objects *) 828 + List.filter (fun m -> not (List.mem m !!objects)) !!available in 829 + Listbox.delete lb_left ~first:(`Num 0) ~last:`End; 830 + Listbox.insert lb_left ~index:`End ~texts:still_available; 831 + Listbox.delete lb_right ~first:(`Num 0) ~last:`End; 832 + Listbox.insert lb_right ~index:`End ~texts:!!objects; 833 + in 834 + 835 + let rescan() = 836 + !available := scan(); 837 + update() 838 + in 839 + 840 + let add() = 841 + if Listbox.curselection lb_left = [] then begin 842 + let popup = Toplevel.create frame in 843 + Wm.title_set popup "Add File"; 844 + Wm.transient_set popup ~master:(Winfo.toplevel frame); 845 + add_headline popup "Add File"; 846 + 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."; 847 + 848 + let modname = ref "" in 849 + label_box popup [ "Name of new module: ", modname ]; 850 + 851 + let p_buttons = Frame.create popup in 852 + let b_ok = Button.create ~font ~text:"OK" 853 + ~command:(fun () -> 854 + if !modname <> "" then 855 + !objects := !!objects @ [ !modname ]; 856 + update(); 857 + destroy popup) p_buttons in 858 + let b_cancel = Button.create ~font ~text:"Cancel" 859 + ~command:(fun () -> destroy popup) p_buttons in 860 + pack ~side:`Left [b_ok; b_cancel]; 861 + 862 + add_para popup ""; 863 + 864 + pack [p_buttons]; 865 + end 866 + else begin 867 + let items = 868 + List.map 869 + (fun index -> Listbox.get lb_left ~index) 870 + (Listbox.curselection lb_left) 871 + in 872 + !objects := !!objects @ items; 873 + update() 874 + end 875 + in 876 + 877 + let del() = 878 + if Listbox.curselection lb_right = [] then begin 879 + ignore 880 + (dialog 881 + ~parent:!top 882 + ~title:"Nothing selected" 883 + ~message:"Please select the modules you want to delete in the right box!" 884 + ~buttons:[ "OK" ] 885 + ~default:0 886 + ()) 887 + end 888 + else begin 889 + let items = 890 + List.map 891 + (fun index -> Listbox.get lb_right ~index) 892 + (Listbox.curselection lb_right) 893 + in 894 + !objects := List.filter (fun m -> not (List.mem m items)) !!objects; 895 + update() 896 + end 897 + in 898 + 899 + let move_dlg() = 900 + ignore 901 + (dialog 902 + ~parent:!top 903 + ~title:"Bad Selection" 904 + ~message:"Please select the (single) module you want to move in the right box!" 905 + ~buttons:[ "OK" ] 906 + ~default:0 907 + ()) 908 + in 909 + 910 + let move g () = 911 + if List.length (Listbox.curselection lb_right) <> 1 then 912 + move_dlg() 913 + else begin 914 + let index = List.hd (Listbox.curselection lb_right) in 915 + let `Num n = index in 916 + let n' = g n in 917 + if n' >= 0 && n' < List.length !!objects then begin 918 + let item = Listbox.get lb_right ~index:(index :> Tk.listbox_index) in 919 + !objects := delete_at n !!objects; 920 + !objects := insert_at n' item !!objects; 921 + update(); 922 + Listbox.selection_set lb_right ~first:(`Num n') ~last:(`Num n'); 923 + end 924 + end 925 + in 926 + 927 + if !!available = [] then rescan() else update(); 928 + Button.configure ~command:add b_add; 929 + Button.configure ~command:del b_del; 930 + Button.configure ~command:(move pred) b_up; 931 + Button.configure ~command:(move succ) b_down; 932 + Button.configure ~command:rescan b_scan; 933 + 934 + (* Returns the [update] function *) 935 + update 936 + ;; 937 + 938 + 939 + let redraw() = 940 + destroy !topframe; 941 + let f = Frame.create !top in 942 + let f1 = Frame.create ~width:5 f in 943 + let f2 = Frame.create f in 944 + let f3 = Frame.create ~width:5 f in 945 + pack ~expand:true ~fill:`Y [f]; 946 + pack ~side:`Left [f1]; 947 + pack ~side:`Left ~fill:`Y [f2]; 948 + pack ~side:`Left [f3]; 949 + let func = List.nth !screens !current_screen in 950 + topframe := coe f; 951 + func f2 952 + ;; 953 + 954 + 955 + let footer frame = 956 + let box = Frame.create frame in 957 + pack ~side:`Bottom ~fill:`X [box]; 958 + let sep1 = Frame.create ~height:15 box in 959 + let b = Frame.create ~height:1 ~background:`Black box in 960 + let sep2 = Frame.create ~height:15 box in 961 + pack [ sep1 ]; 962 + pack ~fill:`X ~expand:true [b]; 963 + pack [ sep2 ]; 964 + 965 + let f = Frame.create box in 966 + let m1 = Frame.create f in 967 + pack ~fill:`X ~expand:true ~side:`Left [ m1 ]; 968 + let prev_b = 969 + Button.create ~font ~text:"Previous" ~state:`Disabled 970 + ~command:(fun () -> decr current_screen; redraw()) m1 in 971 + pack ~side:`Left [prev_b]; 972 + if !current_screen > 0 then 973 + Button.configure ~state:`Normal prev_b; 974 + let m2 = Frame.create f in 975 + let k = ref 0 in 976 + List.iter 977 + (fun scr -> 978 + let k' = !k in 979 + let b = 980 + Button.create ~font ~text:(string_of_int (!k+1)) 981 + ~command:(fun () -> current_screen := k'; redraw()) m2 in 982 + if k' = !current_screen then 983 + Button.configure 984 + ~background:`Blue ~activebackground:`Blue ~foreground:`White b; 985 + pack ~side:`Left [b]; 986 + incr k 987 + ) 988 + !screens; 989 + pack ~side:`Left [m2]; 990 + let m3 = Frame.create f in 991 + pack ~fill:`X ~expand:true ~side:`Left [ m3 ]; 992 + let next_b = 993 + Button.create ~font ~text:"Next" ~state:`Disabled 994 + ~command:(fun () -> incr current_screen; redraw()) m3 in 995 + pack ~side:`Right [next_b]; 996 + if !current_screen < List.length !screens - 1 then 997 + Button.configure ~state:`Normal next_b; 998 + pack ~fill:`X [ f ] 999 + ;; 1000 + 1001 + 1002 + (**********************************************************************) 1003 + 1004 + let first_time = ref true;; 1005 + 1006 + let intro_screen frame = 1007 + add_headline frame "The Makefile and META wizard"; 1008 + add_para frame "This wizard helps you creating Makefiles and META \ 1009 + files for simple projects. It assumes that all your source files \ 1010 + reside in a single directory, and that all source files are OCaml \ 1011 + files (no support for mixed OCaml/C projects). ocamllex, ocamlyacc, \ 1012 + and camlp4 are supported."; 1013 + add_para frame "The wizard generates a Makefile, and the Makefile \ 1014 + produces the META file. The Makefile is not perfect, and is not the ideal \ 1015 + choice for everybody, but it is a starting point for your project. \ 1016 + You can later fine-tune the contents of the Makefile by adding your own rules, \ 1017 + and by overriding the definitions. The Makefile is commented, and not \ 1018 + overly complicated."; 1019 + add_para frame "The settings you enter here can be stored in a file \ 1020 + containing the state of the wizard. This file is called .make-wizard. \ 1021 + It is recommended to use this feature to save the state between the \ 1022 + wizard sessions."; 1023 + (* "" *) 1024 + 1025 + footer frame; 1026 + update(); 1027 + 1028 + if !first_time && Sys.file_exists ".make-wizard" then begin 1029 + match dialog ~parent:frame ~title:"Load .make-wizard?" 1030 + ~message:"Do you want to load the file .make-wizard, and continue your last session?" 1031 + ~buttons:[ "Yes, please load the file"; "No, start with empty fields" ] 1032 + ~default:0 1033 + () 1034 + with 1035 + 0 -> load() 1036 + | _ -> () 1037 + end; 1038 + first_time := false; 1039 + 1040 + ;; 1041 + 1042 + 1043 + add_screen intro_screen;; 1044 + 1045 + (**********************************************************************) 1046 + 1047 + let general_screen frame = 1048 + add_headline frame "General"; 1049 + add_para frame "Please enter the name of the package, the version number, \ 1050 + and the description first. The name must be a single, alphanumeric string \ 1051 + (including _ and -). The version is an arbitrary string, like the description. \ 1052 + All fields are mandatory."; (* "" *) 1053 + 1054 + label_box frame 1055 + [ "Package name: ", wiz_package_name; 1056 + "Package version: ", wiz_package_version; 1057 + "Package description: ", wiz_package_description ]; 1058 + footer frame 1059 + ;; 1060 + 1061 + add_screen general_screen;; 1062 + 1063 + (**********************************************************************) 1064 + 1065 + let pkginfo lb row = (* when the user right-clicks at a listbox row *) 1066 + let pkg = Listbox.get lb (`Num row) in 1067 + let version = 1068 + try Findlib.package_property [] pkg "version" with Not_found -> "N/A" in 1069 + let description = 1070 + try Findlib.package_property [] pkg "description" with Not_found -> "N/A" 1071 + in 1072 + let popup = Toplevel.create !top in 1073 + Wm.transient_set popup ~master:(Winfo.toplevel !top); 1074 + let f = Frame.create popup in 1075 + let title = "About " ^ pkg ^ " (" ^ version ^ ")" in 1076 + add_headline f title; 1077 + Wm.title_set popup title; 1078 + add_para f ("Description: " ^ description); 1079 + add_para f "Modules:"; 1080 + let click sublb _ = 1081 + Listbox.selection_clear sublb ~first:(`Num 0) ~last:`End in 1082 + let (f_sublb, sublb) = scrolled_listbox ~click f in 1083 + let modules = 1084 + try 1085 + Fl_split.in_words 1086 + (Findlib.package_property [] pkg "browse_interfaces") 1087 + with 1088 + Not_found -> 1089 + let dir = Findlib.package_directory pkg in 1090 + let files = Array.to_list(Sys.readdir dir) in 1091 + List.map 1092 + (fun name -> 1093 + String.capitalize (Filename.chop_suffix name ".cmi")) 1094 + (List.filter 1095 + (fun name -> 1096 + Filename.check_suffix name ".cmi") 1097 + files 1098 + ) 1099 + in 1100 + Listbox.insert sublb ~index:`End ~texts:modules; 1101 + pack ~anchor:`W [ f_sublb ]; 1102 + pack ~anchor:`W [ f ]; 1103 + let close = Button.create ~text:"Close" ~font 1104 + ~command:(fun () -> destroy popup) f_sublb in 1105 + pack ~anchor:`Nw ~fill:`X [close] 1106 + ;; 1107 + 1108 + (**********************************************************************) 1109 + 1110 + let preprocessor_scan_extensions() = 1111 + (* Find out all packages with a "preprocessor" predicate *) 1112 + let packages = Fl_package_base.list_packages() in 1113 + let plist = 1114 + List.filter 1115 + (fun pkg -> 1116 + try 1117 + let _ = 1118 + Findlib.package_property [ "preprocessor"; "syntax" ] pkg "archive" 1119 + in true 1120 + with 1121 + Not_found -> false 1122 + ) 1123 + packages in 1124 + (* Add all selected extensions, if they do not occur yet: *) 1125 + let plist' = 1126 + List.filter 1127 + (fun pkg -> 1128 + not (List.mem pkg plist) 1129 + ) 1130 + !wiz_camlp4_selected in 1131 + List.sort Pervasives.compare (plist @ plist') 1132 + ;; 1133 + 1134 + 1135 + let preprocessor_screen frame = 1136 + add_headline frame "Preprocessing"; 1137 + add_para frame "Here you can specify whether your source files are \ 1138 + preprocessed by camlp4. Simply skip this page if you do not want to \ 1139 + invoke a preprocessor, or if you don't know what this means."; (* "" *) 1140 + 1141 + let frame'' = indented_cond_frame frame 1142 + [ wiz_enable_camlp4, "Enable camlp4" ] in 1143 + 1144 + let tv = string_tv frame'' wiz_camlp4_syntax in 1145 + let rb_o = Radiobutton.create 1146 + ~font ~text:"Standard syntax" ~variable:tv ~value:"camlp4o" 1147 + frame'' in 1148 + let rb_r = Radiobutton.create 1149 + ~font ~text:"Revised syntax" ~variable:tv ~value:"camlp4r" 1150 + frame'' in 1151 + pack ~anchor:`W [rb_o; rb_r]; 1152 + 1153 + add_para frame'' "Use the following packaged syntax extensions (click the \ 1154 + right mouse button to find out more about a package):"; (* "" *) 1155 + 1156 + if !wiz_camlp4_extensions = [] then 1157 + wiz_camlp4_extensions := preprocessor_scan_extensions(); 1158 + 1159 + let click lb row = (* when the user clicks at a listbox row *) 1160 + wiz_camlp4_selected := listbox_get_selection lb; 1161 + in 1162 + 1163 + let (f_lb,lb) = scrolled_listbox ~click ~context:pkginfo frame'' in 1164 + Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions; 1165 + listbox_select lb !wiz_camlp4_selected; 1166 + pack ~anchor:`W [f_lb]; 1167 + 1168 + let rescan = Button.create ~text:"Rescan" ~font 1169 + ~command:(fun () -> 1170 + wiz_camlp4_extensions := preprocessor_scan_extensions(); 1171 + Listbox.delete lb ~first:(`Num 0) ~last:`End; 1172 + Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions; 1173 + listbox_select lb !wiz_camlp4_selected; 1174 + ) 1175 + f_lb in 1176 + let clear = Button.create ~text:"Clear" ~font 1177 + ~command:(fun () -> 1178 + wiz_camlp4_selected := []; 1179 + listbox_select lb []) 1180 + f_lb in 1181 + 1182 + pack ~anchor:`Nw ~fill:`X [ rescan; clear ]; 1183 + 1184 + add_para frame'' "Specify here further options to the camlp4 invocation. \ 1185 + For example, you can load camlp4 modules like pa_ifdef.cmo, and pass the -D \ 1186 + options to it."; (* "" *) 1187 + 1188 + label_box frame'' [ "Camlp4 options: ", wiz_camlp4_options ]; 1189 + 1190 + footer frame 1191 + ;; 1192 + 1193 + add_screen preprocessor_screen;; 1194 + 1195 + (**********************************************************************) 1196 + 1197 + let prerequisites_scan_packages() = 1198 + (* Find out all packages *) 1199 + List.sort Pervasives.compare (Fl_package_base.list_packages()) 1200 + ;; 1201 + 1202 + 1203 + let prerequisites_screen frame = 1204 + add_headline frame "Prerequisites"; 1205 + add_para frame "If your modules use packages, you can specify these \ 1206 + prerequisites here. It is sufficient to select the packages on which \ 1207 + your modules depend directly. Indirect dependencies can be resolved \ 1208 + by findlib automatically. Click the right mouse button to find out \ 1209 + more about a package."; (* "" *) 1210 + 1211 + if !wiz_all_packages = [] then 1212 + wiz_all_packages := prerequisites_scan_packages(); 1213 + 1214 + let click lb row = (* when the user clicks at a listbox row *) 1215 + wiz_required_packages := listbox_get_selection lb; 1216 + in 1217 + 1218 + let (f_lb,lb) = scrolled_listbox ~height:18 ~click ~context:pkginfo frame in 1219 + Listbox.insert lb ~index:`End ~texts:!wiz_all_packages; 1220 + listbox_select lb !wiz_required_packages; 1221 + pack ~anchor:`W [f_lb]; 1222 + 1223 + let rescan = Button.create ~text:"Rescan" ~font 1224 + ~command:(fun () -> 1225 + wiz_all_packages := prerequisites_scan_packages(); 1226 + Listbox.delete lb ~first:(`Num 0) ~last:`End; 1227 + Listbox.insert lb ~index:`End ~texts:!wiz_all_packages; 1228 + listbox_select lb !wiz_required_packages; 1229 + ) 1230 + f_lb in 1231 + let clear = Button.create ~text:"Clear" ~font 1232 + ~command:(fun () -> 1233 + wiz_required_packages := []; 1234 + listbox_select lb []) 1235 + f_lb in 1236 + 1237 + pack ~anchor:`Nw ~fill:`X [ rescan; clear ]; 1238 + 1239 + footer frame 1240 + ;; 1241 + 1242 + add_screen prerequisites_screen;; 1243 + 1244 + (**********************************************************************) 1245 + 1246 + let buildlib_scan_modules() = 1247 + let files = Array.to_list(Sys.readdir ".") in 1248 + let suffixes = Fl_split.in_words_ws !wiz_source_suffixes in 1249 + let files' = 1250 + List.filter 1251 + (fun f -> 1252 + List.exists (Filename.check_suffix f) suffixes 1253 + ) 1254 + files in 1255 + let files'' = 1256 + List.map 1257 + (fun f -> 1258 + String.capitalize (Filename.chop_extension f) 1259 + ) 1260 + files' in 1261 + remove_dups (List.sort Pervasives.compare files'') 1262 + ;; 1263 + 1264 + 1265 + let buildlib_screen frame = 1266 + add_headline frame "Build Library"; 1267 + add_para frame "The next question is how to build the library, i.e. the \ 1268 + cma or cmxa archive. It is recommended to create such an archive even if \ 1269 + the real target of the build process is an executable, because you can load \ 1270 + it into the toploop at once. However, make sure that you do not put the \ 1271 + main program of the executable into the archive, as it is usually stripped \ 1272 + off from the executable, and nothing would happen when you start it."; 1273 + (* 1274 + add_para frame "You can select whether you want to create only a bytecode \ 1275 + archive, a native archive, or both. In the latter case, the simplest way \ 1276 + is to begin with the bytecode archive, and to copy your specification to \ 1277 + the native box by pressing the button \"Like bytecode\"."; 1278 + add_para frame "If you do not want to create an archive at all, \ 1279 + skip this page."; 1280 + *) 1281 + (* "" *) 1282 + 1283 + let frame' = indented_cond_frame frame 1284 + [ wiz_byte_enable, "Enable bytecode archive"; 1285 + wiz_nat_enable, "Enable native archive"; ] in 1286 + add_para frame' "Move the available modules to the right-hand box in the required order."; 1287 + 1288 + let update = 1289 + double_listbox frame' (ref wiz_available) (ref wiz_objects) buildlib_scan_modules in 1290 + 1291 + 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)."; 1292 + 1293 + label_box frame [ "Source code suffixes: ", wiz_source_suffixes ]; 1294 + 1295 + footer frame 1296 + ;; 1297 + 1298 + add_screen buildlib_screen;; 1299 + 1300 + (**********************************************************************) 1301 + 1302 + let enter_name parent followup = 1303 + let popup = Toplevel.create parent in 1304 + let title = "New Executable" in 1305 + Wm.transient_set popup ~master:(Winfo.toplevel parent); 1306 + Wm.title_set popup title; 1307 + let frame = Frame.create popup in 1308 + pack [frame]; 1309 + add_headline frame title; 1310 + add_para frame "Of course, the new executable must have a name."; 1311 + let name = ref "" in 1312 + label_box frame [ "Name: ", name ]; 1313 + pack [ Frame.create ~height:10 frame ]; 1314 + let buttons = Frame.create frame in 1315 + let ok_b = Button.create ~font ~text:"OK" 1316 + ~command:(fun () -> destroy popup; followup !name) buttons in 1317 + let cancel_b = Button.create ~font ~text:"Cancel" 1318 + ~command:(fun () -> destroy popup) buttons in 1319 + pack ~side:`Left [ ok_b; cancel_b ]; 1320 + pack [buttons] 1321 + ;; 1322 + 1323 + 1324 + let buildexec_screen frame = 1325 + add_headline frame "Build Executables"; 1326 + add_para frame "You can specify the executables to build in the following \ 1327 + way. Press \"New\" and enter the name of the executable, then add the modules \ 1328 + to link in the box that appears. The cma/cmxa archive from the previous \ 1329 + screen is linked anyway, so its modules cannot be selected again."; 1330 + add_para frame "Leave the list of executables empty if you do not want to \ 1331 + build any."; 1332 + (* "" *) 1333 + 1334 + let update_listbox = ref (fun () -> ()) in 1335 + let show = ref (fun _ -> ()) in 1336 + let hide = ref (fun _ -> ()) in 1337 + 1338 + let click lb row = 1339 + let name = Listbox.get lb ~index:(`Num row) in 1340 + !show name 1341 + in 1342 + 1343 + let newexec() = 1344 + enter_name 1345 + frame 1346 + (fun name -> 1347 + (* This function is called after the user pressed "OK" *) 1348 + if List.mem name !wiz_executables then begin 1349 + (* It is not allowed to enter the same name twice *) 1350 + ignore( 1351 + dialog ~parent:frame ~title:"Already exists" 1352 + ~message:"This name already exists!" ~buttons:["OK"] ()) 1353 + end 1354 + else begin 1355 + wiz_executables := 1356 + List.sort Pervasives.compare (name :: !wiz_executables); 1357 + wiz_exec_objects := (name, ref []) :: !wiz_exec_objects; 1358 + wiz_exec_native := (name, ref false) :: !wiz_exec_native; 1359 + !update_listbox(); 1360 + !show name 1361 + end 1362 + ) 1363 + in 1364 + 1365 + let remexec lb () = 1366 + let sel = listbox_get_selection lb in 1367 + if sel = [] then begin 1368 + ignore( 1369 + dialog ~parent:frame ~title:"Nothing selected" 1370 + ~message:"Select the executable to remove first!" ~buttons:["OK"] ()) 1371 + end 1372 + else begin 1373 + wiz_executables := 1374 + List.filter (fun n -> not (List.mem n sel)) !wiz_executables; 1375 + wiz_exec_objects := 1376 + List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_objects; 1377 + wiz_exec_native := 1378 + List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_native; 1379 + !update_listbox(); 1380 + !hide() 1381 + end 1382 + in 1383 + 1384 + let (f_lb,lb) = scrolled_listbox ~click ~height:3 frame in 1385 + Listbox.configure ~selectmode:`Single lb; 1386 + Listbox.insert lb ~index:`End ~texts:!wiz_executables; 1387 + pack ~anchor:`W [f_lb]; 1388 + 1389 + let new_b = 1390 + Button.create ~font ~text:"New" ~command:newexec f_lb in 1391 + let remove_b = 1392 + Button.create ~font ~text:"Remove" ~command:(remexec lb) f_lb in 1393 + 1394 + pack ~anchor:`Nw ~fill:`X [ new_b; remove_b ]; 1395 + 1396 + let f1 = Frame.create frame in 1397 + pack [f1]; 1398 + let frame' = Frame.create f1 in 1399 + let frame'_packed = ref false in 1400 + let modbox_available = ref (ref []) in 1401 + let modbox_objects = ref (ref []) in 1402 + let modbox_scan() = 1403 + let mlist = buildlib_scan_modules() in 1404 + List.filter 1405 + (fun m -> not (List.mem m !wiz_objects)) mlist 1406 + in 1407 + add_para frame' "Move the available modules to the right-hand box in the required order."; 1408 + let update_modbox = 1409 + double_listbox frame' modbox_available modbox_objects modbox_scan in 1410 + 1411 + add_para frame' "Select the type of the executable:"; 1412 + let radio = Frame.create frame' in 1413 + let type_ref = ref false in 1414 + let type_ref_ref = ref type_ref in 1415 + let type_tv = bool_tv 1416 + ~onchange:(fun () -> !type_ref_ref := !type_ref) 1417 + frame' type_ref in 1418 + let byte_r = Radiobutton.create ~font ~text:"Bytecode executable" 1419 + ~variable:type_tv ~value:"0" radio in 1420 + let nat_r = Radiobutton.create ~font ~text:"Native executable" 1421 + ~variable:type_tv ~value:"1" radio in 1422 + pack ~side:`Left [byte_r; nat_r ]; 1423 + pack ~anchor:`W [radio]; 1424 + let update_radio() = 1425 + Textvariable.set type_tv (if !!type_ref_ref then "1" else "0") 1426 + in 1427 + 1428 + footer frame; 1429 + 1430 + update_listbox := (fun () -> 1431 + Listbox.delete lb ~first:(`Num 0) ~last:`End; 1432 + Listbox.insert lb ~index:`End ~texts:!wiz_executables; 1433 + ); 1434 + show := (fun name -> 1435 + let k = find_pos name !wiz_executables in 1436 + Listbox.selection_clear lb ~first:( `Num 0 ) ~last:`End; 1437 + Listbox.selection_set lb ~first:(`Num k) ~last:(`Num k); 1438 + if not !frame'_packed then ( 1439 + pack [frame']; 1440 + frame'_packed := true; 1441 + ); 1442 + modbox_objects := List.assoc name !wiz_exec_objects; 1443 + type_ref_ref := List.assoc name !wiz_exec_native; 1444 + update_modbox(); 1445 + update_radio() 1446 + ); 1447 + hide := (fun () -> 1448 + if !frame'_packed then ( 1449 + Pack.forget [frame']; 1450 + frame'_packed := false; 1451 + ); 1452 + ) 1453 + ;; 1454 + 1455 + add_screen buildexec_screen;; 1456 + 1457 + (**********************************************************************) 1458 + 1459 + let generate_screen frame = 1460 + add_headline frame "Generate Makefile"; 1461 + add_para frame "Finally, the Makefile can be generated from your inputs. \ 1462 + You can set the name of the Makefile to a non-standard name. Furthermore, \ 1463 + you can specify a second file that will be appended to the generated Makefile, \ 1464 + this is useful to extend the Makefile rules by your own additions."; 1465 + (* "" *) 1466 + 1467 + label_box frame [ "Name of Makefile: ", wiz_makefile_name; 1468 + "Local extensions in: ", wiz_local_makefile_name ; 1469 + "Default target of 'make': ", wiz_make_default; 1470 + ]; 1471 + 1472 + add_para frame ""; 1473 + 1474 + let show_b = 1475 + Button.create ~font ~text:"Show Makefile" 1476 + ~command:(fun () -> 1477 + let maketext = makemake() in 1478 + let popup = Toplevel.create frame in 1479 + Wm.title_set popup "Generated Makefile"; 1480 + add_headline popup "Generated Makefile"; 1481 + let t = Text.create ~width:80 ~height:25 popup in 1482 + pack [t]; 1483 + Text.insert ~index:(`End,[]) ~text:maketext t; 1484 + ) 1485 + frame in 1486 + let save_b = 1487 + Button.create ~font ~text:"Save Makefile" 1488 + ~command:(fun () -> 1489 + let maketext = makemake() in 1490 + let cont = 1491 + not (Sys.file_exists !wiz_makefile_name) || ( 1492 + dialog ~parent:frame ~title:"File already exists" 1493 + ~message:("The file " ^ !wiz_makefile_name ^ 1494 + " already exists. Overwrite?") 1495 + ~buttons:[ "OK"; "Cancel" ] () = 0) in 1496 + if cont then begin 1497 + let f = open_out !wiz_makefile_name in 1498 + output_string f maketext; 1499 + close_out f 1500 + end 1501 + ) 1502 + frame in 1503 + 1504 + pack [show_b; save_b]; 1505 + 1506 + add_headline frame "Quit"; 1507 + 1508 + add_para frame "The following button quits the wizard. You are asked whether you want to save the state first."; 1509 + 1510 + let quit_b = 1511 + Button.create ~font ~text:"Finish & Quit" 1512 + ~command:(fun () -> 1513 + if ask_and_save frame then destroy !top) 1514 + frame in 1515 + 1516 + 1517 + 1518 + pack [show_b; quit_b]; 1519 + 1520 + footer frame 1521 + ;; 1522 + 1523 + add_screen generate_screen;; 1524 + 1525 + 1526 + (**********************************************************************) 1527 + 1528 + Findlib.init(); 1529 + top := openTk(); 1530 + (* current_screen := 5; *) 1531 + Wm.title_set !top "findlib/make-wizard"; 1532 + Wm.protocol_set !top ~name:"WM_DELETE_WINDOW" 1533 + ~command:(fun () -> if ask_and_save !top then destroy !top); 1534 + Toplevel.configure ~width:(pixels(`Pt 450.0)) 1535 + ~height:(pixels (`Pt 650.0)) (Winfo.toplevel !top); 1536 + Pack.propagate_set !top false; 1537 + topframe := coe(Frame.create !top); 1538 + redraw(); 1539 + mainLoop();; 1540 + 1541 + 1542 + (* ====================================================================== 1543 + * History: 1544 + * 1545 + * $Log: make_wizard.ml,v $ 1546 + * Revision 1.3 2002/09/22 20:12:35 gerd 1547 + * Renamed modules (prefix fl_) 1548 + * 1549 + * Revision 1.2 2002/07/29 19:52:23 gerd 1550 + * Fixes for OCaml 3.05 1551 + * 1552 + * Revision 1.1 2002/05/26 14:09:07 gerd 1553 + * Renaming 1554 + * 1555 + * Revision 1.1 2002/05/05 20:40:26 gerd 1556 + * Initial revision 1557 + * 1558 + * 1559 + *)
+494
vendor/opam/ocamlfind/src/findlib-toolbox/make_wizard.pattern
··· 1 + ## $Id$ 2 + ## ---------------------------------------------------------------------- 3 + ## 4 + 5 + ## This is the pattern for the Makefile. It consists of several sections, 6 + ## every section begins with [name] on a single line, and ends where the 7 + ## next section starts. Inside the sections, variables are written as 8 + ## [name], too. 9 + ## Comments that must not be copied to the output file begin with two 10 + ## hash marks. 11 + 12 + [intro] 13 + # ---------------------------------------------------------------------- 14 + # How to build the package [name]: 15 + # ---------------------------------------------------------------------- 16 + # 17 + # make: Same as "make all" 18 + # make all: Normally "make byte", but can also be set to "make opt" 19 + # make byte: Makes the bytecode archive and the bytecode executables 20 + # make opt: Makes the native archive and the native executable 21 + # make install: Install all installable files as package 22 + # make uninstall: Uninstall the package 23 + # make clean: Delete all files that can be remade 24 + # 25 + # The usual order of invocation is: 26 + # - make byte 27 + # - (optionally) make opt 28 + # - make install 29 + # - make clean 30 + # 31 + # You may want to give the -s option if you do not want to see the details 32 + # of the build process (e.g. make -s all). 33 + # 34 + # ---------------------------------------------------------------------- 35 + # Important for developers 36 + # ---------------------------------------------------------------------- 37 + # 38 + # This Makefile writes a copy of itself with appended dependencies. 39 + # The copy is usually stored in the file .make-wizard.[makefile_name]. 40 + # If you want to invoke "make" for targets where the dependencies are 41 + # involved, you have to specify -f .make-wizard.[makefile_name] on 42 + # the command line, e.g. 43 + # 44 + # make -f .make-wizard.[makefile_name] sample.cmo 45 + # 46 + # Otherwise, the dependencies are ignored, and you get errors that are 47 + # hard to explain. 48 + # 49 + # If you want to modify this Makefile, it is a good idea to put the 50 + # modifications into a second file, and to enable the local Makefile 51 + # extension in the wizard. This effects that the modifications are appended 52 + # to this Makefile, so you can add rules and override variables without 53 + # coming into conflict with the wizard. 54 + 55 + [def_general] 56 + # ---------------------------------------------------------------------- 57 + # Definitions 58 + # ---------------------------------------------------------------------- 59 + 60 + NAME = [name] 61 + # The name of the package. 62 + 63 + MFNAME = [makefile_name] 64 + # The name of this Makefile. (You must change this definition if you rename 65 + # the Makefile!) 66 + 67 + MF2NAME = .make-wizard.$(MFNAME) 68 + # The name of the generated Makefile (a copy of this Makefile plus the 69 + # dependencies) 70 + 71 + TEMPNAME = .make-wizard.temps 72 + # The name of a file containing the names of temporary files 73 + 74 + VERSION = [version] 75 + # The version of this package 76 + 77 + DESCRIPTION = [description] 78 + # The description of this package 79 + 80 + GENERATOR_EXTS = .mll .mly 81 + # These suffixes indicate that a generator must be called for them 82 + 83 + MAKE_META = _meta 84 + # Make the META file by this rule. (An empty definition turns META generation 85 + # off.) 86 + 87 + INSTALL = _findlib_install 88 + # Which rule to use for installation 89 + 90 + UNINSTALL = _findlib_uninstall 91 + # Which rule to use for deinstallation 92 + 93 + MAKEMAKE_HOOK = 94 + # Set this to the name of a rule to add your own definitions to $(MF2NAME) 95 + 96 + 97 + ## The def_byte_archive section is only included if the byte archive is 98 + ## enabled: 99 + 100 + [def_byte_archive] 101 + BYTE_ARCHIVE = $(NAME).cma 102 + # The name of the resulting bytecode archive. 103 + 104 + BYTE_OBJECTS = [byte_objects] 105 + # The cmo objects that are linked together, and are put into the byte archive. 106 + 107 + BYTE_FILES = $(BYTE_OBJECTS) $(BYTE_OBJECTS:.cmo=.cmi) $(BYTE_ARCHIVE) 108 + # The files that are generated in order to make the byte archive. Note 109 + # that .ml and .mli files are missing that are generated from 110 + # .mly and .mll files. 111 + 112 + BYTE_INST = $(BYTE_OBJECTS:cmo=cmi) $(BYTE_OBJECTS:.cmo=.mli) $(BYTE_ARCHIVE) 113 + # The files that will be installed after the byte archive is made. Not 114 + # every file exists. 115 + 116 + 117 + ## The def_native_archive section is only included if the native archive is 118 + ## enabled: 119 + 120 + [def_native_archive] 121 + NAT_ARCHIVE = $(NAME).cmxa 122 + # The name of the resulting native archive. 123 + 124 + NAT_OBJECTS = [nat_objects] 125 + # The cmx objects that are linked together, and are put into the native archive. 126 + 127 + NAT_FILES = $(NAT_OBJECTS) $(NAT_OBJECTS:.cmx=.o) $(NAT_OBJECTS:.cmo=.cmi) \ 128 + $(NAT_ARCHIVE) $(NAT_ARCHIVE:.cmxa=.a) 129 + # The files that are generated in order to make the native archive. Note 130 + # that .ml and .mli files are missing that are generated from 131 + # .mly and .mll files. 132 + 133 + NAT_INST = $(NAT_OBJECTS:.cmo=.cmi) $(NAT_OBJECTS:.cmo=.mli) $(NAT_ARCHIVE) \ 134 + $(NAT_ARCHIVE:.cmxa=.a) 135 + # The files that will be installed after the native archive is made. Not 136 + # every file exists. 137 + 138 + 139 + [def_byte_exec] 140 + BYTE_EXEC_TARGETS = [byte_executables] 141 + # The list of bytecode executables. 142 + 143 + BYTE_EXEC_OBJECTS = [byte_exec_objects] 144 + # The list of cmo modules that are linked into bytecode executables 145 + 146 + BYTE_EXEC_FILES = $(BYTE_EXEC_OBJECTS) $(BYTE_EXEC_OBJECTS:.cmo=.cmi) \ 147 + $(BYTE_EXEC_TARGETS) 148 + # The list of files that are generated in order to make the bytecode 149 + # executables. Note that .ml and .mli files are missing that are generated 150 + # from .mly and .mll files. 151 + 152 + BYTE_EXEC_INST = $(BYTE_EXEC_TARGETS) 153 + # The files to install as bytecode executables. 154 + 155 + 156 + [def_nat_exec] 157 + NAT_EXEC_TARGETS = [nat_executables] 158 + # The list of native executables. 159 + 160 + NAT_EXEC_OBJECTS = [nat_exec_objects] 161 + # The list of cmx modules that are linked into native executables 162 + 163 + NAT_EXEC_FILES = $(NAT_EXEC_OBJECTS) $(NAT_EXEC_OBJECTS:.cmx=.cmi) \ 164 + $(NAT_EXEC_OBJECTS:.cmx=.o) $(NAT_EXEC_TARGETS) 165 + # The list of files that are generated in order to make the native 166 + # executables. Note that .ml and .mli files are missing that are generated 167 + # from .mly and .mll files. 168 + 169 + NAT_EXEC_INST = $(NAT_EXEC_TARGETS) 170 + # The files to install as native executables. 171 + 172 + 173 + [def_props] 174 + PREREQUISITES = [prereqs] 175 + # The required packages. 176 + 177 + PPOPTS = [ppopts] 178 + # Preprocessor options. 179 + 180 + MTOPTS = [mtopts] 181 + # Multi-threading options 182 + 183 + INCOPTS = 184 + # -I options (currently unused, but this may change in the future) 185 + 186 + OTHER_INST = META 187 + # Files to install that are not mentioned in the other XXX_INST variables 188 + 189 + #TASKBYTELINKOPTS = -custom 190 + # Uncomment this line to create stand-alone executables 191 + 192 + [def_tools] 193 + # Tools and tasks: "Tools" are the commands to call, and "tasks" are the tools 194 + # to use for certain situations. 195 + 196 + OCAMLFIND = ocamlfind 197 + OCAMLLEX = ocamllex 198 + OCAMLYACC = ocamlyacc 199 + OCAMLDEP = $(OCAMLFIND) ocamldep 200 + OCAMLC = $(OCAMLFIND) ocamlc 201 + OCAMLCP = $(OCAMLFIND) ocamlcp 202 + OCAMLOPT = $(OCAMLFIND) ocamlopt 203 + # 204 + # These are the tools. 205 + 206 + TASKLEX = $(OCAMLLEX) $(TASKLEXOPTS) 207 + TASKYACC = $(OCAMLYACC) $(TASKYACCOPTS) 208 + TASKDEP = $(OCAMLDEP) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" $(TASKDEPOPTS) 209 + TASKCI = $(OCAMLC) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" -c $(TASKCIOPTS) 210 + TASKBYTECO = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c -g $(TASKBYTECOOPTS) 211 + TASKBYTELINK = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKBYTELINKOPTS) 212 + TASKBYTEAR = $(OCAMLC) -a $(TASKBYTEAROPTS) 213 + TASKNATCO = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c $(TASKNATCOOPTS) 214 + TASKNATLINK = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKNATLINKOPTS) 215 + TASKNATAR = $(OCAMLOPT) -a $(TASKNATAROPTS) 216 + TASKINSTALL = $(OCAMLFIND) install $(NAME) $(TASKINSTALLOPTS) 217 + TASKREMOVE = $(OCAMLFIND) remove $(NAME) $(TASKREMOVEOPTS) 218 + # 219 + # These are the tasks. The names mean the following: 220 + # TASKLEX: Used to create a lexer 221 + # TASKYACC: Used to create a parser 222 + # TASKDEP: Used to analyze the dependencies 223 + # TASKCI: Used to compile interface files 224 + # TASKBYTECO, TASKNATCO: Used to compile implementation files 225 + # TASKBYTELINK, TASKNATLINK: Used to create executables 226 + # TASKBYTEAR, TASKNATAR: Used to create archives 227 + # TASKINSTALL: Used to install the package 228 + # TASKREMOVE: Used to remove the package 229 + # INCOPTS: -I options 230 + # PPOPTS: Options to specify the preprocessor 231 + # MTOPTS: -thread (if necessary) 232 + # NATONLY: -native (if necessary) 233 + # For every task <T>, there is a variable for task-specific options <T>OPTS. 234 + 235 + 236 + [rules] 237 + # ---------------------------------------------------------------------- 238 + # Rules 239 + # ---------------------------------------------------------------------- 240 + 241 + 242 + [default_target] 243 + .PHONY: all 244 + all: [default_target] 245 + 246 + 247 + [suffix_rules] 248 + # The suffix rules: They specify how to make a file ending in suffix X from 249 + # a source file ending in suffix Y. For every suffix rule, there is a task 250 + # defining what to do. 251 + 252 + .SUFFIXES: .ml .mli .cmo .cmx .cmi .mll .mly 253 + 254 + .mli.cmi: 255 + @echo "<Making $@>" 256 + $(TASKCI) $< 257 + 258 + .ml.cmo: 259 + @echo "<Making $@>" 260 + $(TASKBYTECO) $< 261 + 262 + .ml.cmx: 263 + @echo "<Making $@>" 264 + $(TASKNATCO) $< 265 + 266 + # The generator rules record the generated files: The "grep" checks whether 267 + # the filename already occurs in $(TEMPNAME), and the "echo" appends the 268 + # filename when missing. 269 + 270 + .mll.ml: 271 + @echo "<Making $@>" 272 + $(TASKLEX) $< 273 + touch $(TEMPNAME) 274 + grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME) 275 + 276 + .mly.ml: 277 + @echo "<Making $@>" 278 + $(TASKYACC) $< 279 + touch $(TEMPNAME) 280 + grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME) 281 + 282 + # The _dummy rule does nothing: 283 + 284 + _dummy: 285 + : 286 + 287 + [generate] 288 + # The following rule checks which lex and yacc targets exist, and calls 289 + # MAKE recursively. 290 + 291 + .PHONY: _meta 292 + _meta: 293 + @echo "<Updating META>" 294 + echo "name = \"$(NAME)\"" >META 295 + echo "version = \"$(VERSION)\"" >>META 296 + echo "description = \"$(DESCRIPTION)\"" >>META 297 + echo "requires = \"$(PREREQUISITES)\"" >>META 298 + test -z "$(BYTE_ARCHIVE)" || \ 299 + echo "archive(byte) = \"$(BYTE_ARCHIVE)\"" >>META 300 + test -z "$(NAT_ARCHIVE)" || \ 301 + echo "archive(native) = \"$(NAT_ARCHIVE)\"" >>META 302 + 303 + .PHONY: _generator 304 + _generator: $(MAKE_META) 305 + @echo "<Checking for generator targets>" 306 + targets=$$( \ 307 + { \ 308 + for obj in _dummy $(BYTE_OBJECTS) $(BYTE_EXEC_OBJECTS); do \ 309 + test "_dummy" != "$$obj" || continue; \ 310 + for ext in $(GENERATOR_EXTS); do \ 311 + if [ -f "$${obj%.cmo}$$ext" ]; then \ 312 + echo "$${obj%.cmo}.ml"; \ 313 + fi; \ 314 + done; \ 315 + done && \ 316 + for obj in _dummy $(NAT_OBJECTS) $(NAT_EXEC_OBJECTS); do \ 317 + test "_dummy" != "$$obj" || continue; \ 318 + for ext in $(GENERATOR_EXTS); do \ 319 + if [ -f "$${obj%.cmx}$$ext" ]; then \ 320 + echo "$${obj%.cmx}.ml"; \ 321 + fi; \ 322 + done; \ 323 + done; \ 324 + } | sort | uniq \ 325 + ) && \ 326 + { test -z "$$targets" || $(MAKE) -f $(MFNAME) $$targets; } 327 + 328 + # The following rule calls ocamldep for the right files, and creates 329 + # a file that consists of the contents of this Makefile, and of the output 330 + # of ocamldep. 331 + 332 + .PHONY: _makemake 333 + _makemake: _generator 334 + @echo "<Analyzing dependencies and creating $(MF2NAME)>" 335 + cat $(MFNAME) >$(MF2NAME) 336 + test -z "$(MAKEMAKE_HOOK)" || $(MAKE) -f $(MFNAME) $(MAKEMAKE_HOOK) 337 + echo "# ---------------------------------------- dependencies:" >>$(MF2NAME) 338 + targets=$$( \ 339 + { \ 340 + nat=-native-filter && \ 341 + byte=-bytecode-filter && \ 342 + for obj in _dummy $(BYTE_OBJECTS); do \ 343 + test "_dummy" != "$$obj" || continue; \ 344 + echo "$${obj%.cmo}.ml"; \ 345 + echo "$${obj%.cmo}.mli"; \ 346 + nat=""; \ 347 + done && \ 348 + for obj in _dummy $(NAT_OBJECTS); do \ 349 + test "_dummy" != "$$obj" || continue; \ 350 + echo "$${obj%.cmx}.ml"; \ 351 + echo "$${obj%.cmx}.mli"; \ 352 + byte=""; \ 353 + done; \ 354 + echo "$$byte $$nat"; \ 355 + } | sort | uniq \ 356 + ) && \ 357 + $(TASKDEP) $$targets >>$(MF2NAME) 358 + ## The following section is appended to _makemake for every executable: 359 + [makemake_exec] 360 + echo "# --- dependencies for [execname]:" >>$(MF2NAME) 361 + $(TASKDEP) [switches] [deptargets] >>$(MF2NAME) 362 + ## Begin next section immediately to avoid empty lines: 363 + [dummy] 364 + 365 + [byte] 366 + 367 + 368 + .PHONY: byte 369 + byte: _byte 370 + 371 + .PHONY: _byte 372 + _byte: _makemake 373 + @echo "<Starting with bytecode targets>" 374 + if [ -n "$(BYTE_ARCHIVE)" ]; then \ 375 + $(MAKE) -f $(MF2NAME) $(BYTE_ARCHIVE); \ 376 + fi 377 + if [ -n "$(BYTE_EXEC_TARGETS)" ]; then \ 378 + $(MAKE) -f $(MF2NAME) $(BYTE_EXEC_TARGETS); \ 379 + fi 380 + @echo "<Done bytecode targets>" 381 + 382 + 383 + [opt] 384 + .PHONY: opt 385 + opt: _opt 386 + 387 + .PHONY: _opt 388 + _opt: _makemake 389 + @echo "<Starting with native targets>" 390 + if [ -n "$(NAT_ARCHIVE)" ]; then \ 391 + $(MAKE) -f $(MF2NAME) $(NAT_ARCHIVE); \ 392 + fi 393 + if [ -n "$(NAT_EXEC_TARGETS)" ]; then \ 394 + $(MAKE) -f $(MF2NAME) $(NAT_EXEC_TARGETS); \ 395 + fi 396 + @echo "<Done native targets>" 397 + 398 + 399 + [byte_archive] 400 + $(BYTE_ARCHIVE): $(BYTE_OBJECTS) 401 + @echo "<Making $(BYTE_ARCHIVE)>" 402 + $(TASKBYTEAR) -o $(BYTE_ARCHIVE) $(BYTE_OBJECTS) 403 + 404 + 405 + [native_archive] 406 + $(NAT_ARCHIVE): $(NAT_OBJECTS) 407 + @echo "<Making $(NAT_ARCHIVE)>" 408 + $(TASKNATAR) -o $(NAT_ARCHIVE) $(NAT_OBJECTS) 409 + 410 + 411 + ## The following section is included for every bytecode executable again. 412 + 413 + [byte_exec] 414 + [execname]: $(BYTE_ARCHIVE) [execobjs] 415 + @echo "<Making [execname]>" 416 + $(TASKBYTELINK) -o [execname] $(BYTE_ARCHIVE) [execobjs] 417 + 418 + 419 + [nat_exec] 420 + [execname]: $(NAT_ARCHIVE) [execobjs] 421 + @echo "<Making [execname]>" 422 + $(TASKNATLINK) -o [execname] $(NAT_ARCHIVE) [execobjs] 423 + 424 + 425 + [clean] 426 + .PHONY: clean 427 + clean: 428 + @echo "<Cleaning up>" 429 + touch $(TEMPNAME) 430 + rm -f $(BYTE_FILES) $(NAT_FILES) $(BYTE_EXEC_FILES) $(NAT_EXEC_FILES) 431 + rm -f $(MF2NAME) 432 + cat $(TEMPNAME) | xargs rm -f 433 + rm -f $(TEMPNAME) 434 + 435 + .PHONY: CLEAN 436 + CLEAN: clean 437 + 438 + .PHONY: distclean 439 + distclean: clean 440 + 441 + 442 + [install] 443 + .PHONY: install 444 + install: $(INSTALL) 445 + 446 + .PHONY: _findlib_install 447 + _findlib_install: 448 + @echo "<Installing>" 449 + files=$$( \ 450 + for f in $(BYTE_INST) $(NAT_INST) $(BYTE_EXEC_INST) $(NAT_EXEC_INST) $(OTHER_INST); do \ 451 + if [ -f "$$f" ]; then echo $$f; fi; \ 452 + done; \ 453 + ) && \ 454 + $(TASKINSTALL) $$files 455 + 456 + .PHONY: uninstall 457 + uninstall: $(UNINSTALL) 458 + 459 + .PHONY: _findlib_uninstall 460 + _findlib_uninstall: 461 + @echo "<Uninstalling>" 462 + $(TASKREMOVE) 463 + 464 + # The following rules just print some variables. 465 + 466 + .PHONY: _print_name 467 + _print_name: 468 + echo "$(NAME)" 469 + 470 + .PHONY: _print_version 471 + _print_version: 472 + echo "$(VERSION)" 473 + 474 + [local] 475 + # ---------------------------------------------------------------------- 476 + # Local additions 477 + # ---------------------------------------------------------------------- 478 + 479 + [trailer] 480 + ## ====================================================================== 481 + ## History: 482 + ## 483 + ## $Log: make_wizard.pattern,v $ 484 + ## Revision 1.2 2003/01/13 00:37:45 gerd 485 + ## Bugfix NATIVE_ARCHIVE ==> NAT_ARCHIVE (reported by 486 + ## Matt Gushee) 487 + ## 488 + ## Revision 1.1 2002/05/26 14:09:07 gerd 489 + ## Renaming 490 + ## 491 + ## Revision 1.1 2002/05/05 20:40:26 gerd 492 + ## Initial revision 493 + ## 494 + ##
+6
vendor/opam/ocamlfind/src/findlib-toolbox/selected.xpm
··· 1 + #define selected_width 16 2 + #define selected_height 16 3 + static unsigned char selected_bits[] = { 4 + 0x55, 0x55, 0x00, 0x80, 0x01, 0x1c, 0x00, 0x82, 0x01, 0x02, 0x00, 0x81, 5 + 0x01, 0x01, 0x80, 0x80, 0x81, 0x00, 0x98, 0x80, 0xa1, 0x00, 0xa0, 0x80, 6 + 0xc1, 0x00, 0xc0, 0x80, 0x01, 0x00, 0xaa, 0xaa};
+1008
vendor/opam/ocamlfind/src/findlib-toolbox/tree_editor.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + 7 + module Filesys = struct 8 + 9 + let join_path path = 10 + if path = [ "" ] then 11 + "/" 12 + else 13 + String.concat "/" path (* TODO *) 14 + 15 + 16 + let split_re = Str.regexp "/" (* TODO *) 17 + 18 + let split_path s = 19 + Str.split split_re s 20 + 21 + 22 + let list path = 23 + let path_name = join_path path in 24 + let d = Unix.opendir path_name in 25 + let l = ref [] in 26 + try 27 + while true do 28 + let e = Unix.readdir d in 29 + if e <> "." && e <> ".." then 30 + l := e :: !l 31 + done; assert false 32 + with 33 + End_of_file -> 34 + Unix.closedir d; 35 + List.sort Pervasives.compare !l 36 + | err -> 37 + Unix.closedir d; 38 + raise err 39 + 40 + let is_directory path = 41 + let path_name = join_path path in 42 + try 43 + (Unix.lstat path_name).Unix.st_kind = Unix.S_DIR 44 + with 45 + _ -> false 46 + 47 + let is_container path = 48 + let path_name = join_path path in 49 + try 50 + (Unix.stat path_name).Unix.st_kind = Unix.S_DIR 51 + with 52 + _ -> false 53 + 54 + end 55 + ;; 56 + 57 + module Filetree_dlg = struct 58 + open Lx_tree.Types;; 59 + open Tk;; 60 + open Widget;; 61 + 62 + 63 + type node = 64 + { path : string list; 65 + mutable name : string; 66 + } 67 + 68 + let some = function Some x -> x | None -> assert false 69 + 70 + let selected = ref [] 71 + let name_tv = lazy(Textvariable.create()) 72 + 73 + let listbox = ref None 74 + let dir_label = ref None 75 + let ok_button = ref None 76 + let cb_enable_ok = ref (fun _ -> true) 77 + 78 + let update_ok_button() = 79 + let dir = Filesys.join_path !selected in 80 + let name = Textvariable.get (Lazy.force name_tv) in 81 + prerr_endline ("Name: " ^ name); 82 + let en = !selected <> [] && name <> "" && 83 + !cb_enable_ok (Filename.concat dir name) in 84 + Button.configure 85 + ~state:(if en then `Normal else `Disabled) (some !ok_button) 86 + 87 + let update_listbox d = 88 + (* Fill listbox: *) 89 + let files = Filesys.list [d] in 90 + let reg_files = 91 + List.filter (fun file -> not(Filesys.is_container [d;file])) files in 92 + Listbox.delete (some !listbox) ~first:(`Num 0) ~last:`End; 93 + Listbox.insert (some !listbox) ~index:`End ~texts:reg_files; 94 + (* Set label: *) 95 + Label.configure ~text:(d ^ ":") (some !dir_label) 96 + 97 + let node_action tw tree ev evinfo = 98 + selected := tree.node.path; 99 + Lx_tree.update tw; 100 + let dir = Filesys.join_path tree.node.path in 101 + update_listbox dir; 102 + update_ok_button() 103 + 104 + let display_node tw tree = 105 + let (foreground,background) = 106 + if tree.node.path = !selected then 107 + (Some `White, Some `Blue) 108 + else 109 + (None, None) 110 + in 111 + 112 + Lx_tree.display_text 113 + ?foreground ?background 114 + ~events:[ `ButtonPress ] ~action:node_action tree.node.name 115 + 116 + let rescan_node tw tree = 117 + let files = Filesys.list tree.node.path in 118 + let subnodes = 119 + List.map 120 + (fun name -> 121 + { path = tree.node.path @ [name]; 122 + name = name; 123 + } 124 + ) 125 + files in 126 + let dirs = List.filter 127 + (fun n -> Filesys.is_container n.path) 128 + subnodes in 129 + let subtrees = 130 + List.map 131 + (fun n -> 132 + { node = n; 133 + children = []; 134 + show = false; 135 + scanned = false; 136 + interactive = true; 137 + } 138 + ) 139 + dirs in 140 + tree.children <- subtrees 141 + 142 + let rec make_tree_from_path ?(loc = []) p = 143 + match p with 144 + p1 :: pr -> 145 + { node = { path = loc @ [p1]; 146 + name = p1; 147 + }; 148 + children = (if pr = [] then [] else 149 + [ make_tree_from_path ~loc:(loc@[p1]) pr ]); 150 + show = true; 151 + scanned = true; 152 + interactive = true; 153 + } 154 + | [] -> 155 + assert false 156 + 157 + let open_dialog ?(title = "Browse...") ?(enable_ok = fun _ -> true) parent = 158 + selected := []; 159 + Textvariable.set (Lazy.force name_tv) ""; 160 + 161 + let top = Toplevel.create parent in 162 + Wm.transient_set top ~master:parent; 163 + Wm.title_set top title; 164 + 165 + cb_enable_ok := enable_ok; 166 + 167 + let l1 = Label.create ~text:"Directories:" top in 168 + pack ~anchor:`W [ l1 ]; 169 + 170 + let dir_tree = 171 + make_tree_from_path ("" :: Filesys.split_path (Sys.getcwd())) in 172 + dir_tree.node.name <- "<Root>"; 173 + 174 + let tframe = Frame.create top in 175 + 176 + let tw = Lx_tree.create 177 + ~display:display_node ~rescan:rescan_node ~width:300 ~height:300 178 + dir_tree 179 + tframe in 180 + let sbar = Scrollbar.create ~orient:`Vertical tframe in 181 + let canvas = Lx_tree.canvas tw in 182 + Canvas.configure ~yscrollcommand:(Scrollbar.set sbar) ~relief:`Sunken 183 + ~borderwidth:3 canvas; 184 + Scrollbar.configure ~command:(Canvas.yview canvas) sbar; 185 + 186 + pack ~side:`Left ~fill:`Both ~expand:true [canvas]; 187 + pack ~side:`Left ~fill:`Y [ sbar]; 188 + pack ~anchor:`W ~fill:`X [tframe]; 189 + 190 + (* Listbox *) 191 + let lab = Label.create ~text:(" ") top in 192 + let lbf = Frame.create top in 193 + let lb = Listbox.create ~height:10 ~font:"fixed" ~exportselection:false 194 + lbf in 195 + let lbs = Scrollbar.create lbf in 196 + Listbox.configure ~yscrollcommand:(Scrollbar.set lbs) lb; 197 + Scrollbar.configure ~command:(Listbox.yview lb) lbs; 198 + pack ~anchor:`W [lab]; 199 + pack ~anchor:`W ~fill:`X [lbf]; 200 + pack ~side:`Left ~expand:true ~fill:`X [lb]; 201 + pack ~side:`Left ~fill:`Y [lbs]; 202 + listbox := Some lb; 203 + dir_label := Some lab; 204 + 205 + (* Entry: *) 206 + let lab' = Label.create ~text:"Filename:" top in 207 + let ent = Entry.create ~font:"fixed" 208 + ~textvariable:(Lazy.force name_tv) top in 209 + pack ~anchor:`W [lab']; 210 + pack ~anchor:`W ~fill:`X [ent]; 211 + 212 + (* Link listbox and entry: *) 213 + Tk.bind ~events:[ `ButtonReleaseDetail 1 ] 214 + ~action:(fun _ -> 215 + match Listbox.curselection lb with 216 + [] -> () 217 + | hd :: _ -> 218 + let s = Listbox.get lb ~index:hd in 219 + Textvariable.set (Lazy.force name_tv) s; 220 + update_ok_button() 221 + ) 222 + lb; 223 + Tk.bind ~events:[ `KeyPress ] 224 + ~action:(fun _ -> 225 + Timer.set ~ms:0 ~callback:update_ok_button) 226 + ent; 227 + 228 + let result = ref None in 229 + 230 + let buttons = Frame.create top in 231 + let ok_b = Button.create ~text:"OK" 232 + ~state:`Disabled 233 + ~command:(fun _ -> 234 + let name = Textvariable.get (Lazy.force name_tv) in 235 + if name <> "" then begin 236 + result := Some (Filesys.join_path !selected, 237 + name); 238 + Tk.destroy top 239 + end else Bell.ring() ) 240 + buttons in 241 + let cancel_b = Button.create ~text:"Cancel" 242 + ~command:(fun _ -> Tk.destroy top) 243 + buttons in 244 + 245 + pack ~expand:true ~fill:`X [buttons]; 246 + pack ~side:`Left [ ok_b; cancel_b ]; 247 + ok_button := Some ok_b; 248 + 249 + Grab.set top; 250 + Tkwait.window top; 251 + 252 + !result 253 + (* returns None if canceled, or Some (dir, name) *) 254 + 255 + end 256 + ;; 257 + 258 + 259 + module S = struct 260 + type t = string 261 + let compare = compare 262 + end 263 + ;; 264 + 265 + 266 + module StringSet = Set.Make(S) 267 + ;; 268 + 269 + 270 + open Lx_tree.Types;; 271 + open Tk;; 272 + open Widget;; 273 + 274 + 275 + let some = Filetree_dlg.some;; 276 + 277 + type filetype = 278 + Regular 279 + | Directory 280 + | Absent 281 + ;; 282 + 283 + 284 + type node = 285 + { path : string list; 286 + name : string; (* last component of [path] *) 287 + mutable is_dir : bool; (* from file list *) 288 + mutable selected : bool; (* from file list *) 289 + mutable realtype : filetype; (* from file system *) 290 + } 291 + ;; 292 + 293 + type file_tree = node tree ;; 294 + 295 + type state = 296 + { mutable current_directory : string; 297 + mutable list_file : string; (* relative to current_directory *) 298 + mutable tree_widget : node tree_widget option; 299 + mutable info_widget : label widget option; 300 + mutable dir_context_menu : menu widget option; 301 + mutable dir_context_suffix_menu : menu widget option; 302 + mutable dir_context_unsuffix_menu : menu widget option; 303 + mutable file_context_menu : menu widget option; 304 + mutable context_menu_tree : node tree; 305 + mutable modified : bool; 306 + topwdg : toplevel widget; 307 + workframe : frame widget; 308 + directory_xpm : image; 309 + selected_xpm : image; 310 + unselected_xpm : image; 311 + mutable display : node tree_widget -> file_tree -> node display_item; 312 + } 313 + ;; 314 + 315 + 316 + let dummy_tree = 317 + { node = { path = []; 318 + name = ""; 319 + is_dir = false; 320 + selected = false; 321 + realtype = Regular; 322 + }; 323 + children = []; 324 + show = false; 325 + scanned = false; 326 + interactive = false; 327 + } 328 + ;; 329 + 330 + 331 + let rescan_node tw tree = 332 + let files = Filesys.list tree.node.path in 333 + let missing_files = 334 + List.map 335 + (fun child -> child.node.name) 336 + (List.filter 337 + (fun child -> 338 + child.node.selected && not(List.mem child.node.name files) 339 + ) 340 + tree.children 341 + ) 342 + in 343 + let all_files = List.sort compare (files @ missing_files) in 344 + let old_children = tree.children in 345 + let new_children = 346 + List.map 347 + (fun filename -> 348 + try 349 + (* maybe the new child is the old child: *) 350 + List.find 351 + (fun old_child -> old_child.node.name = filename) 352 + old_children 353 + with 354 + Not_found -> 355 + let new_path = tree.node.path @ [filename] in 356 + let is_dir = Filesys.is_directory new_path in 357 + let new_tree = 358 + { node = { path = new_path; 359 + name = filename; 360 + is_dir = is_dir; 361 + selected = false; 362 + realtype = Regular; (* Will be updated below *) 363 + }; 364 + children = []; 365 + scanned = not is_dir; 366 + show = false; 367 + interactive = true; 368 + } in 369 + new_tree 370 + ) 371 + all_files 372 + in 373 + (* Update the [realtype] flag: *) 374 + List.iter 375 + (fun child -> 376 + child.node.realtype <- 377 + if List.mem child.node.name files then 378 + (if Filesys.is_directory child.node.path then Directory else Regular) 379 + else 380 + Absent 381 + ) 382 + new_children; 383 + (* Store the result: *) 384 + tree.children <- new_children 385 + ;; 386 + 387 + 388 + let rec selected_files_exist tree = 389 + tree.node.selected || selected_files_exist_in_children tree 390 + 391 + and selected_files_exist_in_children tree = 392 + List.exists selected_files_exist tree.children 393 + ;; 394 + 395 + 396 + let rec expand ?(all = false) tw tree = 397 + let show = 398 + tree.node.is_dir && (all || selected_files_exist_in_children tree) in 399 + tree.show <- tree.show || show; 400 + if show then rescan_node tw tree; 401 + List.iter (fun child -> expand ~all tw child) tree.children 402 + ;; 403 + 404 + 405 + let rec collapse tw tree = 406 + tree.show <- false; 407 + List.iter (fun child -> collapse tw child) tree.children 408 + ;; 409 + 410 + 411 + let suffix_re = Str.regexp "\\.[^.]+$";; 412 + 413 + let rec find_suffixes ?(recursive = false) tw tree = 414 + assert(tree.node.is_dir); 415 + rescan_node tw tree; (* questionable *) 416 + tree.show <- true; 417 + let files = 418 + List.map 419 + (fun ch -> ch.node.name) 420 + tree.children in 421 + let suff = 422 + List.filter 423 + (fun s -> 424 + s <> "" 425 + ) 426 + (List.map 427 + (fun name -> 428 + try 429 + let k = Str.search_forward suffix_re name 0 in 430 + String.sub name k (String.length name - k) 431 + with 432 + Not_found -> "" 433 + ) 434 + files 435 + ) 436 + in 437 + let suff_set = ref (StringSet.empty) in 438 + List.iter 439 + (fun s -> 440 + suff_set := StringSet.add s !suff_set) 441 + suff; 442 + if recursive then begin 443 + List.iter 444 + (fun child -> 445 + if child.node.is_dir then 446 + suff_set := StringSet.union !suff_set (find_suffixes ~recursive tw child) 447 + ) 448 + tree.children 449 + end; 450 + !suff_set 451 + ;; 452 + 453 + 454 + let rec select_suffixes ?(recursive = false) ?(unselect=false) suffix tree = 455 + prerr_endline "select_suffixes"; 456 + List.iter 457 + (fun child -> 458 + let child_suff = 459 + try 460 + let name = child.node.name in 461 + let k = Str.search_forward suffix_re name 0 in 462 + String.sub name k (String.length name - k) 463 + with 464 + Not_found -> "" 465 + in 466 + if child_suff = suffix && not (child.node.is_dir) then 467 + child.node.selected <- not unselect; 468 + if recursive && child.node.is_dir then 469 + select_suffixes ~recursive ~unselect suffix child 470 + ) 471 + tree.children 472 + ;; 473 + 474 + 475 + let rec select_all ?(recursive = false) ?(unselect=false) tree = 476 + prerr_endline "select_all"; 477 + List.iter 478 + (fun child -> 479 + if not (child.node.is_dir) then 480 + child.node.selected <- not unselect; 481 + if recursive && child.node.is_dir then 482 + select_all ~recursive ~unselect child 483 + ) 484 + tree.children 485 + ;; 486 + 487 + 488 + let set_suffix_menu ?unselect tw menu tree = 489 + Menu.delete menu ~first:(`Num 0) ~last:`End; 490 + let suffixes = find_suffixes tw tree in 491 + StringSet.iter 492 + (fun s -> 493 + Menu.add_command 494 + ~label:s 495 + ~command:(fun () -> 496 + select_suffixes ?unselect s tree; 497 + Lx_tree.update tw) 498 + menu 499 + ) 500 + suffixes 501 + ;; 502 + 503 + 504 + let node_action st tw tree ev evinfo = 505 + (* prerr_endline "node_action"; *) 506 + match (ev : Lx_spots.supported_event) with 507 + `ButtonPress -> 508 + begin match evinfo.ev_ButtonNumber with 509 + 1 -> 510 + (* prerr_endline ("name=" ^ node.node.name); *) 511 + if not(tree.node.is_dir) then begin 512 + (* prerr_endline "invert!"; *) 513 + tree.node.selected <- not tree.node.selected; 514 + st.modified <- true; 515 + prerr_endline ("update"); 516 + Lx_tree.update tw; 517 + prerr_endline ("/update"); 518 + end 519 + | 3 -> 520 + (* Context menu *) 521 + let menu = 522 + if tree.node.is_dir 523 + then ( 524 + set_suffix_menu 525 + tw (some st.dir_context_suffix_menu) tree; 526 + set_suffix_menu 527 + ~unselect:true 528 + tw (some st.dir_context_unsuffix_menu) tree; 529 + st.dir_context_menu 530 + ) 531 + else st.file_context_menu in 532 + st.context_menu_tree <- tree; 533 + ( match menu with 534 + Some m -> 535 + Menu.popup ~x:(evinfo.ev_RootX) ~y:(evinfo.ev_RootY) m; 536 + | None -> 537 + () 538 + ) 539 + | _ -> 540 + () 541 + end 542 + 543 + | `Enter -> 544 + begin match st.info_widget with 545 + Some label -> 546 + let text = 547 + match tree.node.realtype, tree.node.is_dir with 548 + Regular,false -> 549 + tree.node.name ^ ": File is " ^ 550 + (if tree.node.selected then "selected" else "not selected") 551 + | Regular,true -> 552 + tree.node.name ^ ": Listed as file, but now a directory" 553 + | Directory,true -> 554 + tree.node.name ^ ": Directory" 555 + | Directory,false -> 556 + tree.node.name ^ ": Listed as directory, but now a file" 557 + | Absent, _ -> 558 + tree.node.name ^ ": does not exist" 559 + in 560 + Label.configure ~text label 561 + | None -> () 562 + end 563 + 564 + | `Leave -> 565 + begin match st.info_widget with 566 + Some label -> 567 + Label.configure ~text:" " label 568 + | None -> () 569 + end 570 + 571 + | _ -> 572 + () 573 + ;; 574 + 575 + 576 + let display_node st = 577 + let node_action_st = node_action st in 578 + fun tw tree -> 579 + let node = tree.node in 580 + let image = 581 + if node.is_dir then 582 + st.directory_xpm 583 + else 584 + if node.selected then 585 + st.selected_xpm 586 + else 587 + st.unselected_xpm 588 + in 589 + 590 + let foreground = 591 + (* Blue means: A selected regular file 592 + * Black means: A non selected regular file 593 + * Red means a problem: 594 + * - The file does not exist 595 + * - The file has the wrong type 596 + *) 597 + match (node.realtype, node.is_dir) with 598 + (Regular, false) -> 599 + (if node.selected then Some `Blue else None) 600 + | (Directory, true) -> 601 + None (* directories can never be selected *) 602 + | _ -> 603 + Some(`Red) 604 + in 605 + 606 + let events = [ `ButtonPress; `Enter; `Leave ] in 607 + 608 + Lx_tree.display_text 609 + ~image ~events ~action:node_action_st ?foreground node.name 610 + ;; 611 + 612 + 613 + let neutral_frame wdg = 614 + Frame.create ~highlightthickness:0 ~borderwidth:0 wdg 615 + ;; 616 + 617 + 618 + let save st = 619 + let rec write_file file path tree = 620 + let full_name = 621 + if path = "" then 622 + tree.node.name 623 + else 624 + Filename.concat path tree.node.name 625 + in 626 + if not tree.node.is_dir && tree.node.selected then begin 627 + output_string file full_name; 628 + output_string file "\n"; 629 + end; 630 + List.iter (fun child -> write_file file full_name child) tree.children 631 + in 632 + 633 + match st.tree_widget with 634 + Some tw -> 635 + let tree = Lx_tree.tree tw in 636 + let filename = Filename.concat st.current_directory st.list_file in 637 + let file = open_out filename in 638 + List.iter (fun child -> write_file file "" child) tree.children; 639 + close_out file; 640 + st.modified <- false; 641 + | None -> 642 + () 643 + ;; 644 + 645 + 646 + let q_save st = 647 + (* Question: save current file list? Returns [true] if the operation 648 + * can be continued 649 + *) 650 + if st.modified then begin 651 + let choice = 652 + Dialog.create ~parent:st.topwdg ~title:"Save?" ~message:"The current tree is modified. Save it to disk?" 653 + ~buttons:[ "Yes"; "No"; "Cancel" ] () in 654 + match choice with 655 + 0 -> save st; true 656 + | 1 -> true 657 + | 2 -> false 658 + end 659 + else 660 + true 661 + ;; 662 + 663 + 664 + let drop st = 665 + st.list_file <- ""; 666 + st.modified <- false; 667 + Frame.configure ~width:400 ~height:600 st.workframe; 668 + List.iter destroy (Winfo.children st.workframe); 669 + st.tree_widget <- None 670 + ;; 671 + 672 + 673 + let create_work_tree st top_node = 674 + let tree_frame = neutral_frame st.workframe in 675 + let info_frame = neutral_frame st.workframe in 676 + 677 + let sbar = Scrollbar.create ~orient:`Vertical tree_frame in 678 + let info_label = 679 + Label.create ~highlightthickness:0 ~borderwidth:0 ~justify:`Left 680 + ~text:" " info_frame in 681 + pack ~anchor:`W ~ipady:4 ~ipadx:4 ~side:`Left [info_label]; 682 + 683 + let width = Winfo.reqwidth st.workframe - Winfo.reqwidth sbar in 684 + let height = Winfo.reqheight st.workframe - Winfo.reqwidth info_label - 14 in 685 + (* TODO: why 14? I think that 8 pixels = 2*ipady is the right value. *) 686 + let tw = Lx_tree.create 687 + ~display:st.display ~rescan:rescan_node ~width ~height 688 + ~background:`White 689 + ~font:"9x15" 690 + top_node 691 + tree_frame in 692 + let canvas = Lx_tree.canvas tw in 693 + Canvas.configure ~yscrollcommand:(Scrollbar.set sbar) canvas; 694 + Scrollbar.configure ~command:(Canvas.yview canvas) sbar; 695 + 696 + Canvas.configure ~highlightthickness:0 canvas; 697 + 698 + pack ~side:`Left ~fill:`Both ~expand:true [canvas]; 699 + pack ~side:`Left ~fill:`Y [ sbar]; 700 + 701 + pack ~anchor:`W [tree_frame; info_frame ]; 702 + 703 + st.tree_widget <- Some tw; 704 + st.info_widget <- Some info_label; 705 + 706 + let dcm = Menu.create ~tearoff:false st.workframe in 707 + let dcm_suffix = Menu.create ~tearoff:false dcm in 708 + let dcm_unsuffix = Menu.create ~tearoff:false dcm in 709 + Menu.add_cascade ~label:"Select by suffix" ~menu:dcm_suffix dcm; 710 + Menu.add_cascade ~label:"Unselect by suffix" ~menu:dcm_unsuffix dcm; 711 + (* 712 + Menu.add_command ~label:".ml" dcm_suffix; 713 + Menu.add_command ~label:".mli" dcm_suffix; 714 + Menu.add_command ~label:".mly" dcm_suffix; 715 + *) 716 + 717 + Menu.add_command ~label:"Select all files" 718 + ~command:(fun () -> 719 + select_all st.context_menu_tree; 720 + Lx_tree.update tw) 721 + dcm; 722 + Menu.add_command ~label:"Unselect all files" 723 + ~command:(fun () -> 724 + select_all ~unselect:true st.context_menu_tree; 725 + Lx_tree.update tw) 726 + dcm; 727 + Menu.add_separator dcm; 728 + Menu.add_command ~label:"Rescan directory" 729 + ~command:(fun () -> 730 + rescan_node tw st.context_menu_tree; 731 + Lx_tree.update tw 732 + ) dcm; 733 + Menu.add_separator dcm; 734 + Menu.add_command ~label:"Expand all" 735 + ~command:(fun () -> 736 + expand ~all:true tw st.context_menu_tree; 737 + Lx_tree.update tw 738 + ) dcm; 739 + Menu.add_command ~label:"Expand as needed" 740 + ~command:(fun () -> 741 + expand tw st.context_menu_tree; 742 + Lx_tree.update tw 743 + ) dcm; 744 + Menu.add_command ~label:"Collapse" 745 + ~command:(fun () -> 746 + collapse tw st.context_menu_tree; 747 + Lx_tree.update tw 748 + ) dcm; 749 + st.dir_context_menu <- Some dcm; 750 + st.dir_context_suffix_menu <- Some dcm_suffix; 751 + st.dir_context_unsuffix_menu <- Some dcm_unsuffix; 752 + ;; 753 + 754 + 755 + let file_new st () = 756 + let enable_ok filename = 757 + not(Sys.file_exists filename) 758 + in 759 + 760 + if q_save st then begin 761 + match Filetree_dlg.open_dialog ~title:"New tree" ~enable_ok st.topwdg with 762 + Some (dir, name) -> 763 + drop st; 764 + st.current_directory <- dir; 765 + st.list_file <- name; 766 + let basename = Filename.basename dir in 767 + let initial_node = 768 + { node = { name = basename; 769 + path = [ dir ]; 770 + is_dir = true; 771 + realtype = Directory; 772 + selected = false; 773 + }; 774 + children = []; 775 + show = false; 776 + scanned = false; 777 + interactive = true; 778 + } in 779 + let filename = Filename.concat dir name in 780 + Unix.close(Unix.openfile filename [Unix.O_RDWR; Unix.O_CREAT] 0o666); 781 + create_work_tree st initial_node 782 + | None -> 783 + () 784 + end 785 + ;; 786 + 787 + 788 + let strip_ws_re = Str.regexp "^[ \r\n\t]*\\(.*\\)[ \r\n\t]*$";; 789 + 790 + let strip_ws s = 791 + if Str.string_match strip_ws_re s 0 then 792 + Str.matched_group 1 s 793 + else 794 + assert false 795 + ;; 796 + 797 + 798 + let file_open st () = 799 + let rec enter_path path node = 800 + match path with 801 + n :: path' -> 802 + begin try 803 + let child = List.find (fun ch -> ch.node.name = n) node.children in 804 + (* or Not_found *) 805 + if path' <> [] then begin 806 + child.node.is_dir <- true; 807 + end; 808 + enter_path path' child 809 + with 810 + Not_found -> 811 + let child = 812 + { node = { name = n; 813 + path = node.node.path @ [n]; 814 + is_dir = (path' <> []); 815 + realtype = Regular; (* Will be updated later *) 816 + selected = true; 817 + }; 818 + children = []; 819 + show = false; 820 + scanned = path' = []; 821 + interactive = true; 822 + } in 823 + node.children <- child :: node.children; 824 + enter_path path' child 825 + end 826 + | [] -> 827 + () 828 + in 829 + 830 + let rec read_file file initial_node = 831 + let line = strip_ws (input_line file) in 832 + if line = "" then read_file file initial_node else begin 833 + let path = Filesys.split_path line in 834 + enter_path path initial_node; 835 + read_file file initial_node 836 + end 837 + in 838 + 839 + let enable_ok filename = 840 + Sys.file_exists filename 841 + in 842 + 843 + if q_save st then begin 844 + match Filetree_dlg.open_dialog ~title:"Open tree" ~enable_ok st.topwdg with 845 + Some (dir, name) -> 846 + drop st; 847 + st.current_directory <- dir; 848 + st.list_file <- name; 849 + let basename = Filename.basename dir in 850 + let initial_node = 851 + { node = { name = basename; 852 + path = [ dir ]; 853 + is_dir = true; 854 + realtype = Directory; 855 + selected = false; 856 + }; 857 + children = []; 858 + show = false; 859 + scanned = false; 860 + interactive = true; 861 + } in 862 + let filename = Filename.concat dir name in 863 + let file = open_in filename in 864 + (try read_file file initial_node with End_of_file -> ()); 865 + close_in file; 866 + create_work_tree st initial_node 867 + | None -> 868 + () 869 + end 870 + ;; 871 + 872 + 873 + let file_save st () = 874 + save st; 875 + ignore(Dialog.create ~parent:st.topwdg ~title:"Saved" ~message:"Tree saved." 876 + ~buttons:[ "OK" ] ()); 877 + ;; 878 + 879 + 880 + let file_quit st () = 881 + if q_save st then destroy st.topwdg 882 + ;; 883 + 884 + 885 + let view_expand ?all st () = 886 + match st.tree_widget with 887 + Some tw -> 888 + expand ?all tw (Lx_tree.tree tw); 889 + Lx_tree.update tw 890 + | None -> 891 + () 892 + ;; 893 + 894 + 895 + let view_collapse st () = 896 + match st.tree_widget with 897 + Some tw -> 898 + collapse tw (Lx_tree.tree tw); 899 + Lx_tree.update tw 900 + | None -> 901 + () 902 + ;; 903 + 904 + 905 + let init_application top = 906 + let directory_xpm = 907 + Imagebitmap.create ~file:"directory.xpm" ~background:`White () in 908 + let selected_xpm = 909 + Imagebitmap.create ~file:"selected.xpm" ~background:`White () in 910 + let unselected_xpm = 911 + Imagebitmap.create ~file:"unselected.xpm" ~background:`White () in 912 + 913 + (* Create the work frame, 400 x 600 pixels *) 914 + 915 + let workframe = Frame.create ~width:400 ~height:600 top in 916 + 917 + (* Create the state record: *) 918 + 919 + let st = 920 + { current_directory = Sys.getcwd(); 921 + list_file = ""; 922 + tree_widget = None; 923 + info_widget = None; 924 + dir_context_menu = None; 925 + dir_context_suffix_menu = None; 926 + dir_context_unsuffix_menu = None; 927 + file_context_menu = None; 928 + context_menu_tree = dummy_tree; 929 + modified = false; 930 + workframe = workframe; 931 + topwdg = top; 932 + directory_xpm = directory_xpm; 933 + selected_xpm = selected_xpm; 934 + unselected_xpm = unselected_xpm; 935 + display = (fun _ _ -> Lx_tree.display_text ""); 936 + } in 937 + st.display <- display_node st; 938 + 939 + (* Because there are currently no toplevel menubars in labltk (they appeared 940 + * first in Tk 8.0), we simulate them using a frame. 941 + *) 942 + 943 + let menuframe = 944 + Frame.create ~relief:`Groove ~borderwidth:2 top in 945 + 946 + let file_mb = 947 + Menubutton.create ~text:"File" menuframe in 948 + 949 + let file_m = 950 + Menu.create file_mb in 951 + Menu.add_command ~label:"New Tree" ~command:(file_new st) file_m; 952 + Menu.add_command ~label:"Open" ~command:(file_open st) file_m; 953 + Menu.add_command ~label:"Check" file_m; 954 + Menu.add_command ~label:"Save" ~command:(file_save st) file_m; 955 + Menu.add_command ~label:"Quit" ~command:(file_quit st) file_m; 956 + Menubutton.configure ~menu:file_m file_mb; 957 + Wm.protocol_set top ~name:"WM_DELETE_WINDOW" ~command:(file_quit st); 958 + 959 + (* 960 + let edit_mb = 961 + Menubutton.create ~text:"Edit" menuframe in 962 + 963 + let edit_m = 964 + Menu.create edit_mb in 965 + (* Undo? *) 966 + Menu.add_command ~label:"Select by suffix" edit_m; 967 + Menu.add_command ~label:"Select by regexp" edit_m; 968 + Menu.add_command ~label:"Select all" edit_m; 969 + Menubutton.configure ~menu:edit_m edit_mb; 970 + *) 971 + 972 + let view_mb = 973 + Menubutton.create ~text:"View" menuframe in 974 + 975 + let view_m = 976 + Menu.create view_mb in 977 + Menu.add_command ~label:"Expand all" ~command:(view_expand ~all:true st) view_m; 978 + Menu.add_command ~label:"Expand as needed" ~command:(view_expand st) view_m; 979 + Menu.add_command ~label:"Collapse all" ~command:(view_collapse st) view_m; 980 + Menubutton.configure ~menu:view_m view_mb; 981 + 982 + pack ~side:`Left [file_mb; (* edit_mb; *) view_mb]; 983 + 984 + pack ~anchor:`W ~fill:`X [menuframe]; 985 + pack ~anchor:`W [workframe] 986 + ;; 987 + 988 + 989 + let top_window = openTk() in 990 + init_application top_window; 991 + Sys.catch_break true; 992 + try 993 + mainLoop() 994 + with 995 + Sys.Break -> 996 + prerr_endline "EXIT"; 997 + () 998 + ;; 999 + 1000 + (* ====================================================================== 1001 + * History: 1002 + * 1003 + * $Log: tree_editor.ml,v $ 1004 + * Revision 1.1 2002/06/08 19:39:53 gerd 1005 + * Initial revision. 1006 + * 1007 + * 1008 + *)
+6
vendor/opam/ocamlfind/src/findlib-toolbox/unselected.xpm
··· 1 + #define unselected_width 16 2 + #define unselected_height 16 3 + static unsigned char unselected_bits[] = { 4 + 0x55, 0x55, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 5 + 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 6 + 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0xaa, 0xaa};
+36
vendor/opam/ocamlfind/src/findlib/META.in
··· 1 + # specifications for "findlib": 2 + description = "Package manager" 3 + requires = "findlib.internal" 4 + requires(toploop) += "findlib.top" 5 + requires(create_toploop) += "findlib.top" 6 + version = "@VERSION@" 7 + 8 + package "internal" ( 9 + version = "@VERSION@" 10 + description = "Package manager" 11 + requires = "@REQUIRES@" 12 + archive(byte) = "findlib.cma" 13 + archive(native) = "findlib.cmxa" 14 + plugin(byte) = "findlib.cma" 15 + plugin(native) = "findlib.cmxs" 16 + ) 17 + 18 + package "dynload" ( 19 + version = "@VERSION@" 20 + description = "Package manager dynamic loader" 21 + requires = "findlib dynlink" 22 + archive(byte) = "findlib_dynload.cma" 23 + archive(native) = "findlib_dynload.cmxa" 24 + #Even if it strange and discouraged to dynload this package 25 + plugin(byte) = "findlib_dynload.cma" 26 + plugin(native) = "findlib_dynload.cmxs" 27 + linkopts = "-linkall" 28 + ) 29 + 30 + package "top" ( 31 + version = "@VERSION@" 32 + description = "Package manager toplevel support" 33 + requires = "findlib.internal" 34 + archive(byte) = "findlib_top.cma" 35 + archive(native) = "findlib_top.cmxa" 36 + )
+198
vendor/opam/ocamlfind/src/findlib/Makefile
··· 1 + # make all: compile to bytecode 2 + # make opt: compile to native code 3 + # make install: install bytecode and/or native code 4 + # 5 + # See Makefile.config for configurable variables. 6 + # Runtime configurations might also be necessary in the site-lib/*/META 7 + # files. 8 + #---------------------------------------------------------------------- 9 + 10 + TOP=../.. 11 + include $(TOP)/Makefile.config 12 + 13 + NAME = findlib 14 + 15 + # Need compiler-libs since ocaml-4.00 16 + OCAMLC = ocamlc -I +compiler-libs 17 + OCAMLOPT = ocamlopt -I +compiler-libs $(OCAMLOPT_G) 18 + OCAMLOPT_SHARED = $(OCAMLOPT) 19 + OCAMLDEP = ocamldep 20 + OCAMLLEX = ocamllex 21 + #CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_o.cmo -- 22 + #CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_dump.cmo -- 23 + 24 + 25 + OBJECTS = fl_compat.cmo fl_split.cmo findlib_config.cmo \ 26 + fl_metatoken.cmo fl_meta.cmo fl_metascanner.cmo fl_topo.cmo \ 27 + fl_package_base.cmo findlib.cmo fl_args.cmo fl_lint.cmo 28 + TOBJECTS = topfind.cmo 29 + 30 + XOBJECTS = $(OBJECTS:.cmo=.cmx) 31 + TXOBJECTS = $(TOBJECTS:.cmo=.cmx) 32 + 33 + OCAMLFIND_OBJECTS = ocaml_args.cmo frontend.cmo 34 + OCAMLFIND_XOBJECTS = $(OCAMLFIND_OBJECTS:.cmo=.cmx) 35 + 36 + # OCAMLFIND_ARCHIVES: set in Makefile.config 37 + OCAMLFIND_XARCHIVES = $(OCAMLFIND_ARCHIVES:.cma=.cmxa) 38 + 39 + NUMTOP_OBJECTS = num_top_printers.cmo num_top.cmo 40 + 41 + DYNLOAD_OBJECTS = fl_dynload.cmo 42 + DYNLOAD_XOBJECTS = $(DYNLOAD_OBJECTS:.cmo=.cmx) 43 + 44 + 45 + all: ocamlfind$(EXEC_SUFFIX) findlib.cma findlib_top.cma topfind $(NUMTOP) \ 46 + findlib_dynload.cma 47 + 48 + opt: ocamlfind_opt$(EXEC_SUFFIX) findlib.cmxa findlib_top.cmxa topfind \ 49 + findlib_dynload.cmxa 50 + 51 + num-top: num_top.cma 52 + 53 + ocamlfind$(EXEC_SUFFIX): findlib.cma $(OCAMLFIND_OBJECTS) 54 + $(OCAMLC) $(CUSTOM) -o ocamlfind$(EXEC_SUFFIX) -g $(OCAMLFIND_ARCHIVES) \ 55 + $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_OBJECTS) 56 + 57 + ocamlfind_opt$(EXEC_SUFFIX): findlib.cmxa $(OCAMLFIND_XOBJECTS) 58 + $(OCAMLOPT) -o ocamlfind_opt$(EXEC_SUFFIX) $(OCAMLFIND_XARCHIVES) \ 59 + $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_XOBJECTS) 60 + 61 + test_parser$(EXEC_SUFFIX): fl_metascanner.cmx test_parser.cmx fl_metatoken.cmx fl_meta.cmx 62 + $(OCAMLOPT) -o test_parser$(EXEC_SUFFIX) fl_meta.cmx fl_metatoken.cmx fl_metascanner.cmx test_parser.cmx 63 + 64 + findlib.cma: $(OBJECTS) 65 + $(OCAMLC) -a -o findlib.cma $(OBJECTS) 66 + 67 + findlib_top.cma: $(TOBJECTS) 68 + $(OCAMLC) -a -o findlib_top.cma $(TOBJECTS) 69 + 70 + findlib.cmxa: $(XOBJECTS) 71 + $(OCAMLOPT) -a -o findlib.cmxa $(XOBJECTS) 72 + if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \ 73 + $(OCAMLOPT_SHARED) -shared -o findlib.cmxs $(XOBJECTS); \ 74 + fi 75 + 76 + findlib_top.cmxa: $(TXOBJECTS) 77 + $(OCAMLOPT) -a -o findlib_top.cmxa $(TXOBJECTS) 78 + if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \ 79 + $(OCAMLOPT_SHARED) -shared -o findlib_top.cmxs $(TXOBJECTS); \ 80 + fi 81 + 82 + findlib_dynload.cma: $(DYNLOAD_OBJECTS) 83 + $(OCAMLC) -a -o findlib_dynload.cma $(DYNLOAD_OBJECTS) 84 + 85 + findlib_dynload.cmxa: $(DYNLOAD_XOBJECTS) 86 + $(OCAMLOPT) -a -o findlib_dynload.cmxa $(DYNLOAD_XOBJECTS) 87 + if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \ 88 + $(OCAMLOPT_SHARED) -shared -o findlib_dynload.cmxs $(DYNLOAD_XOBJECTS); \ 89 + fi 90 + 91 + findlib_config.ml: findlib_config.mlp $(TOP)/Makefile.config 92 + USE_CYGPATH="$(USE_CYGPATH)"; \ 93 + export USE_CYGPATH; \ 94 + cat findlib_config.mlp | \ 95 + $(SH) $(TOP)/tools/patch '@CONFIGFILE@' '$(OCAMLFIND_CONF)' | \ 96 + $(SH) $(TOP)/tools/patch '@STDLIB@' '$(OCAML_CORE_STDLIB)' | \ 97 + $(SH) $(TOP)/tools/patch '@RELATIVE_PATHS@' '$(RELATIVE_PATHS)' | \ 98 + sed -e 's;@AUTOLINK@;$(OCAML_AUTOLINK);g' \ 99 + -e 's;@SYSTEM@;$(SYSTEM);g' \ 100 + >findlib_config.ml 101 + 102 + topfind.ml: topfind.ml.in 103 + if [ "$(ENABLE_TOPFIND_PPXOPT)" = "true" ]; then \ 104 + cp topfind.ml.in topfind.ml; \ 105 + else \ 106 + sed -e '/PPXOPT_BEGIN/,/PPXOPT_END/ d' topfind.ml.in \ 107 + > topfind.ml ; \ 108 + fi 109 + 110 + topfind.compat.in: topfind.in 111 + if [ "$(OCAML_REMOVE_DIRECTORY)" = "1" ]; then \ 112 + cp $< $@; \ 113 + else \ 114 + sed -e '/REMOVE_DIRECTORY_BEGIN/,/REMOVE_DIRECTORY_END/ d' $< \ 115 + > $@ ; \ 116 + fi 117 + 118 + topfind: topfind.compat.in 119 + USE_CYGPATH="$(USE_CYGPATH)"; \ 120 + export USE_CYGPATH; \ 121 + cat topfind.compat.in | \ 122 + $(SH) $(TOP)/tools/patch '@SITELIB@' '$(OCAML_SITELIB)' | \ 123 + $(SH) $(TOP)/tools/patch '@RELATIVE_PATHS@' '$(RELATIVE_PATHS)' \ 124 + >topfind 125 + 126 + num_top.cma: $(NUMTOP_OBJECTS) 127 + $(OCAMLC) -a -o num_top.cma $(NUMTOP_OBJECTS) 128 + 129 + clean: 130 + rm -f *.cmi *.cmo *.cma *.cmx *.a *.lib *.o *.obj *.cmxa \ 131 + fl_meta.ml findlib_config.ml topfind.ml topfind.compat.in topfind \ 132 + ocamlfind$(EXEC_SUFFIX) ocamlfind_opt$(EXEC_SUFFIX) 133 + 134 + install: all 135 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)" 136 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)" 137 + test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)" 138 + test $(INSTALL_TOPFIND) -eq 0 || $(CP) topfind "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/" 139 + files=`$(SH) $(TOP)/tools/collect_files $(TOP)/Makefile.config \ 140 + findlib.cmi findlib.mli findlib.cma findlib.cmxa findlib$(LIB_SUFFIX) findlib.cmxs \ 141 + findlib_config.cmi findlib_config.ml topfind.cmi topfind.mli \ 142 + fl_args.cmi fl_lint.cmi fl_meta.cmi fl_split.cmi fl_topo.cmi ocaml_args.cmi \ 143 + fl_package_base.mli fl_package_base.cmi fl_metascanner.mli fl_metascanner.cmi \ 144 + fl_metatoken.cmi findlib_top.cma findlib_top.cmxa findlib_top$(LIB_SUFFIX) findlib_top.cmxs \ 145 + findlib_dynload.cma findlib_dynload.cmxa findlib_dynload$(LIB_SUFFIX) findlib_dynload.cmxs fl_dynload.mli fl_dynload.cmi \ 146 + META` && \ 147 + $(CP) $$files "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/" 148 + f="ocamlfind$(EXEC_SUFFIX)"; { test -f ocamlfind_opt$(EXEC_SUFFIX) && f="ocamlfind_opt$(EXEC_SUFFIX)"; }; \ 149 + $(INSTALLFILE) $$f "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX)" 150 + # the following "if" block is only needed for 4.00beta2 151 + if [ $(OCAML_REMOVE_DIRECTORY) -eq 0 -a -f "$(OCAML_CORE_STDLIB)/compiler-libs/topdirs.cmi" ]; then \ 152 + cd "$(OCAML_CORE_STDLIB)/compiler-libs/"; \ 153 + $(CP) topdirs.cmi toploop.cmi "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/"; \ 154 + fi 155 + 156 + install-num-top: 157 + $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top" 158 + $(CP) num_top.cma num_top.cmi num_top_printers.cmi \ 159 + "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top/" 160 + 161 + # Note: uninstall-num-top is part of the removal of the META files. 162 + 163 + uninstall: 164 + rm -f $(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/findlib 165 + rm -rf $(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME) 166 + rm -f $(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX) 167 + 168 + 169 + depend: *.ml *.mli fl_meta.ml fl_metascanner.ml findlib_config.ml topfind.ml 170 + $(OCAMLDEP) *.ml *.mli >depend 171 + 172 + # Some 'make' implementations require that .SUFFIXES must occur before 173 + # the first suffix rule. (E.g. AIX) 174 + .SUFFIXES: .mll .cmo .cmi .cmx .ml .mli 175 + # .src 176 + 177 + .ml.cmx: 178 + $(OCAMLOPT) $(OPAQUE) $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $< 179 + 180 + .ml.cmo: 181 + $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -g -c $< 182 + 183 + .mli.cmi: 184 + $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $< 185 + 186 + #.src.ml: 187 + # $(CAMLP4O) -impl $< -o $@ 188 + 189 + # Solaris make does not like the suffix rule .mll.ml, 190 + # so I replaced it by its single application: 191 + fl_meta.ml: fl_meta.mll 192 + $(OCAMLLEX) fl_meta.mll 193 + 194 + # Don't remove fl_metascanner.ml: 195 + .PRECIOUS: fl_metascanner.ml 196 + 197 + include depend 198 +
+553
vendor/opam/ocamlfind/src/findlib/findlib.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + open Fl_compat 7 + 8 + module StrSet = Set.Make(String) 9 + 10 + exception No_such_package 11 + = Fl_package_base.No_such_package 12 + 13 + 14 + exception Package_loop 15 + = Fl_package_base.Package_loop 16 + 17 + type formal_pred = 18 + [ `Pred of string 19 + | `NegPred of string 20 + ] 21 + 22 + let init_called = ref false ;; 23 + 24 + let conf_config_file = ref "";; 25 + let conf_default_location = ref "";; 26 + let conf_meta_directory = ref "";; 27 + let conf_search_path = ref [];; 28 + let conf_command = ref [];; 29 + let conf_stdlib = ref "";; 30 + let conf_ldconf = ref "";; 31 + let conf_ignore_dups_in = ref ([] : string list);; 32 + 33 + let ocamlc_default = "ocamlc";; 34 + let ocamlopt_default = "ocamlopt";; 35 + let ocamlcp_default = "ocamlcp";; 36 + let ocamloptp_default = "ocamloptp";; 37 + let ocamlmklib_default = "ocamlmklib";; 38 + let ocamlmktop_default = "ocamlmktop";; 39 + let ocamldep_default = "ocamldep";; 40 + let ocamlbrowser_default = "ocamlbrowser";; 41 + let ocamldoc_default = "ocamldoc";; 42 + 43 + 44 + let init_manually 45 + ?(ocamlc_command = ocamlc_default) 46 + ?(ocamlopt_command = ocamlopt_default) 47 + ?(ocamlcp_command = ocamlcp_default) 48 + ?(ocamloptp_command = ocamloptp_default) 49 + ?(ocamlmklib_command = ocamlmklib_default) 50 + ?(ocamlmktop_command = ocamlmktop_default) 51 + ?(ocamldep_command = ocamldep_default) 52 + ?(ocamlbrowser_command = ocamlbrowser_default) 53 + ?(ocamldoc_command = ocamldoc_default) 54 + ?ignore_dups_in 55 + ?(ignore_dups_in_list = []) 56 + ?(stdlib = Findlib_config.ocaml_stdlib) 57 + ?(ldconf = Findlib_config.ocaml_ldconf) 58 + ?config 59 + ~install_dir 60 + ~meta_dir 61 + ~search_path () = 62 + conf_command := [ `ocamlc, ocamlc_command; 63 + `ocamlopt, ocamlopt_command; 64 + `ocamlcp, ocamlcp_command; 65 + `ocamloptp, ocamloptp_command; 66 + `ocamlmklib, ocamlmklib_command; 67 + `ocamlmktop, ocamlmktop_command; 68 + `ocamldep, ocamldep_command; 69 + `ocamlbrowser, ocamlbrowser_command; 70 + `ocamldoc, ocamldoc_command; 71 + ]; 72 + let config = match config with 73 + | Some config -> config 74 + | None -> Lazy.force Findlib_config.config_file 75 + in 76 + conf_config_file := config; 77 + conf_search_path := search_path; 78 + conf_default_location := install_dir; 79 + conf_meta_directory := meta_dir; 80 + conf_stdlib := stdlib; 81 + conf_ldconf := ldconf; 82 + conf_ignore_dups_in := 83 + ( match ignore_dups_in with 84 + | None -> [] 85 + | Some d -> [d] 86 + ) @ ignore_dups_in_list; 87 + Fl_package_base.init !conf_search_path stdlib !conf_ignore_dups_in; 88 + init_called := true 89 + ;; 90 + 91 + 92 + let command_names cmd_spec = 93 + try 94 + let cmd_list = Fl_split.in_words cmd_spec in 95 + List.map 96 + (fun cmd_setting -> 97 + try 98 + (* cmd_setting: formal_name=actual_name *) 99 + let l = String.length cmd_setting in 100 + let n = String.index cmd_setting '=' in 101 + let cmd_formal_name = String.sub cmd_setting 0 n in 102 + let cmd_actual_name = String.sub cmd_setting (n+1) (l-n-1) in 103 + cmd_formal_name, cmd_actual_name 104 + with 105 + Not_found -> 106 + prerr_endline ("Warning: Please check the environment variable OCAMLFIND_COMMANDS"); 107 + "", "" 108 + ) 109 + cmd_list 110 + with 111 + Not_found -> 112 + [] 113 + ;; 114 + 115 + let auto_config_file() = 116 + let p = 117 + ( try Sys.getenv "OCAMLFIND_CONF" with Not_found -> "") in 118 + if p = "" then Lazy.force Findlib_config.config_file else p 119 + 120 + let path_to_relocate path = 121 + let prefix = "$PREFIX" in 122 + let len = String.length prefix in 123 + match String.starts_with ~prefix path with 124 + | false -> None 125 + | true -> Some (String.sub path len (String.length path - len)) 126 + 127 + let relocate_paths paths = 128 + let paths = 129 + String.split_on_char Fl_split.path_separator paths 130 + |> List.filter_map (fun path -> 131 + match path_to_relocate path with 132 + | None -> Some path 133 + | Some path -> ( 134 + match Lazy.force Findlib_config.location with 135 + | Some install_location -> 136 + Some (Filename.concat install_location path) 137 + | None -> None)) 138 + in 139 + let sep = String.make 1 Fl_split.path_separator in 140 + String.concat sep paths 141 + ;; 142 + 143 + let init 144 + ?env_ocamlpath ?env_ocamlfind_destdir ?env_ocamlfind_metadir 145 + ?env_ocamlfind_commands ?env_ocamlfind_ignore_dups_in 146 + ?env_ocamlfind_ignore_dups_in_list ?env_camllib ?env_ldconf 147 + ?config ?toolchain () = 148 + 149 + let config_file = 150 + match config with 151 + Some f -> f 152 + | None -> auto_config_file() 153 + in 154 + 155 + let configd_file = 156 + config_file ^ ".d" in 157 + 158 + let vars_of_file f = 159 + let ch = open_in f in 160 + try 161 + let vars = 162 + (Fl_metascanner.parse ch).Fl_metascanner.pkg_defs in 163 + close_in ch; 164 + vars 165 + with 166 + | error -> close_in ch; raise error in 167 + 168 + let vars_of_dir d = 169 + let files = Array.to_list (Sys.readdir d) in 170 + List.flatten 171 + (List.map 172 + (fun file -> 173 + if Filename.check_suffix file ".conf" then 174 + vars_of_file (Filename.concat d file) 175 + else 176 + [] 177 + ) 178 + files) 179 + in 180 + 181 + let config_preds = 182 + match toolchain with 183 + | None -> (try [Sys.getenv "OCAMLFIND_TOOLCHAIN"] with Not_found -> []) 184 + | Some p -> [p] in 185 + 186 + let sys_ocamlc, sys_ocamlopt, sys_ocamlcp, sys_ocamloptp, sys_ocamlmklib, 187 + sys_ocamlmktop, sys_ocamldep, sys_ocamlbrowser, sys_ocamldoc, 188 + sys_search_path, sys_destdir, sys_metadir, sys_stdlib, sys_ldconf = 189 + ( 190 + let config_vars = 191 + if config_file <> "" && 192 + not(Sys.file_exists config_file) && not(Sys.file_exists configd_file) 193 + then 194 + failwith("Config file not found - neither " ^ 195 + config_file ^ " nor the directory " ^ 196 + configd_file); 197 + if Sys.file_exists config_file then 198 + vars_of_file config_file 199 + else 200 + [] in 201 + let configd_vars = 202 + if Sys.file_exists configd_file then 203 + vars_of_dir configd_file 204 + else 205 + [] in 206 + let vars = config_vars @ configd_vars in 207 + if vars <> [] then ( 208 + let found = ref false in 209 + let lookup name default = 210 + let explicit_preds = 211 + List.for_all 212 + (fun p -> Fl_metascanner.predicate_exists p vars) 213 + config_preds in 214 + found := !found || explicit_preds; 215 + try 216 + Fl_metascanner.lookup name config_preds vars 217 + |> relocate_paths 218 + with Not_found -> default 219 + in 220 + let config_tuple = 221 + ( (lookup "ocamlc" ocamlc_default), 222 + (lookup "ocamlopt" ocamlopt_default), 223 + (lookup "ocamlcp" ocamlcp_default), 224 + (lookup "ocamloptp" ocamloptp_default), 225 + (lookup "ocamlmklib" ocamlmklib_default), 226 + (lookup "ocamlmktop" ocamlmktop_default), 227 + (lookup "ocamldep" ocamldep_default), 228 + (lookup "ocamlbrowser" ocamlbrowser_default), 229 + (lookup "ocamldoc" ocamldoc_default), 230 + Fl_split.path (lookup "path" ""), 231 + (lookup "destdir" ""), 232 + (lookup "metadir" "none"), 233 + (lookup "stdlib" Findlib_config.ocaml_stdlib), 234 + (lookup "ldconf" Findlib_config.ocaml_ldconf) 235 + ) in 236 + if not !found && config_preds <> [] then 237 + prerr_endline("ocamlfind: [WARNING] Undefined toolchain: " ^ 238 + String.concat "" config_preds); 239 + config_tuple 240 + ) 241 + else 242 + ( ocamlc_default, ocamlopt_default, ocamlcp_default, ocamloptp_default, 243 + ocamlmklib_default, 244 + ocamlmktop_default, ocamldep_default, ocamlbrowser_default, 245 + ocamldoc_default, 246 + [], 247 + "", 248 + "none", 249 + Findlib_config.ocaml_stdlib, 250 + Findlib_config.ocaml_ldconf 251 + ) 252 + ) 253 + in 254 + 255 + let env_commands = 256 + match env_ocamlfind_commands with 257 + Some x -> command_names x 258 + | None -> command_names (try Sys.getenv "OCAMLFIND_COMMANDS" 259 + with Not_found -> "") 260 + in 261 + let env_destdir = 262 + match env_ocamlfind_destdir with 263 + Some x -> x 264 + | None -> 265 + try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> "" 266 + in 267 + let env_metadir = 268 + match env_ocamlfind_metadir with 269 + Some x -> x 270 + | None -> 271 + try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> "" 272 + in 273 + let env_search_path = 274 + Fl_split.path 275 + (match env_ocamlpath with 276 + Some x -> x 277 + | None -> 278 + try Sys.getenv "OCAMLPATH" with Not_found -> "" 279 + ) 280 + in 281 + let env_stdlib = 282 + match env_camllib with 283 + Some x -> x 284 + | None -> 285 + ( try Sys.getenv "OCAMLLIB" 286 + with 287 + Not_found -> 288 + (try Sys.getenv "CAMLLIB" with Not_found -> "" ) 289 + ) 290 + in 291 + let env_ldconf = 292 + match env_ldconf with 293 + Some x -> x 294 + | None -> 295 + try Sys.getenv "OCAMLFIND_LDCONF" with Not_found -> "" 296 + in 297 + let ignore_dups_in_list = 298 + match env_ocamlfind_ignore_dups_in, env_ocamlfind_ignore_dups_in_list with 299 + | Some x0, Some l -> x0 :: l 300 + | None, Some l -> l 301 + | Some x0, None -> [x0] 302 + | None, None -> 303 + try Fl_split.path (Sys.getenv "OCAMLFIND_IGNORE_DUPS_IN") 304 + with Not_found -> [] in 305 + 306 + let ocamlc, ocamlopt, ocamlcp, ocamloptp, ocamlmklib, ocamlmktop, 307 + ocamldep, ocamlbrowser, ocamldoc, 308 + search_path, destdir, metadir, stdlib, ldconf = 309 + (try List.assoc "ocamlc" env_commands with Not_found -> sys_ocamlc), 310 + (try List.assoc "ocamlopt" env_commands with Not_found -> sys_ocamlopt), 311 + (try List.assoc "ocamlcp" env_commands with Not_found -> sys_ocamlcp), 312 + (try List.assoc "ocamloptp" env_commands with Not_found -> sys_ocamloptp), 313 + (try List.assoc "ocamlmklib" env_commands with Not_found -> sys_ocamlmklib), 314 + (try List.assoc "ocamlmktop" env_commands with Not_found -> sys_ocamlmktop), 315 + (try List.assoc "ocamldep" env_commands with Not_found -> sys_ocamldep), 316 + (try List.assoc "ocamlbrowser" env_commands with Not_found -> sys_ocamlbrowser), 317 + (try List.assoc "ocamldoc" env_commands with Not_found -> sys_ocamldoc), 318 + (env_search_path @ sys_search_path), 319 + (if env_destdir = "" then sys_destdir else env_destdir), 320 + (if env_metadir = "" then sys_metadir else env_metadir), 321 + (if env_stdlib = "" then sys_stdlib else env_stdlib), 322 + (if env_ldconf = "" then sys_ldconf else env_ldconf) 323 + in 324 + 325 + init_manually 326 + ~ocamlc_command: ocamlc 327 + ~ocamlopt_command: ocamlopt 328 + ~ocamlcp_command: ocamlcp 329 + ~ocamloptp_command: ocamloptp 330 + ~ocamlmklib_command: ocamlmklib 331 + ~ocamlmktop_command: ocamlmktop 332 + ~ocamldep_command: ocamldep 333 + ~ocamlbrowser_command: ocamlbrowser 334 + ~ocamldoc_command: ocamldoc 335 + ~ignore_dups_in_list 336 + ~stdlib: stdlib 337 + ~ldconf: ldconf 338 + ~config: config_file 339 + ~install_dir: destdir 340 + ~meta_dir: metadir 341 + ~search_path: search_path 342 + () 343 + ;; 344 + 345 + 346 + let lazy_init() = 347 + if not !init_called then init() 348 + 349 + let config_file() = 350 + lazy_init(); 351 + !conf_config_file;; 352 + 353 + 354 + let default_location() = 355 + lazy_init(); 356 + !conf_default_location;; 357 + 358 + 359 + let meta_directory() = 360 + lazy_init(); 361 + if !conf_meta_directory = "none" then "" else !conf_meta_directory;; 362 + 363 + 364 + let search_path() = 365 + lazy_init(); 366 + !conf_search_path;; 367 + 368 + 369 + let command which = 370 + lazy_init(); 371 + try 372 + List.assoc which !conf_command 373 + with 374 + Not_found -> assert false 375 + ;; 376 + 377 + 378 + let ocaml_stdlib() = 379 + lazy_init(); 380 + !conf_stdlib;; 381 + 382 + 383 + let ocaml_ldconf() = 384 + lazy_init(); 385 + !conf_ldconf;; 386 + 387 + let ignore_dups_in() = 388 + lazy_init(); 389 + !conf_ignore_dups_in;; 390 + 391 + let package_directory pkg = 392 + lazy_init(); 393 + (Fl_package_base.query pkg).Fl_package_base.package_dir 394 + ;; 395 + 396 + 397 + let package_meta_file pkg = 398 + lazy_init(); 399 + (Fl_package_base.query pkg).Fl_package_base.package_meta 400 + ;; 401 + 402 + 403 + let package_property_2 predlist pkg propname = 404 + lazy_init(); 405 + let l = Fl_package_base.query pkg in 406 + Fl_metascanner.lookup_2 propname predlist l.Fl_package_base.package_defs 407 + ;; 408 + 409 + 410 + let package_property predlist pkg propname = 411 + lazy_init(); 412 + let l = Fl_package_base.query pkg in 413 + Fl_metascanner.lookup propname predlist l.Fl_package_base.package_defs 414 + ;; 415 + 416 + 417 + let package_ancestors preds pkg = 418 + lazy_init(); 419 + Fl_package_base.requires ~preds pkg 420 + ;; 421 + 422 + 423 + let package_deep_ancestors preds pkglist = 424 + lazy_init(); 425 + Fl_package_base.requires_deeply ~preds pkglist 426 + ;; 427 + 428 + 429 + let resolve_path ?base ?(explicit=false) p = 430 + lazy_init(); 431 + if p = "" then "" else ( 432 + match p.[0] with 433 + '^' | '+' -> 434 + let stdlibdir = Fl_split.norm_dir (ocaml_stdlib()) in 435 + Filename.concat 436 + stdlibdir 437 + (String.sub p 1 (String.length p - 1)) 438 + | '@' -> 439 + (* Search slash *) 440 + ( try 441 + let k = String.index p '/' in (* or Not_found *) 442 + let pkg = String.sub p 1 (k-1) in 443 + let p' = String.sub p (k+1) (String.length p - k - 1) in 444 + let pkgdir = package_directory pkg in 445 + Filename.concat pkgdir p' 446 + with 447 + Not_found -> 448 + let pkg = String.sub p 1 (String.length p - 1) in 449 + package_directory pkg 450 + ) 451 + | _ -> 452 + ( match base with 453 + None -> p 454 + | Some b -> 455 + if Filename.is_relative p && 456 + (not explicit || not (Filename.is_implicit p)) 457 + then 458 + Filename.concat b p 459 + else 460 + p 461 + ) 462 + ) 463 + ;; 464 + 465 + 466 + let list_packages ?(tab = 20) ?(descr = false) ch = 467 + lazy_init(); 468 + let packages = Fl_package_base.list_packages() in 469 + let packages_sorted = List.sort compare packages in 470 + 471 + List.iter 472 + (fun p -> 473 + let v_string = 474 + try 475 + let v = package_property [] p "version" in 476 + "(version: " ^ v ^ ")" 477 + with 478 + Not_found -> "(version: n/a)" 479 + in 480 + let descr_string = 481 + try package_property [] p "description" 482 + with Not_found -> "(no description)" in 483 + let spaces1 = String.make (max 1 (tab-String.length p)) ' ' in 484 + let spaces2 = String.make tab ' ' in 485 + 486 + if descr then ( 487 + output_string ch (p ^ spaces1 ^ descr_string ^ "\n"); 488 + output_string ch (spaces2 ^ v_string ^ "\n") 489 + ) 490 + else 491 + output_string ch (p ^ spaces1 ^ v_string ^ "\n"); 492 + ) 493 + packages_sorted 494 + ;; 495 + 496 + let list_packages' ?prefix () = 497 + lazy_init(); 498 + Fl_package_base.list_packages ?prefix () 499 + 500 + 501 + type rectype = 502 + | Record_core 503 + | Record_load 504 + 505 + let rec_core = ref StrSet.empty 506 + let rec_load = ref StrSet.empty 507 + let rec_preds = ref [] 508 + 509 + let record_package (rt:rectype) (p:string) = 510 + match rt with 511 + | Record_core -> 512 + rec_core := StrSet.add p !rec_core 513 + | Record_load -> 514 + rec_load := StrSet.add p !rec_load 515 + 516 + let recorded_packages rt = 517 + match rt with 518 + | Record_core -> 519 + StrSet.elements !rec_core 520 + | Record_load -> 521 + StrSet.elements (StrSet.diff !rec_load !rec_core) 522 + 523 + let reset_recordings() = 524 + rec_load := StrSet.empty 525 + 526 + let type_of_recorded_package p = 527 + if StrSet.mem p !rec_core then 528 + Record_core 529 + else 530 + if StrSet.mem p !rec_load then 531 + Record_load 532 + else 533 + raise Not_found 534 + 535 + let is_recorded_package p = 536 + try ignore(type_of_recorded_package p); true with Not_found -> false 537 + 538 + 539 + let rm_preds = 540 + [ "create_toploop"; "toploop"; "executable"; "plugin"; "autolink"; 541 + "preprocessor"; "syntax" ] 542 + 543 + let rm_preds_set = 544 + List.fold_right StrSet.add rm_preds StrSet.empty 545 + 546 + let record_package_predicates preds = 547 + let preds' = 548 + List.filter (fun p -> not(StrSet.mem p rm_preds_set)) preds in 549 + rec_preds := preds' 550 + 551 + let recorded_predicates() = 552 + !rec_preds 553 +
+276
vendor/opam/ocamlfind/src/findlib/findlib.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** The primary findlib interface 7 + * 8 + * The Findlib module is the primary interface of the findlib library. It 9 + * contains functions to look up packages, to interpret META 10 + * files, and to determine the ancestors of packages. 11 + * 12 + * This module must be initialized before it can be used: Call either 13 + * [init] or [init_manually] for this. 14 + *) 15 + 16 + exception No_such_package of string * string 17 + (** First arg is the package name not found, second arg contains additional 18 + * info for the user 19 + *) 20 + 21 + exception Package_loop of string 22 + (** A package is required by itself. The arg is the name of the 23 + * package 24 + *) 25 + 26 + 27 + type formal_pred = 28 + [ `Pred of string (** Positive occurrence of a formal predicate var *) 29 + | `NegPred of string (** Negative occurrence of a formal predicate var *) 30 + ] 31 + (** A formal predicate as it occurs in a package definition *) 32 + 33 + val init : 34 + ?env_ocamlpath: string -> 35 + ?env_ocamlfind_destdir: string -> 36 + ?env_ocamlfind_metadir: string -> 37 + ?env_ocamlfind_commands: string -> 38 + ?env_ocamlfind_ignore_dups_in: string -> 39 + ?env_ocamlfind_ignore_dups_in_list: string list -> 40 + ?env_camllib: string -> 41 + ?env_ldconf: string -> 42 + ?config: string -> 43 + ?toolchain: string -> 44 + unit -> 45 + unit 46 + (** Initializes the library from the configuration file and the environment. 47 + * By default the 48 + * function reads the file specified at compile time, but you can also 49 + * pass a different file name in the [config] argument. 50 + * Furthermore, the environment variables OCAMLPATH, OCAMLFIND_DESTDIR, 51 + * OCAMLFIND_COMMANDS, OCAMLFIND_IGNORE_DUPS_IN, and CAMLLIB are interpreted. 52 + * By default, the function takes 53 + * the values found in the environment, but you can pass different values 54 + * using the [env_*] arguments. By setting these values to empty strings 55 + * they are no longer considered. 56 + * The result of the initialization is determined as follows: 57 + * - The default installation directory is the env variable OCAMLFIND_DESTDIR 58 + * (if present and non-empty), and otherwise the variable [destdir] of the 59 + * configuration file. 60 + * - The installation directory for META files is read from the env 61 + * variable OCAMLFIND_METADIR (if present and non-empty), and otherwise 62 + * from the variable [metadir] of the configuration file, and otherwise 63 + * no such directory is used. 64 + * The special value ["none"] turns this feature off. 65 + * - The search path is the concatenation of the env variable OCAMLPATH 66 + * and the variable [path] of the config file 67 + * - The executables of (ocamlc|ocamlopt|ocamlcp|ocamlmklib|ocamlmktop) are 68 + * determined as follows: if the env variable OCAMLFIND_COMMANDS is set 69 + * and non-empty, its contents specify the executables. Otherwise, if the 70 + * config file variables [ocamlc], [ocamlopt], [ocamlcp], [ocamlmklib] and 71 + * [ocamlmktop] are set, their contents specify the executables. Otherwise, 72 + * the obvious default values are chosen: ["ocamlc"] for [ocamlc], 73 + * ["ocamlopt"] for [ocamlopt], and so on. 74 + * - The directory of the standard library is the value of the environment 75 + * variable CAMLLIB (or OCAMLLIB), or if unset or empty, the value of 76 + * the configuration variable [stdlib], or if unset the built-in location 77 + * - The [ld.conf] file (configuring the dynamic loader) is the value of 78 + * the environment variable OCAMLFIND_LDCONF, or if unset or empty, the 79 + * value of the configuration variable [ldconf], or if unset the 80 + * built-in location. 81 + * - The ocamlfind tool doesn't emit warnings about double cmi files 82 + * for the directories listed in OCAMLFIND_IGNORE_DUPS_IN. Since 83 + * findlib-1.8 this variable is interpreted as colon-separated path. 84 + * (Before, only one directory could be given.) If the variable is not 85 + * set there are no exceptions, and the warnings are always printed. 86 + * Note that both the parameters [env_ocamlfind_ignore_dups_in] (a 87 + * single directory) and [env_ocamlfind_ignore_dups_in_list] (a list 88 + * of directories) override the default. 89 + *) 90 + 91 + 92 + val init_manually : 93 + ?ocamlc_command: string -> (* default: "ocamlc" *) 94 + ?ocamlopt_command: string -> (* default: "ocamlopt" *) 95 + ?ocamlcp_command: string -> (* default: "ocamlcp" *) 96 + ?ocamloptp_command: string -> (* default: "ocamloptp" *) 97 + ?ocamlmklib_command: string -> (* default: "ocamlmklib" *) 98 + ?ocamlmktop_command: string -> (* default: "ocamlmktop" *) 99 + ?ocamldep_command: string -> (* default: "ocamldep" *) 100 + ?ocamlbrowser_command: string -> (* default: "ocamlbrowser" *) 101 + ?ocamldoc_command: string -> (* default: "ocamldoc" *) 102 + ?ignore_dups_in:string -> (* default: None *) 103 + ?ignore_dups_in_list:string list -> (* default: [] *) 104 + ?stdlib: string -> (* default: taken from Findlib_config *) 105 + ?ldconf: string -> 106 + ?config: string -> 107 + install_dir: string -> 108 + meta_dir: string -> 109 + search_path: string list -> 110 + unit -> 111 + unit 112 + (** This is an alternate way to initialize the library directly. 113 + * Environment variables and configuration files are ignored. The 114 + * parameter [config] just sets the file name reported by the 115 + * [config_file] function below. 116 + *) 117 + 118 + 119 + val config_file : unit -> string 120 + (** The location of the configuration file *) 121 + 122 + val default_location : unit -> string 123 + (** Get the default installation directory for packages *) 124 + 125 + val meta_directory : unit -> string 126 + (** Get the META installation directory for packages. 127 + * Returns [""] if no such directory is configured. 128 + *) 129 + 130 + val search_path : unit -> string list 131 + (** Get the search path for packages *) 132 + 133 + val command : [ `ocamlc | `ocamlopt | `ocamlcp | `ocamloptp | `ocamlmklib 134 + | `ocamlmktop | `ocamldep | `ocamlbrowser | `ocamldoc 135 + ] -> 136 + string 137 + (** Get the name/path of the executable *) 138 + 139 + val ocaml_stdlib : unit -> string 140 + (** Get the directory of the standard library *) 141 + 142 + val ocaml_ldconf : unit -> string 143 + (** Get the file name of [ld.conf] *) 144 + 145 + val package_directory : string -> string 146 + (** Get the absolute path of the directory where the given package is 147 + * stored. 148 + * 149 + * Raises [No_such_package] if the package cannot be found. 150 + *) 151 + 152 + val package_meta_file : string -> string 153 + (** Get the absolute path of the META file of the given package *) 154 + 155 + val ignore_dups_in : unit -> string list 156 + (** If [Some d], duplicate packages below [d] are ignored, and do not 157 + * produce warnings. (Only affects the generation of warnings.) 158 + * 159 + * Since findlib-1.8 this configuration is a list. Before, it was a 160 + * [string option]. 161 + *) 162 + 163 + val package_property : string list -> string -> string -> string 164 + (** [package_property predlist pkg propname]: 165 + * Looks up the property [propname] of package [pkg] under the assumption 166 + * that the predicates in [predlist] are true. 167 + * 168 + * Raises [No_such_package] if the package, and [Not_found] if the property 169 + * cannot be found. 170 + * 171 + * EXAMPLES: 172 + * - [package_property [] "p" "requires":] 173 + * get the value of the [requires] clause of package [p] 174 + * - [package_property [ "mt"; "byte" ] "p" "archive":] 175 + * get the value of the [archive] property of package [p] for multi- 176 + * threaded bytecode applications. 177 + *) 178 + 179 + val package_property_2 : string list -> string -> string -> 180 + string * formal_pred list 181 + (** [package_property_2 predlist pkg propname]: This returns two values 182 + [(v, preds)]. The first one, [v], is computed as in [package_property]. 183 + The other list, [preds], contains the predicates that actually had to 184 + be set or not set in order to select the particular variable definition. 185 + *) 186 + 187 + 188 + val package_ancestors : string list -> string -> string list 189 + (** [package_ancestors predlist pkg:] 190 + * Determines the direct ancestors of package [pkg] under the assumption 191 + * that the predicates in [predlist] are true, i.e. the names of the 192 + * packages required by [pkg]. 193 + * The returned list is unsorted. 194 + * 195 + * Raises [No_such_package] if the package [pkg] or one of its ancestors 196 + * could not be found. 197 + *) 198 + 199 + val package_deep_ancestors : string list -> string list -> string list 200 + (** [package_deep_ancestors predlist pkglist:] 201 + * determines the list of direct or indirect ancestors of the packages 202 + * named in [pkglist] under the assumption that the predicates in [predlist] 203 + * are true. 204 + * 205 + * The returned list is topologically sorted: The first element is the 206 + * deepest ancestor; the last element is one of [pkglist]. 207 + * 208 + * Raises [No_such_package] if one of the packages in [pkglist] or one of 209 + * the ancestors cannot be found. Raises [Package_loop] if there is a 210 + * cyclic dependency. 211 + *) 212 + 213 + val resolve_path : ?base:string -> ?explicit:bool -> string -> string 214 + (** Resolves findlib notation in filename paths. The notation 215 + * [ +name/path ] can be used to refer to the subdirectory [name] 216 + * of the standard library directory; the continuation [ /path ] is 217 + * optional. The notation [ \@name/path ] can be used to refer to 218 + * the directory of the package [name]; the continuation [ /path ] 219 + * is optional. For these two notations, absolute paths are returned. 220 + * 221 + * @param base When the function is applied on a relative path, the 222 + * [base] path is prepended. Otherwise, the path is returned as 223 + * it is. 224 + * @param explicit Changes the meaning of [base] so that only paths 225 + * count as relative that include at least one slash. 226 + *) 227 + 228 + val list_packages : ?tab:int -> ?descr:bool -> out_channel -> unit 229 + (** Prints the list of available packages to the [out_channel]. 230 + * 231 + * @param tab The tabulator width, by default 20 232 + * @param descr Whether package descriptions are printed. Default: false 233 + *) 234 + 235 + val list_packages' : ?prefix:string -> unit -> string list 236 + (** Returns the (unsorted) list of all packages. 237 + * 238 + * @param prefix Limit to the packages that starts with it. Default: unlimited 239 + *) 240 + 241 + (** Managing dynamically loaded packages *) 242 + 243 + (** This is a registry of packages that are available in-core. This is both 244 + used for toploops and for plugins. 245 + *) 246 + 247 + type rectype = 248 + | Record_core (** The package is part of the executable core *) 249 + | Record_load (** The package has been dynamically loaded *) 250 + 251 + val record_package : rectype -> string -> unit 252 + (** Record this package *) 253 + 254 + val record_package_predicates : string list -> unit 255 + (** Record the predicates to be used for package loading. Certain predicates 256 + are automatically filtered out if inappropriate. A call of 257 + [record_package_predicates] replaces the set of predicates that was 258 + installed beforehand. 259 + *) 260 + 261 + val recorded_packages : rectype -> string list 262 + (** The list of packages recorded with [record_package] *) 263 + 264 + val is_recorded_package : string -> bool 265 + (** Whether there is a recording for this package *) 266 + 267 + val type_of_recorded_package : string -> rectype 268 + (** Returns the type, or raises [Not_found] *) 269 + 270 + val recorded_predicates : unit -> string list 271 + (** The most recent version of the recorded predicate list *) 272 + 273 + val reset_recordings : unit -> unit 274 + (** Removes all [Record_load] packages from the list of recordings. 275 + This forces that the packages are loaded again. 276 + *)
+114
vendor/opam/ocamlfind/src/findlib/findlib_config.mlp
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + open Fl_compat 6 + 7 + let ( / ) = Filename.concat 8 + 9 + let exists path = 10 + match Sys.file_exists path with 11 + | true -> Some path 12 + | false -> None 13 + 14 + let findlib_conf_of_path path = 15 + match exists (path / "etc" / "findlib.conf") with 16 + | Some etc_path -> etc_path 17 + | None -> path / "lib" / "findlib.conf" 18 + 19 + let install_dir_from_binary path = 20 + let exe_dir = Filename.dirname path in 21 + let install_dir = Filename.dirname exe_dir in 22 + let config_path = findlib_conf_of_path install_dir in 23 + match Sys.file_exists config_path with 24 + | true -> Some install_dir 25 + | false -> None 26 + ;; 27 + 28 + let find_in_path name = 29 + match Sys.getenv_opt "PATH" with 30 + | None -> None 31 + | Some search_in -> ( 32 + let paths = String.split_on_char Fl_split.path_separator search_in in 33 + match List.find_map (fun path -> path / name |> exists) paths with 34 + | None -> None 35 + | Some location -> install_dir_from_binary location) 36 + ;; 37 + 38 + let install_dir_from_ld_library_path paths = 39 + String.split_on_char Fl_split.path_separator paths 40 + |> List.find_map (fun path -> 41 + let parent = Filename.dirname path in 42 + let parent' = Filename.dirname parent in 43 + match Sys.file_exists (findlib_conf_of_path parent') with 44 + | true -> Some parent' 45 + | false -> None) 46 + ;; 47 + 48 + let install_dir_from_ocaml_toplevel_path = install_dir_from_binary 49 + 50 + let install_dir_from_opam_switch_prefix path = 51 + match Sys.file_exists (findlib_conf_of_path path) with 52 + | false -> None 53 + | true -> Some path 54 + 55 + let default = "@CONFIGFILE@" 56 + let fallback = Option.value ~default 57 + 58 + let rec try_vars = function 59 + | [] -> None 60 + | (var, mapper)::xs -> ( 61 + match Sys.getenv_opt var with 62 + | None -> try_vars xs 63 + | Some content -> ( 64 + match mapper content with 65 + | None -> try_vars xs 66 + | Some _ as found -> found)) 67 + 68 + (* exposed condfigure-time setting *) 69 + let uses_relative_paths = @RELATIVE_PATHS@ 70 + 71 + (* the location where we assume to be installed in *) 72 + let location = lazy ( 73 + try_vars [ 74 + ("OPAM_SWITCH_PREFIX", install_dir_from_opam_switch_prefix); 75 + ("CAML_LD_LIBRARY_PATH", install_dir_from_ld_library_path); 76 + ("OCAML_TOPLEVEL_PATH", install_dir_from_ocaml_toplevel_path); 77 + ]) 78 + 79 + let findlib_conf = lazy ( 80 + match Lazy.force location with 81 + | None -> default 82 + | Some location -> location 83 + |> findlib_conf_of_path 84 + |> exists 85 + |> fallback) 86 + 87 + let config_file = lazy ( 88 + match uses_relative_paths with 89 + | false -> default 90 + | true -> Lazy.force findlib_conf) 91 + 92 + let ocaml_has_meta_files = 93 + let ocaml_major = 94 + String.sub Sys.ocaml_version 0 (String.index Sys.ocaml_version '.') in 95 + int_of_string ocaml_major >= 5;; 96 + 97 + let ocaml_stdlib = "@STDLIB@";; 98 + 99 + let ocaml_ldconf = ocaml_stdlib / "ld.conf";; 100 + 101 + let ocaml_has_autolinking = @AUTOLINK@;; 102 + 103 + let libexec_name = "stublibs";; 104 + 105 + let system = "@SYSTEM@";; 106 + (* - "mingw", "mingw64", "win32", "cygwin", "linux_elf", ... *) 107 + 108 + let dll_suffix = 109 + match Sys.os_type with 110 + | "Unix" | "BeOS" -> ".so" 111 + | "Win32" | "Cygwin" -> ".dll" 112 + | "MacOS" -> "" (* don't know *) 113 + | _ -> failwith "Unknown Sys.os_type" 114 + ;;
+104
vendor/opam/ocamlfind/src/findlib/fl_args.ml
··· 1 + (* $Id$ *) 2 + 3 + (* Rewrite a list of arguments args (from Sys.args) so that contracted 4 + options like -L<arg> are transformed to -L <arg>, and become parseable 5 + by Arg. 6 + *) 7 + 8 + let make_ht (l:string list) = 9 + let ht = Hashtbl.create 10 in 10 + List.iter (fun x -> Hashtbl.add ht x ()) l; 11 + ht 12 + 13 + let is_prefix s1 s2 = 14 + let l1 = String.length s1 in 15 + let l2 = String.length s2 in 16 + l2 >= l1 && String.sub s2 0 l1 = s1 17 + 18 + let rewrite_contracted_args spec contracted_opts args = 19 + let args = Array.to_list args in 20 + let switches = 21 + List.map 22 + (fun (name,kind,text) -> name) 23 + (List.filter 24 + (fun (name,kind,text) -> 25 + match kind with 26 + | Arg.Unit _ 27 + | Arg.Set _ 28 + | Arg.Clear _ -> true 29 + | Arg.Tuple _ -> 30 + failwith 31 + "Fl_args.rewrite_for_contracted_args: Arg.Tuple unsupported" 32 + | _ -> false 33 + ) 34 + spec 35 + ) in 36 + let unary_opts = 37 + List.map 38 + (fun (name,kind,text) -> name) 39 + (List.filter 40 + (fun (name,kind,text) -> 41 + match kind with 42 + | Arg.String _ 43 + | Arg.Set_string _ 44 + | Arg.Int _ 45 + | Arg.Set_int _ 46 + | Arg.Float _ 47 + | Arg.Set_float _ -> true 48 + | _ -> false 49 + ) 50 + spec 51 + ) in 52 + let rest_opts = 53 + List.map 54 + (fun (name,kind,text) -> name) 55 + (List.filter 56 + (fun (name,kind,text) -> 57 + match kind with 58 + | Arg.Rest _ -> true 59 + | _ -> false 60 + ) 61 + spec 62 + ) in 63 + 64 + let sw_ht = make_ht switches in 65 + let unary_ht = make_ht unary_opts in 66 + let rest_ht = make_ht rest_opts in 67 + 68 + let rec rewrite (args:string list) = 69 + match args with 70 + | arg :: args_rest when Hashtbl.mem sw_ht arg -> 71 + arg :: rewrite args_rest 72 + | arg :: args_rest when Hashtbl.mem rest_ht arg -> 73 + args 74 + | arg1 :: arg2 :: args_rest when Hashtbl.mem unary_ht arg1 -> 75 + arg1 :: arg2 :: rewrite args_rest 76 + | arg :: args_rest -> 77 + ( try 78 + let args1 = expand arg contracted_opts in 79 + let args2 = rewrite args_rest in 80 + args1 @ args2 81 + with 82 + | Not_found -> 83 + arg :: rewrite args_rest 84 + ) 85 + | [] -> 86 + [] 87 + 88 + and expand arg olo = 89 + match olo with 90 + | olo1 :: olo_rest -> 91 + if is_prefix olo1 arg then 92 + let p = String.length olo1 in 93 + let l = String.length arg in 94 + [ olo1; 95 + String.sub arg p (l-p) 96 + ] 97 + else 98 + expand arg olo_rest 99 + | [] -> 100 + raise Not_found 101 + 102 + in 103 + 104 + Array.of_list (rewrite args)
+59
vendor/opam/ocamlfind/src/findlib/fl_compat.ml
··· 1 + let ( |> ) x f = f x 2 + 3 + module String = struct 4 + let split_on_char sep s = 5 + let r = ref [] in 6 + let j = ref (String.length s) in 7 + for i = String.length s - 1 downto 0 do 8 + if String.unsafe_get s i = sep then begin 9 + r := String.sub s (i + 1) (!j - i - 1) :: !r; 10 + j := i 11 + end 12 + done; 13 + String.sub s 0 !j :: !r 14 + 15 + let starts_with ~prefix s = 16 + let len_s = String.length s 17 + and len_pre = String.length prefix in 18 + let rec aux i = 19 + if i = len_pre then true 20 + else if String.unsafe_get s i <> String.unsafe_get prefix i then false 21 + else aux (i + 1) 22 + in len_s >= len_pre && aux 0 23 + 24 + include String 25 + end 26 + 27 + module List = struct 28 + let rec find_map f = function 29 + | [] -> None 30 + | x :: l -> 31 + begin match f x with 32 + | Some _ as result -> result 33 + | None -> find_map f l 34 + end 35 + 36 + let rec filter_map f = function 37 + | [] -> [] 38 + | x :: l -> ( 39 + match f x with 40 + | None -> filter_map f l 41 + | Some v -> v :: filter_map f l) 42 + 43 + include List 44 + end 45 + 46 + module Option = struct 47 + let value o ~default = match o with Some v -> v | None -> default 48 + 49 + (* can't include Option because it was only introduced in 4.08 *) 50 + (* include Option *) 51 + end 52 + 53 + module Sys = struct 54 + let getenv_opt s = 55 + try Some (Sys.getenv s) 56 + with Not_found -> None 57 + 58 + include Sys 59 + end
+55
vendor/opam/ocamlfind/src/findlib/fl_dynload.ml
··· 1 + (* $Id$ *) 2 + 3 + (* Utilities for loading dynamically packages *) 4 + 5 + open Printf 6 + 7 + let load_pkg ~debug ~loadfile pkg = 8 + if not (Findlib.is_recorded_package pkg) then ( 9 + if debug then 10 + eprintf "[DEBUG] Fl_dynload: about to load: %s\n%!" pkg; 11 + (* Determine the package directory: *) 12 + let d = Findlib.package_directory pkg in 13 + (* First try the new "plugin" variable: *) 14 + let preds = Findlib.recorded_predicates() in 15 + let archive = 16 + try 17 + Findlib.package_property preds pkg "plugin" 18 + with 19 + | Not_found -> 20 + (* Legacy: use "archive" but require that the predicate 21 + "plugin" is mentioned in the definition 22 + *) 23 + try 24 + let v, fpreds = 25 + Findlib.package_property_2 ("plugin"::preds) pkg "archive" in 26 + let need_plugin = 27 + List.mem "native" preds in 28 + if need_plugin && not (List.mem (`Pred "plugin") fpreds) then 29 + "" 30 + else 31 + v 32 + with Not_found -> "" in 33 + (* Split the plugin/archive property and resolve the files: *) 34 + let files = Fl_split.in_words archive in 35 + if debug then 36 + eprintf "[DEBUG] Fl_dynload: files=%S\n%!" archive; 37 + List.iter 38 + (fun file -> 39 + if debug then 40 + eprintf "[DEBUG] Fl_dynload: loading %S\n%!" file; 41 + let file = Findlib.resolve_path ~base:d file in 42 + loadfile file 43 + ) files; 44 + Findlib.record_package Findlib.Record_load pkg 45 + ) 46 + else 47 + if debug then 48 + eprintf "[DEBUG] Fl_dynload: not loading: %s\n%!" pkg 49 + 50 + 51 + let load_packages ?(debug=false) ?(loadfile=Dynlink.loadfile) pkgs = 52 + let preds = Findlib.recorded_predicates() in 53 + let eff_pkglist = 54 + Findlib.package_deep_ancestors preds pkgs in 55 + List.iter (load_pkg ~debug ~loadfile) eff_pkglist
+37
vendor/opam/ocamlfind/src/findlib/fl_dynload.mli
··· 1 + (* $Id$ *) 2 + 3 + (** Utilities for loading dynamically packages *) 4 + 5 + val load_packages : ?debug:bool -> ?loadfile:(string -> unit) -> string list -> unit 6 + (** Load the given packages and all their dependencies dynamically. Packages 7 + already loaded or already in-core are not loaded again. The predicates 8 + are taken from {!Findlib.recorded_predicates}, which are normally the 9 + predicates from the link-time of the executable. 10 + 11 + In order to initialize this module correctly, you need to link the 12 + executable in a special way. This is done by including "findlib.dynload" 13 + in the [ocamlfind] command, e.g. 14 + 15 + {[ ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg m.ml ]} 16 + 17 + It is not sufficient to just link [findlib_dynload.cm(x)a] into the 18 + executable. The above command adds special initialization code that 19 + (a) records the predicates and (b) records the packages already present 20 + in the executable. Also [-linkall] is implicitly added. 21 + 22 + The dynamic package loader works both for bytecode and native code. 23 + The META files of the packages need to specify the cma or cmxs files 24 + in the following way: 25 + 26 + - First, the "plugin" variable is checked (instead of "archive"), e.g. 27 + {[ 28 + plugin(byte) = "my_plugin.cma" 29 + plugin(native) = "my_plugin.cmxs" 30 + ]} 31 + This is the preferred style. 32 + - Second, for bytecode only, the normal "archive" variable is 33 + also accepted if "plugin" is not present. (Because bytecode archives 34 + can normally be dynamically loaded without special preparation.) 35 + - Third, for native-code only, the "archive(plugin)" variable 36 + is also accepted. This is for legacy packages. 37 + *)
+113
vendor/opam/ocamlfind/src/findlib/fl_lint.ml
··· 1 + (* $Id$ -*- tuareg -*- 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + open Fl_metascanner 7 + 8 + module Have = struct 9 + module T = struct 10 + type mode = [`Byte | `Native | `Toploop | `Preprocessor | `Ppx_driver] 11 + type t = [ 12 + `Mode of [ `TooMany | `None] 13 + (** problem in the number of mode (byte,native,syntax,...) 14 + in the variable *) 15 + | `Archive of [`Plugin|`NoPlugin] * mode 16 + (** archive(plugin,...) or archive(...)) *) 17 + | `Plugin of [`Plugin|`NoPlugin] * mode 18 + (** plugin(...) *) 19 + | `Description 20 + | `Requires 21 + | `Version 22 + ] 23 + let compare = compare 24 + end 25 + include T 26 + module Set = Set.Make(T) 27 + module Map = Map.Make(T) 28 + end 29 + 30 + let scan_def acc def = 31 + let add have = Have.Map.add have def acc in 32 + let has_plugin_pred = List.mem (`Pred "plugin") def.def_preds in 33 + let plugin = if has_plugin_pred then `Plugin else `NoPlugin in 34 + let modes = [ "byte", `Byte; 35 + "native", `Native; 36 + "toploop", `Toploop; 37 + "preprocessor", `Preprocessor; 38 + "ppx_driver", `Ppx_driver 39 + ] in 40 + let modes = 41 + List.filter 42 + (fun (p,_) -> List.mem (`Pred p) def.def_preds) 43 + modes 44 + in 45 + let modes = List.map snd modes in 46 + match def.def_var, modes with 47 + (** For archive the modes are used in multiple ways, so we can't 48 + check exhaustiveness or presence. 49 + *) 50 + | "plugin", [] -> add (`Mode(`None)) 51 + | "plugin", _::_::_ -> add (`Mode(`TooMany)) 52 + 53 + | "archive", [mode] -> add (`Archive(plugin,mode)) 54 + | "plugin", [mode] -> add (`Plugin(plugin,mode)) 55 + | "description", _ -> add `Description 56 + | "requires", _ -> add `Requires 57 + | "version", _ -> add `Version 58 + | _ -> acc 59 + 60 + 61 + let warn_def ~warned pkg = 62 + let haves = 63 + List.fold_left scan_def Have.Map.empty pkg.pkg_defs 64 + in 65 + let mem x = Have.Map.mem x haves in 66 + let find x = Have.Map.find x haves in 67 + let warning fmt = warned := true; Printf.printf fmt in 68 + let if_ ?has ?(has_not=[]) msg = 69 + match has, has_not with 70 + | Some has, [] when mem has -> 71 + warning "%a%s\n\n" print_def (find has) msg; 72 + | Some has, has_not when mem has && not (List.exists mem has_not) -> 73 + warning "%a%s\n\n" print_def (find has) msg; 74 + | None, has_not when not (List.exists mem has_not) -> 75 + warning "%s\n\n" msg; 76 + | _ -> () 77 + in 78 + if_ ~has_not:[`Description] 79 + "You should add a description."; 80 + if_ ~has_not:[`Version] 81 + "You should add a version."; 82 + if_ ~has_not:[`Requires] 83 + "You should add the required libraries. You can silent this \ 84 + warning by using the empty string."; 85 + if_ ~has:(`Mode(`TooMany)) 86 + "This variable should have only one mode 87 + (\"byte\", \"native\")."; 88 + if_ ~has:(`Mode(`None)) 89 + "This variable should have at least the predicate \ 90 + \"byte\" or \"native\"."; 91 + let with_mode mode = 92 + if_ ~has:(`Plugin (`Plugin,mode)) 93 + "You must not add the predicate \"plugin\" to the variable \ 94 + \"plugin\"."; 95 + if_ ~has:(`Archive (`Plugin,mode)) ~has_not:[`Plugin (`NoPlugin,mode)] 96 + "This specification of dynamic loading is deprecated, you should add a \ 97 + \"plugin(...)\" variable."; 98 + if_ ~has:(`Archive (`NoPlugin,mode)) 99 + ~has_not:[`Plugin (`NoPlugin,mode);`Archive (`Plugin,mode)] 100 + "This variable indicates how to link statically, you should add a \ 101 + \"plugin(...)\" variable for linking dynamically."; 102 + in 103 + with_mode `Byte; 104 + with_mode `Native 105 + 106 + let warn pkg = 107 + let warned = ref false in 108 + let rec aux pkg = 109 + warn_def ~warned pkg; 110 + List.iter (fun (_,pkg) -> aux pkg) pkg.pkg_children; 111 + in 112 + aux pkg; 113 + !warned
+90
vendor/opam/ocamlfind/src/findlib/fl_meta.mll
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + { open Fl_metatoken } 7 + 8 + rule token = 9 + parse [ 'A'-'Z' 'a'-'z' '_' '0'-'9' '.' ]+ 10 + { 11 + Name (Lexing.lexeme lexbuf) 12 + } 13 + 14 + | '(' 15 + { 16 + LParen 17 + } 18 + 19 + | ')' 20 + { 21 + RParen 22 + } 23 + 24 + | "+=" 25 + { 26 + PlusEqual 27 + } 28 + 29 + | '=' 30 + { 31 + Equal 32 + } 33 + 34 + | '-' 35 + { 36 + Minus 37 + } 38 + 39 + | ',' 40 + { 41 + Comma 42 + } 43 + 44 + | '"' [^ '"' '\\' ]* ( ( "\\\\" | "\\\"" ) [^ '"' '\\' ]* )* '"' 45 + { 46 + let s1 = Lexing.lexeme lexbuf in 47 + let s2 = String.sub s1 1 (String.length s1 - 2) in 48 + let l2 = String.length s2 in 49 + let b = Buffer.create 80 in 50 + let rec fill i = 51 + if i<l2 then 52 + match s2.[i] with 53 + | '\\' -> Buffer.add_char b s2.[i+1]; fill (i+2) 54 + | c -> Buffer.add_char b c; fill (i+1) in 55 + fill 0; 56 + String (Buffer.contents b) 57 + } 58 + 59 + | [ ' ' '\t' '\r' ] 60 + { 61 + Space 62 + } 63 + 64 + | '\n' 65 + { 66 + Newline 67 + } 68 + 69 + | '#' [^ '\n']* '\n' 70 + { 71 + Newline 72 + } 73 + 74 + | '#' [^ '\n']* eof 75 + { 76 + Eof 77 + } 78 + 79 + | eof 80 + { 81 + Eof 82 + } 83 + 84 + | _ 85 + { 86 + Unknown 87 + } 88 + 89 + {} 90 +
+310
vendor/opam/ocamlfind/src/findlib/fl_metascanner.ml
··· 1 + (* $Id$ -*- tuareg -*- 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + open Fl_metatoken 6 + 7 + open Printf 8 + 9 + type formal_pred = [ | `Pred of string | `NegPred of string ] 10 + 11 + type flavour = [ | `BaseDef | `Appendix ] 12 + 13 + type pkg_definition = 14 + { def_var : string; def_flav : flavour; def_preds : formal_pred list; 15 + def_value : string 16 + } 17 + 18 + type pkg_expr = 19 + { pkg_defs : pkg_definition list; pkg_children : (string * pkg_expr) list 20 + } 21 + 22 + exception Error of string 23 + 24 + let string_of_preds pl = 25 + let print = function | `Pred n -> n | `NegPred n -> "-" ^ n 26 + in 27 + if pl = [] 28 + then "" 29 + else "(" ^ ((String.concat "," (List.map print pl)) ^ ")") 30 + 31 + 32 + let scan_lexing buf = 33 + (* transform an in_channel to a token stream; 'Space' tokens are left 34 + * out. 35 + *) 36 + let (line_ref, pos0_ref, eof_found) = ((ref 1), (ref 0), (ref false)) 37 + in 38 + fun () -> 39 + let rec next line pos0 = 40 + let t = Fl_meta.token buf 41 + in 42 + match t with 43 + | Space -> next line pos0 44 + | Newline -> next (line + 1) (Lexing.lexeme_end buf) 45 + | Eof -> (eof_found := true; produce line pos0 Eof) 46 + | _ -> produce line pos0 t 47 + and produce line pos0 t = 48 + (line_ref := line; 49 + pos0_ref := pos0; 50 + let pos = (Lexing.lexeme_start buf) - pos0 in (line, pos, t)) 51 + in 52 + if !eof_found 53 + then produce !line_ref !pos0_ref Eof 54 + else next !line_ref !pos0_ref 55 + 56 + let scan ch = scan_lexing (Lexing.from_channel ch) 57 + 58 + let parse_lexing lexbuf = 59 + let rec mk_set l = 60 + match l with 61 + | x :: l' -> if List.mem x l' then mk_set l' else x :: (mk_set l') 62 + | [] -> [] in 63 + let error_msg msg line col = 64 + Printf.sprintf "%s at line %d position %d" msg line col in 65 + let next_token = scan_lexing lexbuf in 66 + let raise_err error_fun line col = 67 + raise (Error (error_fun line col)) in 68 + let get_tok test error_fun = 69 + let (line, col, tok) = next_token () 70 + in 71 + match test tok with 72 + | None -> raise_err error_fun line col 73 + | Some result -> result in 74 + let get_rule rule arg error_fmt line col = 75 + try rule arg with | Error _ -> raise_err error_fmt line col in 76 + let rec parse_all need_rparen = 77 + match next_token () with 78 + | (line, col, Name "package") -> 79 + let n = 80 + get_tok string_tok 81 + (error_msg "String literal expected after 'package'") in 82 + let () = 83 + get_tok (const_tok LParen) (error_msg "'(' expected after string") in 84 + let subpkg = 85 + get_rule parse_all true 86 + (error_msg "Error in subpackage definition") line col in 87 + let rest = parse_all need_rparen 88 + in 89 + { 90 + pkg_defs = rest.pkg_defs; 91 + pkg_children = (n, subpkg) :: rest.pkg_children; 92 + } 93 + | (line, col, Name n) -> 94 + let (args, flav, value) = 95 + get_rule parse_properties () 96 + (error_msg "Error in 'name = value' clause") line col in 97 + let rest = parse_all need_rparen in (* TODO: Check args *) 98 + let args' = List.sort compare (mk_set args) in 99 + let def = 100 + { 101 + def_var = n; 102 + def_flav = flav; 103 + def_preds = args'; 104 + def_value = value; 105 + } 106 + in 107 + { 108 + pkg_defs = def :: rest.pkg_defs; 109 + pkg_children = rest.pkg_children; 110 + } 111 + | (line, col, Eof) -> 112 + (if need_rparen 113 + then 114 + raise_err 115 + (Printf.sprintf "Unexpected end of file in line %d position %d") 116 + line col 117 + else (); 118 + { pkg_defs = []; pkg_children = []; }) 119 + | (line, col, RParen) -> 120 + (if not need_rparen 121 + then 122 + raise_err 123 + (Printf.sprintf "Unexpected end of file in line %d position %d") 124 + line col 125 + else (); 126 + { pkg_defs = []; pkg_children = []; }) 127 + | (line, col, _) -> 128 + raise_err (error_msg "Expected 'name = value' clause") line col 129 + and parse_properties () = 130 + match next_token () with 131 + | (line, col, LParen) -> 132 + let arg1 = parse_argument () in 133 + let args = parse_arguments () in 134 + let flav = parse_flavour () in 135 + let s = 136 + get_tok string_tok (error_msg "Expected string constant after '='") 137 + in ((arg1 :: args), flav, s) 138 + | (line, col, Equal) -> 139 + let s = 140 + get_tok string_tok 141 + (error_msg "'=' must be followed by a string constant") 142 + in ([], `BaseDef, s) 143 + | (line, col, PlusEqual) -> 144 + let s = 145 + get_tok string_tok 146 + (error_msg "'+=' must be followed by a string constant") 147 + in ([], `Appendix, s) 148 + | (line, col, _) -> 149 + raise_err (error_msg "Expected a '=' or a '(arguments,...)=' clause") 150 + line col 151 + and parse_arguments () = 152 + match next_token () with 153 + | (line, col, Comma) -> 154 + let arg = parse_argument () in 155 + let args = parse_arguments () in arg :: args 156 + | (_, _, RParen) -> [] 157 + | (line, col, _) -> 158 + raise_err (error_msg "Another predicate or a ')' expected") line col 159 + and parse_argument () = 160 + match next_token () with 161 + | (line, col, Name n) -> `Pred n 162 + | (line, col, Minus) -> 163 + let n = get_tok name_tok (error_msg "Name expected after '-'") 164 + in `NegPred n 165 + | (line, col, _) -> 166 + raise_err (error_msg "Name or -Name expected") line col 167 + and parse_flavour () = 168 + match next_token () with 169 + | (line, col, Equal) -> `BaseDef 170 + | (line, col, PlusEqual) -> `Appendix 171 + | (line, col, _) -> raise_err (error_msg "'+' or '+=' expected") line col in 172 + let rec check_defs p l = 173 + match l with 174 + | [] -> () 175 + | def :: l' -> 176 + (List.iter 177 + (fun def' -> 178 + if 179 + (def.def_var = def'.def_var) && 180 + ((def.def_preds = def'.def_preds) && 181 + ((def.def_flav = `BaseDef) && (def'.def_flav = `BaseDef))) 182 + then 183 + (let prefix = 184 + if p = "" then "" else "In subpackage " ^ (p ^ ": ") in 185 + let args = string_of_preds def.def_preds 186 + in 187 + raise 188 + (Error 189 + (prefix ^ 190 + ("Double definition of '" ^ 191 + (def.def_var ^ (args ^ "'")))))) 192 + else ()) 193 + l'; 194 + check_defs p l') in 195 + let rec check_pkg p pkg = 196 + (check_defs p pkg.pkg_defs; 197 + let l = ref [] 198 + in 199 + List.iter 200 + (fun (n, subpkg) -> 201 + let p' = if p = "" then n else p ^ ("." ^ n) 202 + in 203 + (if List.mem n !l 204 + then 205 + raise 206 + (Error ("Double definition for subpackage " ^ p')) 207 + else (); 208 + if String.contains n '.' 209 + then 210 + raise 211 + (Error 212 + ("Subpackage name must not contain '.': \"" ^ 213 + (n ^ "\""))) 214 + else (); 215 + check_pkg p' subpkg; 216 + l := n :: !l)) 217 + pkg.pkg_children) 218 + in 219 + try let pkg = parse_all false in (check_pkg "" pkg; pkg) 220 + with | Error "" -> raise (Error "Syntax Error") 221 + 222 + let parse ch = parse_lexing (Lexing.from_channel ch) 223 + 224 + let escape s = (* no Str available :-( *) 225 + let b = Buffer.create (String.length s) 226 + in 227 + (for k = 0 to (String.length s) - 1 do 228 + (match s.[k] with 229 + | '\\' -> Buffer.add_string b "\\\\" 230 + | '"' -> Buffer.add_string b "\\\"" 231 + | c -> Buffer.add_char b c) 232 + done; 233 + Buffer.contents b) 234 + 235 + let print_def f def = 236 + let format_pred = function | `Pred s -> s | `NegPred s -> "-" ^ s in 237 + fprintf f "%s%s %s \"%s\"\n" def.def_var 238 + (match def.def_preds with 239 + | [] -> "" 240 + | l -> "(" ^ ((String.concat "," (List.map format_pred l)) ^ ")")) 241 + (match def.def_flav with | `BaseDef -> "=" | `Appendix -> "+=") 242 + (escape def.def_value) 243 + 244 + 245 + let rec print f pkg = 246 + (List.iter (print_def f) pkg.pkg_defs; 247 + List.iter 248 + (fun (name, child) -> 249 + (fprintf f "\npackage \"%s\" (\n" (escape name); 250 + print f child; 251 + fprintf f ")\n")) 252 + pkg.pkg_children) 253 + 254 + let rec remove_dups l = 255 + (* FIXME: O(n^2) *) 256 + match l with 257 + x :: l' -> 258 + if List.mem x l' then remove_dups l' else x::remove_dups l' 259 + | [] -> [] 260 + 261 + let lookup_2 name predicate_list def = 262 + let fulfills actual_preds formal_preds = 263 + List.for_all 264 + (function 265 + | `Pred n -> List.mem n predicate_list 266 + | `NegPred n -> not (List.mem n predicate_list)) 267 + formal_preds in 268 + let rec search_base best_n best_value l = 269 + match l with 270 + | [] -> if best_n >= 0 then best_value else raise Not_found 271 + | def :: l' -> 272 + if 273 + (name = def.def_var) && 274 + ((def.def_flav = `BaseDef) && 275 + ((fulfills predicate_list def.def_preds) && 276 + ((List.length def.def_preds) > best_n))) 277 + then search_base 278 + (List.length def.def_preds) 279 + (def.def_value, def.def_preds) 280 + l' 281 + else search_base best_n best_value l' in 282 + let rec search_appdx l = 283 + match l with 284 + | [] -> [] 285 + | def :: l' -> 286 + if 287 + (name = def.def_var) && 288 + ((def.def_flav = `Appendix) && 289 + (fulfills predicate_list def.def_preds)) 290 + then (def.def_value, def.def_preds) :: (search_appdx l') 291 + else search_appdx l' in 292 + let value_a, preds_a = search_base (-1) ("",[]) def in 293 + let additions = search_appdx def in 294 + let values_b = List.map fst additions in 295 + let preds_b = List.flatten (List.map snd additions) in 296 + let value = String.concat " " (value_a :: values_b) in 297 + let preds = remove_dups (preds_a @ preds_b) in 298 + (value, preds) 299 + 300 + let lookup name predicate_list def = 301 + fst(lookup_2 name predicate_list def) 302 + 303 + let predicate_exists p defs = 304 + List.exists 305 + (fun def -> 306 + List.exists (function | `Pred n -> n = p | `NegPred n -> n = p) 307 + def.def_preds) 308 + defs 309 + 310 +
+107
vendor/opam/ocamlfind/src/findlib/fl_metascanner.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** Parses META files *) 7 + 8 + open Fl_metatoken 9 + 10 + type formal_pred = 11 + [ `Pred of string (** Positive occurrence of a formal predicate var *) 12 + | `NegPred of string (** Negative occurrence of a formal predicate var *) 13 + ] 14 + 15 + type flavour = 16 + [ `BaseDef 17 + | `Appendix 18 + ] 19 + (** [`BaseDef] refers to META definitions using the "=" operator, 20 + * and [`Appendix] refers to definitions using the "+=" operator. 21 + *) 22 + 23 + type pkg_definition = 24 + { def_var : string; (** The name of the defined variable *) 25 + def_flav : flavour; (** The flavour of the definition *) 26 + def_preds : formal_pred list; (** The formal predicates of the def *) 27 + def_value : string; (** The value assigned to the variable *) 28 + } 29 + (** A [pkg_definition] is expressed by the syntax 30 + * {[ var(p1,p2,...) = "value" ]} (flavour `BaseDef), 31 + * or the syntax 32 + * {[ var(p1,p2,...) += "value" ]} (flavour `Appendix) 33 + * in the META file. The list of predicates may be omitted. Predicates 34 + * may be negated by using "-", e.g. "-x". 35 + *) 36 + 37 + type pkg_expr = 38 + { pkg_defs : pkg_definition list; 39 + pkg_children : (string * pkg_expr) list; 40 + } 41 + (** A value of type [pkg_expr] denotes the contents of a META file. 42 + * The component [pkg_defs] are the variable definitions. 43 + * The component [pkg_children] contains 44 + * the definitions of the subpackages. 45 + *) 46 + 47 + exception Error of string 48 + 49 + 50 + val parse : in_channel -> pkg_expr 51 + (** [parse ch:] 52 + * scans and parses the file connected with channel [ch]. The file must 53 + * have a syntax compatible with the META format. The return value 54 + * contains the found definitions for the package and all subpackages. 55 + * 56 + * [exception Error of string:] is 57 + * raised on syntax errors. The string explains the error. 58 + *) 59 + 60 + val parse_lexing : Lexing.lexbuf -> pkg_expr 61 + 62 + 63 + val print_def : out_channel -> pkg_definition -> unit 64 + (** [print_def ch def]: 65 + * Outputs the definition to a channel. 66 + *) 67 + 68 + val print : out_channel -> pkg_expr -> unit 69 + (** [print ch expr]: 70 + * Outputs the package expression to a channel. 71 + *) 72 + 73 + 74 + val lookup : 75 + string -> string list -> pkg_definition list -> string 76 + (** [lookup variable_name predicate_list def]: 77 + * 78 + * Returns the value of [variable_name] in [def] under the assumption 79 + * that the predicates in [predicate_list] hold, but no other predicates. 80 + * 81 + * The rules are as follows: In the step (A), only the [`BaseDef] 82 + * definitions are considered. The first base definition is determined where 83 + * all predicates are satisfied and that has the longest predicate list. 84 + * In the step (B) only the [`Appendix] definitions are considered. 85 + * All definitions are determined where all predicates are satisfied. 86 + * The final result is the concatenation of the single result of (A) 87 + * and all results of (B) (in the order they are defined). A space 88 + * character is inserted between two concatenated strings. 89 + * 90 + * When step (A) does not find any matching definition, the exception 91 + * [Not_found] is raised. 92 + *) 93 + 94 + 95 + val lookup_2 : 96 + string -> string list -> pkg_definition list -> string * formal_pred list 97 + (** Like [lookup], but also returns the list of predicates that had to 98 + be considered to select the particular variable definition. 99 + *) 100 + 101 + 102 + val predicate_exists : 103 + string -> pkg_definition list -> bool 104 + (** [predicate_exists variable_name def]: 105 + 106 + Whether [variable_name] is explicitly mentioned in [def]. 107 + *)
+37
vendor/opam/ocamlfind/src/findlib/fl_metatoken.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + 7 + type token = 8 + Name of string 9 + | LParen 10 + | RParen 11 + | Equal 12 + | PlusEqual 13 + | Minus 14 + | Comma 15 + | String of string 16 + | Space 17 + | Newline 18 + | Eof 19 + | Unknown 20 + ;; 21 + 22 + 23 + let name_tok = function 24 + | Name s -> Some s 25 + | _ -> None 26 + 27 + let string_tok = function 28 + | String s -> Some s 29 + | _ -> None 30 + 31 + let const_tok constant tok = 32 + match constant with 33 + | Name _ | String _ -> failwith "expect: only for constant tokens" 34 + | LParen | RParen | Equal | PlusEqual | Minus 35 + | Comma | Space | Newline | Eof | Unknown -> 36 + if constant = tok then Some () 37 + else None
+723
vendor/opam/ocamlfind/src/findlib/fl_package_base.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + open Fl_metascanner 7 + 8 + exception No_such_package of string * string 9 + (* (name, reason) *) 10 + 11 + type package = 12 + { package_name : string; 13 + package_dir : string; 14 + package_meta : string; 15 + package_defs : Fl_metascanner.pkg_definition list; 16 + package_priv : package_priv 17 + } 18 + and package_priv = 19 + { mutable missing_reqs : (string * string) list; 20 + (* If non-empty the package is broken. This may be set by 21 + add_all_relations, and should be checked before using the 22 + package later. Each element corresponds to No_such_package. 23 + *) 24 + } 25 + ;; 26 + 27 + 28 + module Fl_metaentry = 29 + struct 30 + type t = package 31 + type id_t = string 32 + let id m = m.package_name 33 + end 34 + ;; 35 + 36 + 37 + module Fl_metastore = 38 + Fl_topo.Make(Fl_metaentry) 39 + ;; 40 + 41 + 42 + module StringSet = Set.Make(String);; 43 + 44 + 45 + let has_prefix s pref = 46 + String.length s >= String.length pref && 47 + String.sub s 0 (String.length pref) = pref 48 + ;; 49 + 50 + 51 + let ocamlpath = ref [];; 52 + let ocamlstdlib = ref "";; 53 + 54 + let conf_ignore_dups_in = ref ([] : string list) 55 + 56 + let store = Fl_metastore.create();; 57 + (* We collect here only nodes, but no relations. First copy [store] 58 + * and put relations into the copy. 59 + *) 60 + 61 + 62 + let init path stdlib ignore_dups_in = 63 + ocamlpath := path; 64 + ocamlstdlib := stdlib; 65 + conf_ignore_dups_in := ignore_dups_in 66 + ;; 67 + 68 + 69 + let packages_in_meta_file ?(directory_required = false) 70 + ~name:package_name ~dir:package_dir ~meta_file () = 71 + (* Parses the META file whose name is [meta_file]. In [package_name], the 72 + * name of the main package must be passed. [package_dir] is the 73 + * directory associated with the package by default (i.e. before 74 + * it is overridden by the "directory" directive). 75 + * 76 + * directory_required: If true, a "directory" directive is necessary. 77 + * 78 + * Returns the [package] records found in this file. The "directory" 79 + * directive is already applied. 80 + *) 81 + let rec flatten_meta pkg_name_prefix pkg_dir (pkg_name_component,pkg_expr) = 82 + (* Turns the recursive [pkg_expr] into a flat list of [package]s. 83 + * [pkg_dir] is the default package directory. [pkg_name_prefix] is 84 + * the name prefix to prepend to the fully qualified package name, or 85 + * "". [pkg_name_component] is the local package name. 86 + *) 87 + (* Determine the final package directory: *) 88 + let d = 89 + (* The value of "directory", or "" if not applicable *) 90 + try 91 + lookup "directory" [] pkg_expr.pkg_defs 92 + with 93 + Not_found -> 94 + if pkg_name_prefix="" && directory_required then 95 + failwith ("The `directory' directive is required in this META definition"); 96 + 97 + "" 98 + in 99 + let d' = 100 + if d = "" then 101 + pkg_dir 102 + else 103 + match d.[0] with 104 + | '^' 105 + | '+' -> 106 + let rest = String.sub d 1 (String.length d - 1) in 107 + if rest = "" then 108 + !ocamlstdlib 109 + else 110 + Filename.concat !ocamlstdlib rest 111 + | _ -> 112 + if Filename.is_relative d then 113 + Filename.concat pkg_dir d 114 + else 115 + d 116 + in 117 + let p_name = 118 + if pkg_name_prefix = "" then 119 + pkg_name_component 120 + else 121 + pkg_name_prefix ^ "." ^ pkg_name_component in 122 + let p = 123 + { package_name = p_name; 124 + package_dir = d'; 125 + package_meta = meta_file; 126 + package_defs = pkg_expr.pkg_defs; 127 + package_priv = { missing_reqs = [] } 128 + } in 129 + (* Check for exists_if: *) 130 + let p_exists = 131 + try 132 + let def = 133 + List.find (fun def -> def.def_var = "exists_if") p.package_defs in 134 + let files = Fl_split.in_words def.def_value in 135 + List.exists 136 + (fun file -> Sys.file_exists (Filename.concat d' file)) 137 + files 138 + with Not_found -> true in 139 + 140 + if p_exists then 141 + p :: (List.flatten 142 + (List.map (flatten_meta p_name d') pkg_expr.pkg_children)) 143 + else 144 + [] 145 + in 146 + 147 + let ch = open_in meta_file in 148 + try 149 + let pkg_expr = Fl_metascanner.parse ch in 150 + let packages = flatten_meta "" package_dir (package_name, pkg_expr) in 151 + close_in ch; 152 + packages 153 + with 154 + Failure s -> 155 + close_in ch; 156 + failwith ("While parsing '" ^ meta_file ^ "': " ^ s) 157 + | Fl_metascanner.Error s -> 158 + close_in ch; 159 + failwith ("While parsing '" ^ meta_file ^ "': " ^ s) 160 + | any -> 161 + close_in ch; 162 + raise any 163 + ;; 164 + 165 + 166 + let query package_name = 167 + 168 + let package_name_comps = Fl_split.package_name package_name in 169 + if package_name_comps = [] then invalid_arg "Fl_package_base.query"; 170 + let main_name = List.hd package_name_comps in 171 + 172 + let process_file_and_lookup ?directory_required package_dir meta_file = 173 + let packages = 174 + packages_in_meta_file 175 + ?directory_required ~name:main_name ~dir:package_dir ~meta_file () in 176 + let p = 177 + ( try 178 + List.find 179 + (fun p -> p.package_name = package_name) 180 + packages 181 + with 182 + Not_found -> 183 + raise (No_such_package (package_name, "")) 184 + ) in 185 + List.iter (Fl_metastore.add store) packages; 186 + p 187 + in 188 + 189 + let rec run_ocamlpath path = 190 + match path with 191 + [] -> raise(No_such_package(package_name, "")) 192 + | dir :: path' -> 193 + let package_dir = Filename.concat dir main_name in 194 + let meta_file_1 = Filename.concat package_dir "META" in 195 + let meta_file_2 = Filename.concat dir ("META." ^ main_name) in 196 + if Sys.file_exists meta_file_1 then 197 + process_file_and_lookup package_dir meta_file_1 198 + else 199 + if Sys.file_exists meta_file_2 then 200 + process_file_and_lookup ~directory_required:true dir meta_file_2 201 + (* Note: It is allowed to have relative "directory" directives. 202 + * The base directory is [dir] in this case. 203 + *) 204 + else 205 + run_ocamlpath path' 206 + in 207 + 208 + try 209 + Fl_metastore.find store package_name 210 + with 211 + Not_found -> 212 + run_ocamlpath !ocamlpath 213 + ;; 214 + 215 + 216 + exception Package_loop of string 217 + (* A package is required by itself. The arg is the name of the 218 + * package 219 + *) 220 + 221 + 222 + let fixup_thread_needed_1 predlist = 223 + (* When the thread fixup is required to apply, 1st criterion *) 224 + List.mem "mt" predlist 225 + ;; 226 + 227 + 228 + let fixup_thread_needed_2 pkg = 229 + (* When the thread fixup is required to apply, 2nd criterion *) 230 + (pkg <> "unix" && pkg <> "threads" && not (has_prefix pkg "threads.")) 231 + ;; 232 + 233 + 234 + let fixup_thread_base predlist pkg = 235 + (* Add the package "threads" if required *) 236 + if fixup_thread_needed_1 predlist && fixup_thread_needed_2 pkg then 237 + [ "threads" ] 238 + else 239 + [] 240 + ;; 241 + 242 + 243 + let query_requirements ~preds:predlist package_name = 244 + (* Part of [requires] implementation: Load all required packages, but 245 + * do not add relations 246 + *) 247 + let m = query package_name in 248 + (* may raise No_such_package *) 249 + let r = 250 + try Fl_metascanner.lookup "requires" predlist m.package_defs 251 + with Not_found -> "" 252 + in 253 + let ancestors = Fl_split.in_words r @ 254 + fixup_thread_base predlist package_name in 255 + List.iter 256 + (fun p -> 257 + try 258 + let _ = query p in (* may raise No_such_package *) 259 + () 260 + with 261 + No_such_package(pname,_) -> 262 + raise(No_such_package(pname, "required by `" ^ package_name ^ "'")) 263 + ) 264 + ancestors; 265 + ancestors 266 + ;; 267 + 268 + 269 + let add_relations s ancestors package_name = 270 + (* Part of [requires] implementation: Adds the relations from [package_name] 271 + * to [ancestors]. Target store is [s]. 272 + *) 273 + List.iter 274 + (fun p -> 275 + try 276 + Fl_metastore.let_le s p package_name (* add relation *) 277 + with 278 + | Fl_topo.Inconsistent_ordering -> 279 + raise(Package_loop p) 280 + | Not_found -> 281 + (* A relation to a package not part of [s]. We ignore it here. *) 282 + () 283 + ) 284 + ancestors 285 + ;; 286 + 287 + 288 + let add_all_relations preds s = 289 + (* Adds all relations for the packages currently defined in [s]. 290 + Note that missing requirements are not reported immediately (we do 291 + not know here which part of the graph [s] is really accessed), and 292 + instead the error is added to the missing_reqs field, where 293 + it should be checked before used. 294 + *) 295 + let pkgs = ref [] in 296 + Fl_metastore.iter_up 297 + (fun p -> pkgs := p :: !pkgs) 298 + s; 299 + 300 + List.iter 301 + (fun p -> 302 + let pkg = p.package_name in 303 + try 304 + let pkg_ancestors = query_requirements ~preds pkg in 305 + add_relations s pkg_ancestors pkg 306 + with 307 + | No_such_package(n,reason) -> 308 + p.package_priv.missing_reqs <- 309 + (n,reason) :: p.package_priv.missing_reqs 310 + ) 311 + !pkgs 312 + ;; 313 + 314 + 315 + let fixup_thread_deps s = 316 + (* All packages (except "threads", "threads.*", and "unix") are made 317 + * dependent on "threads" 318 + *) 319 + let pkgs = ref [] in 320 + Fl_metastore.iter_up 321 + (fun p -> pkgs := p.package_name :: !pkgs) 322 + s; 323 + 324 + List.iter 325 + (fun pkg -> 326 + if fixup_thread_needed_2 pkg then ( 327 + try 328 + Fl_metastore.let_le s "threads" pkg (* add relation *) 329 + with 330 + Not_found -> 331 + (* Because "threads" does not exist! Normally this is an 332 + * error, because "threads" is also magically added by 333 + * query_requirements. However, there are situations 334 + * where it cannot be expected that required packages 335 + * are loaded, so ignore this case. 336 + *) 337 + () 338 + ) 339 + ) 340 + !pkgs 341 + ;; 342 + 343 + 344 + let requires ~preds package_name = 345 + (* returns names of packages required by [package_name], the fully qualified 346 + * name of the package. It is checked that the packages really exist. 347 + * [preds]: list of true predicates 348 + * May raise [No_such_package] or [Package_loop]. 349 + *) 350 + let ancestors = query_requirements ~preds package_name in 351 + let store' = Fl_metastore.copy store in (* work with a copy *) 352 + add_relations store' ancestors package_name; 353 + if List.mem "mt" preds then fixup_thread_deps store'; 354 + ancestors 355 + ;; 356 + 357 + 358 + let requires_deeply ~preds package_list = 359 + (* returns names of packages required by the packages in [package_list], 360 + * either directly or indirectly. 361 + * It is checked that the packages really exist. 362 + * The list of names is sorted topologically; first comes the deepest 363 + * ancestor. 364 + * [preds]: list of true predicates 365 + * - raises [Not_found] if there is no 'package' 366 + * - raises [Failure] if some of the ancestors do not exist 367 + *) 368 + 369 + let pkgset = ref StringSet.empty in 370 + 371 + let rec query_packages pkglist = 372 + match pkglist with 373 + pkg :: pkglist' -> 374 + if not(StringSet.mem pkg !pkgset) then begin 375 + let pkg_ancestors = query_requirements ~preds pkg in 376 + pkgset := StringSet.add pkg !pkgset; 377 + query_packages pkg_ancestors 378 + end; 379 + query_packages pkglist' 380 + | [] -> 381 + () 382 + in 383 + 384 + (* First query for all packages, such that they are loaded: *) 385 + query_packages package_list; 386 + 387 + (* Now make a copy of the store, and add the relations: *) 388 + let store' = Fl_metastore.copy store in 389 + add_all_relations preds store'; 390 + if List.mem "mt" preds then fixup_thread_deps store'; 391 + 392 + (* Finally, iterate through the graph. Note that the graph may 393 + * contain more members than required, so we have to test explicitly 394 + * whether the packages are contained in pkgset. 395 + *) 396 + 397 + let l = ref [] in 398 + 399 + Fl_metastore.iter_up_at 400 + (fun m -> 401 + if StringSet.mem m.package_name !pkgset then ( 402 + if m.package_priv.missing_reqs <> [] then ( 403 + let (n,reason) = List.hd m.package_priv.missing_reqs in 404 + raise(No_such_package(n,reason)) 405 + ); 406 + l := m.package_name :: !l 407 + ) 408 + ) 409 + store' 410 + package_list; 411 + 412 + List.rev !l 413 + ;; 414 + 415 + 416 + (**********************************************************************) 417 + 418 + (* The following two functions do not use !ocamlpath, because there may 419 + * be duplicates in it. 420 + *) 421 + 422 + let package_definitions ~search_path package_name = 423 + (* Return all META files defining this [package_name] that occur in the 424 + * directories mentioned in [search_path] 425 + *) 426 + 427 + let package_name_comps = Fl_split.package_name package_name in 428 + if package_name_comps = [] then invalid_arg "Fl_package_base.package_definitions"; 429 + let main_name = List.hd package_name_comps in 430 + 431 + let rec run_ocamlpath path = 432 + match path with 433 + [] -> [] 434 + | dir :: path' -> 435 + let package_dir = Filename.concat dir main_name in 436 + let meta_file_1 = Filename.concat package_dir "META" in 437 + let meta_file_2 = Filename.concat dir ("META." ^ main_name) in 438 + if Sys.file_exists meta_file_1 then 439 + meta_file_1 :: run_ocamlpath path' 440 + else 441 + if Sys.file_exists meta_file_2 then 442 + meta_file_2 :: run_ocamlpath path' 443 + else 444 + run_ocamlpath path' 445 + in 446 + run_ocamlpath search_path 447 + ;; 448 + 449 + 450 + let in_report_search_path identify_dir d = 451 + (* Whether package dir d is to be considered for generating reports. 452 + d is sorted out when the ignore_dups_in option is set 453 + *) 454 + List.for_all 455 + (fun id -> 456 + try identify_dir d <> identify_dir id 457 + with _ -> Fl_split.norm_dir d <> Fl_split.norm_dir id 458 + ) 459 + !conf_ignore_dups_in 460 + ;; 461 + 462 + 463 + let package_conflict_report_1 identify_dir () = 464 + let remove_dups_from_path p = 465 + (* Removes directories which are physically the same from the path [p], 466 + * and returns the shortened path 467 + *) 468 + 469 + let dir_identity = Hashtbl.create 20 in 470 + 471 + let rec remove p = 472 + match p with 473 + d :: p' -> 474 + begin try 475 + let id = identify_dir d in (* may raise exceptions *) 476 + if Hashtbl.mem dir_identity id then 477 + remove p' 478 + else begin 479 + Hashtbl.add dir_identity id (); 480 + d :: (remove p') 481 + end 482 + with error -> 483 + (* Don't know anything, so the "directory" remains in the path *) 484 + d :: (remove p') 485 + end 486 + | [] -> 487 + [] 488 + in 489 + 490 + remove p 491 + in 492 + 493 + (* If we have ignore_dups_in this directory is removed from our search 494 + path first 495 + *) 496 + let search_path0 = 497 + List.filter (in_report_search_path identify_dir) !ocamlpath in 498 + 499 + (* Now eliminate all duplicates *) 500 + let search_path = 501 + remove_dups_from_path search_path0 in 502 + 503 + Fl_metastore.iter_up 504 + (fun pkg -> 505 + (* Check only main packages: *) 506 + let package_name_comps = Fl_split.package_name pkg.package_name in 507 + match package_name_comps with 508 + [_] -> 509 + (* pkg is a main package *) 510 + ( let c = package_definitions ~search_path pkg.package_name in 511 + match c with 512 + [] 513 + | [_] -> 514 + () 515 + | _ -> 516 + Printf.eprintf "findlib: [WARNING] Package %s has multiple definitions in %s\n" 517 + pkg.package_name 518 + (String.concat ", " c) 519 + ) 520 + | _ -> 521 + () 522 + ) 523 + store; 524 + flush stderr 525 + ;; 526 + 527 + 528 + let package_conflict_report ?identify_dir () = 529 + match identify_dir with 530 + None -> package_conflict_report_1 (fun s -> s) () 531 + | Some f -> package_conflict_report_1 f () 532 + ;; 533 + 534 + let check_prefix ?prefix f = 535 + match prefix with 536 + | None -> true 537 + | Some prefix -> 538 + let len = String.length prefix in 539 + String.length f >= len && String.sub f 0 len = prefix 540 + 541 + let load_base ?prefix () = 542 + (* Ensures that the cache is completely filled with every package 543 + * of the system that match prefix 544 + *) 545 + let list_directory d = 546 + try 547 + Array.to_list(Sys.readdir d) 548 + with 549 + Sys_error msg -> 550 + prerr_endline ("findlib: [WARNING] cannot read directory " ^ msg); 551 + [] 552 + in 553 + 554 + let process_file ?directory_required main_name package_dir meta_file = 555 + try 556 + let _ = Fl_metastore.find store main_name in 557 + (* Note: If the main package is already loaded into the graph, we 558 + * do not even look at the subpackages! 559 + *) 560 + () 561 + with 562 + Not_found -> 563 + let packages = 564 + try 565 + packages_in_meta_file 566 + ?directory_required ~name:main_name ~dir:package_dir ~meta_file () 567 + with 568 + Failure s -> 569 + prerr_endline ("findlib: [WARNING] " ^ s); [] 570 + in 571 + List.iter (Fl_metastore.add store) packages; 572 + (* Nothing evil can happen! *) 573 + in 574 + 575 + let rec run_ocamlpath path = 576 + match path with 577 + [] -> () 578 + | dir :: path' -> 579 + let files = list_directory dir in 580 + List.iter 581 + (fun f -> 582 + if check_prefix ?prefix f 583 + then 584 + (* If f/META exists: Add package f *) 585 + let package_dir = Filename.concat dir f in 586 + let meta_file_1 = Filename.concat package_dir "META" in 587 + if Sys.file_exists meta_file_1 then 588 + process_file f package_dir meta_file_1 589 + else 590 + (* If f is META.pkgname: Add package pkgname *) 591 + (* We skip over filenames ending in '~' *) 592 + if String.length f >= 6 && String.sub f 0 5 = "META." && 593 + String.sub f (String.length f - 1) 1 <> "~" then begin 594 + let name = String.sub f 5 (String.length f - 5) in 595 + let meta_file_2 = Filename.concat dir f in 596 + process_file ~directory_required:true name dir meta_file_2 597 + end; 598 + ) 599 + files; 600 + run_ocamlpath path' 601 + in 602 + 603 + run_ocamlpath !ocamlpath 604 + ;; 605 + 606 + 607 + let list_packages ?prefix () = 608 + load_base ?prefix (); 609 + 610 + let l = ref [] in 611 + 612 + Fl_metastore.iter_up 613 + (fun m -> 614 + if check_prefix ?prefix m.package_name then 615 + l := m.package_name :: !l 616 + ) 617 + store; 618 + 619 + !l 620 + ;; 621 + 622 + 623 + let package_users ~preds pl = 624 + (* Check that all packages in [pl] really exist, or raise No_such_package: *) 625 + List.iter 626 + (fun p -> let _ = query p in ()) 627 + pl; 628 + load_base(); 629 + let store' = Fl_metastore.copy store in 630 + add_all_relations preds store'; 631 + if List.mem "mt" preds then fixup_thread_deps store'; 632 + 633 + let l = ref [] in 634 + 635 + Fl_metastore.iter_down_at 636 + (fun m -> 637 + if m.package_priv.missing_reqs <> [] then ( 638 + let (n,reason) = List.hd m.package_priv.missing_reqs in 639 + raise(No_such_package(n,reason)) 640 + ); 641 + l := m.package_name :: !l 642 + ) 643 + store' 644 + pl; 645 + 646 + !l 647 + ;; 648 + 649 + 650 + let module_conflict_report_1 identify_dir incpath = 651 + (* Find any *.cmi files occurring twice in incpath. 652 + *) 653 + let dir_of_module = Hashtbl.create 100 in 654 + let dirs = ref [] in 655 + 656 + let examine_dir d = 657 + try 658 + let d = Fl_split.norm_dir d in 659 + let d_id = identify_dir d in 660 + 661 + (* Is d new? *) 662 + if not (List.mem d_id !dirs) then begin 663 + dirs := d_id :: !dirs; 664 + (* Yes: Get all files ending in .cmi *) 665 + try 666 + let d_all = Array.to_list(Sys.readdir d) in (* or Sys_error *) 667 + let d_cmi = 668 + List.filter 669 + (fun n -> Filename.check_suffix n ".cmi") 670 + d_all in 671 + (* Add the modules to dir_of_module: *) 672 + List.iter 673 + (fun m -> 674 + try 675 + let entry = Hashtbl.find dir_of_module m in (* or Not_found *) 676 + entry := d :: !entry 677 + with 678 + Not_found -> 679 + Hashtbl.add dir_of_module m (ref [d]) 680 + ) 681 + d_cmi 682 + with 683 + Sys_error msg -> 684 + prerr_endline ("findlib: [WARNING] cannot read directory " ^ msg) 685 + end 686 + with 687 + | _ -> () (* identify_dir fails *) 688 + in 689 + 690 + let print_report() = 691 + Hashtbl.iter 692 + (fun m dlist -> 693 + match !dlist with 694 + [] 695 + | [_] -> 696 + () 697 + | _ -> 698 + Printf.eprintf "findlib: [WARNING] Interface %s occurs in several directories: %s\n" 699 + m 700 + (String.concat ", " !dlist) 701 + ) 702 + dir_of_module 703 + in 704 + 705 + (* If we have ignore_dups_in this directory is removed from our search 706 + path first 707 + *) 708 + let incpath1 = 709 + List.filter (in_report_search_path identify_dir) incpath in 710 + 711 + 712 + List.iter examine_dir incpath1; 713 + 714 + print_report(); 715 + flush stderr 716 + ;; 717 + 718 + 719 + let module_conflict_report ?identify_dir incpath = 720 + match identify_dir with 721 + None -> module_conflict_report_1 (fun s -> s) incpath 722 + | Some f -> module_conflict_report_1 f incpath 723 + ;;
+181
vendor/opam/ocamlfind/src/findlib/fl_package_base.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** Direct access to the package graph and package files *) 7 + 8 + type package = 9 + { package_name : string; 10 + (** The fully qualified package name, i.e. for subpackages the 11 + * names of the containing packages are prepended and the name 12 + * components are separated by '.' 13 + *) 14 + package_dir : string; 15 + (** The directory where to lookup package files *) 16 + package_meta : string; 17 + (** The path to the META file *) 18 + package_defs : Fl_metascanner.pkg_definition list; 19 + (** The definitions in the META file *) 20 + package_priv : package_priv; 21 + (** Private part of the definition *) 22 + } 23 + (** The definition of a package *) 24 + 25 + and package_priv 26 + 27 + 28 + val init : string list -> string -> string list -> unit 29 + (** This function must be called before [Fl_package_base] can be used. 30 + * The first string corresponds to the [OCAMLPATH] setting, the second 31 + * string is the location of the standard library. The second is the 32 + * list of directories with ignored duplicate cmi files. 33 + * 34 + * This function is called by {!Findlib.init} and {!Findlib.init_manually}, 35 + * so it is already sufficient to initialize the [Findlib] module. 36 + *) 37 + 38 + 39 + (** {1 The package graph} *) 40 + 41 + (** The functions in this section operate on a representation of the 42 + * package graph in memory. The graph is usually only partially available, 43 + * as only packages are loaded that are queried for. 44 + *) 45 + 46 + 47 + exception No_such_package of string * string 48 + (** First arg is the package name not found, second arg contains additional 49 + * info for the user. - This is the same exception as in [Findlib]. 50 + *) 51 + 52 + exception Package_loop of string 53 + (** A package is required by itself. The arg is the name of the 54 + * package. - This is the same exception as in [Findlib]. 55 + *) 56 + 57 + val query : string -> package 58 + (** Returns the [package] definition for the fully-qualified package name, 59 + * or raises [No_such_package]. It is allowed to query for subpackages. 60 + * 61 + * This function loads package definitions into the graph kept in memory. 62 + *) 63 + 64 + val requires : preds:string list -> string -> string list 65 + (** Analyzes the direct requirements of the package whose name is passed as 66 + * second argument under the assumption that the predicates [preds] 67 + * hold. The function returns the names of the required packages. 68 + * It is checked whether these packages exist. 69 + * 70 + * If there is the "mt" predicate, missing dependencies on "threads" 71 + * are silently added. 72 + * 73 + * The function may raise [No_such_package] or [Package_loop]. 74 + * 75 + * This function loads package definitions into the graph kept in memory. 76 + *) 77 + 78 + val requires_deeply : preds:string list -> string list -> string list 79 + (** Analyzes the direct or indirect requirements of the packages whose names 80 + * are passed as second argument under the assumption that the predicates 81 + * [preds] hold. The function returns the names of the required packages. 82 + * It is checked whether these packages exist. 83 + * 84 + * If there is the "mt" predicate, missing dependencies on "threads" 85 + * are silently added. 86 + * 87 + * The function may raise [No_such_package] or [Package_loop]. 88 + * 89 + * This function loads package definitions into the graph kept in memory. 90 + *) 91 + 92 + val package_conflict_report : 93 + ?identify_dir:(string -> 'a) -> unit -> unit 94 + (** Checks whether there are several META files for the same main 95 + * packages. Complaints are printed to stderr. 96 + * 97 + * Only packages in the loaded part of the package graph are checked (i.e. 98 + * packages for which there was a query). 99 + * 100 + * It is recommended to pass the ~identify_dir function whose task 101 + * it is to return a unique value for every existing directory. 102 + * For example, 103 + * {[ fun d -> 104 + * let s = Unix.stat d in 105 + * (s.Unix.st_dev, s.Unix.st_ino) 106 + * ]} 107 + * could be an implementation for this function. The default is 108 + * the identity (and not this nice implementation to avoid dependencies 109 + * on the Unix module). 110 + *) 111 + 112 + val module_conflict_report : ?identify_dir:(string -> 'a) -> string list -> unit 113 + (** Checks whether there are cmi files for the same modules. The 114 + * directories passed as first argument are checked. (Note: 115 + * Neither the '+' nor the '@' notation are recognized.) 116 + * Complaints about double cmi files are printed to stderr. 117 + * 118 + * @param identify_dir See [package_conflict_report]. 119 + *) 120 + 121 + val load_base : ?prefix:string -> unit -> unit 122 + (** Ensures that the complete package graph is loaded into memory. 123 + * This is a time-consuming operation. Warnings may be printed to 124 + * stderr. 125 + * 126 + * @param prefix Limit to the packages that starts with it. Default: unlimited 127 + *) 128 + 129 + val list_packages : ?prefix:string -> unit -> string list 130 + (** Ensures that the complete package graph is loaded into memory 131 + * (like [load_base]), and returns the (unsorted) list of all 132 + * packages. 133 + * 134 + * @param prefix Limit to the packages that starts with it. Default: unlimited 135 + *) 136 + 137 + val package_users : preds:string list -> string list -> string list 138 + (** Ensures that the complete package graph is loaded into memory 139 + * (like [load_base]), and determines the packages using one of 140 + * the packages passed as second argument. The [preds] are assumed 141 + * for the evaluation of the [requires] directives. 142 + * The returned list is sorted in ascending order. 143 + * 144 + * If there is the "mt" predicate, missing dependencies on "threads" 145 + * are silently added. 146 + * 147 + * Raises [No_such_package] if one of the passed packages cannot 148 + * be found. 149 + *) 150 + 151 + 152 + (** {1 Parsing META files} *) 153 + 154 + (** The functions in this section access directly files and directories. 155 + * The package graph is unknown. 156 + *) 157 + 158 + val packages_in_meta_file : 159 + ?directory_required:bool -> 160 + name:string -> dir:string -> meta_file:string -> unit -> package list 161 + (** Parses the META file whose name is [meta_file]. In [name], the 162 + * name of the main package must be passed. [dir] is the 163 + * directory associated with the package by default (i.e. before 164 + * it is overridden by the "directory" directive). 165 + * 166 + * Returns the package records found in this file. The "directory" 167 + * directive is already applied. 168 + * 169 + * @param directory_required If true, it is checked whether there is a 170 + * "directory" directive in the main package. If this directive is missing, 171 + * the function will fail. 172 + *) 173 + 174 + val package_definitions : search_path:string list -> string -> string list 175 + (** Return all META files defining this package that occur in the 176 + * directories mentioned in [search_path]. The package name must be 177 + * fully-qualified. For simplicity, however, only the name of the main 178 + * package is taken into account (so it is a good idea to call this 179 + * function only for main packages). 180 + *) 181 +
+146
vendor/opam/ocamlfind/src/findlib/fl_split.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + 7 + let in_words s = 8 + (* splits s in words separated by commas and/or whitespace *) 9 + let l = String.length s in 10 + let rec split i j = 11 + if j < l then 12 + match s.[j] with 13 + (' '|'\t'|'\n'|'\r'|',') -> 14 + if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1)) 15 + else split (j+1) (j+1) 16 + | _ -> 17 + split i (j+1) 18 + else 19 + if i<j then [ String.sub s i (j-i) ] else [] 20 + in 21 + split 0 0 22 + ;; 23 + 24 + 25 + let in_words_ws s = 26 + (* splits s in words separated by whitespace *) 27 + let l = String.length s in 28 + let rec split i j = 29 + if j < l then 30 + match s.[j] with 31 + (' '|'\t'|'\n'|'\r') -> 32 + if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1)) 33 + else split (j+1) (j+1) 34 + | _ -> 35 + split i (j+1) 36 + else 37 + if i<j then [ String.sub s i (j-i) ] else [] 38 + in 39 + split 0 0 40 + ;; 41 + 42 + 43 + let package_name s = 44 + (* splits s in words separated by dots. 45 + * As a special case, when s="." the package "." is returned. 46 + *) 47 + let l = String.length s in 48 + let rec split i j = 49 + if j < l then 50 + match s.[j] with 51 + '.' -> 52 + if i<j then (String.sub s i (j-i)) :: (split (j+1) (j+1)) 53 + else split (j+1) (j+1) 54 + | _ -> 55 + split i (j+1) 56 + else 57 + if i<j then [ String.sub s i (j-i) ] else [] 58 + in 59 + if s="." then 60 + ["."] 61 + else 62 + split 0 0 63 + ;; 64 + 65 + 66 + let is_valid_package_name s = 67 + (* Use this only for installation/deinstallation of packages! *) 68 + not(String.contains s '.') 69 + ;; 70 + 71 + 72 + let path_separator = 73 + match Sys.os_type with 74 + | "Unix" | "BeOS" -> ':' 75 + | "Cygwin" -> ';' (* You might want to change this *) 76 + | "Win32" -> ';' 77 + | "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" 78 + | _ -> failwith "Findlib: unknown operating system" 79 + ;; 80 + 81 + 82 + let path str = 83 + (* split "str" into parts separated by "path_separator" *) 84 + let l = String.length str in 85 + let rec split_up j k = 86 + if k < l then begin 87 + let c = str.[k] in 88 + if c = path_separator then begin 89 + if k - j > 0 then 90 + String.sub str j (k-j) :: split_up (k+1) (k+1) 91 + else 92 + split_up (k+1) (k+1) 93 + end 94 + else 95 + split_up j (k+1) 96 + end 97 + else 98 + if k - j > 0 then 99 + [ String.sub str j (k-j) ] 100 + else 101 + [] 102 + in 103 + split_up 0 0 104 + ;; 105 + 106 + 107 + let norm_dir s = 108 + (* Converts the file name of the directory [d] to the normal form. 109 + * For Unix, the '/' characters at the end are removed, and multiple 110 + * '/' are deleted. 111 + * For Windows, all '/' characters are converted to '\'. Two 112 + * backslashes at the beginning are tolerated. 113 + *) 114 + let b = Buffer.create 80 in 115 + let l = String.length s in 116 + let norm_dir_unix() = 117 + Buffer.add_char b s.[0]; 118 + for k = 1 to l - 1 do 119 + let c = s.[k] in 120 + if not ((c = '/' && s.[k-1] = '/') || (c = '/' && k = l-1)) then 121 + Buffer.add_char b c 122 + done 123 + in 124 + let is_slash = 125 + function 126 + | '/' | '\\' -> true 127 + | _ -> false in 128 + let norm_dir_win() = 129 + if l >= 1 then 130 + if s.[0] = '/' then Buffer.add_char b '\\' else Buffer.add_char b s.[0]; 131 + if l >= 2 then 132 + if s.[1] = '/' then Buffer.add_char b '\\' else Buffer.add_char b s.[1]; 133 + for k = 2 to l - 1 do 134 + let c = s.[k] in 135 + if is_slash c then ( 136 + if not (is_slash s.[k-1] || k = l-1) then 137 + Buffer.add_char b '\\' 138 + ) else 139 + Buffer.add_char b c 140 + done 141 + in 142 + match Sys.os_type with 143 + "Unix" | "BeOS" | "Cygwin" -> norm_dir_unix(); Buffer.contents b 144 + | "Win32" -> norm_dir_win(); Buffer.contents b 145 + | _ -> failwith "This os_type is not supported" 146 + ;;
+344
vendor/opam/ocamlfind/src/findlib/fl_topo.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (* TODO: 7 + * - Use a hashtable in 'find' 8 + * - implement le_than with an 'iter' like method 9 + *) 10 + 11 + 12 + (**********************************************************************) 13 + 14 + 15 + module type IdentifiedType = 16 + sig 17 + type t 18 + type id_t 19 + val id : t -> id_t 20 + end 21 + 22 + exception Inconsistent_ordering 23 + 24 + module type S = 25 + sig 26 + type key 27 + type el_t 28 + type t 29 + val create : unit -> t 30 + val add : t -> el_t -> unit 31 + val let_le : t -> key -> key -> unit 32 + val find : t -> key -> el_t 33 + val le_than : t -> key -> key -> bool 34 + val key : el_t -> key 35 + val iter_up : (el_t -> unit) -> t -> unit 36 + val iter_down : (el_t -> unit) -> t -> unit 37 + val iter_up_at : (el_t -> unit) -> t -> key list -> unit 38 + val iter_down_at : (el_t -> unit) -> t -> key list -> unit 39 + 40 + val clear : t -> unit 41 + val replace : t -> key -> el_t -> unit 42 + val delete : t -> key -> unit 43 + 44 + val copy : t -> t 45 + end 46 + 47 + 48 + (**********************************************************************) 49 + 50 + module Make(H: IdentifiedType) = 51 + struct 52 + 53 + type key = H.id_t 54 + 55 + type el_t = H.t 56 + 57 + type 'a node = 58 + { mutable content : 'a; 59 + mutable smaller : 'a node list; 60 + mutable bigger : 'a node list; 61 + mutable mark : bool; (* used in 'iter' *) 62 + (* mutable ppmark : bool *) (* used in 'private_property' *) 63 + } 64 + 65 + type t = 66 + { mutable cnt : el_t node list; 67 + mutable lock : bool 68 + } 69 + 70 + let copy ord = 71 + (* This operation is quite expensive when the graph has already 72 + * relations. In findlib, this case is avoided, and is here only 73 + * implemented for completeness. 74 + *) 75 + let ord' = 76 + { cnt = List.map (fun n -> { n with 77 + smaller = []; 78 + bigger = []; 79 + mark = false }) ord.cnt; 80 + lock = false 81 + } in 82 + let combined_list = List.combine ord.cnt ord'.cnt in 83 + let lookup_node n = 84 + (* Find the new node corresponding to old node n *) 85 + try List.assq n combined_list 86 + with Not_found -> assert false 87 + in 88 + List.iter2 89 + (fun n n' -> 90 + (* n: old node, n': new node *) 91 + let smaller = List.map lookup_node n.smaller in 92 + let bigger = List.map lookup_node n.bigger in 93 + n'.smaller <- smaller; 94 + n'.bigger <- bigger; 95 + ) 96 + ord.cnt 97 + ord'.cnt; 98 + ord' 99 + 100 + 101 + let rec delete_all p l = 102 + match l with 103 + x::l' -> 104 + if p x then delete_all p l' else x :: delete_all p l' 105 + | [] -> [] 106 + 107 + 108 + (******************************************************************) 109 + 110 + let create () = { cnt = []; lock = false } 111 + 112 + let clear ordering = 113 + ordering.cnt <- []; 114 + ordering.lock <- false 115 + 116 + (******************************************************************) 117 + 118 + let add ordering x = 119 + (* Is there already a node with the same key? *) 120 + let k = H.id x in 121 + if List.exists (fun y -> H.id y.content = k) ordering.cnt then 122 + raise Inconsistent_ordering; 123 + 124 + (* Ok, add the node to the list *) 125 + let nx = { content = x; 126 + smaller = []; 127 + bigger = []; 128 + mark = false 129 + } in 130 + ordering.cnt <- nx :: ordering.cnt 131 + 132 + 133 + (******************************************************************) 134 + 135 + let find_node ordering kx = 136 + let rec search l = 137 + match l with 138 + [] -> raise Not_found 139 + | y :: l' -> if H.id y.content = kx then y else search l' 140 + in 141 + search ordering.cnt 142 + 143 + 144 + let find ordering kx = (find_node ordering kx).content 145 + 146 + (******************************************************************) 147 + 148 + let replace ordering kx x' = 149 + let x = find_node ordering kx in 150 + x.content <- x' 151 + 152 + (******************************************************************) 153 + 154 + let delete ordering kx = 155 + let x = find_node ordering kx in 156 + ordering.cnt <- delete_all (fun a -> a == x) ordering.cnt; 157 + List.iter 158 + (fun x -> 159 + x.smaller <- delete_all (fun a -> a == x) x.smaller; 160 + x.bigger <- delete_all (fun a -> a == x) x.bigger) 161 + ordering.cnt 162 + 163 + 164 + (******************************************************************) 165 + 166 + let le_than ordering kx ky = 167 + (* Find x, y: *) 168 + let x = find_node ordering kx in 169 + let y = find_node ordering ky in 170 + 171 + let rec search x1 = 172 + if x1 == y then 173 + true 174 + else 175 + List.exists search x1.bigger 176 + 177 + in 178 + search x 179 + 180 + (******************************************************************) 181 + 182 + let let_le ordering kx ky = 183 + (* Find x, y: *) 184 + let x = find_node ordering kx in 185 + let y = find_node ordering ky in 186 + 187 + (* If already done just return (this is an idempotent function) *) 188 + if not (List.memq x y.smaller) then begin 189 + 190 + (* let x <= y. This is only allowed if not (y <= x) *) 191 + if le_than ordering ky kx then 192 + raise Inconsistent_ordering; 193 + 194 + (* Ok, add the relation *) 195 + x.bigger <- y :: x.bigger; 196 + y.smaller <- x :: y.smaller 197 + end 198 + 199 + (******************************************************************) 200 + 201 + let key x = H.id x 202 + 203 + (******************************************************************) 204 + 205 + let iter upwards f ordering = 206 + 207 + let in_direction n = 208 + if upwards then n.bigger else n.smaller in 209 + 210 + let against_direction n = 211 + if upwards then n.smaller else n.bigger in 212 + 213 + (* the following is written as if for iter_up. *) 214 + 215 + let rec find_biggest ordlist = 216 + (* find biggest, non-marked node *) 217 + match ordlist with 218 + [] -> raise Not_found 219 + | nx :: ordlist' -> if not nx.mark && in_direction nx = [] 220 + then nx 221 + else find_biggest ordlist' 222 + in 223 + 224 + let rec run_up n = 225 + (* iterate over all nodes <= x and return their number *) 226 + 227 + let rec run_up_list l = 228 + match l with 229 + [] -> 0 230 + | x :: l' -> run_up x + run_up_list l' 231 + in 232 + 233 + if n.mark then 234 + (* have already visited this node *) 235 + 0 236 + else 237 + let u = run_up_list (against_direction n) in 238 + n.mark <- true; 239 + f n.content; 240 + u + 1 241 + in 242 + 243 + (* Lock *) 244 + if ordering.lock then 245 + failwith "iter_up: recursive application not allowed"; 246 + ordering.lock <- true; 247 + 248 + (* clear all marks *) 249 + List.iter (fun nx -> nx.mark <- false) ordering.cnt; 250 + 251 + (* Catch exceptions *) 252 + 253 + try 254 + (* while there is a biggest node... *) 255 + let c = ref 0 in (* counter *) 256 + while !c < List.length ordering.cnt do 257 + 258 + (* Find a biggest node *) 259 + let n_biggest = find_biggest ordering.cnt in 260 + 261 + (* run through the graph *) 262 + c := !c + run_up n_biggest 263 + 264 + done; 265 + 266 + (* unlock *) 267 + ordering.lock <- false 268 + 269 + with 270 + any -> (* unlock, too *) 271 + ordering.lock <- false; 272 + raise any 273 + 274 + 275 + let iter_up = iter true 276 + let iter_down = iter false 277 + 278 + 279 + (******************************************************************) 280 + 281 + let iter_at upwards f ordering startpoints = 282 + 283 + (* 284 + let in_direction n = 285 + if upwards then n.bigger else n.smaller in 286 + *) 287 + 288 + let against_direction n = 289 + if upwards then n.smaller else n.bigger in 290 + 291 + (* the following is written as if for iter_up. *) 292 + 293 + let rec run_up n = 294 + (* iterate over all nodes <= x and return their number *) 295 + 296 + let rec run_up_list l = 297 + match l with 298 + [] -> 0 299 + | x :: l' -> run_up x + run_up_list l' 300 + in 301 + 302 + if n.mark then 303 + (* have already visited this node *) 304 + 0 305 + else 306 + let u = run_up_list (against_direction n) in 307 + n.mark <- true; 308 + f n.content; 309 + u + 1 310 + in 311 + 312 + (* Lock *) 313 + if ordering.lock then 314 + failwith "iter_up: recursive application not allowed"; 315 + ordering.lock <- true; 316 + 317 + (* clear all marks *) 318 + List.iter (fun nx -> nx.mark <- false) ordering.cnt; 319 + 320 + (* Catch exceptions *) 321 + 322 + try 323 + 324 + List.iter 325 + (fun start -> 326 + let _ = run_up (find_node ordering start) in ()) 327 + startpoints; 328 + 329 + (* unlock *) 330 + ordering.lock <- false 331 + 332 + with 333 + any -> (* unlock, too *) 334 + ordering.lock <- false; 335 + raise any 336 + 337 + 338 + let iter_up_at = iter_at true 339 + let iter_down_at = iter_at false 340 + 341 + 342 + (******************************************************************) 343 + 344 + end
+42
vendor/opam/ocamlfind/src/findlib/fl_topo.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (* The type topo.t is a partially ordered relation. You can add an element 7 + * by giving all descendents ... 8 + *) 9 + 10 + module type IdentifiedType = 11 + sig 12 + type t 13 + type id_t 14 + val id : t -> id_t 15 + end 16 + 17 + exception Inconsistent_ordering 18 + 19 + module type S = 20 + sig 21 + type key 22 + type el_t 23 + type t 24 + val create : unit -> t 25 + val add : t -> el_t -> unit 26 + val let_le : t -> key -> key -> unit 27 + val find : t -> key -> el_t 28 + val le_than : t -> key -> key -> bool 29 + val key : el_t -> key 30 + val iter_up : (el_t -> unit) -> t -> unit 31 + val iter_down : (el_t -> unit) -> t -> unit 32 + val iter_up_at : (el_t -> unit) -> t -> key list -> unit 33 + val iter_down_at : (el_t -> unit) -> t -> key list -> unit 34 + val clear : t -> unit 35 + val replace : t -> key -> el_t -> unit 36 + val delete : t -> key -> unit 37 + val copy : t -> t 38 + end 39 + 40 + module Make(H: IdentifiedType): 41 + (S with type el_t = H.t 42 + and type key = H.id_t)
+2694
vendor/opam/ocamlfind/src/findlib/frontend.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + open Findlib;; 7 + 8 + exception Usage;; 9 + exception Silent_error;; 10 + 11 + type mode = 12 + M_use | M_query | M_install | M_remove | M_compiler of string | M_dep 13 + | M_printconf | M_list | M_browser | M_call of (string*string) 14 + | M_doc | M_lint | M_printppx 15 + ;; 16 + 17 + 18 + type psubst = 19 + Const of string 20 + | Percent of string * modifier 21 + | Lookup of string * modifier 22 + 23 + and modifier = 24 + | Plain 25 + | Plus 26 + ;; 27 + 28 + let sys_error code arg = 29 + if arg = "" then 30 + Sys_error (Unix.error_message code) 31 + else 32 + Sys_error (arg ^ ": " ^ Unix.error_message code) 33 + 34 + 35 + let slashify s = 36 + match Findlib_config.system with 37 + | "mingw" | "mingw64" | "cygwin" -> 38 + let b = Buffer.create 80 in 39 + String.iter 40 + (function 41 + | '\\' -> Buffer.add_char b '/' 42 + | c -> Buffer.add_char b c 43 + ) 44 + s; 45 + Buffer.contents b 46 + | _ -> 47 + s 48 + 49 + 50 + let out_path ?(prefix="") s = 51 + match Findlib_config.system with 52 + | "mingw" | "mingw64" | "cygwin" -> 53 + let u = slashify s in 54 + prefix ^ 55 + (if String.contains u ' ' then 56 + (* Desperate attempt to fix the space problem in paths. 57 + Note that we invoke commands via Unix.open_process, and 58 + this function already quotes the arguments on win32. 59 + However, for -ccopt arguments, one quoting level seems 60 + to be lost, and we have to add another level to compensate. 61 + E.g. for the list of args 62 + [ -ccopt; -L/my programs/include -L/somewhere ] 63 + we get after out_path 64 + [ -ccopt; "-I/my programs/include -L/somewhere" ] 65 + which actually translates to 66 + -ccopt "\"-I/my programs/include\" \"-L/somewhere\"" 67 + on the command line, i.e. a double-quoted argument. 68 + *) 69 + "\"" ^ u ^ "\"" 70 + else 71 + u 72 + ) 73 + | _ -> 74 + prefix ^ slashify s 75 + 76 + 77 + 78 + let percent_subst ?base spec lookup s = 79 + (* spec = [ "%c", [ "ctext1"; "ctext2"; ... ]; 80 + * "%d", [ "dtext1"; "dtext2"; ... ] ] 81 + * All occurrences of %c in the string s are replaced as specified in spec. 82 + * spec is an association list with the %-notation as keys 83 + * and lists of strings as values. The result is a list of strings containing 84 + * every combination of substituted values. 85 + * 86 + * Support for the %(name) syntax: In this case, the name is taken as 87 + * key for the [lookup] function, which either returns the string value 88 + * or raises Not_found. 89 + * 90 + * "+" modifier: A "+" after "%" causes that Findlib.resolve_path is 91 + * called for the substitution string (e.g. %+c, %+(name)). 92 + * 93 + * Example: 94 + * spec = [ "%a", [ "file1" ] ] 95 + * lookup = function "archive" -> "file2" | _ -> raise Not_found 96 + * Here, %a is substituted by file1, and %(archive) is substituted by 97 + * file2. 98 + * 99 + * ?base: The base parameter for Findlib.resolve_path. 100 + *) 101 + let l = String.length s in 102 + 103 + let fail() = 104 + failwith "bad format string" in 105 + 106 + let parenthesized_name j = 107 + try 108 + if j+1>=l then raise Not_found; 109 + let k = String.index_from s (j+1) ')' in 110 + let name = String.sub s (j+1) (k-j-1) in 111 + (name, k+1) 112 + with Not_found -> 113 + fail() in 114 + 115 + let rec preprocess i j = 116 + if j<l then begin 117 + match s.[j] with 118 + '%' -> 119 + if j+1<l then begin 120 + let prev = Const(String.sub s i (j-i)) in 121 + let c = s.[j+1] in 122 + match c with 123 + '%' -> 124 + prev :: Const "%" :: preprocess (j+2) (j+2) 125 + | '(' -> 126 + let name, j_next = parenthesized_name (j+1) in 127 + prev :: Lookup(name,Plain) :: preprocess j_next j_next 128 + | '+' -> 129 + if j+2<l then begin 130 + let c = s.[j+2] in 131 + match c with 132 + | '%' | '+' -> fail() 133 + | '(' -> 134 + let name, j_next = parenthesized_name (j+2) in 135 + prev :: Lookup(name,Plus) :: preprocess j_next j_next 136 + | _ -> 137 + let name = "%" ^ String.make 1 c in 138 + prev :: Percent(name,Plus) :: preprocess (j+3) (j+3) 139 + end 140 + else fail() 141 + | _ -> 142 + let name = "%" ^ String.make 1 c in 143 + prev :: Percent(name,Plain) :: preprocess (j+2) (j+2) 144 + end 145 + else fail() 146 + | _ -> 147 + preprocess i (j+1) 148 + end 149 + else 150 + if i<j then 151 + [Const(String.sub s i (j-i))] 152 + else 153 + [] 154 + in 155 + 156 + let plus_subst u = 157 + String.concat 158 + " " 159 + (List.map 160 + (Findlib.resolve_path ?base) 161 + (Fl_split.in_words u)) in 162 + 163 + let any_subst modi u = 164 + match modi with 165 + | Plain -> u 166 + | Plus -> plus_subst u in 167 + 168 + let rec subst prefix l = 169 + match l with 170 + [] -> [prefix] 171 + | Const s :: l' -> 172 + subst (prefix ^ s) l' 173 + | Percent(name,modi) :: l' -> 174 + let replacements0 = 175 + try List.assoc name spec 176 + with Not_found -> failwith "bad format string" in 177 + let replacements = 178 + List.map (any_subst modi) replacements0 in 179 + List.flatten 180 + (List.map 181 + (fun replacement -> 182 + subst (prefix ^ replacement) l') 183 + replacements) 184 + | Lookup(name,modi) :: l' -> 185 + let replacement0 = 186 + try lookup name 187 + with Not_found -> "" in 188 + let replacement = 189 + any_subst modi replacement0 in 190 + subst (prefix ^ replacement) l' 191 + in 192 + 193 + subst "" (preprocess 0 0) 194 + ;; 195 + 196 + 197 + let rec remove_dups l = 198 + match l with 199 + x :: l' -> 200 + if List.mem x l' then remove_dups l' else x::remove_dups l' 201 + | [] -> [] 202 + ;; 203 + 204 + 205 + let arg n = 206 + if n < Array.length Sys.argv then Sys.argv.(n) else raise Not_found 207 + ;; 208 + 209 + 210 + let escape_if_needed s = 211 + if String.contains s ' ' then "\"" ^ String.escaped s ^ "\"" else s 212 + ;; 213 + 214 + 215 + let use_package prefix pkgnames = 216 + (* may raise No_such_package *) 217 + let pdirs = 218 + List.map 219 + (fun pname -> 220 + "-I " ^ out_path(package_directory pname) 221 + ) 222 + pkgnames 223 + in 224 + 225 + print_endline (prefix ^ String.concat " " pdirs) 226 + ;; 227 + 228 + 229 + let read_ldconf filename = 230 + let lines = ref [] in 231 + let f = open_in filename in 232 + try 233 + while true do 234 + let line = input_line f in 235 + if line <> "" then 236 + lines := line :: !lines 237 + done; 238 + assert false 239 + with 240 + End_of_file -> 241 + close_in f; 242 + List.rev !lines 243 + | other -> 244 + close_in f; 245 + raise other 246 + ;; 247 + 248 + 249 + let write_ldconf filename lines new_lines = 250 + let f = open_out filename in 251 + try 252 + List.iter 253 + (fun line -> output_string f (line ^ "\n")) 254 + (lines @ new_lines); 255 + close_out f; 256 + prerr_endline("Updated " ^ filename); 257 + with 258 + Sys_error e -> 259 + prerr_endline ("ocamlfind: [WARNING] Cannot write " ^ filename); 260 + prerr_endline ("Reason: " ^ e); 261 + prerr_endline ("This file contains the directories with DLLs."); 262 + if new_lines <> [] then begin 263 + prerr_endline ("It is recommended to add the following line(s) to this file:"); 264 + List.iter prerr_endline new_lines 265 + end 266 + ;; 267 + 268 + 269 + let is_dll p = 270 + let sfx = Findlib_config.dll_suffix in 271 + sfx <> "" && Filename.check_suffix p sfx 272 + ;; 273 + 274 + 275 + let identify_dir d = 276 + match Sys.os_type with 277 + | "Win32" -> 278 + failwith "identify_dir" (* not available *) 279 + | _ -> 280 + let s = Unix.stat d in 281 + (s.Unix.st_dev, s.Unix.st_ino) 282 + ;; 283 + 284 + 285 + let conflict_report incpath pkglist = 286 + (* Check whether there are several definitions for packages 287 + * in the current path. We remove duplicate directories first. 288 + * Note that all other checks are not sensitive to duplicate directories. 289 + *) 290 + Fl_package_base.package_conflict_report ~identify_dir (); 291 + 292 + (* Second check whether there are module conflicts *) 293 + let pkgpath = 294 + List.map Findlib.package_directory pkglist in 295 + Fl_package_base.module_conflict_report ~identify_dir (pkgpath @ incpath); 296 + 297 + (* Finally check whether there are multiple DLLs: *) 298 + (* Note: Only the directories mentioned in ld.conf are checked, but not the 299 + * directories in [incpath], and not the directories in CAML_LD_LIBRARY_PATH. 300 + * The idea of this check is to ensure a proper installation, and not to 301 + * complain about the user's special configuration. 302 + *) 303 + let ldconf = ocaml_ldconf() in 304 + if ldconf <> "ignore" then begin 305 + let dll_dirs = remove_dups (read_ldconf ldconf) in 306 + let dll_pairs = 307 + List.flatten 308 + (List.map 309 + (fun dll_dir -> 310 + let files = 311 + try Array.to_list (Sys.readdir dll_dir) 312 + with _ -> 313 + prerr_endline ("ocamlfind: [WARNING] Cannot read directory " ^ 314 + dll_dir ^ " which is mentioned in ld.conf"); 315 + [] 316 + in 317 + List.map 318 + (fun file -> (file, dll_dir)) 319 + (List.filter is_dll files) 320 + ) 321 + dll_dirs 322 + ) in 323 + let dll_hash = Hashtbl.create 50 in 324 + List.iter 325 + (fun (file, dll_dir) -> Hashtbl.add dll_hash file dll_dir) 326 + dll_pairs; 327 + Hashtbl.iter 328 + (fun file dll_dir -> 329 + let locations = Hashtbl.find_all dll_hash file in 330 + if List.length locations > 1 then begin 331 + prerr_endline ("ocamlfind: [WARNING] The DLL " ^ file ^ 332 + " occurs in multiple directories: " ^ dll_dir) 333 + end 334 + ) 335 + dll_hash 336 + end 337 + ;; 338 + 339 + 340 + let check_package_list l = 341 + (* may raise No_such_package *) 342 + List.iter 343 + (fun pkg -> 344 + let _ = package_directory pkg in 345 + () 346 + ) 347 + l 348 + ;; 349 + 350 + 351 + type verbosity = 352 + | Normal 353 + | Verbose 354 + | Only_show 355 + 356 + 357 + let run_command ?filter verbose cmd args = 358 + let printable_cmd = 359 + cmd ^ " " ^ String.concat " " (List.map escape_if_needed args) in 360 + ( match verbose with 361 + | Normal -> 362 + () 363 + | Verbose -> 364 + print_endline ("+ " ^ printable_cmd); 365 + if filter <> None then 366 + print_string 367 + (" (output of this command is filtered by ocamlfind)\n") 368 + | Only_show -> 369 + print_endline printable_cmd 370 + ); 371 + flush stdout; 372 + 373 + if verbose <> Only_show then ( 374 + let filter_input, cmd_output = 375 + match filter with 376 + None -> Unix.stdin (* dummy *), Unix.stdout 377 + | Some f -> Unix.pipe() 378 + in 379 + 380 + (* Signals: On SIGINT, we wait until the subprocess finishes, and 381 + * die then. This allows us to call interactive commands as subprocesses. 382 + *) 383 + 384 + let old_sigint = 385 + Sys.signal Sys.sigint Sys.Signal_ignore in 386 + 387 + let need_exe = 388 + List.mem Findlib_config.system [ "win32"; "win64"; "mingw"; "mingw64" ] in 389 + 390 + let fixed_cmd = 391 + if need_exe then ( 392 + if Filename.check_suffix cmd ".exe" then cmd else cmd ^ ".exe" 393 + ) 394 + else 395 + cmd in 396 + 397 + let pid = 398 + Unix.create_process 399 + fixed_cmd 400 + (Array.of_list (cmd :: args)) 401 + Unix.stdin 402 + cmd_output 403 + Unix.stderr 404 + in 405 + 406 + begin match filter with 407 + Some filter_fun -> 408 + begin 409 + Unix.close cmd_output; 410 + let ch = Unix.in_channel_of_descr filter_input in 411 + try 412 + while true do 413 + let line = input_line ch in 414 + match filter_fun line with 415 + None -> () (* Suppress line *) 416 + | Some line' -> print_endline line' 417 + done; 418 + assert false 419 + with 420 + End_of_file -> 421 + close_in ch; 422 + flush stdout 423 + end 424 + | None -> () 425 + end; 426 + 427 + let (_,status) = Unix.waitpid [] pid in 428 + Sys.set_signal Sys.sigint old_sigint; 429 + begin 430 + match status with 431 + Unix.WEXITED 0 -> () 432 + | Unix.WEXITED n -> 433 + if verbose = Verbose then 434 + print_string (cmd ^ " returned with exit code " ^ string_of_int n ^ "\n"); 435 + exit n 436 + | Unix.WSIGNALED _ -> 437 + print_string (cmd ^ " got signal and exited\n"); 438 + exit 2 439 + | Unix.WSTOPPED _ -> 440 + failwith "Your operating system does not work correctly" 441 + end 442 + ) 443 + ;; 444 + 445 + 446 + (**************** preprocessor ******************************************) 447 + 448 + let select_pp_packages syntax_preds packages = 449 + if syntax_preds = [] then 450 + (* No syntax predicates, no preprocessor! *) 451 + [] 452 + else 453 + List.filter 454 + (fun pkg -> 455 + let al = try package_property syntax_preds pkg "archive" 456 + with Not_found -> "" in 457 + let w = Fl_split.in_words al in 458 + w <> [] 459 + ) 460 + packages 461 + 462 + 463 + let process_pp_spec syntax_preds packages pp_opts = 464 + (* Returns: pp_command *) 465 + (* may raise No_such_package *) 466 + 467 + (* [packages]: all packages given on the command line. May include 468 + * packages for compilation and for preprocessing. 469 + * 470 + * The difficulty is now that the preprocessor packages may have 471 + * requirements that are non-preprocessor packages. To get exactly 472 + * the preprocessor packages and its requirements, we do: 473 + * 474 + * 1. Determine the subset of [packages] that are preprocessor 475 + * packages by checking whether they have an "archive" for 476 + * [syntax_preds], i.e. the preprocessor packages mentioned 477 + * on the command line = [cl_pp_packages]. 478 + * 479 + * 2. Add their requirements = [pp_packages] 480 + * 481 + * Because the packages are now mixed, we must evaluate for 482 + * [syntax_preds] + "byte". 483 + *) 484 + 485 + (* One packages must now have the variable "preprocessor", usually camlp4 *) 486 + let cl_pp_packages = select_pp_packages syntax_preds packages in 487 + let pp_packages = 488 + package_deep_ancestors syntax_preds cl_pp_packages in 489 + 490 + let preprocessor_cmds = 491 + List.flatten 492 + (List.map (fun pname -> 493 + try 494 + [ pname, 495 + package_property syntax_preds pname "preprocessor" 496 + ] 497 + with 498 + Not_found -> [] 499 + ) 500 + pp_packages 501 + ) 502 + in 503 + 504 + let preprocessor_cmd = 505 + if syntax_preds <> [] then 506 + match preprocessor_cmds with 507 + [] -> 508 + failwith("Using -syntax, but no package is selected specifying \ 509 + a preprocessor as required for -syntax") 510 + | [_, cmd] -> Some cmd 511 + | _ -> 512 + failwith("Several packages are selected that specify \ 513 + preprocessors: " ^ 514 + String.concat ", " 515 + (List.map 516 + (fun (n,v) -> 517 + "package " ^ n ^ " defines `" ^ v ^ "'") 518 + preprocessor_cmds 519 + ) 520 + ) 521 + else 522 + None 523 + in 524 + 525 + let pp_i_options = 526 + List.flatten 527 + (List.map 528 + (fun pkg -> 529 + let pkgdir = package_directory pkg in 530 + [ "-I"; slashify pkgdir ] 531 + ) 532 + pp_packages) in 533 + 534 + let pp_archives = 535 + if preprocessor_cmd = None then 536 + [] 537 + else 538 + List.flatten 539 + (List.map 540 + (fun pkg -> 541 + let al = 542 + try package_property ("byte" :: syntax_preds) pkg "archive" 543 + with Not_found -> "" in 544 + Fl_split.in_words al 545 + ) 546 + pp_packages) in 547 + 548 + match preprocessor_cmd with 549 + None -> [] 550 + | Some cmd -> 551 + ["-pp"; 552 + cmd ^ " " ^ 553 + String.concat " " (List.map Filename.quote pp_i_options) ^ " " ^ 554 + String.concat " " (List.map Filename.quote pp_archives) ^ " " ^ 555 + String.concat " " (List.map Filename.quote pp_opts)] 556 + ;; 557 + 558 + (**************** ppx extensions ****************************************) 559 + 560 + let process_ppx_spec predicates packages ppx_opts = 561 + (* Returns: ppx_commands *) 562 + (* may raise No_such_package *) 563 + 564 + let ppx_packages = 565 + package_deep_ancestors predicates packages in 566 + 567 + let ppx_opts = 568 + List.map 569 + (fun opt -> 570 + match Fl_split.in_words opt with 571 + | pkg :: ((_ :: _) as opts) -> 572 + let exists = 573 + try ignore(package_directory pkg); true 574 + with No_such_package _ -> false in 575 + if not exists then 576 + failwith ("The package named in -ppxopt does not exist: " ^ 577 + pkg); 578 + pkg, opts 579 + | _ -> 580 + failwith "-ppxopt must include package name, e.g. -ppxopt \"foo,-name bar\"" 581 + ) 582 + ppx_opts in 583 + 584 + let meta_ppx_opts = 585 + List.concat 586 + (List.map 587 + (fun pname -> 588 + try 589 + let opts = package_property predicates pname "ppxopt" in 590 + (* Split by whitespace to get (package,options) combinations. 591 + Then, split by commas to get individual options. *) 592 + List.map 593 + (fun opts -> 594 + match Fl_split.in_words opts with 595 + | pkg :: ((_ :: _) as opts) -> 596 + let exists = 597 + try ignore(package_directory pkg); true 598 + with No_such_package _ -> false in 599 + if not exists then 600 + failwith ("The package named in ppxopt variable does not exist: " ^ 601 + pkg ^ " (from " ^ pname ^ ")"); 602 + let base = package_directory pname in 603 + pkg, List.map (resolve_path ~base ~explicit:true) opts 604 + | _ -> 605 + failwith ("ppxopt variable must include package name, e.g. " ^ 606 + "ppxopt=\"foo,-name bar\" (from " ^ pname ^ ")") 607 + ) 608 + (Fl_split.in_words_ws opts) 609 + with Not_found -> [] 610 + ) 611 + ppx_packages 612 + ) in 613 + 614 + List.flatten 615 + (List.map 616 + (fun pname -> 617 + let base = package_directory pname in 618 + let options = 619 + try 620 + List.concat 621 + (List.map (fun (_, opts) -> opts) 622 + (List.filter (fun (pname', _) -> pname' = pname) 623 + (meta_ppx_opts @ ppx_opts))) 624 + with Not_found -> [] 625 + in 626 + try 627 + let preprocessor = 628 + resolve_path 629 + ~base ~explicit:true 630 + (package_property predicates pname "ppx") in 631 + ["-ppx"; String.concat " " (preprocessor :: options)] 632 + with Not_found -> [] 633 + ) 634 + ppx_packages) 635 + 636 + (**************** Generic argument processing *************************) 637 + 638 + let merge_native_arguments native_spec f_unit f_string f_special_list = 639 + List.map 640 + (fun (switch_name, switch_has_arg, help_text) -> 641 + let f = 642 + try 643 + List.assoc switch_name f_special_list 644 + with 645 + Not_found -> 646 + if switch_has_arg then 647 + f_string switch_name 648 + else 649 + f_unit switch_name in 650 + (switch_name, f, help_text) 651 + ) 652 + native_spec 653 + ;; 654 + 655 + 656 + let parse_args 657 + ?(current = Arg.current) ?(args = Sys.argv) 658 + ?(align = true) 659 + spec anon usage = 660 + try 661 + Arg.parse_argv 662 + ~current 663 + args 664 + (if align then Arg.align spec else spec) 665 + anon 666 + usage 667 + with 668 + | Arg.Help text -> 669 + print_string text; 670 + exit 0 671 + | Arg.Bad text -> 672 + prerr_string text; 673 + exit 2 674 + 675 + 676 + (************************* format expansion *************************) 677 + 678 + 679 + let expand predicates eff_packages format = 680 + (* may raise No_such_package *) 681 + 682 + (* format: 683 + * %p package name 684 + * %d package directory 685 + * %m META file 686 + * %D description 687 + * %v version 688 + * %a archive file(s) 689 + * %A archive files as single string 690 + * %o link option(s) 691 + * %O link options as single string 692 + *) 693 + 694 + List.flatten 695 + (List.map 696 + (fun pkg -> 697 + let dir = package_directory pkg in 698 + (* May raise No_such_package *) 699 + let spec = 700 + [ "%p", [pkg]; 701 + "%d", [out_path dir]; 702 + "%m", [out_path (package_meta_file pkg)]; 703 + "%D", [try package_property predicates pkg "description" 704 + with Not_found -> "[n/a]"]; 705 + "%v", [try package_property predicates pkg "version" 706 + with Not_found -> "[unspecified]"]; 707 + "%a", Fl_split.in_words 708 + (try package_property predicates pkg "archive" 709 + with Not_found -> ""); 710 + "%A", [String.concat " " 711 + (Fl_split.in_words 712 + (try package_property predicates pkg "archive" 713 + with Not_found -> ""))]; 714 + "%o", Fl_split.in_words_ws 715 + (try package_property predicates pkg "linkopts" 716 + with Not_found -> ""); 717 + "%O", [String.concat " " 718 + (Fl_split.in_words_ws 719 + (try package_property predicates pkg "linkopts" 720 + with Not_found -> ""))]; 721 + ] 722 + in 723 + let lookup = package_property predicates pkg in 724 + percent_subst ~base:dir spec lookup format) 725 + eff_packages) 726 + ;; 727 + 728 + 729 + let help_format() = 730 + print_endline 731 + "Formats for -format strings: 732 + 733 + %p package name 734 + %d package directory 735 + %m META file 736 + %D description 737 + %v version 738 + %a archive file(s) 739 + %+a archive file(s), converted to absolute paths 740 + %A archive files as single string 741 + %+A archive files as single string, converted to absolute paths 742 + %o link option(s) 743 + %O link options as single string 744 + %(name) the value of the property <name> 745 + %+(name) the value of the property <name>, converted to absolute paths 746 + (like <archive>)"; 747 + flush stdout 748 + 749 + 750 + 751 + (************************** QUERY SUBCOMMAND ***************************) 752 + 753 + let query_package () = 754 + 755 + let long_format = 756 + "package: %p\ndescription: %D\nversion: %v\narchive(s): %A\nlinkopts: %O\nlocation: %d\n" in 757 + let i_format = 758 + "-I %d" in 759 + let l_format = 760 + if Findlib_config.system = "win32" || Findlib_config.system = "win64" then 761 + (* Microsoft toolchain *) 762 + "-ccopt \"/link /libpath:%d\"" 763 + else 764 + "-ccopt -L%d" in 765 + let a_format = 766 + "%+a" in 767 + let o_format = 768 + "%o" in 769 + let p_format = 770 + "%p" in 771 + 772 + let predicates = ref [] in 773 + let format = ref "%d" in 774 + let separator = ref "\n" in 775 + let prefix = ref "" in 776 + let suffix = ref "\n" in 777 + let recursive = ref false in 778 + let descendants = ref false in 779 + let pp = ref false in 780 + let qe = ref false in 781 + let qo = ref false in 782 + 783 + let packages = ref [] in 784 + 785 + let append_predicate s = 786 + let pl = Fl_split.in_words s in 787 + predicates := !predicates @ pl 788 + in 789 + 790 + 791 + parse_args 792 + [ "-predicates", Arg.String append_predicate, 793 + " specifies comma-separated list of assumed predicates"; 794 + "-format", Arg.String (fun s -> format := s), 795 + "<fmt> specifies the output format"; 796 + "-separator", Arg.String (fun s -> separator := s), 797 + " specifies the string that separates multiple answers"; 798 + "-prefix", Arg.String (fun s -> prefix := s), 799 + "<p> a string printed before the first answer"; 800 + "-suffix", Arg.String (fun s -> suffix := s), 801 + "<s> a string printed after the last answer"; 802 + "-recursive", Arg.Set recursive, 803 + " select direct and indirect ancestors/descendants, too"; 804 + "-r", Arg.Set recursive, 805 + " same as -recursive"; 806 + "-descendants", Arg.Unit (fun () -> descendants := true; recursive := true), 807 + " query descendants instead of ancestors; implies -recursive"; 808 + "-d", Arg.Unit (fun () -> descendants := true; recursive := true), 809 + " same as -descendants"; 810 + "-pp", Arg.Unit (fun () -> pp := true; recursive := true), 811 + " get preprocessor pkgs (predicates are taken as syntax preds)"; 812 + "-long-format", Arg.Unit (fun () -> format := long_format), 813 + " specifies long output format"; 814 + "-l", Arg.Unit (fun () -> format := long_format), 815 + " same as -long-format"; 816 + "-i-format", Arg.Unit (fun () -> format := i_format), 817 + " prints -I options for ocamlc"; 818 + "-l-format", Arg.Unit (fun () -> format := l_format), 819 + " prints -ccopt -L options for ocamlc"; 820 + "-a-format", Arg.Unit (fun () -> format := a_format), 821 + " prints names of archives to be linked in for ocamlc"; 822 + "-o-format", Arg.Unit (fun () -> format := o_format), 823 + " prints link options for ocamlc"; 824 + "-p-format", Arg.Unit (fun () -> format := p_format), 825 + " prints package names"; 826 + "-help-format", Arg.Unit help_format, 827 + " lists the supported formats for -format"; 828 + "-qe", Arg.Set qe, 829 + " do not print most errors, just set the exit code"; 830 + "-qo", Arg.Set qo, 831 + " do not print regular output"; 832 + ] 833 + (fun p -> packages := !packages @ Fl_split.in_words p) 834 + "usage: ocamlfind query [ -predicates <p> | -format <f> | 835 + -long-format | -i-format | 836 + -l-format | -a-format | 837 + -o-format | -p-format | 838 + -prefix <p> | -suffix <s> | 839 + -separator <s> | 840 + -descendants | -recursive ] package ..."; 841 + 842 + ignore(config_file()); (* ensure findlib is initialized *) 843 + try 844 + let predicates1 = 845 + if !pp then 846 + "preprocessor" :: "syntax" :: !predicates 847 + else 848 + !predicates in 849 + let packages1 = 850 + if !pp then 851 + let predicates2 = 852 + List.filter (fun p -> p <> "byte" && p <> "native") predicates1 in 853 + select_pp_packages predicates2 !packages 854 + else 855 + !packages in 856 + let eff_packages = 857 + if !recursive then begin 858 + if !descendants then 859 + Fl_package_base.package_users ~preds:predicates1 packages1 860 + else 861 + package_deep_ancestors predicates1 packages1 862 + end 863 + else 864 + packages1 865 + in 866 + 867 + let answers = expand predicates1 eff_packages !format in 868 + 869 + if not !qo then ( 870 + print_string !prefix; 871 + print_string (String.concat !separator answers); 872 + print_string !suffix; 873 + ) 874 + with 875 + ( Findlib.No_such_package _ 876 + | Failure _ 877 + | Sys_error _ 878 + ) when !qe -> raise Silent_error 879 + ;; 880 + 881 + 882 + (**************** OCAMLC/OCAMLMKTOP/OCAMLOPT subcommands ****************) 883 + 884 + type pass_file_t = 885 + Pass of string 886 + | Impl of string (* Forces module implementation: -impl <file> *) 887 + | Intf of string (* Forces module interface: -intf <file> *) 888 + | Cclib of string (* Option for the C linker: -cclib <opt> *) 889 + ;; 890 + 891 + 892 + let contracted_ocamlmklib_options = 893 + [ "-l"; "-L"; "-R"; "-F"; "-Wl,-rpath,"; "-Wl,-R" ] 894 + (* The ocamlmklib options where the argument is directly attached to the 895 + switch (e.g. -L<path> instead of -L <path>) 896 + *) 897 + 898 + 899 + let ocamlc which () = 900 + 901 + (* let destdir = ref (default_location()) in *) 902 + 903 + let switches = ref [] in 904 + let pass_options = ref [] in 905 + let pass_files = ref [] in 906 + let incpath = ref [] in 907 + let only_show = ref false in 908 + 909 + let dll_pkgs = ref [] in 910 + let dll_pkgs_all = ref false in 911 + 912 + let linkpkg = ref false in 913 + 914 + let packages = ref [] in 915 + let predicates = ref [] in 916 + let dontlink = ref [] in 917 + 918 + let syntax_preds = ref [] in 919 + let pp_opts = ref [] in 920 + let ppx_opts = ref [] in 921 + let pp_specified = ref false in 922 + 923 + let type_of_threads = 924 + try package_property [] "threads" "type_of_threads" 925 + with Not_found -> "ignore" 926 + in 927 + let threads_default = 928 + match type_of_threads with 929 + "posix" -> `POSIX_threads 930 + | "vm" -> `VM_threads 931 + | _ -> `None 932 + in 933 + let threads = ref `None in 934 + let support_threads() = 935 + if threads_default = `None then 936 + failwith "threading is not supported on this platform" in 937 + 938 + let add_switch name = 939 + Arg.Unit (fun () -> 940 + switches := name :: !switches; 941 + pass_options := !pass_options @ [name]) in 942 + let add_spec_fn name s = 943 + pass_options := !pass_options @ [name; s] in 944 + let add_spec name = 945 + Arg.String (add_spec_fn name) in 946 + let add_contracted_spec_fn name s = 947 + pass_options := !pass_options @ [name ^ s] in 948 + let add_contracted_spec name = 949 + Arg.String (add_contracted_spec_fn name) in 950 + let add_pkg = 951 + Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in 952 + let add_pred = 953 + Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in 954 + let add_dontlink = 955 + Arg.String (fun s -> dontlink := !dontlink @ (Fl_split.in_words s)) in 956 + let add_syntax_pred = 957 + Arg.String (fun s -> syntax_preds := !syntax_preds @ (Fl_split.in_words s)) in 958 + let add_pp_opt = 959 + Arg.String (fun s -> pp_opts := !pp_opts @ [s]) in 960 + let add_dll_pkg = 961 + Arg.String (fun s -> dll_pkgs := !dll_pkgs @ (Fl_split.in_words s)) in 962 + let ignore_error = ref false in 963 + 964 + let native_spec_opt = 965 + match which with 966 + | "ocamlc" -> Ocaml_args.ocamlc_spec 967 + | "ocamlcp" -> Ocaml_args.ocamlcp_spec 968 + | "ocamlmklib" -> Ocaml_args.ocamlmklib_spec 969 + | "ocamlmktop" -> Ocaml_args.ocamlmktop_spec 970 + | "ocamlopt" -> Ocaml_args.ocamlopt_spec 971 + | "ocamloptp" -> Ocaml_args.ocamloptp_spec 972 + | _ -> None in 973 + let native_spec = 974 + match native_spec_opt with 975 + | None -> failwith ("Not supported in your configuration: " ^ which) 976 + | Some s -> s in 977 + 978 + let arg_spec = 979 + List.flatten 980 + [ [ 981 + "-package", add_pkg, 982 + "<name> Refer to package when compiling"; 983 + "-linkpkg", Arg.Set linkpkg, 984 + " Link the packages in"; 985 + "-predicates", add_pred, 986 + "<p> Add predicate <p> when resolving package properties"; 987 + "-dontlink", add_dontlink, 988 + "<name> Do not link in package <name> and its ancestors"; 989 + "-syntax", add_syntax_pred, 990 + "<p> Use preprocessor with predicate <p>"; 991 + "-ppopt", add_pp_opt, 992 + "<opt> Append option <opt> to preprocessor invocation"; 993 + "-ppxopt", Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]), 994 + "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>"; 995 + "-dllpath-pkg", add_dll_pkg, 996 + "<pkg> Add -dllpath for this package"; 997 + "-dllpath-all", Arg.Set dll_pkgs_all, 998 + " Add -dllpath for all linked packages"; 999 + "-ignore-error", Arg.Set ignore_error, 1000 + " Ignore the 'error' directive in META files"; 1001 + "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]), 1002 + "<opt> Pass option <opt> directly to ocamlc/opt/mklib/mktop"; 1003 + "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]), 1004 + " Pass all remaining options directly"; 1005 + "-only-show", Arg.Set only_show, 1006 + " Only show the constructed command, but do not exec it\nSTANDARD OPTIONS:"; 1007 + ]; 1008 + 1009 + merge_native_arguments 1010 + native_spec 1011 + add_switch 1012 + add_spec 1013 + ( 1014 + [ "-cclib", 1015 + Arg.String (fun s -> pass_files := !pass_files @ [ Cclib s ]); 1016 + 1017 + "-I", (Arg.String 1018 + (fun s -> 1019 + let s = resolve_path s in 1020 + if Sys.file_exists s then incpath := s :: !incpath; (* reverted below *) 1021 + add_spec_fn "-I" (slashify s) )); 1022 + 1023 + "-impl", 1024 + Arg.String (fun s -> pass_files := !pass_files @ [ Impl(slashify s) ]); 1025 + 1026 + "-intf", 1027 + Arg.String (fun s -> pass_files := !pass_files @ [ Intf(slashify s) ]); 1028 + 1029 + "-pp", 1030 + Arg.String (fun s -> pp_specified := true; add_spec_fn "-pp" s); 1031 + 1032 + "-thread", 1033 + Arg.Unit (fun _ -> support_threads(); threads := threads_default); 1034 + 1035 + "-vmthread", 1036 + Arg.Unit (fun _ -> support_threads(); threads := `VM_threads); 1037 + 1038 + "-", 1039 + Arg.String (fun s -> pass_files := !pass_files @ [ Pass s ]); 1040 + 1041 + ] @ 1042 + if which = "ocamlmklib" then 1043 + List.map 1044 + (fun opt -> 1045 + (opt, add_contracted_spec opt) 1046 + ) 1047 + contracted_ocamlmklib_options 1048 + else 1049 + [] 1050 + ) 1051 + ] in 1052 + 1053 + let (current,args) = 1054 + if which = "ocamlmklib" then 1055 + (* Special processing for -L, -R etc. *) 1056 + let c = !(Arg.current) in 1057 + let l = Array.length Sys.argv in 1058 + let args1 = Array.sub Sys.argv (c+1) (l-c-1) in 1059 + let args2 = 1060 + Array.append 1061 + [| Sys.argv.(0) |] 1062 + (Fl_args.rewrite_contracted_args 1063 + arg_spec 1064 + contracted_ocamlmklib_options 1065 + args1 1066 + ) in 1067 + (ref 0, args2) 1068 + else 1069 + (Arg.current, Sys.argv) in 1070 + 1071 + parse_args 1072 + ~current 1073 + ~args 1074 + arg_spec 1075 + (fun s -> pass_files := !pass_files @ [ Pass s]) 1076 + ("usage: ocamlfind " ^ which ^ " [options] file ..."); 1077 + 1078 + (* ---- Start requirements analysis ---- *) 1079 + 1080 + begin match which with 1081 + "ocamlc" -> predicates := "byte" :: !predicates; 1082 + | "ocamlcp" -> predicates := "byte" :: !predicates; 1083 + | "ocamlmklib" -> predicates := "byte" :: "native" :: !predicates; 1084 + | "ocamlmktop" -> predicates := "byte" :: "create_toploop" :: !predicates; 1085 + | "ocamlopt" -> predicates := "native" :: !predicates; 1086 + | "ocamloptp" -> predicates := "native" :: !predicates; 1087 + | _ -> failwith "unsupported backend" 1088 + end; 1089 + 1090 + incpath := List.rev !incpath; 1091 + 1092 + ( match !threads with 1093 + `None -> 1094 + () 1095 + 1096 + | `VM_threads -> 1097 + if which = "ocamlopt" then 1098 + failwith "ocamlopt does not support multi-threaded programs for your configuration"; 1099 + pass_options := !pass_options @ [ "-vmthread" ]; 1100 + predicates := "mt" :: "mt_vm" :: !predicates; 1101 + 1102 + | `POSIX_threads -> 1103 + if not Findlib_config.ocaml_has_meta_files then 1104 + pass_options := !pass_options @ [ "-thread" ]; 1105 + predicates := "mt" :: "mt_posix" :: !predicates; 1106 + ); 1107 + 1108 + if List.mem "-p" !switches then 1109 + predicates := "gprof" :: !predicates; 1110 + 1111 + if Findlib_config.ocaml_has_autolinking && 1112 + not (List.mem "-noautolink" !switches) 1113 + then 1114 + predicates := "autolink" :: !predicates; 1115 + 1116 + if !syntax_preds <> [] then begin 1117 + predicates := "syntax" :: !predicates; 1118 + syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds; 1119 + end; 1120 + 1121 + let verbose = 1122 + if List.mem "-verbose" !switches then Verbose else 1123 + if !only_show then Only_show else 1124 + Normal in 1125 + 1126 + if !pp_specified && !syntax_preds <> [] then 1127 + prerr_endline("ocamlfind: [WARNING] -pp overrides the effect of -syntax partly"); 1128 + 1129 + (* check packages: *) 1130 + check_package_list !packages; 1131 + check_package_list !dontlink; 1132 + 1133 + let eff_packages = 1134 + package_deep_ancestors !predicates !packages in 1135 + 1136 + let eff_dontlink = 1137 + package_deep_ancestors !predicates !dontlink in 1138 + 1139 + let eff_link = 1140 + List.flatten 1141 + (List.map 1142 + (fun pkg -> if List.mem pkg eff_dontlink then [] else [pkg]) 1143 + eff_packages) in 1144 + 1145 + 1146 + let eff_packages_dl = 1147 + remove_dups (List.map package_directory eff_packages) in 1148 + 1149 + let eff_link_dl = 1150 + remove_dups (List.map package_directory eff_link) in 1151 + 1152 + (* Conflict report: *) 1153 + conflict_report (!incpath @ ["."; Findlib.ocaml_stdlib() ]) eff_packages; 1154 + 1155 + (* ---- End of requirements analysis ---- *) 1156 + 1157 + (* Add the pkg_<name> predicates: *) 1158 + predicates := List.map (fun pkg -> "pkg_" ^ pkg) eff_packages @ !predicates; 1159 + 1160 + (* Check on [warning] directives: *) 1161 + List.iter 1162 + (fun pkg -> 1163 + try 1164 + let warning = package_property !predicates pkg "warning" in 1165 + prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^ 1166 + "': " ^ warning) 1167 + with 1168 + Not_found -> () 1169 + ) 1170 + eff_packages; 1171 + 1172 + (* Check on [error] directives: *) 1173 + List.iter 1174 + (fun pkg -> 1175 + try 1176 + let error = package_property !predicates pkg "error" in 1177 + if !ignore_error then 1178 + prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^ 1179 + "' signals error: " ^ error) 1180 + else 1181 + failwith ("Error from package `" ^ pkg ^ "': " ^ error) 1182 + with 1183 + Not_found -> () 1184 + ) 1185 + eff_packages; 1186 + 1187 + if verbose = Verbose then begin 1188 + if !syntax_preds <> [] then 1189 + print_string ("Effective set of preprocessor predicates: " ^ 1190 + String.concat "," !syntax_preds ^ "\n"); 1191 + print_string ("Effective set of compiler predicates: " ^ 1192 + String.concat "," !predicates ^ "\n"); 1193 + end; 1194 + 1195 + let stdlibdir = Fl_split.norm_dir (Findlib.ocaml_stdlib()) in 1196 + let threads_dir = Filename.concat stdlibdir "threads" in 1197 + let vmthreads_dir = Filename.concat stdlibdir "vmthreads" in 1198 + 1199 + let create_toploop = 1200 + List.mem "create_toploop" !predicates && List.mem "findlib" eff_link in 1201 + let have_dynload = 1202 + List.mem "findlib.dynload" eff_link in 1203 + let initl_file_needed = 1204 + create_toploop || have_dynload in 1205 + 1206 + let initl_file_name = 1207 + if initl_file_needed then 1208 + Filename.temp_file "findlib_initl" ".ml" 1209 + else 1210 + "" 1211 + in 1212 + 1213 + (* initl_file_name: the initialization code inserted at the end of 1214 + * the cma/cmo list (initl = init last) 1215 + *) 1216 + 1217 + if initl_file_needed then begin 1218 + (* Generate initializer for "findlib_top.cma" *) 1219 + let initl = open_out_gen 1220 + [Open_wronly; Open_trunc; Open_text] 1221 + 0o777 1222 + initl_file_name in 1223 + try 1224 + List.iter 1225 + (fun pkg -> 1226 + Printf.fprintf 1227 + initl 1228 + "let () = Findlib.record_package Findlib.Record_core %S;;\n" 1229 + pkg 1230 + ) 1231 + eff_packages; 1232 + output_string initl 1233 + ("let () = Findlib.record_package_predicates [" ^ 1234 + String.concat ";" 1235 + (List.map 1236 + (fun pred -> "\"" ^ String.escaped pred ^ "\"") 1237 + !predicates 1238 + ) ^ 1239 + "];;\n"); 1240 + close_out initl; 1241 + with 1242 + any -> 1243 + close_out initl; 1244 + Sys.remove initl_file_name; 1245 + raise any 1246 + end; 1247 + 1248 + if initl_file_needed && verbose <> Only_show then 1249 + at_exit 1250 + (fun () -> 1251 + let tr f x = try f x with _ -> () in 1252 + tr Sys.remove initl_file_name; 1253 + tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmi"); 1254 + tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmo"); 1255 + ); 1256 + 1257 + let exclude_list = 1258 + if Findlib_config.ocaml_has_meta_files then 1259 + [ stdlibdir ] 1260 + else 1261 + [ stdlibdir; threads_dir; vmthreads_dir ] in 1262 + (* Don't generate -I options for these directories because there is 1263 + * also some magic in ocamlc/ocamlopt that would not work otherwise 1264 + *) 1265 + 1266 + let i_options = 1267 + List.flatten 1268 + (List.map 1269 + (fun pkgdir -> 1270 + let npkgdir = Fl_split.norm_dir pkgdir in 1271 + if List.mem npkgdir exclude_list then 1272 + [] 1273 + else 1274 + [ "-I"; slashify pkgdir; 1275 + (* "-ccopt"; out_path ~prefix:"-I" pkgdir; -- see comment *) 1276 + ]) 1277 + eff_packages_dl) in 1278 + (* We no longer emit -ccopt options, because ocamlc/ocamlopt already 1279 + do that for each -I if the C compiler needs to be invoked 1280 + (so far I tracked it, ocamlc/ocamlopt have always done this, even 1281 + back in 1996). 1282 + *) 1283 + 1284 + let l_options = [] in 1285 + (* Also, no longer -ccopt -L options. Current ocamlc/ocamlopt do that 1286 + for each -I option passed to them anyway, so we can omit that here. 1287 + See ocaml change (quite old, but I was not aware of it): 1288 + http://camlcvs.inria.fr/cgi-bin/cvsweb/ocaml/asmcomp/asmlink.ml.diff?r1=1.38;r2=1.39 1289 + *) 1290 + (* 1291 + let l_options = 1292 + List.flatten 1293 + (List.map 1294 + (fun pkgdir -> 1295 + let npkgdir = Fl_split.norm_dir pkgdir in 1296 + if List.mem npkgdir exclude_list then 1297 + [] 1298 + else 1299 + if Findlib_config.system = "win32" || Findlib_config.system = "win64" then 1300 + (* Microsoft toolchain *) 1301 + [ "-ccopt"; out_path ~prefix:"/link /libpath:" pkgdir ] 1302 + else 1303 + [ "-ccopt"; out_path ~prefix:"-L" pkgdir; ]) 1304 + eff_link_dl) in 1305 + *) 1306 + 1307 + let archives = 1308 + List.flatten 1309 + (List.map 1310 + (fun pkg -> 1311 + let al = try package_property !predicates pkg "archive" 1312 + with Not_found -> "" in 1313 + let al_ext = 1314 + if have_dynload && pkg = "findlib.dynload" then 1315 + [ initl_file_name ] 1316 + else 1317 + [] in 1318 + let pkg_dir = 1319 + if not Findlib_config.ocaml_has_meta_files && pkg = "threads" then 1320 + (* MAGIC for pre-5.x days *) 1321 + match !threads with 1322 + `None -> stdlibdir 1323 + | `VM_threads -> vmthreads_dir 1324 + | `POSIX_threads -> threads_dir 1325 + else 1326 + package_directory pkg in 1327 + let pkg_dir = slashify pkg_dir in 1328 + List.map 1329 + (fun arch -> 1330 + resolve_path ~base:pkg_dir arch) 1331 + (Fl_split.in_words al @ al_ext) 1332 + ) 1333 + eff_link) 1334 + @ 1335 + (if create_toploop then 1336 + [ initl_file_name ] 1337 + else 1338 + [] 1339 + ) 1340 + in 1341 + 1342 + let linkopts = 1343 + List.flatten 1344 + (List.map 1345 + (fun pkg -> 1346 + let ol = try package_property !predicates pkg "linkopts" 1347 + with Not_found -> "" in 1348 + Fl_split.in_words_ws ol) 1349 + (List.rev eff_link)) in 1350 + 1351 + let pp_command = 1352 + if !pp_specified then 1353 + [] 1354 + else 1355 + process_pp_spec !syntax_preds !packages !pp_opts 1356 + in 1357 + 1358 + let ppx_commands = 1359 + process_ppx_spec !predicates !packages !ppx_opts 1360 + in 1361 + 1362 + let pass_files' = 1363 + List.flatten 1364 + (List.map 1365 + (function 1366 + Pass s -> 1367 + if s <> "" && s.[0] = '-' 1368 + then [ "-"; String.sub s 1 (String.length s - 1) ] 1369 + else [ resolve_path s ] 1370 + | Impl s -> 1371 + [ "-impl"; resolve_path s ] 1372 + | Intf s -> 1373 + [ "-intf"; resolve_path s ] 1374 + | Cclib s -> 1375 + [ "-cclib"; s ] 1376 + ) 1377 + !pass_files) 1378 + in 1379 + 1380 + let dll_dirs = 1381 + remove_dups 1382 + ((List.map package_directory !dll_pkgs) @ 1383 + (if !dll_pkgs_all then eff_link_dl else [])) in 1384 + 1385 + let dll_options = 1386 + List.flatten 1387 + (List.map 1388 + (fun pkg -> ["-dllpath"; slashify pkg] ) 1389 + dll_dirs) in 1390 + 1391 + let mklib_options = 1392 + ["-ocamlc"; Findlib.command `ocamlc; 1393 + "-ocamlopt"; Findlib.command `ocamlopt] in 1394 + 1395 + let arguments = 1396 + (if which = "ocamlmklib" then mklib_options else []) @ 1397 + !pass_options @ (* other options from the command line *) 1398 + i_options @ (* Generated -I options from package analysis *) 1399 + pp_command @ (* Optional preprocessor command *) 1400 + ppx_commands @ (* Optional ppx extension commands *) 1401 + (if !linkpkg then l_options else []) @ (* Generated -ccopt -L options *) 1402 + (if !linkpkg then archives else []) @ (* Gen file names to link *) 1403 + pass_files' @ (* File names from cmd line *) 1404 + (if !linkpkg then linkopts else []) @ (* Generated link options *) 1405 + dll_options (* Generated -dllpath options *) 1406 + in 1407 + 1408 + let actual_command = 1409 + match which with 1410 + "ocamlc" -> Findlib.command `ocamlc 1411 + | "ocamlopt" -> Findlib.command `ocamlopt 1412 + | "ocamlcp" -> Findlib.command `ocamlcp 1413 + | "ocamlmklib" -> Findlib.command `ocamlmklib 1414 + | "ocamlmktop" -> Findlib.command `ocamlmktop 1415 + | "ocamloptp" -> Findlib.command `ocamloptp 1416 + | _ -> assert false 1417 + in 1418 + 1419 + run_command verbose actual_command arguments 1420 + ;; 1421 + 1422 + 1423 + (************************************************************************) 1424 + 1425 + let ocamldoc() = 1426 + 1427 + let packages = ref [] in 1428 + let predicates = ref [] in 1429 + let syntax_preds = ref [] in 1430 + let pp_opts = ref [] in 1431 + let ppx_opts = ref [] in 1432 + let pp_specified = ref false in 1433 + 1434 + let verbose = ref Normal in 1435 + 1436 + let options = ref [] in 1437 + 1438 + let native_spec = 1439 + match Ocaml_args.ocamldoc_spec with 1440 + | None -> failwith "Not supported in your configuration: ocamldoc" 1441 + | Some s -> s in 1442 + 1443 + parse_args 1444 + ~align:false 1445 + ( Arg.align 1446 + [ "-package", 1447 + Arg.String (fun s -> 1448 + packages := !packages @ Fl_split.in_words s), 1449 + "<name> Add this package to the search path"; 1450 + 1451 + "-predicates", 1452 + Arg.String (fun s -> 1453 + predicates := !predicates @ Fl_split.in_words s), 1454 + "<p> Add predicate <p> when calculating dependencies"; 1455 + 1456 + "-syntax", 1457 + Arg.String (fun s -> 1458 + syntax_preds := !syntax_preds @ Fl_split.in_words s), 1459 + "<p> Use preprocessor with predicate <p>"; 1460 + 1461 + "-ppopt", 1462 + Arg.String (fun s -> pp_opts := !pp_opts @ [s]), 1463 + "<opt> Append option <opt> to preprocessor invocation"; 1464 + 1465 + "-ppxopt", 1466 + Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]), 1467 + "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>"; 1468 + 1469 + "-thread", 1470 + Arg.Unit (fun () -> predicates := "mt" :: "mt_posix" :: !predicates), 1471 + " Assume kernel multi-threading when doing dependency analyses"; 1472 + 1473 + "-vmthread", 1474 + Arg.Unit (fun () -> predicates := "mt" :: "mt_vm" :: !predicates), 1475 + " Assume bytecode multi-threading when doing dependency analyses"; 1476 + 1477 + "-passopt", 1478 + Arg.String (fun s -> options := !options @ [s]), 1479 + "<opt> Pass this option directly to ocamldoc"; 1480 + 1481 + "-passrest", 1482 + Arg.Rest (fun s -> options := !options @ [s]), 1483 + " Pass all remaining options directly to ocamldoc"; 1484 + 1485 + "-only-show", 1486 + Arg.Unit (fun () -> verbose := Only_show), 1487 + " Only show the constructed command but do not exec it"; 1488 + 1489 + "-verbose", 1490 + Arg.Unit (fun () -> verbose := Verbose), 1491 + " Be verbose\nSTANDARD OPTIONS:"; 1492 + ] 1493 + @ 1494 + ( merge_native_arguments 1495 + native_spec 1496 + (fun s -> 1497 + Arg.Unit (fun () -> 1498 + options := !options @ [s])) 1499 + (fun s -> 1500 + Arg.String (fun arg -> 1501 + options := !options @ [s; arg])) 1502 + [ "-v", Arg.Unit (fun () -> verbose := Verbose); 1503 + "-pp", Arg.String (fun s -> 1504 + pp_specified := true; 1505 + options := !options @ ["-pp"; s]); 1506 + ] 1507 + ) 1508 + ) 1509 + (fun s -> options := !options @ [s]) 1510 + "usage: ocamlfind ocamldoc <options> <files>..."; 1511 + 1512 + check_package_list !packages; 1513 + 1514 + if !syntax_preds <> [] then ( 1515 + predicates := "syntax" :: !predicates; 1516 + syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds; 1517 + ); 1518 + 1519 + if !verbose = Verbose then begin 1520 + if !syntax_preds <> [] then 1521 + print_string ("Effective set of preprocessor predicates: " ^ 1522 + String.concat "," !syntax_preds ^ "\n"); 1523 + print_string ("Effective set of compiler predicates: " ^ 1524 + String.concat "," !predicates ^ "\n"); 1525 + end; 1526 + 1527 + if !pp_specified && !syntax_preds <> [] then 1528 + prerr_endline("Warning: -pp overrides the effect of -syntax partly"); 1529 + 1530 + let pp_command = 1531 + if !pp_specified then 1532 + [] 1533 + else 1534 + process_pp_spec !syntax_preds !packages !pp_opts 1535 + in 1536 + 1537 + let ppx_commands = 1538 + process_ppx_spec !predicates !packages !ppx_opts 1539 + in 1540 + 1541 + let eff_packages = 1542 + package_deep_ancestors !predicates !packages in 1543 + 1544 + (* Check on [error] directives (turned into warnings): *) 1545 + List.iter 1546 + (fun pkg -> 1547 + try 1548 + let error = package_property !predicates pkg "error" in 1549 + prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^ 1550 + "' signals error: " ^ error) 1551 + with 1552 + Not_found -> () 1553 + ) 1554 + eff_packages; 1555 + 1556 + let eff_packages_dl = 1557 + remove_dups (List.map package_directory eff_packages) in 1558 + 1559 + let arguments = 1560 + (List.flatten (List.map (fun d -> [ "-I"; slashify d ]) eff_packages_dl)) @ 1561 + pp_command @ 1562 + ppx_commands @ 1563 + !options in 1564 + 1565 + let actual_command = Findlib.command `ocamldoc in 1566 + 1567 + run_command !verbose actual_command arguments 1568 + ;; 1569 + 1570 + 1571 + (************************************************************************) 1572 + 1573 + (* From ocamldep source code: *) 1574 + let depends_on_char, continuation_char = 1575 + match Sys.os_type with 1576 + | "Unix" | "BeOS" | "Win32" | "Cygwin" -> ':', '\\' 1577 + | "MacOS" -> '\196', '\182' 1578 + | _ -> assert false 1579 + ;; 1580 + 1581 + 1582 + let suppress_targets suffix = 1583 + (* If [line] begins with "target: dependencies ...", and [target] is a 1584 + * file name ending in [suffix], this line is suppressed, and all 1585 + * follow-up lines. 1586 + *) 1587 + let do_suppress = ref false in 1588 + fun line -> 1589 + let target = 1590 + try 1591 + let k = String.index_from line 0 depends_on_char in (* or Not_found *) 1592 + let target_string = String.sub line 0 k in 1593 + if String.contains target_string ' ' then raise Not_found; 1594 + Some target_string 1595 + with 1596 + Not_found -> None 1597 + in 1598 + begin match target with 1599 + Some target_string -> 1600 + do_suppress := Filename.check_suffix target_string suffix; 1601 + | None -> 1602 + () 1603 + end; 1604 + if !do_suppress then 1605 + None 1606 + else 1607 + Some line 1608 + ;; 1609 + 1610 + 1611 + let ocamldep () = 1612 + 1613 + let switches = ref [] in 1614 + let pass_options = ref [] in 1615 + let pass_files = ref [] in 1616 + 1617 + let packages = ref [] in 1618 + let predicates = ref [] in 1619 + let syntax_preds = ref [] in 1620 + let pp_opts = ref [] in 1621 + let ppx_opts = ref [] in 1622 + let pp_specified = ref false in 1623 + 1624 + let verbose = ref Normal in 1625 + let native_filter = ref false in 1626 + let bytecode_filter = ref false in 1627 + 1628 + let add_switch name = 1629 + Arg.Unit (fun () -> 1630 + switches := name :: !switches; 1631 + pass_options := !pass_options @ [name]) in 1632 + let add_spec_fn name s = 1633 + pass_options := !pass_options @ [name; s] in 1634 + let add_spec name = Arg.String (add_spec_fn name) in 1635 + let add_pred = 1636 + Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in 1637 + let add_syntax_pred = 1638 + Arg.String (fun s -> syntax_preds := !syntax_preds @ (Fl_split.in_words s)) in 1639 + let add_pp_opt = 1640 + Arg.String (fun s -> pp_opts := !pp_opts @ [s]) in 1641 + let add_pkg = 1642 + Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in 1643 + 1644 + let native_spec = 1645 + match Ocaml_args.ocamldep_spec with 1646 + | None -> failwith "Not supported in your configuration: ocamldep" 1647 + | Some s -> s in 1648 + 1649 + parse_args 1650 + ( [ 1651 + "-syntax", add_syntax_pred, 1652 + "<p> Use preprocessor with predicate <p>"; 1653 + "-package", add_pkg, 1654 + "<p> Add preprocessor package <p>"; 1655 + "-predicates", add_pred, 1656 + "<p> Add predicate <p> when calculating dependencies"; 1657 + "-ppopt", add_pp_opt, 1658 + "<opt> Append option <opt> to preprocessor invocation"; 1659 + "-ppxopt", Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]), 1660 + "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>"; 1661 + "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]), 1662 + "<opt> Pass option <opt> directly to ocamlc/opt/mktop"; 1663 + "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]), 1664 + " Pass all remaining options directly"; 1665 + "-native-filter", Arg.Set native_filter, 1666 + " Output only dependencies for native code (implies -native)"; 1667 + "-bytecode-filter", Arg.Set bytecode_filter, 1668 + " Output only dependencies for bytecode"; 1669 + "-only-show", Arg.Unit (fun () -> verbose := Only_show), 1670 + " Only show the constructed command but do not exec it"; 1671 + 1672 + "-verbose", Arg.Unit (fun () -> verbose := Verbose), 1673 + " Print calls to external commands\nSTANDARD OPTIONS:"; 1674 + ] 1675 + @ 1676 + ( merge_native_arguments 1677 + native_spec 1678 + add_switch 1679 + add_spec 1680 + [ "-I", 1681 + Arg.String (fun s -> add_spec_fn "-I" (slashify (resolve_path s))); 1682 + 1683 + "-pp", Arg.String (fun s -> pp_specified := true; 1684 + add_spec_fn "-pp" s); 1685 + ] 1686 + ) 1687 + ) 1688 + (fun s -> pass_files := !pass_files @ [ s]) 1689 + ("usage: ocamlfind ocamldep [options] file ..."); 1690 + 1691 + check_package_list !packages; 1692 + 1693 + if !native_filter && !bytecode_filter then 1694 + failwith "The options -native-filter and -bytecode-filter are incompatible"; 1695 + 1696 + if !native_filter && not (List.mem "-native" !switches) then 1697 + pass_options := "-native" :: !pass_options; 1698 + 1699 + if !syntax_preds <> [] then 1700 + syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds; 1701 + 1702 + if !verbose = Verbose && !syntax_preds <> [] then 1703 + print_string ("Effective set of preprocessor predicates: " ^ 1704 + String.concat "," !syntax_preds ^ "\n"); 1705 + 1706 + if !pp_specified && !syntax_preds <> [] then 1707 + prerr_endline("Warning: -pp overrides the effect of -syntax partly"); 1708 + 1709 + let pp_command = 1710 + if !pp_specified then 1711 + [] 1712 + else 1713 + process_pp_spec !syntax_preds !packages !pp_opts 1714 + in 1715 + 1716 + let ppx_commands = 1717 + process_ppx_spec !predicates !packages !ppx_opts 1718 + in 1719 + 1720 + let arguments = 1721 + !pass_options @ 1722 + pp_command @ 1723 + ppx_commands @ 1724 + !pass_files 1725 + in 1726 + 1727 + let actual_command = Findlib.command `ocamldep in 1728 + let filter = 1729 + if !native_filter then 1730 + (* Suppress when target is ".cmo": *) 1731 + Some (suppress_targets ".cmo") 1732 + else 1733 + if !bytecode_filter then 1734 + (* Suppress when target is ".cmx": *) 1735 + Some (suppress_targets ".cmx") 1736 + else 1737 + None 1738 + in 1739 + 1740 + run_command ?filter !verbose actual_command arguments 1741 + ;; 1742 + 1743 + 1744 + (************************************************************************) 1745 + 1746 + let ocamlbrowser () = 1747 + (* let switches = ref [] in *) 1748 + let pass_options = ref [] in 1749 + let add_all = ref false in 1750 + 1751 + let packages = ref [] in 1752 + 1753 + (* 1754 + let add_switch name = 1755 + Arg.Unit (fun () -> 1756 + switches := name :: !switches; 1757 + pass_options := !pass_options @ [name]) in 1758 + *) 1759 + let add_spec_fn name s = 1760 + pass_options := !pass_options @ [name; s] in 1761 + (* let add_spec name = Arg.String (add_spec_fn name) in *) 1762 + let add_pkg = 1763 + Arg.String (fun s -> packages := !packages @ (Fl_split.in_words s)) in 1764 + 1765 + parse_args 1766 + [ 1767 + "-I", Arg.String (fun s -> add_spec_fn "-I" (slashify(resolve_path s))), 1768 + "<dir> Add <dir> to the list of include directories"; 1769 + "-all", Arg.Set add_all, 1770 + " Add all packages to include path"; 1771 + "-package", add_pkg, 1772 + "<p> Add package <p> to include path"; 1773 + "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]), 1774 + "<opt> Pass option <opt> directly to ocamlbrowser"; 1775 + "-passrest", Arg.Rest (fun s -> pass_options := !pass_options @ [s]), 1776 + " Pass all remaining options directly"; 1777 + ] 1778 + (fun s -> raise (Arg.Bad ("Unexpected argument: " ^ s))) 1779 + ("usage: ocamlfind ocamlbrowser [options] file ..."); 1780 + 1781 + if !add_all then packages := Fl_package_base.list_packages(); 1782 + check_package_list !packages; 1783 + 1784 + let arguments = 1785 + !pass_options @ 1786 + (List.flatten 1787 + (List.map 1788 + (fun pkg -> 1789 + let dir = Findlib.package_directory pkg in 1790 + [ "-I"; slashify dir ] 1791 + ) 1792 + !packages 1793 + ) 1794 + ) 1795 + in 1796 + 1797 + let actual_command = Findlib.command `ocamlbrowser in 1798 + 1799 + run_command Normal actual_command arguments 1800 + ;; 1801 + 1802 + 1803 + (************************************************************************) 1804 + 1805 + 1806 + let copy_file ?(rename = (fun name -> name)) ?(append = "") src dstdir = 1807 + (* A system-independent function to copy the file src to dstdir *) 1808 + let outname = rename (Filename.basename src) in 1809 + let ch_in = open_in_bin src in 1810 + (* Determine the permissions of the file: the permissions of the 1811 + * user bits are extended to all groups (user, group, world bits), 1812 + * and the umask is applied to the result. 1813 + * Furthermore, the mtime of the file is preserved. This seems to be 1814 + * important for BSD-style archives (otherwise the system is confused 1815 + * and wants that ranlib is run again). For simplicity, the atime is 1816 + * set to the mtime, too. 1817 + *) 1818 + let s = Unix.stat src in 1819 + let perm = s.Unix.st_perm in 1820 + let user_perm = (perm land 0o700) lsr 6 in 1821 + let perm' = user_perm lor (user_perm lsl 3) lor (user_perm lsl 6) in 1822 + try 1823 + let outpath = Filename.concat dstdir outname in 1824 + if Sys.file_exists outpath then 1825 + prerr_endline ("ocamlfind: [WARNING] Overwriting file " ^ outpath); 1826 + let ch_out = open_out_gen 1827 + [Open_wronly; Open_creat; Open_trunc; Open_binary] 1828 + perm' 1829 + outpath in 1830 + try 1831 + let buflen = 4096 in 1832 + let buf = Bytes.create buflen in 1833 + let pos = ref 0 in 1834 + let len = ref (input ch_in buf 0 buflen) in 1835 + while !len > 0 do 1836 + output ch_out buf !pos !len; 1837 + len := input ch_in buf !pos buflen; 1838 + done; 1839 + output_string ch_out append; 1840 + close_out ch_out; 1841 + close_in ch_in; 1842 + Unix.utimes outpath s.Unix.st_mtime s.Unix.st_mtime; 1843 + 1844 + prerr_endline("Installed " ^ outpath); 1845 + with 1846 + exc -> close_out ch_out; raise exc 1847 + with 1848 + exc -> close_in ch_in; raise exc 1849 + ;; 1850 + 1851 + 1852 + let install_create_directory pkgname dstdir = 1853 + try 1854 + Unix.mkdir dstdir 0o777 1855 + with 1856 + Unix.Unix_error(Unix.EEXIST,_,_) -> 1857 + () 1858 + | Unix.Unix_error(Unix.ENOENT,_,_) 1859 + | Unix.Unix_error(Unix.ENOTDIR,_,_) -> 1860 + failwith ("Bad configuration: Cannot mkdir " ^ dstdir ^ " because a path component does not exist or is not a directory") 1861 + | Unix.Unix_error(e,_,_) -> 1862 + failwith ("Cannot mkdir " ^ dstdir ^ ": " ^ 1863 + Unix.error_message e) 1864 + ;; 1865 + 1866 + 1867 + let create_owner_file pkg file = 1868 + let outpath = file ^ ".owner" in 1869 + let f = open_out outpath in 1870 + try 1871 + output_string f (pkg ^ "\n"); 1872 + close_out f; 1873 + prerr_endline("Installed " ^ outpath); 1874 + with 1875 + exc -> close_out f; raise exc 1876 + ;; 1877 + 1878 + let trim_cr s = 1879 + let len = String.length s in 1880 + if len > 0 && String.get s (len-1) = '\r' then 1881 + String.sub s 0 (len-1) 1882 + else 1883 + s 1884 + 1885 + let find_owned_files pkg dir = 1886 + let files = Array.to_list(Sys.readdir dir) in 1887 + List.filter 1888 + (fun file -> 1889 + let owner_file = 1890 + if Filename.check_suffix file ".owner" then 1891 + file 1892 + else 1893 + file ^ ".owner" in 1894 + (List.mem owner_file files) && ( 1895 + try 1896 + let fd = 1897 + Unix.openfile (Filename.concat dir owner_file) [Unix.O_RDONLY] 0 in 1898 + let f = 1899 + Unix.in_channel_of_descr fd in 1900 + try 1901 + let line = trim_cr (input_line f) in 1902 + let is_my_file = (line = pkg) in 1903 + close_in f; 1904 + is_my_file 1905 + with 1906 + | End_of_file -> close_in f; false 1907 + | exc -> close_in f; raise exc 1908 + with 1909 + | Unix.Unix_error(Unix.ENOENT,_,_) -> 1910 + (* the owner file might have been removed by a package 1911 + removal that is being done in parallel 1912 + *) 1913 + false 1914 + | Unix.Unix_error(code, _, arg) -> 1915 + raise(sys_error code arg) 1916 + ) 1917 + ) 1918 + files 1919 + ;; 1920 + 1921 + 1922 + 1923 + exception Missing_archives of Fl_metascanner.pkg_expr 1924 + 1925 + let rec patch_archives pkgdir pkg = 1926 + (* First remove all missing files from archive variables: *) 1927 + let defs' = 1928 + List.map 1929 + (fun def -> 1930 + if def.Fl_metascanner.def_var = "archive" then ( 1931 + let files = Fl_split.in_words def.Fl_metascanner.def_value in 1932 + let files' = 1933 + List.filter 1934 + (fun file -> 1935 + let p = Findlib.resolve_path ~base:pkgdir file in 1936 + Sys.file_exists p) 1937 + files in 1938 + { def with 1939 + Fl_metascanner.def_value = String.concat " " files' 1940 + } 1941 + ) 1942 + else def 1943 + ) 1944 + pkg.Fl_metascanner.pkg_defs in 1945 + (* Remove empty archive variables: *) 1946 + let defs'' = 1947 + List.filter 1948 + (fun def -> 1949 + def.Fl_metascanner.def_var <> "archive" || 1950 + Fl_split.in_words def.Fl_metascanner.def_value <> [] 1951 + ) 1952 + defs' in 1953 + (* Return the package or raise Not_found if all archives vanished: *) 1954 + let children = 1955 + (* Recursive patch, remove all Not_found packages: *) 1956 + List.flatten 1957 + (List.map 1958 + (fun (name, child) -> 1959 + try [ name, patch_archives pkgdir child ] 1960 + with Missing_archives _ -> [] 1961 + ) 1962 + pkg.Fl_metascanner.pkg_children) in 1963 + let pkg' = 1964 + { Fl_metascanner.pkg_defs = defs''; 1965 + pkg_children = children 1966 + } in 1967 + if List.exists (fun def -> def.Fl_metascanner.def_var = "archive") defs'' then 1968 + pkg' 1969 + else 1970 + raise (Missing_archives pkg') 1971 + ;; 1972 + 1973 + 1974 + let rec patch_pkg pkgdir pkg patches = 1975 + match patches with 1976 + | [] -> pkg 1977 + | (`Version v) :: patches' -> 1978 + let def = 1979 + { Fl_metascanner.def_var = "version"; 1980 + def_flav = `BaseDef; 1981 + def_preds = []; 1982 + def_value = v 1983 + } in 1984 + let defs = 1985 + List.filter 1986 + (fun d -> d.Fl_metascanner.def_var <> "version") 1987 + pkg.Fl_metascanner.pkg_defs in 1988 + let pkg' = 1989 + { pkg with 1990 + Fl_metascanner.pkg_defs = def :: defs 1991 + } in 1992 + patch_pkg pkgdir pkg' patches' 1993 + | (`Rmpkg n) :: patches' -> 1994 + let children = 1995 + List.filter 1996 + (fun (name,_) -> name <> n) 1997 + pkg.Fl_metascanner.pkg_children in 1998 + let pkg' = 1999 + { pkg with 2000 + Fl_metascanner.pkg_children = children 2001 + } in 2002 + patch_pkg pkgdir pkg' patches' 2003 + | `Archives :: patches' -> 2004 + let pkg' = 2005 + try patch_archives pkgdir pkg 2006 + with 2007 + Missing_archives p -> p in 2008 + patch_pkg pkgdir pkg' patches' 2009 + ;; 2010 + 2011 + 2012 + exception Skip_file;; 2013 + 2014 + type which = Auto | Dll | No_dll;; 2015 + 2016 + let meta_pkg meta_name = 2017 + let f = open_in meta_name in 2018 + try 2019 + let pkg = Fl_metascanner.parse f in 2020 + close_in f; 2021 + pkg 2022 + with 2023 + | Failure s 2024 + | Fl_metascanner.Error s -> 2025 + close_in f; 2026 + failwith ("Cannot parse '" ^ meta_name ^ "': " ^ s) 2027 + 2028 + let char_lowercase_ascii c = 2029 + (* Char.lowercase_ascii and String.lowercase_ascii first available in 2030 + OCaml-4.03, but we want to support earlier versions too 2031 + *) 2032 + if (c >= 'A' && c <= 'Z') 2033 + then Char.unsafe_chr(Char.code c + 32) 2034 + else c 2035 + 2036 + let string_lowercase_ascii s = 2037 + let n = String.length s in 2038 + let b = Bytes.create n in 2039 + for i = 0 to n - 1 do 2040 + Bytes.unsafe_set b i (char_lowercase_ascii (String.unsafe_get s i)) 2041 + done; 2042 + Bytes.to_string b 2043 + 2044 + 2045 + let install_package () = 2046 + let destdir = ref (default_location()) in 2047 + let metadir = ref (meta_directory()) in 2048 + let ldconf = ref (ocaml_ldconf()) in 2049 + let don't_add_directory_directive = ref false in 2050 + let pkgname = ref "" in 2051 + let auto_files = ref [] in 2052 + let dll_files = ref [] in 2053 + let nodll_files = ref [] in 2054 + let which = ref Auto in 2055 + let add_files = ref false in 2056 + let optional = ref false in 2057 + let patches = ref [] in 2058 + 2059 + let keywords = 2060 + [ "-destdir", (Arg.String (fun s -> destdir := s)), 2061 + ("<path> Set the destination directory (default: " ^ 2062 + !destdir ^ ")"); 2063 + "-metadir", (Arg.String (fun s -> metadir := s)), 2064 + ("<path> Install the META file into this directory (default: "^ 2065 + (if !metadir = "" then "none" else !metadir) ^ ")"); 2066 + "-ldconf", (Arg.String (fun s -> ldconf := s)), 2067 + ("<path> Update this ld.conf file (default: " ^ !ldconf ^ ")"); 2068 + "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive), 2069 + " never append directory='...' to META"; 2070 + "-dll", Arg.Unit (fun () -> which := Dll), 2071 + " The following files are DLLs"; 2072 + "-nodll", Arg.Unit (fun () -> which := No_dll), 2073 + " The following files are not DLLs"; 2074 + "-add", Arg.Unit (fun () -> add_files := true), 2075 + " Add files to the package"; 2076 + "-optional", Arg.Set optional, 2077 + " The following files are optional"; 2078 + "-patch-version", Arg.String (fun s -> patches := !patches @ [`Version s]), 2079 + "<v> Set the package version to <v>"; 2080 + "-patch-rmpkg", Arg.String (fun s -> patches := !patches @ [`Rmpkg s]), 2081 + "<n> Remove the subpackage <n>"; 2082 + "-patch-archives", Arg.Unit (fun () -> patches := !patches @ [`Archives]), 2083 + " Remove non-existing archives"; 2084 + ] in 2085 + let errmsg = "usage: ocamlfind install [options] <package_name> <file> ..." in 2086 + 2087 + parse_args 2088 + keywords 2089 + (fun s -> 2090 + if !pkgname = "" 2091 + then pkgname := s 2092 + else 2093 + if not !optional || Sys.file_exists s then 2094 + match !which with 2095 + Auto -> auto_files := s :: !auto_files 2096 + | Dll -> dll_files := s :: !dll_files 2097 + | No_dll -> nodll_files := s :: !nodll_files 2098 + ) 2099 + errmsg; 2100 + if !pkgname = "" then (Arg.usage keywords errmsg; exit 1); 2101 + if not (Fl_split.is_valid_package_name !pkgname) then 2102 + failwith "Package names must not contain the character '.'!"; 2103 + 2104 + let pkgdir = Filename.concat !destdir !pkgname in 2105 + let dlldir = Filename.concat !destdir Findlib_config.libexec_name in 2106 + let has_metadir = !metadir <> "" in 2107 + let meta_dot_pkg = "META." ^ !pkgname in 2108 + 2109 + (* The list of all files to install: *) 2110 + let full_list = !auto_files @ !dll_files @ !nodll_files in 2111 + (* Check whether there are DLLs: *) 2112 + let (l1,l2) = List.partition is_dll !auto_files in 2113 + let dll_list = l1 @ !dll_files in 2114 + let nodll_list = l2 @ !nodll_files in 2115 + let have_libexec = Sys.file_exists dlldir in 2116 + let pkgdir_list = if have_libexec then nodll_list else full_list in 2117 + let pkgdir_eff_list = 2118 + (* The files that will be placed into pkgdir: *) 2119 + List.map 2120 + (fun f -> 2121 + if f = meta_dot_pkg then "META" else f) 2122 + (List.filter 2123 + (fun f -> 2124 + not has_metadir || 2125 + (f <> "META" && f <> meta_dot_pkg)) 2126 + pkgdir_list) in 2127 + 2128 + (* Check whether META exists: (And check syntax) *) 2129 + let meta_name = 2130 + try 2131 + List.find 2132 + (fun p -> 2133 + let b = Filename.basename p in 2134 + b = "META" || b = meta_dot_pkg) 2135 + nodll_list 2136 + with 2137 + | Not_found -> 2138 + if !add_files then ( 2139 + let m1 = Filename.concat !metadir meta_dot_pkg in 2140 + let m2 = Filename.concat pkgdir "META" in 2141 + if Sys.file_exists m1 then 2142 + m1 2143 + else 2144 + if Sys.file_exists m2 then 2145 + m2 2146 + else 2147 + failwith "Cannot find META in package dir" 2148 + ) 2149 + else 2150 + failwith "The META file is missing" in 2151 + 2152 + let meta_pkg = meta_pkg meta_name in 2153 + 2154 + if not !add_files then ( 2155 + (* Check for frequent reasons why installation can go wrong *) 2156 + if Sys.file_exists (Filename.concat !metadir meta_dot_pkg) then 2157 + failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ Filename.concat !metadir meta_dot_pkg ^ " already exists)"); 2158 + 2159 + if Sys.file_exists (Filename.concat pkgdir "META") then 2160 + failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ pkgdir ^ "/META already exists)"); 2161 + ); 2162 + List.iter 2163 + (fun f -> 2164 + let f' = Filename.concat pkgdir f in 2165 + if Sys.file_exists f' then 2166 + failwith ("Conflict with file: " ^ f')) 2167 + pkgdir_eff_list; 2168 + 2169 + if have_libexec then begin 2170 + List.iter 2171 + (fun dll -> 2172 + let b = Filename.basename dll in 2173 + if Sys.file_exists (Filename.concat dlldir b) then 2174 + failwith ("Conflict with another package: Library " ^ b ^ 2175 + " is already installed"); 2176 + ) 2177 + dll_list 2178 + end; 2179 + 2180 + (* Create the package directory: *) 2181 + install_create_directory !pkgname pkgdir; 2182 + 2183 + (* Now copy the files into the package directory (except META): *) 2184 + List.iter 2185 + (fun p -> 2186 + try 2187 + copy_file 2188 + ~rename: (fun f -> 2189 + if f = "META" || f = meta_dot_pkg then 2190 + raise Skip_file 2191 + else 2192 + f) 2193 + p 2194 + pkgdir 2195 + with 2196 + Skip_file -> () 2197 + ) 2198 + pkgdir_list; 2199 + 2200 + (* Copy the DLLs into the libexec directory if necessary *) 2201 + if have_libexec then begin 2202 + List.iter 2203 + (fun p -> 2204 + copy_file p dlldir; 2205 + create_owner_file !pkgname 2206 + (Filename.concat dlldir (Filename.basename p)) 2207 + ) 2208 + dll_list 2209 + end; 2210 + 2211 + (* Extend ld.conf if necessary: *) 2212 + if dll_list <> [] && !ldconf <> "ignore" && not have_libexec then begin 2213 + if Sys.file_exists !ldconf then 2214 + begin 2215 + let lines = read_ldconf !ldconf in 2216 + write_ldconf !ldconf lines [ pkgdir ] 2217 + end 2218 + else 2219 + prerr_endline("ocamlfind: [WARNING] You have installed DLLs but there is no ld.conf") 2220 + end; 2221 + 2222 + if dll_list <> [] && have_libexec && !ldconf <> "ignore" then begin 2223 + (* Check whether libexec is mentioned in ldconf *) 2224 + (* FIXME: We have to be careful with case-insensitive filesystems. 2225 + Currently, we only check for Win32, but also OS X may have ci 2226 + filesystems. So some better check would be nice. 2227 + *) 2228 + let lines = read_ldconf !ldconf in 2229 + let dlldir_norm = Fl_split.norm_dir dlldir in 2230 + let dlldir_norm_lc = string_lowercase_ascii dlldir_norm in 2231 + let ci_filesys = (Sys.os_type = "Win32") in 2232 + let check_dir d = 2233 + let d' = Fl_split.norm_dir d in 2234 + (d' = dlldir_norm) || 2235 + (ci_filesys && string_lowercase_ascii d' = dlldir_norm_lc) in 2236 + if not (List.exists check_dir lines) then 2237 + prerr_endline("ocamlfind: [WARNING] You have installed DLLs but the directory " ^ dlldir_norm ^ " is not mentioned in ld.conf"); 2238 + end; 2239 + 2240 + (* Finally, write the META file: *) 2241 + let write_meta append_directory dir name = 2242 + (* If there are patches, write the patched META, else copy the file: *) 2243 + if !patches = [] then 2244 + copy_file 2245 + ~rename:(fun _ -> name) 2246 + ?append:(if append_directory then 2247 + Some("\ndirectory=\"" ^ pkgdir ^ 2248 + "\" # auto-added by ocamlfind\n") 2249 + else 2250 + None) 2251 + meta_name 2252 + dir 2253 + else ( 2254 + let p = Filename.concat dir name in 2255 + let patched_pkg = patch_pkg pkgdir meta_pkg !patches in 2256 + let out = open_out p in 2257 + Fl_metascanner.print out patched_pkg; 2258 + if append_directory then 2259 + output_string out ("\ndirectory=\"" ^ pkgdir ^ 2260 + "\" # auto-added by ocamlfind\n"); 2261 + close_out out; 2262 + prerr_endline ("Installed " ^ p); 2263 + ) 2264 + in 2265 + if not !add_files then ( 2266 + if has_metadir then 2267 + write_meta true !metadir meta_dot_pkg 2268 + else 2269 + write_meta false pkgdir "META"; 2270 + ); 2271 + 2272 + (* Check if there is a postinstall script: *) 2273 + let postinstall = Filename.concat !destdir "postinstall" in 2274 + if Sys.file_exists postinstall then 2275 + run_command Verbose postinstall [ slashify !destdir; !pkgname ] 2276 + ;; 2277 + 2278 + 2279 + let reserved_names = [ Findlib_config.libexec_name; "postinstall"; "postremove" ];; 2280 + 2281 + let remove_package () = 2282 + let destdir = ref (default_location()) in 2283 + let destdir_set = ref false in 2284 + let metadir = ref (meta_directory()) in 2285 + let ldconf = ref (ocaml_ldconf()) in 2286 + let pkgname = ref "" in 2287 + 2288 + let keywords = 2289 + [ "-destdir", (Arg.String (fun s -> destdir := s; destdir_set := true)), 2290 + ("<path> Set the destination directory (default: " ^ 2291 + !destdir ^ ")"); 2292 + "-metadir", (Arg.String (fun s -> metadir := s)), 2293 + ("<path> Remove the META file from this directory (default: " ^ 2294 + (if !metadir = "" then "none" else !metadir) ^ ")"); 2295 + "-ldconf", (Arg.String (fun s -> ldconf := s)), 2296 + ("<path> Update this ld.conf file (default: " ^ !ldconf ^ ")"); 2297 + ] in 2298 + let errmsg = "usage: ocamlfind remove [options] <package_name>" in 2299 + 2300 + parse_args 2301 + keywords 2302 + (fun s -> 2303 + if !pkgname = "" 2304 + then pkgname := s 2305 + else raise (Arg.Bad "too many arguments") 2306 + ) 2307 + errmsg; 2308 + if !pkgname = "" then (Arg.usage keywords errmsg; exit 1); 2309 + if List.mem !pkgname reserved_names then 2310 + failwith ("You are not allowed to remove this thing by ocamlfind!"); 2311 + if not (Fl_split.is_valid_package_name !pkgname) then 2312 + failwith "Package names must not contain the character '.'!"; 2313 + 2314 + let meta_dot_pkg = "META." ^ !pkgname in 2315 + let has_metadir = !metadir <> "" in 2316 + let pkgdir = Filename.concat !destdir !pkgname in 2317 + let dlldir = Filename.concat !destdir Findlib_config.libexec_name in 2318 + let have_libexec = Sys.file_exists dlldir in 2319 + 2320 + (* Warn if there is another package with the same name: *) 2321 + let other_pkgdir = 2322 + try Findlib.package_directory !pkgname with No_such_package _ -> "" in 2323 + if other_pkgdir <> "" && not !destdir_set then begin 2324 + (* Is pkgdir = other_pkgdir? - We check physical identity: *) 2325 + try 2326 + let s_other_pkgdir = Unix.stat other_pkgdir in 2327 + try 2328 + let s_pkgdir = Unix.stat pkgdir in 2329 + if (s_pkgdir.Unix.st_dev <> s_other_pkgdir.Unix.st_dev) || 2330 + (s_pkgdir.Unix.st_ino <> s_other_pkgdir.Unix.st_ino) 2331 + then 2332 + 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"); 2333 + with 2334 + Unix.Unix_error(Unix.ENOENT,_,_) -> 2335 + 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"); 2336 + with 2337 + Unix.Unix_error(_,_,_) -> () (* ignore, it's only a warning *) 2338 + end; 2339 + 2340 + (* First remove the META file. If it is already gone, assume that a 2341 + parallel running removal removed it already. 2342 + *) 2343 + 2344 + (* If there is a metadir, remove the META file from it: *) 2345 + let meta_removal_ok = 2346 + if has_metadir then ( 2347 + let f = Filename.concat !metadir meta_dot_pkg in 2348 + try 2349 + Unix.unlink f; 2350 + prerr_endline ("Removed " ^ f); 2351 + true 2352 + with 2353 + | Unix.Unix_error(Unix.ENOENT,_,_) -> 2354 + prerr_endline ("ocamlfind: [WARNING] No such file: " ^ f); 2355 + false 2356 + | Unix.Unix_error(code, _, arg) -> 2357 + raise(sys_error code arg) 2358 + ) else 2359 + let f = Filename.concat pkgdir "META" in 2360 + try 2361 + Unix.unlink f; 2362 + prerr_endline ("Removed " ^ f); 2363 + true 2364 + with 2365 + | Unix.Unix_error(Unix.ENOENT,_,_) -> 2366 + prerr_endline ("ocamlfind: [WARNING] No such file: " ^ f); 2367 + false 2368 + | Unix.Unix_error(code, _, arg) -> 2369 + raise(sys_error code arg) in 2370 + 2371 + if meta_removal_ok then ( 2372 + 2373 + (* Remove files from libexec directory: *) 2374 + if have_libexec then begin 2375 + let dll_files = find_owned_files !pkgname dlldir in 2376 + List.iter 2377 + (fun file -> 2378 + let absfile = Filename.concat dlldir file in 2379 + Sys.remove absfile; 2380 + prerr_endline ("Removed " ^ absfile) 2381 + ) 2382 + dll_files 2383 + end; 2384 + 2385 + (* Remove the files from the package directory: *) 2386 + if Sys.file_exists pkgdir then begin 2387 + let files = Sys.readdir pkgdir in 2388 + Array.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files; 2389 + Unix.rmdir pkgdir; 2390 + prerr_endline ("Removed " ^ pkgdir) 2391 + end 2392 + else 2393 + prerr_endline("ocamlfind: [WARNING] No such directory: " ^ pkgdir); 2394 + 2395 + (* Modify ld.conf *) 2396 + if !ldconf <> "ignore" then begin 2397 + if Sys.file_exists !ldconf then 2398 + begin 2399 + let lines = read_ldconf !ldconf in 2400 + let d = Fl_split.norm_dir pkgdir in 2401 + let exists = List.exists (fun p -> Fl_split.norm_dir p = d) lines in 2402 + if exists then begin 2403 + let lines' = List.filter (fun p -> Fl_split.norm_dir p <> d) lines in 2404 + write_ldconf !ldconf lines' [] 2405 + end 2406 + end 2407 + end; 2408 + 2409 + (* Check if there is a postremove script: *) 2410 + let postremove = Filename.concat !destdir "postremove" in 2411 + if Sys.file_exists postremove then 2412 + run_command Verbose postremove [ slashify !destdir; !pkgname ] 2413 + ) 2414 + ;; 2415 + 2416 + 2417 + let list_packages() = 2418 + 2419 + let descr = ref false in 2420 + 2421 + let keywords = 2422 + [ "-describe", Arg.Set descr, 2423 + " Output package descriptions"; 2424 + ] in 2425 + let errmsg = "usage: ocamlfind list [options]" in 2426 + 2427 + parse_args 2428 + keywords 2429 + (fun _ -> Arg.usage keywords errmsg; exit 1) 2430 + errmsg; 2431 + 2432 + Findlib.list_packages ~descr:!descr stdout; 2433 + Fl_package_base.package_conflict_report ~identify_dir () 2434 + ;; 2435 + 2436 + 2437 + let print_configuration() = 2438 + let dir s = 2439 + if Sys.file_exists s then 2440 + s 2441 + else 2442 + s ^ " (not found)" 2443 + in 2444 + 2445 + let var = ref None in 2446 + let errmsg = "usage: ocamlfind printconf (conf|path|destdir|metadir|metapath|stdlib|ldconf)" in 2447 + 2448 + parse_args 2449 + [] 2450 + (fun s -> 2451 + if !var <> None then raise(Arg.Bad "Unexpected argument"); 2452 + match s with 2453 + ("conf" | "path" | "destdir" | "metadir" | "metapath" | "stdlib" | "ldconf") -> 2454 + var := Some s 2455 + | _ -> 2456 + raise(Arg.Bad "Bad argument"); 2457 + ) 2458 + errmsg; 2459 + 2460 + match !var with 2461 + None -> 2462 + print_endline "Effective configuration:"; 2463 + Printf.printf "Configuration file:\n %s\n" 2464 + (dir (Findlib.config_file())); 2465 + Printf.printf "Search path:\n"; 2466 + List.iter 2467 + (fun p -> Printf.printf " %s\n" (dir p)) 2468 + (Findlib.search_path()); 2469 + Printf.printf "Packages will be installed in/removed from:\n %s\n" 2470 + (dir (Findlib.default_location())); 2471 + Printf.printf "META files will be installed in/removed from:\n %s\n" 2472 + (let md = Findlib.meta_directory() in 2473 + if md = "" then "the corresponding package directories" else dir md 2474 + ); 2475 + Printf.printf "The standard library is assumed to reside in:\n %s\n" 2476 + (Findlib.ocaml_stdlib()); 2477 + Printf.printf "The ld.conf file can be found here:\n %s\n" 2478 + (Findlib.ocaml_ldconf()); 2479 + flush stdout 2480 + | Some "conf" -> 2481 + print_endline (Findlib.config_file()) 2482 + | Some "path" -> 2483 + List.iter print_endline (Findlib.search_path()) 2484 + | Some "destdir" -> 2485 + print_endline (Findlib.default_location()) 2486 + | Some "metadir" -> 2487 + print_endline (Findlib.meta_directory()) 2488 + | Some "metapath" -> 2489 + let mdir = Findlib.meta_directory() in 2490 + let ddir = Findlib.default_location() in 2491 + print_endline 2492 + (if mdir <> "" then mdir ^ "/META.%s" else ddir ^ "/%s/META") 2493 + | Some "stdlib" -> 2494 + print_endline (Findlib.ocaml_stdlib()) 2495 + | Some "ldconf" -> 2496 + print_endline (Findlib.ocaml_ldconf()) 2497 + | _ -> 2498 + assert false 2499 + ;; 2500 + 2501 + 2502 + let ocamlcall pkg cmd = 2503 + let dir = package_directory pkg in 2504 + let path = Filename.concat dir cmd in 2505 + begin 2506 + try Unix.access path [ Unix.X_OK ] 2507 + with 2508 + Unix.Unix_error (Unix.ENOENT, _, _) -> 2509 + failwith ("Cannot find command: " ^ path) 2510 + | Unix.Unix_error (Unix.EACCES, _, _) -> 2511 + failwith ("Cannot execute: " ^ path) 2512 + | other -> 2513 + Unix.handle_unix_error (fun () -> raise other) () 2514 + end; 2515 + let args = Array.to_list (Array.sub Sys.argv 2 (Array.length Sys.argv -2)) in 2516 + run_command Normal path args 2517 + ;; 2518 + 2519 + (** lint META file *) 2520 + let lint () = 2521 + 2522 + let meta_files = Queue.create () in 2523 + 2524 + parse_args 2525 + ~align:false 2526 + ( Arg.align [ 2527 + ]) 2528 + (fun s -> if Sys.file_exists s 2529 + then Queue.add s meta_files 2530 + else raise(Arg.Bad (Printf.sprintf "%s: file doesn't exists" s))) 2531 + "usage: ocamlfind lint <options> <files>..."; 2532 + 2533 + let error = 2534 + Queue.fold (fun error file -> 2535 + let pkg = meta_pkg file in 2536 + let error = Fl_lint.warn pkg || error in 2537 + error 2538 + ) false meta_files in 2539 + exit (if error then 1 else 0) 2540 + ;; 2541 + 2542 + 2543 + (** print ppx options *) 2544 + let print_ppx () = 2545 + 2546 + let packages = ref [] in 2547 + let predicates = ref [] in 2548 + let ppx_opts = ref [] in 2549 + 2550 + let add_pred = 2551 + Arg.String (fun s -> predicates := !predicates @ (Fl_split.in_words s)) in 2552 + let add_ppx_opt = 2553 + Arg.String (fun s -> ppx_opts := !ppx_opts @ [s]) in 2554 + 2555 + parse_args 2556 + [ "-predicates", add_pred, 2557 + " specifies comma-separated list of assumed predicates"; 2558 + "-ppxopt", add_ppx_opt, 2559 + "<pkg>,<opts> Append options <opts> to ppx invocation for package <pkg>"; 2560 + ] 2561 + (fun p -> packages := !packages @ [p]) 2562 + "usage: ocamlfind printppx [options] package ..."; 2563 + 2564 + let ppx_commands = 2565 + process_ppx_spec !predicates !packages !ppx_opts 2566 + in 2567 + print_endline (String.concat " " (List.map escape_if_needed ppx_commands)) 2568 + ;; 2569 + 2570 + 2571 + let rec select_mode () = 2572 + let k = !Arg.current in 2573 + let m_string = try arg (k+1) with Not_found -> raise Usage in 2574 + let m = 2575 + match m_string with 2576 + ("use"|"-use") -> incr Arg.current; M_use 2577 + | ("query"|"-query") -> incr Arg.current; M_query 2578 + | ("install"|"-install") -> incr Arg.current; M_install 2579 + | ("remove"|"-remove") -> incr Arg.current; M_remove 2580 + | ("ocamlc"|"-ocamlc"|"c") -> incr Arg.current; M_compiler "ocamlc" 2581 + | ("ocamlcp"|"-ocamlcp"|"cp") -> incr Arg.current; M_compiler "ocamlcp" 2582 + | ("ocamloptp"|"-ocamloptp"|"optp") -> incr Arg.current; M_compiler "ocamloptp" 2583 + | ("ocamlmklib"|"-ocamlmklib"|"mklib") -> incr Arg.current; M_compiler "ocamlmklib" 2584 + | ("ocamlmktop"|"-ocamlmktop"|"mktop") -> incr Arg.current; M_compiler "ocamlmktop" 2585 + | ("ocamlopt"|"-ocamlopt"|"opt") -> incr Arg.current; M_compiler "ocamlopt" 2586 + | ("ocamldep"|"-ocamldep"|"dep") -> incr Arg.current; M_dep 2587 + | ("ocamlbrowser"|"-ocamlbrowser"|"browser") -> incr Arg.current; M_browser 2588 + | ("ocamldoc"|"-ocamldoc"|"doc") -> incr Arg.current; M_doc 2589 + | ("printconf"|"-printconf") -> incr Arg.current; M_printconf 2590 + | ("list"|"-list") -> incr Arg.current; M_list 2591 + | ("lint"|"-lint") -> incr Arg.current; M_lint 2592 + | ("printppx"|"-printppx") -> incr Arg.current; M_printppx 2593 + | "-toolchain" -> 2594 + let t = try arg (k+2) with Not_found -> raise Usage in 2595 + Findlib.init ~toolchain:t (); 2596 + Arg.current := k+2; 2597 + select_mode() 2598 + | s when String.contains m_string '/' -> 2599 + incr Arg.current; 2600 + let k = String.index m_string '/' in 2601 + let pkg = String.sub m_string 0 k in 2602 + let cmd = String.sub m_string (k+1) (String.length m_string - k - 1) in 2603 + M_call(pkg,cmd) 2604 + | _ -> raise Usage 2605 + in 2606 + 2607 + m 2608 + ;; 2609 + 2610 + 2611 + let main() = 2612 + try 2613 + let m = select_mode() in 2614 + let l = Array.length Sys.argv in 2615 + let k = !Arg.current in 2616 + let rest = Array.sub Sys.argv (k+1) (l-k-1) in 2617 + match m with 2618 + M_use -> if rest = [| |] then raise Usage; 2619 + if rest.(0) = "-p" then begin 2620 + if l<4 then raise Usage; 2621 + use_package rest.(1) 2622 + (List.tl(List.tl(Array.to_list rest))) 2623 + end 2624 + else 2625 + use_package "" (Array.to_list rest) 2626 + | M_query -> query_package () 2627 + | M_install -> install_package() 2628 + | M_remove -> remove_package () 2629 + | M_printconf -> print_configuration () 2630 + | M_list -> list_packages() 2631 + | M_dep -> ocamldep() 2632 + | M_browser -> ocamlbrowser() 2633 + | M_doc -> ocamldoc() 2634 + | M_call(pkg,cmd) -> ocamlcall pkg cmd 2635 + | M_compiler which -> ocamlc which () 2636 + | M_lint -> lint() 2637 + | M_printppx -> print_ppx() 2638 + with 2639 + Usage -> 2640 + prerr_endline "Usage: ocamlfind query [-help | other options] <package_name> ..."; 2641 + prerr_endline " or: ocamlfind ocamlc [-help | other options] <file> ..."; 2642 + prerr_endline " or: ocamlfind ocamlcp [-help | other options] <file> ..."; 2643 + prerr_endline " or: ocamlfind ocamlmklib [-help | other options] <file> ..."; 2644 + prerr_endline " or: ocamlfind ocamlmktop [-help | other options] <file> ..."; 2645 + if Ocaml_args.ocamlopt_spec <> None then 2646 + prerr_endline " or: ocamlfind ocamlopt [-help | other options] <file> ..."; 2647 + if Ocaml_args.ocamloptp_spec <> None then 2648 + prerr_endline " or: ocamlfind ocamloptp [-help | other options] <file> ..."; 2649 + prerr_endline " or: ocamlfind ocamldep [-help | other options] <file> ..."; 2650 + prerr_endline " or: ocamlfind ocamlbrowser [-help | other options]"; 2651 + prerr_endline " or: ocamlfind ocamldoc [-help | other options] <file> ..."; 2652 + prerr_endline " or: ocamlfind install [-help | other options] <package_name> <file> ..."; 2653 + prerr_endline " or: ocamlfind remove [-help | other options] <package_name>"; 2654 + prerr_endline " or: ocamlfind printppx [-help | other options] <package_name> ..."; 2655 + prerr_endline " or: ocamlfind printconf [-help] [variable]"; 2656 + prerr_endline " or: ocamlfind lint [-help] <file>"; 2657 + prerr_endline " or: ocamlfind list"; 2658 + prerr_endline " or: ocamlfind pkg/cmd arg ..."; 2659 + prerr_endline "Select toolchain with:"; 2660 + prerr_endline " ocamlfind -toolchain <t> <command>"; 2661 + prerr_endline "Abbreviations:"; 2662 + prerr_endline " e.g. ocamlfind opt instead of ocamlfind ocamlopt"; 2663 + exit 2 2664 + | Failure f -> 2665 + prerr_endline ("ocamlfind: " ^ f); 2666 + exit 2 2667 + | Sys_error f -> 2668 + prerr_endline ("ocamlfind: " ^ f); 2669 + exit 2 2670 + | Findlib.No_such_package(pkg,info) -> 2671 + prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' not found" ^ 2672 + (if info <> "" then " - " ^ info else "")); 2673 + exit 2 2674 + | Findlib.Package_loop pkg -> 2675 + prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' requires itself"); 2676 + exit 2 2677 + | Silent_error -> 2678 + exit 2 2679 + ;; 2680 + 2681 + 2682 + try 2683 + Sys.catch_break true; 2684 + main() 2685 + with 2686 + any -> 2687 + prerr_endline ("Uncaught exception: " ^ Printexc.to_string any); 2688 + let raise_again = 2689 + try ignore(Sys.getenv "OCAMLFIND_DEBUG"); true 2690 + with Not_found -> false 2691 + in 2692 + if raise_again then raise any; 2693 + exit 3 2694 + ;;
+32
vendor/opam/ocamlfind/src/findlib/num_top.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + let print_outcome = false 7 + let error_fmt = Format.err_formatter 8 + 9 + let printers = [ 10 + "Num_top_printers.nat_printer"; 11 + "Num_top_printers.big_int_printer"; 12 + "Num_top_printers.ratio_printer"; 13 + "Num_top_printers.num_printer"; 14 + ] 15 + 16 + let eval_phrase s = 17 + let lexbuf = Lexing.from_string s in 18 + let phrase = !Toploop.parse_toplevel_phrase lexbuf in 19 + Toploop.execute_phrase print_outcome error_fmt phrase 20 + 21 + let install_all () = 22 + List.fold_left 23 + (fun outcome phrase -> 24 + outcome && eval_phrase (Printf.sprintf "#install_printer %s;;" phrase)) 25 + true printers 26 + 27 + let _ = 28 + if not (install_all ()) then begin 29 + Format.fprintf error_fmt 30 + "Something weird happened while installing Num library printers"; 31 + Format.pp_print_flush error_fmt () 32 + end
+18
vendor/opam/ocamlfind/src/findlib/num_top.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** 7 + Load this module in the toplevel to install printers for the following types 8 + defined in the "num" library: 9 + - Nat.nat 10 + - Big_int.big_int 11 + - Ratio.ratio 12 + - Num.num 13 + 14 + No functions exported. 15 + 16 + Copyright (C) 2003 Stefano Zacchiroli <zack@debian.org> 17 + *) 18 +
+17
vendor/opam/ocamlfind/src/findlib/num_top_printers.ml
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + let nat_printer fmt v = 7 + Format.fprintf fmt "<nat %s>" (Nat.string_of_nat v) 8 + 9 + let big_int_printer fmt v = 10 + Format.fprintf fmt "<big_int %s>" (Big_int.string_of_big_int v) 11 + 12 + let ratio_printer fmt v = 13 + Format.fprintf fmt "<ratio %s>" (Ratio.string_of_ratio v) 14 + 15 + let num_printer fmt v = 16 + Format.fprintf fmt "<num %s>" (Num.string_of_num v) 17 +
+19
vendor/opam/ocamlfind/src/findlib/num_top_printers.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** 7 + Printers for types defined in the "num" library. Meant to be used as printers 8 + in the ocaml toplevel. See num_top.mli. 9 + 10 + Copyright (C) 2003 Stefano Zacchiroli <zack@debian.org> 11 + 12 + Released under the same terms as findlib. 13 + *) 14 + 15 + val nat_printer : Format.formatter -> Nat.nat -> unit 16 + val big_int_printer : Format.formatter -> Big_int.big_int -> unit 17 + val ratio_printer : Format.formatter -> Ratio.ratio -> unit 18 + val num_printer: Format.formatter -> Num.num -> unit 19 +
+87
vendor/opam/ocamlfind/src/findlib/test_parser.ml
··· 1 + let with_open_in file func = 2 + let chan = open_in file in 3 + let result = 4 + try func chan 5 + with exn -> close_in chan; raise exn 6 + in 7 + close_in chan; result 8 + ;; 9 + 10 + type test_mode = Compare_both | Only of (old_or_new * int) 11 + and old_or_new = Old | New 12 + 13 + let read_file file = 14 + let buf = Buffer.create 100 in 15 + with_open_in file (fun ch -> 16 + try while true do Buffer.add_string buf (input_line ch) done 17 + with End_of_file -> ()); 18 + Buffer.contents buf 19 + 20 + let test mode file = 21 + match mode with 22 + | Compare_both -> 23 + let ast1 = with_open_in file Fl_metascanner.parse in 24 + let ast2 = with_open_in file Fl_metascanner.parse2 in 25 + Printf.printf "%s tested %s\n" file (if ast1 = ast2 then "OK" else "FAIL") 26 + | Only (old_or_new, niter) -> 27 + let content = read_file file in 28 + for i = 1 to niter do 29 + let parse = match old_or_new with 30 + | Old -> Fl_metascanner.parse_lexing 31 + | New -> Fl_metascanner.parse2_lexing in 32 + ignore (parse (Lexing.from_string content)) 33 + done 34 + 35 + let rec explore mode path = 36 + if Sys.is_directory path then 37 + let traverse file = explore mode (Filename.concat path file) in 38 + Array.iter traverse (Sys.readdir path) 39 + else if Filename.basename path = "META" then 40 + test mode path 41 + 42 + let () = 43 + let test_mode, targets = (* command-line option handling *) 44 + let only_old = ref false in 45 + let only_new = ref false in 46 + let niter = ref 1 in 47 + let targets = ref [] in 48 + let usage = "test_parser <options> <path> <path> ....\n \ 49 + recursively traverse paths and compare the two parsers \ 50 + on each file named META" 51 + in 52 + let options = [ 53 + ("--niter", Arg.Set_int niter, "iterate the parser for performance comparison (only in --only-old or --only-new modes)"); 54 + ("--only-old", Arg.Set only_old, "only test the old parser"); 55 + ("--only-new", Arg.Set only_new, "only test the new parser"); 56 + ] in 57 + let action path = targets := path :: !targets in 58 + Arg.parse options action usage; 59 + let quit_with_usage () = Arg.usage options usage; exit 1 in 60 + let test_mode = 61 + match !only_old, !only_new with 62 + | false, false -> Compare_both 63 + | false, true -> Only (New, !niter) 64 + | true, false -> Only (Old, !niter) 65 + | true, true -> 66 + prerr_endline "--only-only and --new-only cannot be \ 67 + both set at the same time"; 68 + quit_with_usage (); 69 + in 70 + if !targets = [] then quit_with_usage (); 71 + test_mode, !targets 72 + in 73 + let traverse path = 74 + if Sys.file_exists path then explore test_mode path 75 + else Printf.eprintf "Error: path %s does not exist and was ignored.\n" path 76 + in 77 + List.iter traverse targets 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 +
+148
vendor/opam/ocamlfind/src/findlib/topfind.in
··· 1 + (* $Id$ -*- tuareg -*- *) 2 + 3 + (* For Ocaml-3.03 and up, so you can do: #use "topfind" and get a 4 + * working findlib toploop. 5 + *) 6 + 7 + (* To access Toploop in OCaml >= 4.00. This directory will be later removed from path if possible *) 8 + #directory "+compiler-libs";; 9 + 10 + let exists path = 11 + match Sys.file_exists path with 12 + | true -> Some path 13 + | false -> None 14 + in 15 + 16 + let ( / ) = Filename.concat in 17 + 18 + let findlib_conf_of_path path = 19 + match exists (path / "etc" / "findlib.conf") with 20 + | Some etc_path -> etc_path 21 + | None -> path / "lib" / "findlib.conf" 22 + in 23 + 24 + let install_dir_from_opam_switch_prefix path = 25 + match Sys.file_exists (findlib_conf_of_path path) with 26 + | false -> None 27 + | true -> Some path 28 + in 29 + 30 + let install_dir_from_ocaml_toplevel_path path = 31 + let exe_dir = Filename.dirname path in 32 + let install_dir = Filename.dirname exe_dir in 33 + let config_path = findlib_conf_of_path install_dir in 34 + match Sys.file_exists config_path with 35 + | true -> Some install_dir 36 + | false -> None 37 + in 38 + 39 + let fl_split_path_separator = 40 + match Sys.os_type with 41 + | "Unix" | "BeOS" -> ':' 42 + | "Cygwin" -> ';' (* You might want to change this *) 43 + | "Win32" -> ';' 44 + | "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" 45 + | _ -> failwith "Findlib: unknown operating system" 46 + in 47 + 48 + let string_split_on_char sep s = 49 + let r = ref [] in 50 + let j = ref (String.length s) in 51 + for i = String.length s - 1 downto 0 do 52 + if String.unsafe_get s i = sep then begin 53 + r := String.sub s (i + 1) (!j - i - 1) :: !r; 54 + j := i 55 + end 56 + done; 57 + String.sub s 0 !j :: !r 58 + in 59 + 60 + let rec list_find_map f = function 61 + | [] -> None 62 + | x :: l -> 63 + begin match f x with 64 + | Some _ as result -> result 65 + | None -> list_find_map f l 66 + end 67 + in 68 + 69 + let install_dir_from_ld_library_path paths = 70 + let v = string_split_on_char fl_split_path_separator paths in 71 + list_find_map (fun path -> 72 + let parent = Filename.dirname path in 73 + let parent' = Filename.dirname parent in 74 + match Sys.file_exists (findlib_conf_of_path parent') with 75 + | true -> Some parent' 76 + | false -> None) v 77 + in 78 + 79 + let getenv_opt v = try Some (Sys.getenv v) with Not_found -> None in 80 + 81 + let rec try_vars = function 82 + | [] -> None 83 + | (var, mapper)::xs -> ( 84 + match getenv_opt var with 85 + | None -> try_vars xs 86 + | Some content -> ( 87 + match mapper content with 88 + | None -> try_vars xs 89 + | Some _ as found -> found)) 90 + in 91 + 92 + let location = 93 + match try_vars [ 94 + ("OPAM_SWITCH_PREFIX", install_dir_from_opam_switch_prefix); 95 + ("CAML_LD_LIBRARY_PATH", install_dir_from_ld_library_path); 96 + ("OCAML_TOPLEVEL_PATH", install_dir_from_ocaml_toplevel_path); 97 + ] with 98 + | Some location -> location 99 + | None -> "@SITELIB@" 100 + in 101 + 102 + let findlib_directory = match @RELATIVE_PATHS@ with 103 + | true -> location / "lib" / "findlib" 104 + | false -> "@SITELIB@/findlib" 105 + in 106 + 107 + let () = Topdirs.dir_directory findlib_directory in 108 + (* OCaml-4.00 requires to use dir_directory before we load anything *) 109 + 110 + let exec_test s = 111 + let l = Lexing.from_string s in 112 + let ph = !Toploop.parse_toplevel_phrase l in 113 + let fmt = Format.make_formatter (fun _ _ _ -> ()) (fun _ -> ()) in 114 + try 115 + Toploop.execute_phrase false fmt ph 116 + with 117 + _ -> false 118 + in 119 + 120 + (* one of the few observable differences... *) 121 + let is_native = (Gc.get ()).Gc.stack_limit = 0 in 122 + 123 + let suffix = if is_native then "cmxs" else "cma" in 124 + 125 + (* First test whether findlib_top is already loaded. If not, load it now. 126 + * The test works by executing the toplevel phrase "Topfind.reset" and 127 + * checking whether this causes an error. 128 + *) 129 + if not (exec_test "Topfind.reset;;") then ( 130 + Topdirs.dir_load Format.err_formatter (findlib_directory / ("findlib." ^ suffix)); 131 + Topdirs.dir_load Format.err_formatter (findlib_directory / ("findlib_top." ^ suffix))) 132 + ;; 133 + (* phrase has to end here otherwise Topfind is not accessible *) 134 + 135 + (* REMOVE_DIRECTORY_BEGIN *) 136 + (* OCaml < 4.00 do not have this so only include this code if it was detected *) 137 + let () = Topdirs.dir_remove_directory "+compiler-libs" in 138 + (* REMOVE_DIRECTORY_END *) 139 + 140 + (* The following is always executed. It is harmless if findlib was already 141 + * initialized 142 + *) 143 + let is_native = (Gc.get ()).Gc.stack_limit = 0 in 144 + let pred = if is_native then "native" else "byte" in 145 + 146 + Topfind.add_predicates [ pred; "toploop" ]; 147 + Topfind.don't_load ["findlib"]; 148 + Topfind.announce ();;
+342
vendor/opam/ocamlfind/src/findlib/topfind.ml.in
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + let predicates = ref ("toploop" :: Findlib.recorded_predicates());; 7 + (* We also want things like "syntax" here which are not allowed in 8 + Findlib, hence we maintain our own list 9 + *) 10 + 11 + let ocaml_stdlib = lazy (Findlib.ocaml_stdlib ());; 12 + let directories = ref [ ] ;; 13 + 14 + 15 + (* Note: Sys.interactive is always _true_ during toploop startup. 16 + * When a script is executed, it is set to false just before the 17 + * script starts. This is important for ocamlmktop-generated toploops: 18 + * For initialization code linked into the toploop, Sys.interactive 19 + * is _true_. It is set to false just before the script starts. 20 + *) 21 + 22 + let real_toploop = 23 + !Sys.interactive;; 24 + 25 + let log = ref (if real_toploop then prerr_endline else ignore) 26 + 27 + let rec remove_dups l = 28 + match l with 29 + x :: l' -> 30 + if List.mem x l' then remove_dups l' else x::remove_dups l' 31 + | [] -> [] 32 + ;; 33 + 34 + let add_predicates pl = 35 + predicates := remove_dups (pl @ !predicates); 36 + Findlib.record_package_predicates !predicates;; 37 + 38 + let syntax s = 39 + add_predicates [ "syntax"; s ];; 40 + 41 + let standard_syntax () = syntax "camlp4o";; 42 + let revised_syntax () = syntax "camlp4r";; 43 + 44 + 45 + let add_dir d = 46 + let d = Fl_split.norm_dir d in 47 + let ocaml_stdlib = Lazy.force ocaml_stdlib in 48 + if d <> ocaml_stdlib && not (List.mem d !directories) then begin 49 + Topdirs.dir_directory d; 50 + directories := d :: !directories; 51 + !log (d ^ ": added to search path") 52 + end 53 + ;; 54 + 55 + let exec_string s = 56 + let l = Lexing.from_string s in 57 + let ph = !Toploop.parse_toplevel_phrase l in 58 + (* PPXOPT_BEGIN *) 59 + let ph = Toploop.preprocess_phrase Format.err_formatter ph in 60 + (* PPXOPT_END *) 61 + let fmt = Format.make_formatter (fun _ _ _ -> ()) (fun _ -> ()) in 62 + try 63 + Toploop.execute_phrase false fmt ph 64 + with 65 + _ -> false 66 + ;; 67 + 68 + let load pkglist = 69 + List.iter 70 + (fun pkg -> 71 + let _stdlibdir = Findlib.ocaml_stdlib() in 72 + let loaded = 73 + Findlib.is_recorded_package pkg && 74 + Findlib.type_of_recorded_package pkg = Findlib.Record_load in 75 + let incore = 76 + Findlib.is_recorded_package pkg && 77 + Findlib.type_of_recorded_package pkg = Findlib.Record_core in 78 + if not loaded then begin 79 + (* Determine the package directory: *) 80 + let d = Findlib.package_directory pkg in 81 + add_dir d; 82 + (* Leave pkg out if mentioned in !forbidden *) 83 + if not incore then begin 84 + (* Determine the 'archive' property: *) 85 + let archive = 86 + try Findlib.package_property !predicates pkg "archive" 87 + with 88 + Not_found -> "" 89 + in 90 + (* Split the 'archive' property and load the files: *) 91 + let archives = Fl_split.in_words archive in 92 + List.iter 93 + (fun arch -> 94 + let arch' = Findlib.resolve_path ~base:d arch in 95 + !log (arch' ^ ": loaded"); 96 + Topdirs.dir_load 97 + Format.std_formatter arch') 98 + archives; 99 + (* Determine the 'ppx' property: *) 100 + let ppx = 101 + try 102 + Some(Findlib.resolve_path 103 + ~base:d ~explicit:true 104 + (Findlib.package_property !predicates pkg "ppx") 105 + ) 106 + with Not_found -> None 107 + and ppxopts = 108 + try 109 + List.map 110 + (fun opt -> 111 + match Fl_split.in_words opt with 112 + | pkg :: opts -> 113 + pkg, 114 + List.map 115 + (Findlib.resolve_path ~base:d ~explicit:true) opts 116 + | _ -> assert false) 117 + (Fl_split.in_words_ws 118 + (Findlib.package_property !predicates pkg "ppxopt")) 119 + with Not_found -> [] in 120 + (* Feed the 'ppx' property into the toplevel. To remain compatible 121 + with pre-4.01 OCaml, construct and execute a phrase instead of directly 122 + altering Clflags. *) 123 + begin match ppx with 124 + | Some ppx -> 125 + 126 + 127 + begin try 128 + match Hashtbl.find Toploop.directive_table "ppx" with 129 + | Toploop.Directive_string fn -> 130 + fn ppx; !log (ppx ^ ": activated") 131 + | _ -> assert false 132 + with Not_found -> 133 + failwith "Package defines a ppx preprocessor, but OCaml is too old. \ 134 + Use OCaml >= 4.02.0 for ppx support." 135 + end 136 + | None -> () 137 + end; 138 + (* Feed the 'ppxopt' property into the toplevel. *) 139 + match ppxopts with 140 + | [] -> () 141 + | _ -> 142 + (* PPXOPT_BEGIN *) 143 + List.iter 144 + (fun (pkg, opts) -> 145 + ignore (exec_string ("[@@@findlib.ppxopt " ^ 146 + (String.concat ", " 147 + (List.map (Printf.sprintf "%S") (pkg :: opts))) ^ 148 + "];;")); 149 + !log (pkg ^ ": " ^ (String.concat " " opts) ^ 150 + ": option added")) 151 + ppxopts 152 + (* 153 + (* PPXOPT_END *) 154 + failwith "Package defines a ppx preprocessor option, but OCaml is too old. \ 155 + Use OCaml >=4.02.1 for ppxopt support." 156 + (* PPXOPT_BEGIN *) 157 + *) 158 + (* PPXOPT_END *) 159 + end; 160 + (* The package is loaded: *) 161 + Findlib.record_package Findlib.Record_load pkg 162 + end) 163 + pkglist 164 + ;; 165 + 166 + 167 + let load_deeply pkglist = 168 + (* Get the sorted list of ancestors *) 169 + let eff_pkglist = 170 + Findlib.package_deep_ancestors !predicates pkglist in 171 + List.iter (fun pkg -> 172 + try let error = Findlib.package_property !predicates pkg "error" in 173 + failwith ("Error from package `" ^ pkg ^ "': " ^ error) 174 + with Not_found -> ()) eff_pkglist ; 175 + (* Load the packages in turn: *) 176 + load eff_pkglist 177 + ;; 178 + 179 + 180 + let check_existence pkglist = 181 + List.iter 182 + (fun pkg -> 183 + let _ = Findlib.package_directory pkg in () 184 + ) 185 + pkglist 186 + ;; 187 + 188 + 189 + let don't_load pkglist = 190 + check_existence pkglist; 191 + List.iter (Findlib.record_package Findlib.Record_core) pkglist 192 + ;; 193 + 194 + 195 + let don't_load_deeply pkglist = 196 + (* Check if packages exist: *) 197 + check_existence pkglist; 198 + (* Get the sorted list of ancestors *) 199 + let eff_pkglist = 200 + Findlib.package_deep_ancestors !predicates pkglist in 201 + (* Add this to the list of core packages: *) 202 + List.iter (Findlib.record_package Findlib.Record_core) eff_pkglist 203 + ;; 204 + 205 + 206 + let reset() = 207 + Findlib.reset_recordings() 208 + ;; 209 + 210 + 211 + let have_mt_support() = 212 + Findlib.package_property [] "threads" "type_of_threads" = "posix" 213 + ;; 214 + 215 + 216 + let load_mt_support() = 217 + (* Load only if package "threads" is not yet loaded. *) 218 + if not(Findlib.is_recorded_package "threads") then ( 219 + (* This works only for POSIX threads. *) 220 + if have_mt_support() then ( 221 + add_predicates ["mt"; "mt_posix"]; 222 + add_dir (Filename.concat (Findlib.ocaml_stdlib()) "threads"); 223 + load_deeply ["unix"]; 224 + load_deeply ["threads"]; 225 + ) 226 + else ( 227 + failwith "It is not possible to load support for vmthreads dynamically. Use\n 228 + 'ocamlfind ocamlmktop -o vmtop -package threads,findlib -linkpkg -vmthread'\n 229 + to create a toploop with integrated vmthreads library." 230 + ) 231 + ) 232 + ;; 233 + 234 + 235 + let list_packages() = 236 + Findlib.list_packages stdout; 237 + flush stdout 238 + ;; 239 + 240 + 241 + let protect f arg = 242 + try 243 + let _ = f arg in () 244 + with 245 + Failure s -> 246 + print_endline s 247 + | Fl_package_base.No_such_package(pkg, reason) -> 248 + print_endline ("No such package: " ^ pkg ^ 249 + (if reason <> "" then " - " ^ reason else "")) 250 + | Fl_package_base.Package_loop pkg -> 251 + print_endline ("Package requires itself: " ^ pkg) 252 + ;; 253 + 254 + 255 + (* Add "#require" directive: *) 256 + 257 + Hashtbl.add 258 + Toploop.directive_table 259 + "require" 260 + (Toploop.Directive_string 261 + (fun s -> 262 + protect load_deeply (Fl_split.in_words s) 263 + )) 264 + ;; 265 + 266 + (* Add "#predicates" directive: *) 267 + Hashtbl.add 268 + Toploop.directive_table 269 + "predicates" 270 + (Toploop.Directive_string 271 + (fun s -> 272 + protect add_predicates (Fl_split.in_words s) 273 + )) 274 + ;; 275 + 276 + 277 + (* Add "#camlp4o" directive: *) 278 + 279 + Hashtbl.add 280 + Toploop.directive_table 281 + "camlp4o" 282 + (Toploop.Directive_none 283 + (fun () -> 284 + protect (fun () -> 285 + standard_syntax(); 286 + load_deeply ["camlp4"]) () 287 + )) 288 + ;; 289 + 290 + (* Add "#camlp4r" directive: *) 291 + 292 + Hashtbl.add 293 + Toploop.directive_table 294 + "camlp4r" 295 + (Toploop.Directive_none 296 + (fun () -> 297 + protect (fun () -> 298 + revised_syntax(); 299 + load_deeply ["camlp4"]) () 300 + )) 301 + ;; 302 + 303 + 304 + (* Add "#list" directive: *) 305 + 306 + Hashtbl.add 307 + Toploop.directive_table 308 + "list" 309 + (Toploop.Directive_none 310 + (fun () -> 311 + protect list_packages () 312 + )) 313 + ;; 314 + 315 + 316 + (* Add "#thread" directive: *) 317 + 318 + Hashtbl.add 319 + Toploop.directive_table 320 + "thread" 321 + (Toploop.Directive_none 322 + (fun () -> 323 + protect load_mt_support () 324 + )) 325 + ;; 326 + 327 + 328 + let announce() = 329 + if real_toploop then begin 330 + (* Assume we are in a toploop and not a script *) 331 + let msg_thread = 332 + " #thread;; to enable threads\n" in 333 + print_endline 334 + ("Findlib has been successfully loaded. Additional directives:\n" ^ 335 + " #require \"package\";; to load a package\n" ^ 336 + " #list;; to list the available packages\n" ^ 337 + " #camlp4o;; to load camlp4 (standard syntax)\n" ^ 338 + " #camlp4r;; to load camlp4 (revised syntax)\n" ^ 339 + " #predicates \"p,q,...\";; to set these predicates\n" ^ 340 + " Topfind.reset();; to force that packages will be reloaded\n" ^ 341 + (if have_mt_support() then msg_thread else "")) 342 + end ;;
+122
vendor/opam/ocamlfind/src/findlib/topfind.mli
··· 1 + (* $Id$ 2 + * ---------------------------------------------------------------------- 3 + * 4 + *) 5 + 6 + (** Load packages from toploops and scripts 7 + * 8 + * The [Topfind] module is part of the [findlib] package. The module 9 + * depends on the presence of a toploop. When building a toploop, it is 10 + * automatically linked in if "findlib" is linked in, e.g. 11 + * {[ 12 + * ocamlfind ocamlmktop ...options... -package findlib -linkpkg 13 + * ]} 14 + * 15 + * When the platform supports DLLs, another possibility to get a toploop 16 + * with findlib directives is to load the file "topfind" (normally installed 17 + * in the standard library directory): 18 + * {[ 19 + * $ ocaml 20 + * Objective Caml version 3.04 21 + * # #use "topfind";; 22 + * Findlib has been successfully loaded. Additional directives: 23 + * #require "package";; to load a package 24 + * #list;; to list the available packages 25 + * #camlp4o;; to load camlp4 (standard syntax) 26 + * #camlp4r;; to load camlp4 (revised syntax) 27 + * Topfind.reset();; to force that packages will be reloaded 28 + * ~ : unit = () 29 + * # _ 30 + * ]} 31 + * 32 + * This works even in scripts (but the startup message is suppressed in this 33 + * case). 34 + * 35 + * The module is not thread-safe; if used in a multi-threaded script, all 36 + * packgage loading must have happened before the first thread forks. 37 + * 38 + * The Topfind module contains some functions simplifying package loading 39 + * in scripts. Most important, there is a new directive [#require] for 40 + * the same purpose (see below). 41 + * 42 + * The [Topfind] module needs some initialization, in particular the 43 + * [predicates] variable needs to be 44 + * set, and the packages already compiled into the toploop needs to be 45 + * declared by the [don't_load] 46 + * function. If the toploop has been built by [ocamlfind], 47 + * the necessary initialization is 48 + * automatically compiled in. 49 + *) 50 + 51 + (** {1 Directives} 52 + * 53 + * This module also defines the following directives for the toploop: 54 + * 55 + * - [#require "<package>"] 56 + * loads the package (and if necessary the prerequisites of the package) 57 + * - [#camlp4o] 58 + * loads camlp4 and selects standard syntax 59 + * - [#camlp4r] 60 + * loads camlp4 and selects revised syntax 61 + * - [#list] 62 + * lists the available packages (calls external command "ocamlfind") 63 + * - [#thread] 64 + * enables multi-threading if possible 65 + * - [#predicates "p1,p2,..."] 66 + * adds these predicates 67 + *) 68 + 69 + (** {1 Functions and variables} *) 70 + 71 + val predicates : string list ref 72 + (** The list of predicates used for package loading *) 73 + 74 + val add_predicates : string list -> unit 75 + (** Adds predicates to the list of predicates *) 76 + 77 + val syntax : string -> unit 78 + (** Emulates the [-syntax] option *) 79 + 80 + val standard_syntax : unit -> unit 81 + (** Adds predicates that select the standard syntax. Same as 82 + * [syntax "camlp4o"] 83 + *) 84 + 85 + val revised_syntax : unit -> unit 86 + (** Adds predicates that select the revised syntax. Same as 87 + * [syntax "camlp4r"] 88 + *) 89 + 90 + val don't_load : string list -> unit 91 + (** The packages named in pkglist are added to the list of packages which 92 + * are already loaded. 93 + *) 94 + 95 + val don't_load_deeply : string list -> unit 96 + (** The packages named in pkglist and all direct and indirect ancestors 97 + * are added to the list of packages which are already loaded. 98 + *) 99 + 100 + val load : string list -> unit 101 + (** The packages from the passed package list are loaded, from left to 102 + * right, but packages that have already been loaded are left out. 103 + *) 104 + 105 + val load_deeply : string list -> unit 106 + (** The packages from the passed package list and all direct or indirect 107 + * ancestors are loaded in topological order. Packages that have already 108 + * been loaded are left out. 109 + *) 110 + 111 + val reset : unit -> unit 112 + (** All entries in the list of loaded packages that have been added by 113 + * [load] or [load_deeply] functions are removed from this list. This 114 + * means that if you execute the same [load] or [load_deeply] functions 115 + * again, the packages will be reloaded. 116 + *) 117 + 118 + val announce : unit -> unit 119 + (** Output the startup message *) 120 + 121 + val log : (string -> unit) ref 122 + (** Function used to log messages from this module. *)
+30
vendor/opam/ocamlfind/tools/cmd_from_same_dir
··· 1 + #! /bin/sh 2 + 3 + # Check whether ocamlc and ocamlc.opt are installed in the same 4 + # directory (or whatever command names are passed as $1). 5 + 6 + get_path () { 7 + IFS=":" 8 + for d in $PATH; do 9 + if test -x "$d/$1"; then 10 + IFS="$oldifs" 11 + echo "$d/$1" 12 + return 13 + fi 14 + done 15 + IFS="$oldifs" 16 + #--- The following is not portable enough: 17 + # if test -x `type -p ls`; then 18 + # # type -p works! 19 + # type -p $1 20 + # else 21 + # # use 'which' instead 22 + # p=`which $1` 23 + # test -x "$p" && echo $p 24 + # fi 25 + } 26 + 27 + p1="$(get_path "$1").opt" 28 + p2="$(get_path "$1.opt")" 29 + 30 + [ "X$p1" = "X$p2" ]
+16
vendor/opam/ocamlfind/tools/collect_files
··· 1 + #! /bin/sh 2 + # 3 + # $Id$ 4 + # ---------------------------------------------------------------------- 5 + # 6 + # usage: collect_files file ... 7 + # 8 + # Prints the names of the files passed as arguments which actually 9 + # exist and are regular files. 10 + 11 + for x in "$@"; do 12 + if [ -f "$x" ]; then 13 + echo "$x" 14 + fi 15 + done 16 +
+10
vendor/opam/ocamlfind/tools/extract_args/Makefile
··· 1 + all: extract_args 2 + 3 + extract_args.ml: extract_args.mll 4 + ocamllex -o extract_args.ml extract_args.mll 5 + 6 + extract_args: extract_args.ml 7 + ocamlc -o extract_args extract_args.ml 8 + 9 + clean: 10 + rm -f *.cmo *.cmi *.cma extract_args extract_args.ml
+153
vendor/opam/ocamlfind/tools/extract_args/extract_args.mll
··· 1 + (* $Id$ *) 2 + 3 + (* Runs ocamlc -help and extract the command-line signature *) 4 + 5 + { 6 + open Printf 7 + } 8 + 9 + let whitespace = [ ' ' '\t' ] 10 + 11 + rule get_switch = parse 12 + | whitespace* ('-' [ '-' 'a'-'z' 'A'-'Z' '0'-'9' '_' ',' ]+ as switch_name) 13 + whitespace? (_* as help_text) eof 14 + {Some (switch_name, help_text)} 15 + | whitespace* '-' whitespace+ (_* as help_text) eof 16 + {Some ("-", help_text)} 17 + | _? 18 + {None} 19 + 20 + and has_argument = parse 21 + | whitespace* [ '<' '[' '{' ] 22 + {true} 23 + | _? 24 + {false} 25 + 26 + { 27 + let read_lines file = 28 + let f = open_in file in 29 + let lines = ref [] in 30 + try 31 + while true do 32 + lines := input_line f :: !lines 33 + done; 34 + assert false 35 + with 36 + | End_of_file -> 37 + close_in f; 38 + List.rev !lines 39 + | error -> 40 + close_in f; 41 + raise error 42 + ;; 43 + 44 + 45 + let get_help cmd = 46 + let temp_file = 47 + Filename.temp_file "findlib" ".txt" in 48 + let help_out = 49 + try 50 + let code = 51 + Sys.command (sprintf "%s -help >%s 2>&1" 52 + cmd 53 + (Filename.quote temp_file)) in 54 + if code <> 0 then 55 + raise Not_found; (* Assume command does not exist! *) 56 + let lines = read_lines temp_file in 57 + Sys.remove temp_file; 58 + lines 59 + with error -> 60 + Sys.remove temp_file; raise error in 61 + help_out 62 + ;; 63 + 64 + 65 + let get_switch s = get_switch (Lexing.from_string s) 66 + let has_argument s = has_argument (Lexing.from_string s) 67 + 68 + 69 + let rec extract_signature lines = 70 + match lines with 71 + | [] -> 72 + [] 73 + | line :: lines' -> 74 + match get_switch line with 75 + | Some (switch_name, help_text) -> 76 + let has_arg = has_argument help_text in 77 + let help_lines, lines'' = extract_help_continuation lines' in 78 + let help_text' = String.concat "\n" (help_text :: help_lines) in 79 + let r = 80 + (switch_name, has_arg, help_text') in 81 + r :: extract_signature lines'' 82 + | None -> 83 + extract_signature lines' 84 + 85 + and extract_help_continuation lines = 86 + match lines with 87 + | [] -> 88 + ( [], [] ) 89 + | line :: lines' -> 90 + if get_switch line <> None then 91 + ( [], lines ) 92 + else 93 + let help_lines, lines'' = extract_help_continuation lines' in 94 + (line :: help_lines, lines'') 95 + ;; 96 + 97 + 98 + let rm_help_switch switches = 99 + List.filter 100 + (fun (name, _, _) -> 101 + name <> "-help" && name <> "--help") 102 + switches 103 + ;; 104 + 105 + 106 + let output_some_signature f name switches = 107 + fprintf f "let %s_spec = Some [\n" name; 108 + List.iter 109 + (fun (switch_name, has_arg, help_text) -> 110 + fprintf f " \"%s\",\n" (String.escaped switch_name); 111 + fprintf f " %b,\n" has_arg; 112 + fprintf f " \"%s\";\n\n" (String.escaped help_text) 113 + ) 114 + switches; 115 + fprintf f "];;\n\n" 116 + ;; 117 + 118 + 119 + let output_none f name = 120 + fprintf f "let %s_spec = None;;\n\n" name 121 + ;; 122 + 123 + 124 + let main() = 125 + let f = ref stdout in 126 + let progs = ref [] in 127 + Arg.parse 128 + [ "-o", Arg.String (fun s -> f := open_out s), 129 + "<file> Save generated module to this file"; 130 + ] 131 + (fun arg -> progs := arg :: !progs) 132 + "usage: extract_args <options> <command> ..."; 133 + 134 + progs := List.rev !progs; 135 + 136 + List.iter 137 + (fun prog -> 138 + try 139 + let help_lines = get_help prog in (* or Not_found *) 140 + let switches = rm_help_switch (extract_signature help_lines) in 141 + output_some_signature !f prog switches 142 + with 143 + Not_found -> 144 + output_none !f prog 145 + ) 146 + !progs; 147 + 148 + close_out !f 149 + ;; 150 + 151 + 152 + main();; 153 + }
+5
vendor/opam/ocamlfind/tools/file_exists
··· 1 + #! /bin/sh 2 + 3 + # Approximation of: test -e $1 4 + 5 + test -d "$1" -o -f "$1"
+122
vendor/opam/ocamlfind/tools/make-package-macosx
··· 1 + #!/bin/sh 2 + 3 + # Shell script from Pietro Abate <pietro.abate@anu.edu.au> to create 4 + # Mac OS X packages. Call from Makefile by "make package-macosx". 5 + 6 + ######################################################################### 7 + # # 8 + # Objective Caml # 9 + # # 10 + # Damien Doligez, projet Moscova, INRIA Rocquencourt # 11 + # # 12 + # Copyright 2003 Institut National de Recherche en Informatique et # 13 + # en Automatique. All rights reserved. This file is distributed # 14 + # under the terms of the Q Public License version 1.0. # 15 + # # 16 + ######################################################################### 17 + 18 + # $Id: make-package-macosx,v 1.10.2.2 2006/01/04 13:05:49 doligez Exp $ 19 + # adapted to findlib by Pietro.Abate <pietro.abate@anu.edu.au> 20 + 21 + set -x 22 + 23 + cd package-macosx 24 + rm -rf findlib.pkg findlib-rw.dmg 25 + mkdir -p resources 26 + 27 + cat >Description.plist <<EOF 28 + <?xml version="1.0" encoding="UTF-8"?> 29 + <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 30 + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 31 + <plist version="1.0"> 32 + <dict> 33 + <key>IFPkgDescriptionDeleteWarning</key> 34 + <string></string> 35 + <key>IFPkgDescriptionDescription</key> 36 + <string>The findlib library manager</string> 37 + <key>IFPkgDescriptionTitle</key> 38 + <string>Findlib</string> 39 + <key>IFPkgDescriptionVersion</key> 40 + <string>${VERSION}</string> 41 + </dict> 42 + </plist> 43 + EOF 44 + 45 + cat >Info.plist <<EOF 46 + <?xml version="1.0" encoding="UTF-8"?> 47 + <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 48 + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 49 + <plist version="1.0"> 50 + <dict> 51 + <key>CFBundleGetInfoString</key> 52 + <string>The findlib library manager ${VERSION}</string> 53 + <key>CFBundleIdentifier</key> 54 + <string>http://www.ocaml-programming.de/packages/</string> 55 + <key>CFBundleName</key> 56 + <string>Findlib</string> 57 + <key>CFBundleShortVersionString</key> 58 + <string>${VERSION}</string> 59 + <key>IFPkgFlagAllowBackRev</key> 60 + <true/> 61 + <key>IFPkgFlagAuthorizationAction</key> 62 + <string>AdminAuthorization</string> 63 + <key>IFPkgFlagDefaultLocation</key> 64 + <string>/</string> 65 + <key>IFPkgFlagInstallFat</key> 66 + <false/> 67 + <key>IFPkgFlagIsRequired</key> 68 + <false/> 69 + <key>IFPkgFlagRelocatable</key> 70 + <false/> 71 + <key>IFPkgFlagRestartAction</key> 72 + <string>NoRestart</string> 73 + <key>IFPkgFlagRootVolumeOnly</key> 74 + <true/> 75 + <key>IFPkgFlagUpdateInstalledLanguages</key> 76 + <false/> 77 + <key>IFPkgFormatVersion</key> 78 + <real>0.10000000149011612</real> 79 + </dict> 80 + </plist> 81 + EOF 82 + 83 + # stop here -> | 84 + cat >resources/ReadMe.txt <<EOF 85 + This package installs The findlib library manager ${VERSION}. 86 + You need Mac OS X 10.4.x (Tiger). 87 + 88 + Files will be installed in the following directories: 89 + 90 + /usr/local/bin - command-line executables 91 + /usr/local/lib/ocaml - library and support files 92 + /usr/local/man - manual pages 93 + EOF 94 + 95 + chmod -R g-w root 96 + sudo chown -R root:admin root 97 + 98 + /Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \ 99 + -build -p "`pwd`/findlib.pkg" -f "`pwd`/root" -i "`pwd`/Info.plist" \ 100 + -d "`pwd`/Description.plist" -r "`pwd`/resources" 101 + 102 + size=`du -s findlib.pkg | cut -f 1` 103 + size=`expr $size + 8192` 104 + 105 + hdiutil create -sectors $size findlib-rw.dmg 106 + name=`hdid -nomount findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1` 107 + newfs_hfs -v 'Findlib' $name 108 + hdiutil detach $name 109 + 110 + name=`hdid findlib-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1` 111 + if test -d '/Volumes/Findlib'; then 112 + ditto -rsrcFork findlib.pkg "/Volumes/Findlib/findlib.pkg" 113 + cp resources/ReadMe.txt "/Volumes/Findlib/" 114 + else 115 + echo 'Unable to mount the disk image as "/Volumes/Findlib"' >&2 116 + exit 3 117 + fi 118 + open "/Volumes/Findlib" 119 + hdiutil detach $name 120 + 121 + rm -rf "findlib-${VERSION}.dmg" 122 + hdiutil convert findlib-rw.dmg -format UDZO -o "findlib-${VERSION}.dmg"
+28
vendor/opam/ocamlfind/tools/patch
··· 1 + #! /bin/sh 2 + 3 + # Usage: patch @VARIABLE@ value [extra-args-for-cygpath] 4 + # Environment variable USE_CYGPATH is honoured. 5 + 6 + varname="$1" 7 + varvalue="$2" 8 + 9 + if [ "${USE_CYGPATH}" = "1" ]; then 10 + #varvalue="$(echo "$varvalue" | sed -e 's;/;\\;g')" 11 + varvalue="$(cygpath -w -l $3 "$varvalue")" 12 + varvalue="$(echo "$varvalue" | sed -e 's;\\;\\\\\\\\;g;s/;/\\;/g')" 13 + # e.g. c:\file is transformed to c:\\\\file 14 + else 15 + case `uname` in 16 + MINGW*) 17 + varvalue="$(echo "$varvalue" | sed -e 's;\\;\\\\\\\\;g')" 18 + # Convert the first letter drive to DOS style (naive). 19 + # This is necessary because OCaml uses DOS paths even if 20 + # run under MSYS. 21 + varvalue="$(echo "$varvalue" | sed -e 's;^/\([a-z]\)/;\1:/;g')" 22 + ;; 23 + esac 24 + fi 25 + 26 + sed -e 's;'"$varname"';'"$varvalue"';g' 27 + # e.g. c:\\\\file is parsed by sed as c:\\file which is correct for the 28 + # ocaml string
+52
vendor/opam/ocamlfind/tools/safe_camlp4
··· 1 + #! /bin/sh 2 + 3 + # Call camlp4 with fallback method if dynamic loading is not supported 4 + 5 + dl_string="dynamic loading not supported on this platform" 6 + fn_string="The external function .* is not available" 7 + 8 + tmp_stderr="tmp.safe_camlp4_stderr.$$" 9 + tmp_camlp4="tmp.safe_camlp4_camlp4.$$" 10 + 11 + trap "rm -f $tmp_stderr $tmp_camlp4" 0 12 + 13 + print_stderr=1 14 + code=0 15 + 16 + camlp4 "$@" 2>$tmp_stderr || { 17 + code=$? 18 + grep "$dl_string" $tmp_stderr >/dev/null 2>&1; t1=$? 19 + grep "$fn_string" $tmp_stderr >/dev/null 2>&1; t2=$? 20 + if [ $t1 -eq 0 -o $t2 -eq 0 ]; then 21 + # Fallback: 22 + print_stderr=0 23 + cp4_mods="" 24 + cp4_args="" 25 + i=0 26 + for arg in "$@"; do 27 + if [ $i -gt 0 ]; then 28 + cp4_mods="$cp4_mods -I $arg" 29 + cp4_args="$cp4_args -I $arg" 30 + i=0 31 + else 32 + case "$arg" in 33 + *.cma|*.cmo) 34 + cp4_mods="$cp4_mods $arg" ;; 35 + -I) 36 + i=1 ;; 37 + *) 38 + cp4_args="$cp4_args $arg" ;; 39 + esac 40 + fi 41 + done 42 + mkcamlp4 -o $tmp_camlp4 $cp4_mods || exit 43 + ./$tmp_camlp4 $cp4_args || exit 44 + code=0 45 + fi 46 + } 47 + 48 + if [ $print_stderr -gt 0 ]; then 49 + cat $tmp_stderr >&2 50 + fi 51 + 52 + exit $code