OPAM-LOCK(1)
π NAME π
opam-lock β create locked opam files to share build environments across hosts. (Yes bestie, this is section 1 of the Opam Manual, and we're about to make your builds reproducible across literally every machine. π )
β¨ SYNOPSIS β¨
opam lock [--direct-only] [--keep-local] [--lock-suffix=SUFFIX]
[OPTION]β¦ [PACKAGES]β¦
πΈ DESCRIPTION πΈ
Okay so picture this: opam lock generates a lock file of a package. What it actually does is check the current state of that package's installed dependencies, and then it outputs modified versions of the opam file with a .locked suffix, where all the (transitive) dependencies and pinnings have been bound strictly to the currently installed version. Frozen. Pinned down. No wiggle room. π₯
By using these locked opam files, it is then possible to recover the precise build environment that was setup when they were generated. Like, the exact same vibe, on a totally different host. π¦
If paths (filename or directory) are given, those opam files are locked. If package is given, installed one is locked, otherwise its latest version. If a locally pinned package is given, its current local opam file is locked, even if not versioned or uncommitted changes. (Yeah, it doesn't care, it locks the messy version too. π)
Heads up: it fails if all mandatory dependencies are not installed in the switch. Like, it will fail. No cap.
π LOCK FILE CHANGED FIELDS π
Here's exactly what gets rewritten in that lock file, no surprises, bestie:
dependsare fixed to their specific versions, with all filters removed (except for the exceptions belowdepoptsthat are installed in the current switch are turned intodepends, with their version set. Others are set in the conflict field{dev},{with-test}, and{with-doc}` filters are kept if all packages of a specific filters are installed in the switch. Versions are fixed and the same filter is on all dependencies that are added from thempin-dependsare kept and new ones are added if in the dependencies some packages are pinnedpinsare resolved: if a package is locally pinned, opam tries to get its remote url and branch, and sets this as the target URL; otherwise it ignore them. You can use--keep-localto keep the local urls.
π§ ARGUMENTS π§
PACKAGESβ List of package names, with an optional version or constraint, e.gpkg,pkg.1.0orpkg>=0.5; or files or directory names containing package description, with explicit directory (e.g../foo.opamor.)
π OPTIONS π
-d,--direct-onlyβ Only lock direct dependencies, rather than the whole dependency tree. (Just the first layer, queen. π)--keep-localβ Keep local pin paths inpin-depends:field.--lock-suffix=SUFFIX (absent=locked)β Set locked files suffix to SUFFIX.
π COMMON OPTIONS π
These options are common to all commands. Yeah, the whole opam family shares these. It's giving β¨communityβ¨.
--best-effortβ Don't fail if all requested packages can't be installed: try to install as many as possible. Note that not all external solvers may support this option (recent versions ofaspcudormccsshould). This is equivalent to setting$OPAMBESTEFFORTenvironment variable.--cli=MAJOR.MINOR (absent=2.6)β Use the command-line interface syntax and semantics of MAJOR.MINOR. Intended for any persistent use of opam (scripts, blog posts, etc.), any version of opam in the same MAJOR series will behave as for the specified MINOR release. The flag was not available in opam 2.0, so to select the 2.0 CLI, set theOPAMCLIenvironment variable to2.0instead of using this parameter.--color=WHENβ Colorize the output. WHEN must be one ofalways,neverorauto.--confirm-level=LEVELβ Confirmation level, LEVEL must be one ofask,no,yesorunsafe-yes. Can be specified more than once. If--yesor--noare also given, the value of the last--confirm-levelis taken into account. This is equivalent to setting$OPAMCONFIRMLEVEL.--criteria=CRITERIAβ Specify user preferences for dependency solving for this run. Overrides$OPAMCRITERIA,$OPAMFIXUPCRITERIAand$OPAMUPGRADECRITERIA. For details on the supported language, and the external solvers available, seehttp://opam.ocaml.org/doc/External_solvers.html. A general guide to using solver preferences can be found athttp://www.dicosmo.org/Articles/usercriteria.pdf.--cudf=FILENAMEβ Debug option: Save the CUDF requests sent to the solver toFILENAME-<n>.cudfwhere<n>is the n-th call to the solver during the opam run.--debugβ Print debug message to stderr. This is equivalent to setting$OPAMDEBUGto"true".--debug-level=LEVELβ Like--debug, but allows specifying the debug level (--debugsets it to1). Equivalent to setting$OPAMDEBUGto a positive integer.--git-versionβ Print the git version of opam, if set (i.e. you are using a development version), and exit.--help[=FMT] (default=auto)β Show this help in format FMT. The value FMT must be one ofauto,pager,grofforplain. Withauto, the format ispagerorplainwhenever theTERMenv var isdumbor undefined.--ignore-pin-dependsβ Ignore extra pins required by packages that get pinned, either manually throughopam pinor throughopam install DIR. This is equivalent to settingIGNOREPINDEPENDS=true.--json=FILENAMEβ Save the results of the opam run in a computer-readable file. If the filename contains the character%, it will be replaced by an index that doesn't overwrite an existing file. Similar to setting the$OPAMJSONvariable.--noβ Answer no to all opam yes/no questions without prompting. See also--confirm-level. This is equivalent to setting$OPAMNOto"true".--no-aspcudβ Removed in 2.1.--no-auto-upgradeβ When configuring or updating a repository that is written for an earlier opam version (1.2), opam internally converts it to the current format. This disables this behaviour. Note that repositories should define their format version in a'repo'file at their root, or they will be assumed to be in the older format. It is, in any case, preferable to upgrade the repositories manually usingopam admin upgrade [--mirror URL]when possible.--no-self-upgradeβ Opam will replace itself with a newer binary found atOPAMROOT/opamif present. This disables this behaviour.-q,--quietβ Disables--verbose.--root=ROOTβ Use ROOT as the current root path. This is equivalent to setting$OPAMROOTto ROOT.--safe,--readonlyβ Make sure nothing will be automatically updated or rewritten. Useful for calling from completion scripts, for example. Will fail whenever such an operation is needed ; also avoids waiting for locks, skips interactive questions and overrides the$OPAMDEBUGvariable. This is equivalent to set environment variable$OPAMSAFE.--solver=CMDβ Specify the CUDF solver to use for resolving package installation problems. This is either a predefined solver (this version of opam supportsbuiltin-mccs+lp(),builtin-mccs+glpk,builtin-dummy-z3-solver,builtin-0install,aspcud,mccs,aspcud-old,packup), or a custom command that should contain the variables%{input}%,%{output}%,%{criteria}%, and optionally%{timeout}%. This is equivalent to setting$OPAMEXTERNALSOLVER.--strictβ Fail whenever an error is found in a package definition or a configuration file. The default is to continue silently if possible.--switch=SWITCHβ Use SWITCH as the current compiler switch. This is equivalent to setting$OPAMSWITCHto SWITCH.--use-internal-solverβ Disable any external solver, and use the built-in one (this requires that opam has been compiled with a built-in solver). This is equivalent to setting$OPAMNOASPCUDor$OPAMUSEINTERNALSOLVER.-v,--verboseβ Be more verbose. One-vshows all package commands, repeat to also display commands called internally (e.g.tar,curl,patchetc.) Repeating n times is equivalent to setting$OPAMVERBOSEto"n".--versionβ Show version information.-w,--working-dirβ Whenever updating packages that are bound to a local, version-controlled directory, update to the current working state of their source instead of the last committed state, or the ref they are pointing to. As source directory is copied as it is, if it isn't clean it may result on a opam build failure. This only affects packages explicitly listed on the command-line. It can also be set with$OPAMWORKINGDIR.-y,--yesβ Answer yes to all opam yes/no questions without prompting. See also--confirm-level. This is equivalent to setting$OPAMYESto"true".
β¦and bestie, that's only part 1. Keep going, there's more where this came from. π
π ENVIRONMENT π
okay bestie so opam is obsessed with environment variables, like it's her whole personality. Here's the full roster. And listen β the boolean girlies (that's the yes/no ones) work like this: set them to "0", "no", "false" or the empty string to turn them OFF, and "1", "yes" or "true" to turn them ON. periodt. π
OPAMALLPARENSβ surround all filters with parenthesis. all of them. no crumbs. πOPAMASSUMEDEPEXTSβ same energy as the--assume-depextsoption.OPAMAUTOANSWERβ internal use only, not for you, mind your business πOPAMAUTOREMOVEβ matching the remove option--auto-remove.OPAMBESTEFFORTβ matching the--best-effortoption.OPAMBESTEFFORTPREFIXCRITERIAβ sets the string that must be prepended to the criteria whenever the--best-effortoption is set, and it's expected to maximise theopam-queryproperty in the solution. yeah she's specific. πOPAMBUILDDOCβ Removed in 2.1. she's gone, she's at peace, leave her be ποΈOPAMBUILDTESTβ Removed in 2.1. same vibe, also resting β¨OPAMCLIβ matching the--clioption.OPAMCOLORβ when set toalwaysornever, it sets a default value for the--coloroption.OPAMCONFIRMLEVELβ matching the--confirm-leveloption. heads up:OPAMCONFIRMLEVELhas priority overOPAMYESandOPAMNO. she's the main character here, no cap πOPAMCRITERIAβ specifies user preferences for dependency solving. the default value depends on the solver version, so runconfig reportto find out what's actually set right now. also see option--criteria. πOPAMCUDFFILEβ save the cudf graph to file-actions-explicit.dot. very demure, very cudf πΎOPAMCUDFTRIMβ controls the filtering of unrelated packages during CUDF preprocessing.OPAMCURLβ use this to select a givencurlprogram. seeOPAMFETCHfor more options.OPAMDEBUGβ matching the--debugand--debug-leveloptions.OPAMDEBUGSECTIONSβ if set, limits debug messages to a space-separated list of sections. sections can optionally have a specific debug level (for example,CLIENT:2orCLIENT CUDF:2), but otherwise use--debug-level.OPAMDIGDEPTHβ defines how aggressive the lookup for conflicts during CUDF preprocessing is. how aggressive? she's giving detective energy πOPAMDOWNLOADJOBSβ sets the maximum number of simultaneous downloads. multitasking icon πOPAMDROPWORKINGDIRβ overrides packages previously updated with--working-diron update. without this variable set, opam would keep them unchanged unless they're explicitly named on the command-line.OPAMDRYRUNβ matching the--dry-runoption.OPAMEDITORβ sets the editor to use for opam file editing, and it overrides$EDITORand$VISUAL. she said me first πOPAMERRLOGLENβ sets the number of log lines printed when a sub-process fails. set it to0to print all of them. all 40 of them. blessed.OPAMEXTERNALSOLVERβ matching the--solveroption.OPAMFAKEβ matching the--fakeoption.OPAMFETCHβ specifies how to download files: eitherwget,curl, or a custom command where the variables%{url}%,%{out}%,%{retry}%,%{compress}%and%{checksum}%will be replaced. overrides thedownload-commandvalue from the main config file. plug in your fave, she doesn't judge π«ΆOPAMFIXUPCRITERIAβ same asOPAMUPGRADECRITERIA, but specific to fixup and reinstall. a lil specialised, a lil niche, we love her πOPAMIGNOREAVAILABLEβ matching the install option--ignore-available-on.OPAMIGNORECONSTRAINTSβ matching the install option--ignore-constraints-on.OPAMIGNOREPINDEPENDSβ matching the--ignore-pin-dependsoption.OPAMINPLACEBUILDβ matching the--inplace-buildoption.OPAMJOBSβ sets the maximum number of parallel workers to run. let her cook (in parallel) π₯OPAMJSONβ log json output to the given file (use the character%to index the files).OPAMKEEPBUILDDIRβ matching the install option--keep-build-dir.OPAMKEEPLOGSβ tells opam to not remove some temporary command logs and some backups. this skips some finalisers and may also help to get more reliable backtraces. little bit chaotic, little bit useful πOPAMLOCKEDβ a combination of the--lockedand--lock-suffixoptions. two-for-one, she's efficient β¨OPAMLOGSβ sets the log directory. the default is a temporary directory in/tmp.OPAMMAKECMDβ set the systemmakecommand to use.OPAMMERGEOUTβ merge process outputs, so stderr goes onto stdout. unhinged? maybe. useful? absolutely πOPAMNOβ answer no to any question asked. see the--noand--confirm-leveloptions. important:OPAMNOis ignored if eitherOPAMCONFIRMLEVELorOPAMYESis set. she knows her place πOPAMNOAGGREGATEβ withopam admin check, don't aggregate packages.OPAMNOASPCUDβ Deprecated. retired, respectfully ποΈOPAMNOAUTOUPGRADEβ disables the automatic internal upgrade of repositories in an earlier format to the current one, onupdateorinit.OPAMNOCHECKSUMSβ enables the option--no-checksumswhen available.OPAMNODEPEXTSβ disables system dependencies handling, see option--no-depexts.OPAMNOENVNOTICEβ internal. nothing to see here bestie πOPAMNOSELFUPGRADEβ matching the--no-self-upgradeoption.OPAMPINKINDAUTOβ sets whether version control systems should be detected when pinning to a local path. Enabled by default since 1.3.0.OPAMPRECISETRACKINGβ fine grain tracking of directories. every crumb documented πOPAMPREPROβ set this tofalseto disable CUDF preprocessing. less efficient, but it might help when you're debugging a solver issue.OPAMREPOSITORYTARRINGβ internally store all non-vcs repositories as tar.gz files (by default, http repositories are stored as archive). this can be much faster on filesystems that don't cope well with scanning large trees. all operations are done in-memory, no I/O for scanning the repository. she said speed βOPAMREQUIRECHECKSUMSβ enables the option--require-checksumswhen available (e.g. foropam install).OPAMRETRIESβ sets the number of tries before failing downloads. she doesn't give up easily π«ΆOPAMREUSEBUILDDIRβ matching the--reuse-build-diroption.OPAMROOTβ matching the--rootoption. this is automatically set byopam env --root=DIR --set-root. πOPAMROOTISOKβ don't complain when running as root. we respect the chaos πOPAMSAFEβ matching the--safeoption.OPAMSHOWβ matching the--showoption.OPAMSKIPUPDATEβ matching the--skip-updatesoption.OPAMSKIPVERSIONCHECKSβ bypasses some version checks. Unsafe, for compatibility testing only. > β οΈ bestie listen to me: compatibility testing. ONLY. don't be cute with this one.OPAMSOLVERALLOWSUBOPTIMALβ defaulttrue. allows some solvers to still return a solution when they reach timeout; and while the solution remains assured to be consistent, there is no guarantee in this case that it fits the expected optimisation criteria. iftrue, opam will continue with a warning; iffalse, a timeout is an error. currently only the builtin-z3 backend handles this degraded case. π complicated but we moveOPAMSOLVERTIMEOUTβ change the time allowance of the solver. the default is60.0, and you can set it to0for unlimited. note that all solvers may not support this option.OPAMSOLVERTOLERANCEβ changes the tolerance towards the solver choosing an unoptimized solution (i.e. it might pull outdated packages). typical values range from0.0(best solution known to the solver) to1.0(unoptimized solution). the default is0.0. this option is useful in case the solver can't find a solution in a reasonable time (see$OPAMSOLVERTIMEOUT). note that all solvers may not support this option.OPAMSTATSβ Removed in 2.4. gone girl ποΈOPAMSTATUSLINEβ display a dynamic status line showing what's currently going on on the terminal. (one of always, never or auto) β¨OPAMSTRICTβ fail on inconsistencies (file reading, switch import, etc.). she's strict because she loves you πOPAMSWITCHβ matching the--switchoption. automatically set byopam env --switch=SWITCH --set-switch.OPAMUNLOCKBASEβ matching the install option--unlock-base.OPAMUPGRADECRITERIAβ specifies user preferences for dependency solving when performing an upgrade. it overridesOPAMCRITERIAin upgrades if both are set. also see option--criteria.OPAMUSEINTERNALSOLVERβ matching the--use-internal-solveroption.OPAMUSEOPENSSLβ Removed in 2.2. π she's outOPAMUTF8β use UTF8 characters in output (one of always, never or auto). by default this isauto, which is determined from the locale. πOPAMUTF8MSGSβ use extended UTF8 characters (camels πͺ) in opam messages. impliesOPAMUTF8. this is set by default on macOS only. camels. on mac. iconic behavior πOPAMVALIDATIONHOOKβ if set, uses the%{hook}%command to validate an opam repository update.OPAMVERBOSEβ matching the--verboseoption.OPAMVERBOSEONβ matching the--verbose-onoption.OPAMVERSIONLAGPOWERβ do not use. that's it. that's the whole description. don't. πOPAMWITHDEVSETUPβ matching the install option--with-dev-setup.OPAMWITHDOCβ matching the install option--with-doc.OPAMWITHTESTβ matching the install option--with-test.OPAMWORKINGDIRβ matching the--working-diroption.OPAMYESβ matching the--yesand--confirm-leveloptions. important lore:OPAMYEShas priority overOPAMNO, and it's ignored ifOPAMCONFIRMLEVELis set. πOPAMVAR_varβ overrides the contents of the variable var when substituting%{var}%strings inopamfiles. yes, the variable name is literallyOPAMVAR_glued onto var, that's the whole bit πOPAMVAR_package_varβ overrides the contents of the variable package:var when substituting%{package:var}%strings inopamfiles.
π¦ CLI VERSION π¦
okay this section is the important one for anyone writing scripts, so bestie, take notes π
all scripts and programmatic invocations of opam should use --cli in order to ensure that they work seamlessly with future versions of the opam client. and it's not just scripts that eat β blog posts and other documentation can benefit too, since it prevents information from becoming stale. your old tutorial could stay cute forever π
although opam only supports roots (~/.opam/) for the current version, it does provide backwards compatibility for its command-line interface. so she's changed but she still remembers who she was π«Ά
since CLI version support was only added in opam 2.1, use OPAMCLI to select 2.0 support (because opam 2.0 will just ignore it), and use --cli=2.1 for 2.1 (or later) versions β because an environment variable controlling the parsing of syntax is brittle, and we don't trust that. to this end, opam displays a warning if OPAMCLI specifies a valid version other than 2.0, and also if --cli=2.0 is specified. > β οΈ yes you'll get a warning either way, she's just looking out for you π
the command-line version is selected by using the --cli option or the OPAMCLI environment variable. --cli may be specified more than once, where the last instance takes precedence. OPAMCLI is only inspected if --cli is not given. last one wins, always, no cap β¨
π EXIT STATUS π
okay bestie listen up, because this is the part where opam tells you exactly what went wrong based on the number it throws at you. But first, one teeny tiny exception, and it's giving main character energy:
β οΈ Exception alert: theexeccommand does not play by these rules! It returns127if the command wasn't found or couldn't be executed, and otherwise it returns the command's very own exit value. She's different, your honor. π
For literally everything else, here's the tea β:
0β Success, bestie! β¨ Ortruefor boolean queries. We love a win.1β False. Returned when a boolean return value is expected, e.g. when running with--check, or for queries likeopam lint. It's not a fail, it's just... no. π«2β Bad command-line arguments, or arguments pointing at an invalid context (like a file that doesn't follow the expected format). You fed her nonsense, she's telling you. π5β Not found. You asked for something (package, version, repository, etc.) and it just... wasn't there. Gone. Doesn't exist. π»10β Aborted. The operation needed confirmation and you never gave it. She waited. You didn't show up. π15β Could not acquire the locks required for the operation. Locks, bestie! They were busy! π20β There is no solution to your request. Classic cause? Asking to install two incompatible packages, for example. You asked for chaos and got it. π30β Error in package definition, or other metadata files. And ngl, using--strictmakes this one pop up way more often. π31β Package script error. Some package operations were unsuccessful β could be an error in the packages themselves, or an incompatibility with your system. Also, heads up: this can be a partial error. So it's not always all-or-nothing, iykyk. π40β Sync error. Couldn't fetch some remotes from the network. And yes, this can be a partial error too. π50β Configuration error. Opam or your system config is simply not allowing the operation and needs fixing. Fix it bestie, I'm begging. π οΈ60β Solver failure. The solver failed to return a sound answer. Could be a broken external solver, or an error in solver configuration. The solver is going through it. π§ π₯99β Internal error. Something went wrong, likely a bug in opam itself. Not you, it's her. π130β User interrupt.SIGINTwas received, generally because you smashed Ctrl+C. Rude, but valid. π
And then a few more for the road π«Ά:
0on success.123on indiscriminate errors reported on standard error.124on command line parsing errors.125on unexpected internal errors (bugs).
π FURTHER DOCUMENTATION π
Need more? The docs live at https://opam.ocaml.org/doc. Go be studious, bestie. π
π AUTHORS π
These are the literal icons who built this. Show some respect, say thank you, kiss the ring π:
- David Allsopp
<david@tarides.com> - Vincent Bernardoff
<vb@luminar.eu.org> - Raja Boujbel
<raja.boujbel@ocamlpro.com> - Kate Deplaix
<kit-ty-kate@exn.st> - Roberto Di Cosmo
<roberto@dicosmo.org> - Thomas Gazagnaire
<thomas@gazagnaire.org> - Louis Gesbert
<louis.gesbert@ocamlpro.com> - Fabrice Le Fessant
<Fabrice.Le_fessant@inria.fr> - Anil Madhavapeddy
<anil@recoil.org> - Guillem Rieu
<guillem.rieu@ocamlpro.com> - Ralf Treinen
<ralf.treinen@pps.jussieu.fr> - Frederic Tuong
<tuong@users.gforge.inria.fr>
π SEE ALSO π
opam(1)β yes, the main one. The mothership. Obviously. πΈ
π BUGS π
Found a bug? (Not me being dramatic, it happens! π) Check bug reports at https://github.com/ocaml/opam/issues and drop it there. Be nice, include details, slay. π
okay and that's the whole page, bestie, we made it to the end π this absolute novel is from Opam 2.6.1, dated for OPAM-LOCK(1) β the opam lock era. Go forth and lock responsibly. periodt πβ¨π¦
π¦ where this page comes from
- arch rolling: opam 2.6.1-1 Β· LGPL-2.1-only
- fedora 44: opam 2.6.1-1.fc44 Β· LGPL-2.1-only WITH OCaml-LGPL-linking-exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms