diff --git a/doc/Makefile b/doc/Makefile index 89ef1c0fec6..9bb6c85a537 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -11,12 +11,9 @@ else JBUILDER_FILE= endif -BASESRC=../_build/default/src - ifndef OPAM OPAM = $(JBUILDER) exec -- opam endif -SRCDIR = $(sort $(foreach x,$(wildcard $(BASESRC)/*/*),$(dir $x))) TOPICS = $(shell $(OPAM) help topics) TOPICS_ADMIN = cache filter index lint list upgrade @@ -27,14 +24,6 @@ ifndef OPAM_INSTALLER OPAM_INSTALLER = $(JBUILDER) exec -- opam-installer endif -SRCEXTDIR = ../src_ext/lib - -ifneq ($(wildcard $(SRCEXTDIR)),) - OCAMLDOC = ocamldoc $(patsubst %,-I %,$(SRCDIR) $(SRCEXTDIR) +compiler-libs) -else - OCAMLDOC = ocamlfind ocamldoc $(patsubst %,-package %,$(PACKS) compiler-libs.toplevel) $(patsubst %,-I %,$(SRCDIR)) -endif - .PHONY: man html dev-manual pages all: man dev html pages @@ -52,25 +41,41 @@ man: $(OPAM_INSTALLER) $(HELPFMT) > man/opam-installer.1 man-html: man - rm -rf $@ + rm -rf man-html mkdir -p $@ - for f in $(wildcard man/*); do\ - man2html -r $$f > man-html/$$(basename $$f .1).html;\ + echo '' >$@/index.html + echo '' >>$@/index.html + echo ' Opam man-pages index' >>$@/index.html + echo '' >>$@/index.html + echo '

Opam $(version) man-pages index

' >>$@/index.html + echo '' >>$@/index.html + echo '' >>$@/index.html dev: $(MAKE) -C dev-manual +ODOC_PFX = _build/default/_doc + html: - rm -rf html/ocamldoc - mkdir -p html/ocamldoc + rm -rf html + mkdir -p html + cd .. && $(JBUILDER) build @doc + cp ../$(ODOC_PFX)/odoc.css html/ + for f in ../$(ODOC_PFX)/*/*.html ../$(ODOC_PFX)/*/*/*.html; do\ + mkdir -p $$(dirname html/$${f#../$(ODOC_PFX)/});\ + cp $$f html/$${f#../$(ODOC_PFX)/};\ + done sed 's/%{OPAMVERSION}%/'$(version)'/g' index.html > html/index.html - $(OCAMLDOC) $(wildcard $(BASESRC)/*/*.mli) $(wildcard $(BASESRC)/*/*.ml) -html -d html/ocamldoc || true - $(OCAMLDOC) $(wildcard $(BASESRC)/*/*.mli) $(wildcard $(BASESRC)/*/*.ml) -dot -o dependencies.dot || true - tred dependencies.dot | \ - dot -Tsvg > \ - html/ocamldoc/dependencies.svg \ - || true +# Not to break older links, add manpages to the `ocamldoc` dir + mkdir -p html/ocamldoc + cd html/ocamldoc && for f in ../*/*/index.html; do\ + ln -sf $$f $$(basename $$(dirname $$f)).html;\ + done pages/%.html: pages/%.md omd $^ -o $@ diff --git a/doc/index.html b/doc/index.html index ae926326ef4..33624842d1b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -38,7 +38,7 @@

opam %{OPAMVERSION}% API and libraries documentation

- + @@ -46,47 +46,47 @@

opam %{OPAMVERSION}% API and libraries documentation

Generic standard and system library - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -94,47 +94,47 @@

opam %{OPAMVERSION}% API and libraries documentation

Definition of opam datastructures and its file interface - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -142,31 +142,31 @@

opam %{OPAMVERSION}% API and libraries documentation

Handling of remote sources - + - + - + - + - + - + - + - + - + - + - + - + @@ -174,19 +174,19 @@

opam %{OPAMVERSION}% API and libraries documentation

Solver and Cudf interaction - + - + - + - + - + - + @@ -194,33 +194,33 @@

opam %{OPAMVERSION}% API and libraries documentation

Handling of the ~/.opam hierarchy, repository and switch states - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -236,11 +236,11 @@

opam %{OPAMVERSION}% API and libraries documentation

- + - + @@ -250,45 +250,45 @@

opam %{OPAMVERSION}% API and libraries documentation

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -298,21 +298,16 @@

opam %{OPAMVERSION}% API and libraries documentation

- + - + - +
src/coresrc/core opam-core library
opamVersion.ml
opamVersion.ml (generated) Current opam version
opamCoreConfig.ml
opamCoreConfig.ml Configuration options for this lib (record, global reference and setter)
opamVersionCompare.ml
opamVersionCompare.ml Version comparison function used throughout. From the Dose suite.
opamJson.ml
opamJson.ml Wrapper on Jsonm; only needed for some debug options
opamStd.ml
opamStd.ml Generic stdlib functions (String, List, Option, Sys submodules...)
opamConsole.ml
opamConsole.ml Console output, ANSI color, logging and user querying
opamCompat.ml.4.01/4.02
opamCompat.ml.4.01/4.02 Compatibility layer (Bytes, etc.) for different OCaml versions
System handling
opamProcess.ml
opamProcess.ml Process and job handling, with logs, termination status, etc.
opamSystem.ml
opamSystem.ml Bindings of lots of filesystem and system operations
opamHash.ml
opamHash.ml Type and computation of file checksums
opamFilename.ml
opamFilename.ml Higher level file and directory name manipulation AND file operations, wrappers on OpamSystem using the filename type
opamDirTrack.ml
opamDirTrack.ml Tracking of changes in a given filesystem subtree
opamParallel.ml
opamParallel.ml Parallel execution of jobs following a directed graph
opamUrl.ml
opamUrl.ml URL parsing and printing, with support for our different backends
Windows support
opamStubsTypes.ml
opamStubsTypes.ml Types in the stubs definitions (shared between both implementations)
opamStubs.ml
opamStubs.ml C stubs for Windows. A “dummy” alternate is provided for Unix, which doesn’t require any C code
src/formatsrc/format opam-format library
opamFormatConfig.ml
opamFormatConfig.ml Configuration options for this lib (record, global reference and setter)
opamTypes.mli
opamTypes.mli Definitions of many types used throughout
opamTypesBase.ml
opamTypesBase.ml Helper functions on the base types. Often opened
opamPath.ml
opamPath.ml Defines the file hierarchy in ~/.opam
basic types, used as keys
opamPackage.ml
opamPackage.ml The package type, and package name type (name+version, values often called "nv" in the code)
opamRepositoryName.ml
opamRepositoryName.ml The repository type
opamSwitch.ml
opamSwitch.ml The switch type
opamVariable.ml
opamVariable.ml opam variables with scope (global or module)
more advanced types
opamFilter.ml
opamFilter.ml Formulas on variables, as used in opam files build scripts
opamFormula.ml
opamFormula.ml Formulas on packages, opt. with sub-formulas on versions, and conversion functions
file format
opamLineLexer.mll
opamLineLexer.mll A simple lexer to list of lines, which are lists of words
opamPp.ml
opamPp.ml Bidirectional transformations on top of the parser and printer
opamFormat.ml
opamFormat.ml opam config files syntax and conversion tools
opamFile.ml
opamFile.ml Handles all opam file formats as record types and submodules, conversion to and from syntax
src/repositorysrc/repository opam-repository library
opamRepositoryConfig.ml
opamRepositoryConfig.ml Configuration options for this lib (record, global reference, setter, initialisation)
opamRepositoryBackend.ml
opamRepositoryBackend.ml Signature for repository handlers and some helpers for the repository type
opamRepositoryPath.ml
opamRepositoryPath.ml Defines the file hierarchy in repositories
opamDownload.ml
opamDownload.ml Configuration init and handling of downloading commands
opamHTTP.ml
opamHTTP.ml Main HTTP backend
opamLocal.ml
opamLocal.ml Rsync backend, for local or ssh sources
opamVCS.ml
opamVCS.ml Layer for handling version control sources
opamDarcs.ml
opamDarcs.ml Darcs support (through OpamVCS)
opamGit.ml
opamGit.ml Git support (through OpamVCS)
opamHg.ml
opamHg.ml Mercurial support (through OpamVCS)
opamRepository.ml
opamRepository.ml Operations on repositories (update, fetch...) based on the above backends
src/solversrc/solver opam-solver library
opamSolverConfig.ml
opamSolverConfig.ml Configuration options for this lib (record, global reference, setter, initialisation)
opamActionGraph.ml
opamActionGraph.ml Handles graphs of actions (package changes), based on ocamlgraph
opamCudfSolver.ml
opamCudfSolver.ml Bindings to implementation of CUDF solvers, either built-in or external
opamCudf.ml
opamCudf.ml Solver interaction, conversion of answer to solution
opamSolver.ml
opamSolver.ml Entry point, conversion of universe to cudf, dependencies computation
src/statesrc/state opam-state library
opamStateConfig.ml
opamStateConfig.ml Configuration options for this lib (record, global reference, setter, initialisation)
opamScript.ml
opamScript.ml (generated) Shell config scripts as OCaml strings
opamStateTypes.mli
opamStateTypes.mli Defines the types holding global, repository and switch states
opamFormatUpgrade.ml
opamFormatUpgrade.ml Handles upgrade of an opam root from earlier opam versions
opamSysPoll.ml
opamSysPoll.ml Detection of host system (arch, os, distribution)
opamGlobalState.ml
opamGlobalState.ml Loading and handling of the global state of an opam root
opamRepositoryState.ml
opamRepositoryState.ml loading and handling of the repository state of an opam root (i.e. what is in ~/.opam/repo)
opamSwitchState.ml
opamSwitchState.ml Loading and querying a switch state
opamPackageVar.ml
opamPackageVar.ml Resolution and handling of opam variables + filters
opamFileTools.ml
opamFileTools.ml Generic tools for handling package metadata
opamSwitchAction.ml
opamSwitchAction.ml Switch-related actions and changes
opamEnv.ml
opamEnv.ml Process environment setup and handling, shell configuration
opamPinned.ml
opamPinned.ml Specific query and handling of pinned packages
opamUpdate.ml
opamUpdate.ml Synchronisation and downloading of repositories and package sources
Code for process injection shared between opamWindows.c and opam-putenv.c
opamWindows.c C stubs themselves
opamWin32Stubs.ml
opamWin32Stubs.ml OCaml external declarations for the stubs
src/clientsrc/client opam-client library and exec
opam-client library
opamClientConfig.ml
opamClientConfig.ml Configuration options for this lib (record, global reference, setter, initialisation), plus helper for global setup
opamAction.ml
opamAction.ml Handles concrete actions on packages, like installations and removals
opamSolution.ml
opamSolution.ml Interface with the solver, processing of full solutions through actions
opamConfigCommand.ml
opamConfigCommand.ml Functions for the "opam config" subcommand
opamPinCommand.ml
opamPinCommand.ml Functions for the "opam pin" subcommand
opamRepositoryCommand.ml
opamRepositoryCommand.ml Functions for the "opam repository" subcommand
opamSwitchCommand.ml
opamSwitchCommand.ml Functions for the "opam switch" subcommand
opamListCommand.ml
opamListCommand.ml Functions for the "opam list" subcommand
opamInitDefaults.ml
opamInitDefaults.ml Defines the built-in "opamrc" to use by default on "opam init"
opamClient.ml
opamClient.ml High-level execution of the main user commands ("install", "upgrade", "remove"), and wrapper for Pin commands
opamAuxCommands.ml
opamAuxCommands.ml Some command helpers and extra opam management functions
opamAdminRepoUpgrade.ml
opamAdminRepoUpgrade.ml Handles converting package repositories from the format of older opam versions to the current format
opamAdminCheck.ml
opamAdminCheck.ml Implements the repository checks of the 'opam admin check' command.
opamGitVersion.mli
opamGitVersion.mli (generated) Current git version of opam
opamArg.ml
opamArg.ml Command-line argument parsers and helpers
opamAdminCommand.ml
opamAdminCommand.ml All sub-commands of the "opam admin" command
opamCommands.ml
opamCommands.ml Opam CLI commands and their handlers as Cmdliner terms
Main opam CLI
opamMain.ml
opamMain.ml Main opam entry point
Auxiliary standalone tools
opam_admin_top.ml
opam_admin_top.ml Tiny library for admin-scripts, included in opam-admin.top
opam-putenv.c Tiny C tool used on Windows for cross-architecture process injection
opam_check.ml
opam_check.ml Tiny tool used in internal checks ("make tests")
opam_installer.ml
opam_installer.ml Handles opam's ".install" files
- - -

Raw ocamldoc index

-

Graph of module dependencies

- diff --git a/doc/pages/External_solvers.md b/doc/pages/External_solvers.md new file mode 100644 index 00000000000..63ce79b7247 --- /dev/null +++ b/doc/pages/External_solvers.md @@ -0,0 +1,109 @@ +# External Solvers + +Resolving package installations in the presence of dependencies and conflicts is +known to be an +[NP-complete problem](https://hal.archives-ouvertes.fr/file/index/docid/149566/filename/ase.pdf). +Thankfully, a [big effort](http://www.mancoosi.org/) has already been put into +solving it efficiently: + +The `opam` package manager is an instance of the approach described in the article "[A modular package manager architecture](http://dl.acm.org/citation.cfm?id=2401012)", which was one of the outcomes of the [Mancoosi](http://www.mancoosi.org) research project. This architecture relies on dependency solvers for package managers, that communicate with the package manager front-end via the [CUDF format](http://www.mancoosi.org/cudf/). + +## Installation and compatibility + +As of 2.0.0, opam comes with a CUDF solver built-in by default, so unless you +have specifically compiled without it, you shouldn't have to be worried about +installing an external solver. However, these are still supported, and can be +useful in some specific cases. An external solver can be chosen over the +built-in one using the `--solver` command-line argument, the +`$OPAMEXTERNALSOLVER` environment variable, or the `solver:` field in the +`~/.opam/config` file. If no solver was built in or selected, opam will detect +the availability of `aspcud`, `packup` or `mccs` commands on your system and use +one automatically. + +The following CUDF solvers have been tested: + +- [aspcud](http://www.cs.uni-potsdam.de/wv/aspcud/) (recommended solution until opam 1.2.2) +- [packup](http://sat.inesc-id.pt/~mikolas/sw/packup/) +- [mccs](http://www.i3s.unice.fr/~cpjm/misc/mccs.html) (a modified version of which is now being used as the built-in solver) +- [p2Cudf](https://wiki.eclipse.org/Equinox/p2/CUDFResolver), which can be + downloaded + [here](http://eclipse.org/equinox/p2/p2CUDF/org.eclipse.equinox.p2.cudf-1.14.jar) + and used with the configuration string `java -jar -obj + %{criteria}% %{input}% %{output}%`. + +These have been developed by a variety of research teams during the +[MISC competitions](http://www.mancoosi.org/misc/) run yearly from 2010 to 2012. + +# Specifying user Preferences for the External Solvers + +A fundamental distinguishing feature of the `opam` package manager is the fact that it is designed to reuse state-of-the-art dependency solving technology that gives the users the possibility to express their preferences regarding the operations to be performed during an installation, instead of being bound to an hard-coded strategy. +This section provides basic documentation on this feature, and its usage. + +## What are user preferences for installations, and why are them important? +When you request the installation of some packages, say p1...pn, `opam` has a lot to do: it needs to look at all the packages already installed on your machine, find all packages available from the repositories, consider your request, and then come up with a set of actions to be performed to satisfy your request. + +Unfortunately, there are a lot of assumptions hidden in your mind when you tell `opam` that you want p1...pn installed: should it choose the latest version of the p1...pn? That seems a sensible thing to do, but sometimes installing a recent version of a package p may lead to downgrading or removing another package q, which is something you might not want. What should `opam` do in this case? Remove q to get the latest p, or keep q and get the most recent p that is compatible with it? +Well, the answer is: it depends! It depends on what _you_ really want, and different users may have different points of view. + +User preferences, supported by `CUDF`-compatible solvers, are the means you can use to make the assumptions in your mind explicit and known to the solver used by `opam`, so that the actions performed on your machine correspond to your personalised needs. + +## How do I express my preferences? + +Preferences are expressed using a simple language built by prefixing a little set of combinators with the `-` (minus) or `+` (plus) operators. The most useful combinators are the following ones: + +* `new` : the number of new packages +* `changed` : the number of packages modified +* `removed` : the number of packages removed +* `notuptodate` : the number of packages that are not at their latest version + +For example, the preference `-removed` tells the solver that among all possible ways of satisfying your request, it should choose one that minimises the number of packages removed. + +These combinators can be combined in a comma separated sequence, that is treated in lexicographic order by the solver. + +### Default preferences for an upgrade +For example, the preference `-removed,-notuptodate,-changed` tells the solver that after ensuring that removals are minimised, it should look for a solution that minimises also the number of packages wich are not at their latest version, and then reduce the changes to a minimum. + +This is close to the default preference setting used by `opam` when you perform an update or an upgrade, and in practice it tries to bring _all_ your packages to the latest version available, as far as this does not implies removing too many packages. It can be set using the environment variable `OPAMUPGRADECRITERIA`, or the [`solver-upgrade-criteria:`](Manual.html#configfield-solver-upgrade-criteria) configuration field. + +### Default preferences for an install +When you request to install a (set of) package(s), in general you do not expect to see all your existing packages updated, and this is why in this case it is preferable to use a different value `-removed,-changed,-notuptodate` that tries to minimise changes to the system. It can be set using the environment variable `OPAMCRITERIA`, or the [`solver-criteria:`](Manual.html#configfield-solver-criteria) configuration field. + +### Specifying preferences for opam + +`opam` allows to specify your criteria on the command line, using the `--criteria` option, that will apply only to the current command. +For example if you are a very conservative user, you might try issueing the following command: +``` +opam install --criteria="-removed,-changed" ... +``` + +This can also be used for some tricks: if for example you want to repair your set of installed packages, you can use the `opam upgrade` command without specifying a preference for newer versions in the criteria (although you may prefer to run `opam upgrade --fixup` in this case): +``` +opam upgrade --criteria="-changed" +``` + +## Yes, there are different versions of the user preference language + +The different editions of the MISC competition led to improving the preferences language, by allowing the user progressively more flexibility. Recent solvers give access to a more sophisticated set of preferences, described in [the 2012 MISC competition rules](http://www.mancoosi.org/misc-2012/criteria/). +For example, using `aspcud >=1.8.0`, you could use + + `-count(removed),-count(down),-sum(solution,installedsize),-notuptodate(solution),-count(changed)` + +to instruct a solver to minimise downgrades, and mininise the installed size, among other criteria. + +The default criteria used by opam use a custom CUDF property `version-lag` that +gives a monotonic measure of the "age" of packages, by counting the number of +newer revisions of the package. They can be seen using the `opam config report` +command: + +``` +# install-criteria -removed,-count[version-lag,request],-count[version-lag,changed],-changed +# upgrade-criteria -removed,-count[version-lag,solution],-new +``` + +Notice that these criteria are written for the built-in solver which, being +derived from [`mccs`](https://github.com/AltGr/ocaml-mccs), uses a slightly +different syntax for the criteria: the `-sum(subset,property)` criterion should +be written `-count[property,subset]` instead. We also make use of the `request` +subset here, which applies only to the packages that were part of the user +request, and was introduced in aspcud 1.9.0 and is not part of the official mccs +release. diff --git a/doc/pages/FAQ.md b/doc/pages/FAQ.md index 5bca59b5540..a1f8db6b7b5 100644 --- a/doc/pages/FAQ.md +++ b/doc/pages/FAQ.md @@ -4,18 +4,6 @@ > interested in the more advanced [Tricks](Tricks.html) for specific use-cases > or advanced users. -#### 🐫 opam fails, trying to reinstall already installed packages at first upgrade ? - -It might be that you are still using Ubuntu "utopic", that shipped with a broken -opam package. That shouldn't happen and didn't in any stable opam release. See -[the bug-report on Ubuntu's launchpad](https://bugs.launchpad.net/ubuntu/+source/opam/+bug/1401346) -for the details. - -The best fix is to upgrade your [opam](Install.html) using the community -packages. - ---- - #### 🐫 What is opam for ? Easily installing, upgrading and managing your OCaml compiler(s), tools and @@ -33,19 +21,23 @@ used for different systems using specific repositories (e.g. for the #### 🐫 How to get, install and upgrade opam ? See the [install guide](Install.html). -If upgrading, you can bootstrap using `opam install opam-devel`. + +If upgrading, you can bootstrap using `opam install opam-devel`, and follow the +instructions. --- #### 🐫 Where is the manual ? -opam has git-like, hierarchical manpages. Try `opam --help` for a starting point. +opam has git-like, hierarchical +[manpages](https://opam.ocaml.org/doc/2.0/man/opam.html). Try `opam --help` for +a starting point. Or get started from the [Usage](Usage.html) guide. If you want to know more about opam packages, see the [Packaging Howto](Packaging.html). -The reference on the internals and file formats is in the [Manual](Manual.html). +The full reference on the internals and file formats is in the [Manual](Manual.html). You may also want to browse the [library APIs](api/). @@ -61,8 +53,12 @@ installations. If you choose to create "local switches", the installation prefix will be put in the specified directory with `/_opam/` appended. Nothing else will be changed. -The `opam build` command creates a local switch in the current directory, in the -form of a `_opam/` subdirectory. + +Please note, however, that programs you install using opam won't themselves be +bound by any restrictions. + +On Linux, and since opam 2.0.0~rc2, package instructions (build, install, +remove) are also run in a sandbox and guaranteed not to affect your system. --- @@ -134,6 +130,10 @@ opam switch import --switch The file format is human-readable, so you are free to edit the file before doing the `import` if you need to customise the installation. +You may also want to have a look at the `opam lock` plugin, that can memorise +the precise set of installed dependencies for a local package, and the +associated `opam install DIR --locked` command that can restore them. + --- #### 🐫 I installed a package by hand / used ``ocamlfind remove`` / fiddled with the installed packages and opam is out of sync. Help ! @@ -161,8 +161,8 @@ there are several ways you can recover: #### 🐫 What are the minimum requirements ? 1GB of memory should be all you need. It was reported that you may run into -problems with 512MB of RAM and no swap. Of course, software packages themselves -may be more greedy. +problems with 512MB of RAM and no swap. Of course, compiling the packages may +need more. --- @@ -173,30 +173,34 @@ using your system package manager (apt-get, yum, pacman, homebrew, etc.) since they are outside the scope of opam. opam metadata includes documentation about these external dependencies, on a -variety of systems/distributions, in the form of a `depext:` field. The `depext` -opam plugin can take care of them for you: +variety of systems/distributions, in the form of a +[`depexts:`](https://opam.ocaml.org/doc/2.0/Manual.html#opamfield-depexts) +field. Opam should print the required system dependencies, as documented for +your OS, upon failure, and the `depext` opam plugin can take care of installing +them for you: ``` opam depext ``` -This should install `opam-depext` if needed, check your OS, and prompt to -install the system packages required by your packages or their dependencies, -through your OS's packaging system. +This should install `opam-depext` if needed and prompt to install the system +packages required by your opam packages or their dependencies, through your OS's +packaging system. If that doesn't work... * Check for hints printed by the failing package -* Dependencies for your specific system may not be known, but check the output - of `opam list --rec --required-by ,... --external`: it will - list dependencies on all known systems and may get you in the right direction. * Lookup the development packages corresponding to the error in your system's package repositories. +* Dependencies for your specific system may not be known, but check the output + of `opam list --rec --resolve ,... --columns name,depexts:`: + it will list dependencies on all known systems and may get you in the right + direction. In any of these cases, that's useful information that was missing from the opam repository: we would really appreciate that you take a minute to save others the trouble of looking by filling an issue in [the opam-repository tracker](https://github.com/ocaml/opam-repository/issues), -with your system details, the output of `opam depext --flags`, and the solution, +with your system details, the output of `opam config report`, and the solution, if you found it. Thanks! --- @@ -221,13 +225,10 @@ As a last resort, you can bypass the checksum checks using `--no-checksums`. #### 🐫 opam is prompting me to install or upgrade packages that I am not interested in, or doesn't install the latest version by default. Why ? What can I do ? * You can be more explicit in your request (`opam upgrade PACKAGES`, `opam - install 'PACKAGE>=VERSION' PACKAGE...`, etc.) -* Action resolution in a package set is known to be a NP-complete problem; opam - uses state-of-the-art algorithms through an external, dedicated solver: make - sure you have a recent - [external solver installed](Install.html#ExternalSolvers) -* Another benefit of the external solvers is that they allow to be [quite - expressive](Specifying_Solver_Preferences.html) on your expectations. + install 'PACKAGE>=VERSION' PACKAGE...`, etc.). The latest version may not be + available on your system, in this case this will tell you why. +* See how to set [solver preferences](External_solvers.html) that could match your intentions better than the defaults +* Check for pending reinstallations `opam reinstall --list-pending` --- @@ -241,15 +242,12 @@ requesting, here is how to find out. We'll suppose you were trying to install * The above may find a solution by using older version of the packages, in that case try and force the latest versions thusly: `opam install foo.2.0 bar.1.1` (you can also use constraints like `'foo>=2.0'`). -* Like in the previous question, make sure you have - [aspcud](http://potassco.sourceforge.net/) or another supported solver - installed, the proposed solutions may not be as accurate without it. --- #### 🐫 Where do I report Bugs, Issues and Feature Requests? -- Bug reports and feature requests for the opam tool should be reported on +- Bug reports and feature requests for the opam **tool** should be reported on [opam's issue-tracker](https://github.com/ocaml/opam/issues). Please include the output of `opam config report` whenever applicable. @@ -262,20 +260,23 @@ issue-tracker](https://github.com/ocaml/opam-repository/issues). insights and evolution of opam internals can discussed on the [opam-devel mailing-list](http://lists.ocaml.org/listinfo/opam-devel). -- You may also try IRC channel `#opam` on Freenode. +- https://discuss.ocaml.org is a good place for community assistance. + +- You may also try IRC channel `#ocaml` on Freenode. --- #### 🐫 How to link to libraries installed with opam ? The standard way of doing this is to use -[ocamlfind](https://opam.ocaml.org/packages/ocamlfind), which is -orthogonal to opam: `ocamlfind query `. - -Your libraries are installed to the directory returned by ``opam config var -lib``, which is by default `~/.opam//lib`. Note that using `ocamlc`'s -option `-I +dir` will make `dir` relative to `lib/ocaml`, and will only work for -the libraries that ship with the compiler. Also, remember to add the dependency when +[ocamlfind](https://opam.ocaml.org/packages/ocamlfind), which is orthogonal to +opam: `ocamlfind query `. If you use [dune](https://github.com/ocaml/dune), +this should be completely transparent. + +Your libraries are installed to the directory returned by ``opam var lib``, +which is by default `~/.opam//lib`. Note that using `ocamlc`'s option +`-I +dir` will make `dir` relative to `lib/ocaml`, and will only work for the +libraries that ship with the compiler. Also, remember to add the dependency when you package your project ! --- diff --git a/doc/pages/Install.md b/doc/pages/Install.md index 4c5d0365af9..e424efa8cba 100644 --- a/doc/pages/Install.md +++ b/doc/pages/Install.md @@ -1,45 +1,49 @@ # How to install opam -This page describes how to install and configure opam and [external -solvers](#ExternalSolvers). For further help on how to use opam, -either read `opam --help` or move on to the [Usage](Usage.html) guide. +This page describes how to install and configure opam. For further help on how +to use opam, either read [`opam --help`](man/opam.html) or move on to the +[Usage](Usage.html) guide. + ## Upgrading from a previous version Generally, you should just reproduce the same installation steps as for the original installation: upgrade from your system's package manager, or re-run the binary installer. Opam will automatically update its internal repository at -`~/.opam` on first run if needed (backup that if you may want to rollback the -upgrade without starting over). +`~/.opam` on first run if needed (if using our installer script, a backup can be +made automatically). + +Then see the [Upgrade guide](Upgrade_guide.html) to check the changes. ## Binary distribution -The quickest way to get the latest opam up and working is to run: +The quickest way to get the latest opam up and working is to run +[this script](https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh): ``` -wget https://raw.github.com/ocaml/opam/master/shell/opam_installer.sh -O - | sh -s /usr/local/bin +sh <(curl -sL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) ``` This will simply check your architecture, download and install the proper -pre-compiled binary and run `opam init`. +pre-compiled binary, backup your opam data if from an older version, and run +`opam init`. -(If you don't have `wget`, or have trouble installing it, another -option is to simply copy the contents of `opam_installer.sh` to your -system and run it. Use your browser to go to the URL listed above after -`wget`, copy the text in the page that opens, and save that text into a file -named "opam_installer.sh". Make this file executable and run it.) +(If you have troule with `curl`, just +[download the script](https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) +and run `sh install.sh`) We provide pre-compiled binaries for: -- Linux i686, amd64 and arm7 +- Linux i686, amd64, arm7, arm64 - OSX (intel 64 bits) (other platforms are available using the other methods below) -You can pick your download -[here](https://github.com/ocaml/opam/releases/latest), and simply put it in your -PATH as `opam`, e.g. +If you don't like scripts, you can just pick your download +[here](https://github.com/ocaml/opam/releases), put it in your PATH as +`opam`, and set it as executable, e.g. ``` -sudo cp /usr/local/bin +sudo cp /usr/local/bin/opam +sudo chmod a+x /usr/local/bin/opam ``` @@ -68,7 +72,7 @@ yaourt -S opam-git #### Debian Binary packages of opam are available for the -[stable](http://packages.debian.org/jessie/opam) (a bit outdated), +[stable](http://packages.debian.org/jessie/opam), [testing](http://packages.debian.org/stretch/opam) and [unstable](http://packages.debian.org/sid/opam) distributions, from the official repositories. You should be set with: @@ -77,21 +81,11 @@ repositories. You should be set with: apt-get install opam ``` -There are also unofficial packages from the -[OpenSUSE Build Service](http://software.opensuse.org/download.html?project=home%3Aocaml&package=opam), -for the latest version, when not yet in the Debian repositories: - -``` -wget http://download.opensuse.org/repositories/home:ocaml/Debian_7.0/Release.key -apt-key add - < Release.key -echo 'deb http://download.opensuse.org/repositories/home:/ocaml/Debian_7.0/ /' >> /etc/apt/sources.list.d/opam.list -apt-get update -``` - #### [Exherbo](http://exherbo.org) The -[`dev-ocaml/opam`](http://git.exherbo.org/summer/packages/dev-ocaml/opam/index.html) package can be installed with the command: +[`dev-ocaml/opam`](http://git.exherbo.org/summer/packages/dev-ocaml/opam/index.html) +package can be installed with the command: ``` cave resolve -x dev-ocaml/opam @@ -105,9 +99,8 @@ cave resolve -x repository/ocaml-unofficial #### [Fedora](http://fedoraproject.org), [CentOS](http://centos.org) and RHEL -RPMs for Fedora, CentOS and Red Hat Enterprise Linux are available with -instructions on the -[OpenSUSE Build Server](https://software.opensuse.org/package/opam). +No native packages at the moment, you will need to use our pre-built binaries, +or build from sources. #### Mageia @@ -127,17 +120,13 @@ cd /usr/ports/sysutils/opam make install ``` -Note that the `aspcud` external solver is not yet available on OpenBSD, so you -may see some odd upgrade attempts due to the use of the internal solver. - #### OSX Opam packages for [homebrew](http://mxcl.github.com/homebrew/) and [MacPorts](http://www.macports.org/) are available: ``` -brew install opam # Homebrew, OSX Mavericks or later -brew install opam --without-aspcud # Homebrew, OSX Mountain Lion or lower +brew install opam # Homebrew port install opam # MacPort ``` @@ -147,16 +136,14 @@ for Opam usage. #### Ubuntu -The latest version of Opam is available in Ubuntu universe starting from 15.10 -"Wily": +Ubuntu has native packages for opam: ``` apt install opam ``` -Ubuntu 12.04 LTS "Precise" doesn't have an opam package and the package in 14.04 -LTS "Trusty" is an older release. We provide binary packages of the latest -version for these two releases: +We also provide our own for the latest versions opam version, if not yet +available on your Ubuntu release: ``` add-apt-repository ppa:avsm/ppa @@ -184,22 +171,15 @@ Sources of the latest stable version of opam are available on Github: * [Opam releases on Github](https://github.com/ocaml/opam/releases) You can also download the full archives, including opam dependencies (these -don't require any extra downloads, just the OCaml compiler -- 4.01.0 or later): +don't require any extra downloads, just the OCaml compiler -- 4.02.3 or later +for the latest version): +* [2.0.0~rc](https://github.com/ocaml/opam/releases/download/2.0.0-rc/opam-full-2.0.0-rc.tar.gz) + MD5: 6e89905dbe9203dee3e883b70e210285 + SHA384: 8a9ee03cdcd78a7d44e92c9b1c6e841605a49ecff4ebd977a632708ef6250f9f3ec488ecd1852f76d1b6cfc2d8ad9117 * [1.2.2](https://github.com/ocaml/opam/releases/download/1.2.2/opam-full-1.2.2.tar.gz) MD5: 7d348c2898795e9f325fb80eaaf5eae8 - SHA1: 415ff0506378ab8dfa428fcd0aff3aa28337d93b -* [1.2.1](https://github.com/ocaml/opam/releases/download/1.2.1/opam-full-1.2.1.tar.gz) - MD5: 04e8823a099ab631943952e4c2ab18fc - SHA1: 189e309ee0659723abaaad5f887f5caf89b34422 -* [1.2.0](https://github.com/ocaml/opam/releases/download/1.2.0/opam-full-1.2.0.tar.gz) - MD5 (opam-full-1.2.0.tar.gz) = 17cc252c6c80fc503c4878eac8d123e7 -* [1.1.2](https://github.com/ocaml/opam/releases/download/1.1.2/opam-full-1.1.2.tar.gz) - MD5 (opam-full-1.1.2.tar.gz) = ba2a4136b65003c04d905de786f3c3ab -* [1.1.1](https://github.com/ocaml/opam/releases/download/1.1.1/opam-full-1.1.1.tar.gz) - MD5 (opam-full-1.1.1.tar.gz) = a7bebe947b3e6c1c10ccafabb839d374 -* [1.1.0](http://www.ocamlpro.com/pub/opam-full-1.1.0.tar.gz) - MD5 (opam-full-1.1.0.tar.gz) = d6e2f56b10c0be73b5677963e6659d24 + SHA384: 3a0a7868b5f510c1248959ed350eecacfe1abd886e373fd31066ce10871354010ef057934df026e5fad389ead6c2857d Follow the instructions in the included [`README.md`](https://github.com/ocaml/opam#readme) to get opam built and @@ -217,44 +197,3 @@ necessary pre-requisites installed to run ocamlbrew, and then run: ``` curl -kL https://raw.github.com/hcarty/ocamlbrew/master/ocamlbrew-install | env OCAMLBREW_FLAGS="-r" bash ``` - -# External Solvers - -Resolving package installations in the presence of dependencies and -conflicts is known to be an [NP-complete -problem](https://hal.archives-ouvertes.fr/file/index/docid/149566/filename/ase.pdf). -Thankfully, a big effort has already been put into solving it very -efficiently: opam relies on this effort and delegates the solving -process to _external solvers_. opam integrates a simple solver, so it -can used without any extra dependencies, but for best results you -should have one of those solvers on your system: - -- [aspcud](http://www.cs.uni-potsdam.de/wv/aspcud/) (recommended) -- [packup](http://sat.inesc-id.pt/~mikolas/sw/packup/) -- [mccs](http://www.i3s.unice.fr/~cpjm/misc/mccs.html) -- [p2Cudf](https://wiki.eclipse.org/Equinox/p2/CUDFResolver), which may be the - easiest if dependencies are a problem, as it comes as a single jar file. - [Dowload it](http://eclipse.org/equinox/p2/p2CUDF/org.eclipse.equinox.p2.cudf-1.14.jar) - and set the solver configuration string to - `java -jar -obj %{criteria}% %{input}% %{output}%`. - -We recommend installing one through your packaging system whenever -possible: this should already have been taken care of if you installed -opam through your packaging system (see https://github.com/ocaml/opam/wiki/Distributions -for details for each distribution). If you have trouble installing an -external solver and have reliable network connectivity, -[Irill](http://www.irill.org/) kindly provides a ["Solver -farm"](http://cudf-solvers.irill.org/) which can be used as a remote -solver by opam. - -Opam will detect the availability of `aspcud`, `packup` or `mccs` commands on -your system and should switch to using them directly. You can explicitly specify -which external solver to use by using the `--solver` command-line argument, the -`$OPAMEXTERNALSOLVER` environment variable, or the `solver:` field in the -`~/.opam/config` file. - -External solvers also allow to specify [fine-grained -preferences](Specifying_Solver_Preferences.html). `aspcud` -is currently recommended because it supports a richer language of -[solver preferences](Specifying_Solver_Preferences.html#Yestherearedifferentversionsoftheuserpreferencelanguage) -giving opam more control over the requested solution. diff --git a/doc/pages/Manual.md b/doc/pages/Manual.md index 34357b459f5..57dca551550 100644 --- a/doc/pages/Manual.md +++ b/doc/pages/Manual.md @@ -8,7 +8,7 @@ This manual gathers reference information on opam and primarily of use for packagers, package maintainers and repository maintainers. * For simple usage of opam, see the [Usage](Usage.html) page, and the - comprehensive built-in documentation `opam [command] --help`. + comprehensive built-in documentation [`opam [command] --help`](man/index.html). * For a gentler introduction to packaging, see the [Packaging guide](Packaging.html) * If you want to hack on opam or build related tools, the API documentation can @@ -1291,7 +1291,7 @@ for opam. - `solver-criteria: `: can be used to tweak the solver criteria used for the resolution of operations. These depend on the solver used, see the - [Solver Criteria](Specifying_Solver_Preferences.html) page for details. + [Solver Criteria](External_solvers.html) page for details. - `solver-upgrade-criteria: `, `solver-fixup-criteria: `: similar to [`solver-criteria`](#configfield-solver-criteria), but specific to diff --git a/doc/pages/Packaging.md b/doc/pages/Packaging.md index 987d6ebb215..f543110a532 100644 --- a/doc/pages/Packaging.md +++ b/doc/pages/Packaging.md @@ -1,87 +1,21 @@ -## Tl;dr +# Creating and publishing opam packages -Create a local package from the current directory +An opam package is defined by a `.opam`, or simply `opam` file, +containing its metadata. This short guide will get you through writing this +definition, testing it, and publishing to the +[opam-repository](https://github.com/ocaml/opam-repository). -``` -$ opam pin add . -``` +## Creating a package definition file -Get a local copy of an existing package and install from there +For complete documentation of the format, see [the manual]((Manual.html#Packagedefinitions). -``` -$ opam source --pin -``` +If your project does not yet have a package definition, get to the root of its +source, and then either +- run `opam pin .` to create and edit a template, and test your definition right +away, +- or create a `.opam` file and edit it by hand. -Get it back to normal - -``` -$ opam pin remove -``` - -Publish to the opam repository: -* Use the [opam-publish](https://github.com/OCamlPro/opam-publish#opam-publish) - tool (`opam install opam-publish`) -* Or by hand: - - Fork [https://github.com/ocaml/opam-repository](https://github.com/ocaml/opam-repository) - - Add `packages//./opam` with your metadata - - File a [pull request](https://github.com/ocaml/opam-repository/compare/) - - -# Creating opam packages - -An opam package is basically a bunch of data about a software project: -* A name, version and description -* Some dependencies and constraints on other packages, compiler versions, etc. -* Build, install and remove instructions -* Some additional information (bugtracker, homepage, license, doc...) - -This document will go through a simple way to get it in the right format, -whether you are packaging your own project or someone else's. It's not a -[complete guide](Manual.html#Packagedefinitions) to the opam file format. - - -## Creating a local package - -We'll be assuming that you have a working opam installation. If not, please -first read the [install guide](Install.html). - - -### Get the source - -Let's start from the root directory of your project source, typically obtained -from a version-controlled repository or from a tarball. - -``` -$ wget https://.../project.tar.gz && tar xvzf project.tar.gz -# Or -$ git clone git://.../project.git -... -$ cd project -``` - -### Opam pin - -opam provides a feature that allows you to register packages locally, -without the need for them to exist in a repository. We call this __pinning__, -because it is an extension of the very common feature that allows to __pin__ a -package to a specific version number in other package managers. - -So let's create a package __pinned__ to the current directory. We just need to -choose a name and issue the command: - -``` -$ opam pin add . -n -``` -(`-n` tells opam to not try and install just yet, we'll get to it later) - - -### The "opam" file - -At this stage, opam will be looking for metadata for the package ``, on -its repository and in the source directory. Not finding any, it will open an -editor with a pre-filled template for your package's `opam` file. It's best to -keep the project's `README` file open at this stage, as it should contain the -information we're interested in, only in a less normalised format. +The file follows a simple `field: ` format: ``` opam-version: "2.0" @@ -96,139 +30,77 @@ authors: "Name " license: "" homepage: "" bug-reports: "" +dev-repo: "" +depends: [ "ocaml" "ocamlfind" ] build: [ ["./configure" "--prefix=%{prefix}%"] [make] ] install: [make "install"] -dev-repo: "" -depends: [ "ocaml" "ocamlfind" ] ``` -The `opam-version` and `maintainer` fields are mandatory; you should -remove the others rather than leave them empty. -* `synopsis` should be a one-line description of what your package does, used in - listings. It is recommended to also add a `description` field for a longer - explanation (hint: you may delimit long strings with triple-quotation mark - delimiters `"""` to avoid escaping issues). -* You'll probably be the `maintainer` for now, so give a way to contact you in - case your package needs maintenance. -* Most interesting is the `build` field, that tells opam how to compile the - project. Each element of the list is a single command in square brackets, - containing arguments either as a string (`"./configure"`) or a variable name - (`make`, defined by default to point at the chosen "make" command -- think - `$(MAKE)` in Makefiles). `%{prefix}%` is another syntax to replace variables - within strings. `opam config list` will give you the list of available - variables. `build` instructions shouldn't need to write outside of the - package's source directory. -* `install` is similar to `build`, but tells opam how to install. This is indeed - `install: [ [make "install"] ]`, but the extra square brackets are optional - when there is a single element, just add them if you need more than one - command. -* `depends` should be a list of existing opam package names that your package - relies on to build and run. You'll be guaranteed those are there when you - execute the `build` instructions, and won't be changed or removed while your - package is installed. If contributing to the default repository at - https://opam.ocaml.org, it is quite unlikely that you don't need at least - `"ocaml"` there. - -A few other fields are available, but that should be enough to get started. Like -`install`, most fields may contain lists in square brackets rather than a single -element: `maintainer`, `author`, `homepage`, `bug-reports`, `license` and -`depends`. You may add a `remove` field, but since opam 2.0, removal of -installed files is done automatically, so that should only be needed if your -`install` modified existing files. - -For the list of available fields and specification of the format, see the -[opam manual](Manual.html#opam). - -One you save and quit, opam will run a series of checks (similar to `opam -lint`), and let you edit again in case of errors. - - -## Installing - -The best test is to let opam attempt to install your just created package. As -for any package, you do it by hand with: +The `depends:`, `build:` and `install:` are the most important fields here. If +your project uses [`dune`](https://github.com/ocaml/dune), skip `install:` and +use: ``` -$ opam install --verbose +build: ["dune" "build" "-p" name] ``` -At this point, opam will get a snapshot of the project, resolve its dependencies -and propose a course of actions for the install. Let it go and see if your -project installs successfully; it's a good idea to use `--verbose` as it will -make opam print the output of the external commands, in particular the ones in -the `build` instructions. +See [below](The-file-format-in-more-detail) for more on the format. -You can now check that everything is installed as expected. +## Testing -If you need to change anything, simply do +Make sure you have committed everything if using a version-control system +(_e.g._ `git add *.opam && git commit`), and just run ``` -$ opam pin edit +opam install . ``` -to get back to editing the `opam` file. Manually editing the `opam` file in -your source tree, then running `opam upgrade ` also works. - -So far, so good! You may have missed dependencies in case they were already -installed on your system, but that will be checked automatically by the -continuous integration system when you attempt to publish your package to the -opam repository, so don't worry. - +from the root of your project. This will attempt to install the newly-defined +package so you can check it goes as expected. -## Distributing your package +## Publishing -The easiest way to get your package into the opam repository is to use -[opam-publish](https://github.com/ocaml/opam-publish), a tool that automates -most of the steps to get a full package ready, reviewed and published. The -official OCaml repository is hosted on Github and uses its pull-request -mechanism for requests, reviews and merges. +Publishing is done using Github's pull-request mechanism, which allows automated +checks to be run, and discussion to happen with the maintainers before your +contribution is merged. You will need a [Github](https://github.com/) account. -Your package needs to be hosted somewhere to be made widely available. While the -opam repository at https://opam.ocaml.org can cache package archives, it is not -intended as a primary hosting. If your project is hosted on Github, a tag is -enough to make an archive available. +Submitting is most easily done using the `opam-publish` plugin. Run `opam +publish --help` for more options. -### With opam-publish +### If the project is hosted on Github +First tag the project. Assuming this is version 0.1: ``` -$ opam publish prepare [URL] +git tag -a 0.1 +git push 0.1 ``` +Alternatively, you can create a release using the web UI +(https://github.com/USER/REPO/releases/new). -This will automatically install `opam-publish` if needed, then run it. `[URL]` -is the URL from which the archive containing the sources of your package is -available — if your source is hosted on Github and the last pushed git tag -corresponds to your release, it can be omitted altogether! +Then just run `opam publish` from your source directory and follow the steps. -This command will provide you with a `./` directory. Check the -files in that directory, it's the full contents of what will be included in the -opam repository. +### If not -When you are ready, go on with +Assuming your release is available as an archive at +`https://foo.bar/project-0.1.tar.gz`, run: ``` -$ opam publish submit [DIR] +opam publish https://foo.bar/project-0.1.tar.gz . ``` -Where `[DIR]` can be omitted in the same circumstances as before, and is -otherwise the name of the generated `./` directory. +from your source directory. The final `.` argument indicates to search for +package definitions in the current directory rather than in the archive. -This will submit a pull-request in your name to Github, proposing the addition -of your package definition to the main OCaml repository. You will be redirected -to the page where you can view the status of your pull request, get reviews and -discuss. +> `opam publish` can be re-run any number of times to update an existing +> submission, or propose changes to an already released package. -If any modifications are needed, you just need to re-run the command to update -the existing pull-request. - -### By hand - -#### 1. Creating the metadata - -Copy your `opam` file and add to it a section with the following format: +### Without opam-publish +First, you will need to add a section in the following format to the package +definition, to specify where to retrieve the source of the package: ``` url { src: "https://address/of/project.1.0.tar.gz" @@ -236,101 +108,73 @@ url { } ``` -The checksum is a simple md5 of the archive, which you can obtain with _e.g._: +Then get to https://github.com/ocaml/opam-repository and select `Fork` on the +top-right. Clone the resulting repository, add your package definition, and +push back, as such: ``` -$ curl -L "https://address/of/project.1.0.tar.gz" | md5sum +git clone git@github.com:USER/opam-repository --branch 2.0.0 +cd opam-repository +cp OPAM_FILE packages/NAME/NAME.VERSION/opam +git add packages +git commit +git push origin HEAD:add-pkg-NAME ``` -You will then need to create a patch to the repository: - -#### 2. Requesting addition to opam-repository +Then, back to the web UI, Github should propose to file a pull-request for your +newly pushed branch. If not, select the `new pull request` button on the left. +Make sure to file your pull-request against the `2.0.0` base branch, since +package definitions in 1.2 format are not yet accepted on `master`. -Publishing is handled through Github, using the pull-request mechanism. If -you're not familiar with it, it is a fancy way to: -* Make a patch to the opam repository -* Propose this patch for review and integration. This will also trigger tests - that your package installs successfully from scratch. -1. Go to https://github.com/ocaml/opam-repository and hit the `Fork` button on - the top right corner (you may be asked to login or register) - -2. Get the `clone URL` on the right, and, from the shell, run `git clone ` - to get your local copy - -3. Add the `opam` file with the `url {}` section into a - `packages//./` directory in the repository, and - make that a git commit: - - ``` - $ cd opam-repository/packages - $ mkdir -p /. - $ cp /./ - $ git add - $ git commit -m "Adding new package ." - ``` - -4. Sending that back to github is just a matter of running `git push` - -5. Back to the web interface, refresh, hit the `Pull request` button, check your - changes and confirm; - -6. Wait for feedback! - -### Once you are done - -Don't forget to `opam pin remove ` once your project is on the -repository, if you don't want to continue using your local version. Remember -that as long as the package is pinned, opam will use the metadata found in its -source if any, but otherwise only what is in the opam repository matters. Use -`opam pin list` to list all currently pinned packages. - -## Some tricks - -* You may skip the first step and pin to a remote version-controlled - repository directly, using for example - - ``` - $ opam pin add git://github.com/me/project.git - ``` - -* opam will propose to save your opam file back to your source, but if you want - to take a peek at the internal version it's at - `~/.opam//.opam-switch/overlay//`. You may also check it with - `opam show --raw `. -* Since 1.2.1, opam will also use files `.opam`, or metadata found in a - subdirectory `opam` or `.opam` in your source tree. This can be - useful if different opam packages are built from the same source. -* You can set opam to use your local clone of the repository with - - ``` - $ opam repository add my-dev-repo path/to/opam-repository - ``` +## The file format in more detail - Don't forget to `opam pin remove `, and test your changes to the - repo directly. Don't forget to `opam update my-dev-repo` after you made - changes to it. +### The basics -* Pins can also be used to try out experimental changes to a project with - minimal effort: you can pin to a git repository and even to a specific branch, - tag or hash by adding `#BRANCH` to the target. So say you want to try out - Joe's GitHub pull-request present on his branch `new-feature` on his fork of - `project`, just do +The `opam-version` and `maintainer` fields are mandatory; you should +remove the others rather than leave them empty. +* `synopsis` should be a one-line description of what your package does, used in + listings. It is recommended to also add a `description` field for a longer + explanation (hint: you may delimit long strings with triple-quotation mark + delimiters `"""` to avoid escaping issues). +* You'll probably be the `maintainer` for now, so give a way to contact you in + case your package needs maintenance. +* Most interesting is the `build` field, that tells opam how to compile the + project. Each element of the list is a single command in square brackets, + containing arguments either as a string (`"./configure"`) or a variable name + (`make`, defined by default to point at the chosen "make" command -- think + `$(MAKE)` in Makefiles). `%{prefix}%` is another syntax to replace variables + within strings. `opam config list` will give you a list of available + variables. `build` instructions shouldn't need to write outside of the + package's source directory. +* `install` is similar to `build`, but tells opam how to install. The example + above should indeed be `install: [ [make "install"] ]`, but the extra square + brackets are optional when there is a single element. This field can be + skipped if your package generates a + [`.install`](Manual.html#lt-pkgname-gt-install) file, like is the + case when using `dune`. +* `depends` should be a list of existing opam package names that your package + relies on to build and run. You'll be guaranteed those are there when you + execute the `build` instructions, and won't be changed or removed while your + package is installed. If contributing to the default repository at + https://opam.ocaml.org, it is quite unlikely that you don't need at least + `"ocaml"` there. - ``` - $ opam pin project git://github.com/Joe/project.git#new-feature - ``` +> Note: when running local shell scripts during _e.g._ `build:`, it is +> preferable to use `build: ["sh" "-exc" "./SCRIPT"]` than call the script +> directly. - and opam will use that to get the source (and possibly updated metadata) of - the package; this works with any branch of any git (or even Mercurial, or - Darcs) repo, it's not github specific. -* We've been focusing on git above, but opam can handle darcs and mercurial - repositories too, using `darcs://` and `hg://`. +A few other fields are available, but that should be enough to get started. Like +`install`, most fields may contain lists in square brackets rather than a single +element: `maintainer`, `author`, `homepage`, `bug-reports`, `license` and +`depends`. You may add a `remove` field, but since opam 2.0, removal of +installed files is done automatically, so that should only be needed if your +`install` modified existing files. -## More on opam files +### Advanced usage -The opam files can express much more than what was shown above. Without getting -into too much detail, here are some of the most useful features: +This is just a very short introduction, don't be afraid to consult +[the reference](Manual.html#opam) for details and more: * [**Version constraints**](Manual.html#PackageFormulas): an optional version constraint can be added after any package name in `depends`: simply write @@ -340,29 +184,31 @@ into too much detail, here are some of the most useful features: conjunction (all of them are required), but you can use the logical "and" `&` and "or" `|` operators, and even group with parentheses. The same is true for version constraints: `("pkg1" & "pkg2") | "pkg3" {>= "3.2" & != "3.7"}`. -* [**Build depends**](Manual.html#Filteredpackageformulas): you may add the key - `build` in the version constraints, e.g. `"package" {build & >= "3.2"}`, to - indicate that there is no run-time dependency to this package: it is required - but won't trigger rebuilds of your package when changed. +* [**Build depends**](Manual.html#Filteredpackageformulas): you may add, among + others, the key `build` in the version constraints, _e.g._ + `"package" {build & >= "3.2"}`, to indicate that there is no run-time + dependency to this package: it is required but won't trigger rebuilds of your + package when changed. * [**OS constraints**](Manual.html#opamfield-available): The `available` field is a formula that determines your package's availability based on the - operating system or other global opam variables. For example: + operating system or other + [global opam variables](Manual.html#Global-variables). For example: ``` - available: [ os != "darwin" ] + available: [ os != "macos" ] ``` * [**Conflicts**](Manual.html#opamfield-conflicts): some packages just can't coexist. The `conflicts` field is a list of packages, with optional version - constraints. See also `conflict-class` for _families_ of incompatible - packages. + constraints. See also [`conflict-class`](Manual.html#opamfield-conflict-class) + for _families_ of incompatible packages. * [**Optional dependencies**](Manual.html#opamfield-depopts): they change the way your package builds, but are not mandatory. The `depopts` field is a package formula like `depends`. simple list of package names. If you require specific versions, add a `conflicts` field with the ones that won't work. * [**Variables**](Manual.html#Variables): you can get a list of predefined variables that you can use in your opam rules with `opam config list`. -* [**Filters**](Manual.html#Filters): full commands, or single command - arguments, may need to be omitted depending on the environment. This uses the +* [**Filters**](Manual.html#Filters): dependencies, commands and single command + arguments may need to be omitted depending on the environment. This uses the same optional argument syntax as above, postfix curly braces, with boolean conditions: @@ -371,5 +217,3 @@ into too much detail, here are some of the most useful features: [make "byte"] { !ocaml-native } [make "native"] { ocaml-native } ``` - -For more, see the [opam Manual](Manual.html) diff --git a/doc/pages/Tricks.md b/doc/pages/Tricks.md index 0021e18487e..f4f11139981 100644 --- a/doc/pages/Tricks.md +++ b/doc/pages/Tricks.md @@ -7,7 +7,7 @@ - `opam upgrade --dry-run` (display only) - if you really want to try out the results: * `opam switch export testing-state.export` - * `opam switch tmp-testing --alias-of system` + * `opam switch create tmp-testing --empty` * `opam switch import testing-state.export --fake` * try actions with `--fake` (registers them in opam, but doesn't actually run the build/install commands) @@ -16,7 +16,6 @@ * `opam --cudf=cudf-file` * or `opam config cudf-universe >cudf-file-1.cudf` * run e.g. aspcud with `aspcud cudf-file-1.cudf /dev/stdout CRITERIA` - * `admin-scripts/cudf-debug.ml cudf-file-1.cudf` may help with conflicts --- diff --git a/doc/pages/Upgrade_guide.md b/doc/pages/Upgrade_guide.md index ebd88ddf5a3..5e7a9d2fcc9 100644 --- a/doc/pages/Upgrade_guide.md +++ b/doc/pages/Upgrade_guide.md @@ -87,6 +87,9 @@ doesn't affect the pinned package. - [`opam install --destdir`](man/opam-install.html#lbAF) can be used to copy build artefacts of given packages to an external prefix +- __sandboxing__ of package build/install/remove commands is enabled by default + on Linux. You may need to install the + [bubblewrap](https://github.com/projectatomic/bubblewrap) tool for this. ## File formats @@ -94,24 +97,29 @@ doesn't affect the pinned package. > #### Repositories and migration > -> Repositories for 1.2 and 2.0 have a different format. +> **Repositories for 1.2 and 2.0 have a different format**, but everything +> should be transparent unless you publish packages: > -> - the `master` branch of the -> [main repository](https://github.com/ocaml/opam-repository/tree/master) -> remains in 1.2 format for now +> - [**The main repository**](https://github.com/ocaml/opam-repository/tree/master) +> remains in format **1.2** for now. This means the the `master` branch, and +> the contents of https://opam.ocaml.org/packages. +> - [**There is a 2.0.0 branch**](https://github.com/ocaml/opam-repository/tree/master) +> that is served at `opam.ocaml.org/2.0`. > -> - opam can do the conversion (1.2 → 2.0) on the fly +> Everything from 1.2 is converted to 2.0 when needed (on the fly by opam, +> [automatically](https://github.com/AltGr/camelus/tree/2.0) on the git +> repository, or manually using +> [`opam admin upgrade`](man/opam-admin-upgrade.html)). > -> - the repository has a -> [`2.0.0` branch](https://github.com/ocaml/opam-repository/tree/2.0.0) that has -> all patches to the `master` branch ported automatically -> -> - opam 2.0 will be redirected to the repository at https://opam.ocaml.org/2.0, -> which is based on the `2.0.0` branch, automatically + +> When publishing packages, remember that: > -> - you can use -> [`opam admin upgrade [--mirror=BASEURL]`](man/opam-admin-upgrade.html) -> to manually upgrade a repository to the 2.0 format +> - packages in **1.2 format** must be published to `master`, and they will be +> available to **everyone** +> - packages in **2.0 format** must be published to the `2.0.0` branch — e.g. +> using the new +> [opam-publish.2.0](https://github.com/ocaml/opam-publish/tree/2.0). They +> will **only** be available to opam 2.0 users. - compiler definition files: these no longer exist, as compilers have been replaced by normal package definitions (that should have diff --git a/doc/pages/Usage.md b/doc/pages/Usage.md index 15fa248abca..5af30b519ad 100644 --- a/doc/pages/Usage.md +++ b/doc/pages/Usage.md @@ -21,8 +21,6 @@ details. ``` # ** Get started ** opam init # Initialize ~/.opam -opam init --compiler=ocaml-base-compiler.4.04.0 - # Initialize with a freshly compiled OCaml 4.04.0 # ** Lookup ** opam list -a # List all available packages @@ -32,6 +30,7 @@ opam show PACKAGE # Display information about PACKAGE # ** Install ** opam install PACKAGE # Download, build and install the latest version of PACKAGE # and all its dependencies +opam remove PACKAGE # Uninstall the given package # ** Upgrade ** opam update # Update the packages database @@ -69,16 +68,17 @@ It will also update any packages that are bound to version-controlled sources. ### Looking up packages -There are three useful commands for that: +There are three commands for that: * `opam list` List installed packages, or packages matching various selection - criteria -* `opam search` Search in package descriptions + criteria. +* `opam search` Search in package descriptions. * `opam show` Print details on a given package. ### opam install -This command installs packages along with all their dependencies. You can -specify one or several packages, along with version constraints. E.g: +This command downloads, builds and installs packages along with all their +dependencies. You can specify one or several packages, along with version +constraints. E.g: ``` opam install lwt @@ -86,12 +86,6 @@ opam install ocp-indent ocp-index.1.0.2 opam install "ocamlfind>=1.4.0" ``` -If opam seems unable to fulfill very simple installation requests or -propose non-sensical install plans, it may be due to limitations of -its internal dependency solver; you should check that you have an -[External dependency solver](Install.html#ExternalSolvers) on your -system. - ### opam upgrade Will attempt to upgrade the installed packages to their newest versions. You @@ -101,24 +95,24 @@ packages from being upgraded. ### opam switch This command enables the user to have several installations on disk, each with -their own prefix, set of installed packages, and OCaml version. Use cases +their own prefix, set of installed packages, compiler version, etc.. Use cases include having to work or test with different OCaml versions, keeping separate development environments for specific projects, etc. Use `opam switch create [name] ` to _switch_ to a different compiler. Don't forget to run the advertised `eval $(opam env)` to update your PATH accordingly. Replace `[name]` with a directory name to have the switch -bound to that directory, and automatically selected when opam is run from there: -this is typically done within projects that require a specific compiler or set -of opam packages. +created in that directory, and automatically selected when opam is run from +there: this is typically done within projects that require a specific compiler +or set of opam packages. Creating a new switch requires re-compiling OCaml, unless you use the `ocaml-system` package, that relies on the global OCaml installation. ### opam pin -This command allows to pin a package to a specific version, but in fact, as you -know if you've read the [Packaging guide](Packaging.html), it can do much more. +This command allows to pin a package to a specific version, but has been +extended to allow much more than that. The syntax is @@ -126,9 +120,9 @@ The syntax is opam pin add ``` -Where `` may be a version, but also a local path, an http address or -even a git, mercurial or darcs URL. The package will be kept up-to-date with its -origin on `opam update` and when explicitly mentioned in a command, so that +Where `` may be a version, but also a local path, the URL of an archive, +or even a git, mercurial or darcs URL. The package will be kept up-to-date with +its origin on `opam update` and when explicitly mentioned in a command, so that you can simply run `opam upgrade ` to re-compile it from its upstream. If the upstream includes opam metadata, that will be used as well. @@ -139,26 +133,42 @@ opam pin add opam-lib https://github.com/ocaml/opam.git#1.2 # specific branch opam pin add opam-lib --dev-repo # upstream repository ``` -This can be used in conjunction with `opam source` to start and hack an existing -package before you know it: +This actually a powerful mechanism to divert any package definition, and can +even be used to locally create packages that don't have entries in the +repositories. + +This can be used in conjunction with `opam source` to patch an existing package +in a breeze: ``` opam source --dev-repo --pin cd ; hack hack hack; -opam upgrade +opam upgrade . ``` ### opam repo opam is configured by default to use the community's software repository at -[opam.ocaml.org](https://opam.ocaml.org), but this can easily be -changed at `opam init` time or later. - -`opam repo add
` will make opam use the definitions of any -package versions defined at `
`, falling back to the previously defined -repositories for those which aren't defined. The `
` may point to an -http, local or version-controlled repository. The newly configured repository is -only selected for the current switch (since opam 2.0), unless you add `--all`. +[opam.ocaml.org](https://opam.ocaml.org), but third-party repositories can +easily be used in addition, or in replacement. + +``` +opam repo add
+``` + +defines the alias `` to refer to the package repository found at +`
`. Without further options, that repository will be set to lookup for +package definitions over what was already defined **in the current switch +only**. See options `--all` and `--set-default` to affect other and newly +created switches, respectively. + +The `
` may point to an HTTP, local or version-controlled repository. To +create a new switch bound to specific repositories, it's easier to use instead: + +``` +opam switch create --repos =
,default +``` + Defining your own repository, either locally or online, is quite easy: you can start off by cloning diff --git a/doc/pages/index.menu b/doc/pages/index.menu index 699266cbece..0ed1962d848 100644 --- a/doc/pages/index.menu +++ b/doc/pages/index.menu @@ -3,7 +3,7 @@ # .md -> A markdown page # empty -> A menu divider #source: https://github.com/ocaml/opam/tree/master/doc/pages -opam 2.0 DOCUMENTATION (work in progress) +opam 2.0 documentation Install.md Upgrade_guide.md @@ -12,6 +12,6 @@ Usage.md FAQ.md Tricks.md Packaging.md -Specifying_Solver_Preferences.md +External_solvers.md Manual.md diff --git a/src/client/opamCommands.ml b/src/client/opamCommands.ml index 0c11c13e0db..754cd9548ad 100644 --- a/src/client/opamCommands.ml +++ b/src/client/opamCommands.ml @@ -2150,8 +2150,8 @@ let pin ?(unpin_only=false) () = "add", `add, ["PACKAGE"; "TARGET"], "Pins package $(i,PACKAGE) to $(i,TARGET), which may be a version, a path, \ or a URL.\n\ - $(i,PACKAGE) can be omitted if $(i,TARGET) is a local path containing a \ - package description with a name. $(i,TARGET) can be replaced by \ + $(i,PACKAGE) can be omitted if $(i,TARGET) contains one or more \ + package descriptions. $(i,TARGET) can be replaced by \ $(b,--dev-repo) if a package by that name is already known. If \ $(i,TARGET) is $(b,-), the package is pinned as a virtual package, \ without any source. opam will infer the kind of pinning from the format \ @@ -2161,9 +2161,9 @@ let pin ?(unpin_only=false) () = using $(b,#branch) e.g. $(b,git://host/me/pkg#testing).\n\ If $(i,PACKAGE) is not a known package name, a new package by that name \ will be locally created.\n\ - The package version may be specified by using the format \ - $(i,NAME).$(i,VERSION) for $(i,PACKAGE), in the source opam file, or with \ - $(b,edit)."; + For source pinnings, the package version may be specified by using the \ + format $(i,NAME).$(i,VERSION) for $(i,PACKAGE), in the source opam file, \ + or with $(b,edit)."; "remove", `remove, ["NAMES...|TARGET"], "Unpins packages $(i,NAMES), restoring their definition from the \ repository, if any. With a $(i,TARGET), unpins everything that is \