Get that Linux feeling - on Windows
Cygwin package files
Package naming scheme
Use the upstream's version followed by a release suffix (i.e. findutils 4.5.12 becomes 4.5.12-1, 4.5.12-2, etc., until findutils 4.5.13 is packaged, which would be 4.5.13-1, etc).
For upstream released versions, the release suffix counts from 1. A release suffix starting with 0 and containing the pre-release identifier should be used for upstream pre-release versions (as per these examples), so they sort before released versions.
To ensure there is no ambiguity in splitting a package-version-release into it's components:
- The name must not contain a hyphen followed by a digit.
- The version and release must start with a digit.
- The release must not contain a hyphen.
Version and release sort according to the following rules:
- Contiguous chunks of digits or alphabetic characters are compared
- Non-alphanumeric separators for these contiguous chunks are ignored
- Alphabetic chunks sort before digit chunks
- Digit chunks sort numerically and alphabetic chunks sort lexicographically
- If all chunks are equal, the string with any suffix remaining is the greater
A package with a higher version is greater, regardless of the release. When two packages have an identical version, the one with the higher release is greater.
A complete package currently consists of three files:
- a binary tar file, named
- a source tar file, named
- a .hint file, named
bash$ ls -1 release/boffo boffo-1.0-1.tar.xz boffo-1.0-1-src.tar.xz boffo-1.0-1.hint
Binary tar files generally contain the executable files that will be installed on a user's system plus any auxiliary files needed by the package. See the package contents section below for more details on the contents of a binary tar file.
Source tar files should contain the source files, patches and scripts needed to rebuild the package. While installing these files is optional, the inclusion of a source tar file is part of the totality that makes up a Cygwin package and so, these files are not optional. In some cases, there may be multiple packages generated from the same source; for instance, one might have a "boffo" package and its associated shared library in "libboffo7", where both are generated from the same source tar file. See the package contents section below for more details on the contents of a source tar file, and the package-version-release.hint section for information on the "external-source:" option.
Note that package files may be .bz2, .gz, .xz or .zst compressed. .gz is obsolete and .xz is preferred for new package submissions.
The files paths within both the source and the binary package files are quite important. Since setup extracts into a predetermined directory, you must structure your package contents accordingly.
Binary packages are extracted in /, include all file paths from the root in
your archive, e.g.:
usr/bin/boffo.exe usr/share/boffo/boffo.dat etc...
The package is configured using (at a minimum) the following paths:
--prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib --localstatedir=/var --datadir=/usr/share --mandir=/usr/share/man --infodir=/usr/share/info
- All executables in your binary package are stripped.
- Source packages are extracted in /usr/src (so the paths in your source tar
file should not include /usr/src). On extraction, the tar file should put the
sources in a directory with the same name as the package tar file minus the
boffo-1.0-1/boffo.cygport boffo-1.0-1/boffo-1.0.tar.xz boffo-1.0-1/boffo-1.0-1.src.patch etc...
Generally, this will contain the original source tar file, exactly as downloaded from the original upstream, any needed patch files, and a cygport script that drives the packaging process.
- In your binary package, you may choose to include a file /usr/share/doc/Cygwin/foo-vendor-suffix.README containing (at a minimum) the information needed for an end user to recreate the package. This includes CFLAGS settings, configure parameters, etc. (You can adapt this generic README.)
- In your binary package include a directory /usr/share/doc/foo/ that includes any binary-relevant upstream documentation, such as ChangeLogs, copyright licences, READMEs etc.
- If you are not creating your package from an installed virtual root, be sure to check that the file permissions are appropriate.
- If the package has any global settings (i.e. in files in /etc) that are not overrideable on a per user basis (sshd, as a daemon, is an example of this) do not include the relevant config files in your package. Instead install the files into /etc/defaults and include in your post-install script to install the settings files. Be sure that if you would overwrite an already present file that the user is offered the choice of keeping their own or overwriting with your defaults.
- Ensure that your package handles being installed on binary and text mounts correctly.
Package post-install and pre-remove scripts
If your package requires certain commands to be executed after the files in the package are installed, include them in a file in the package called /etc/postinstall/<package>.<suffix>.
The file is executed with the Cygwin bash shell if suffix is ".sh"; with the Cygwin dash shell if suffix is ".dash"; and with the Windows cmd.exe command interpreter if suffix is ".bat" or ".cmd". If suffix is unknown, the file is ignored.
After the script has been successfully run, it is renamed by appending the suffix ".done" to its previous name, to prevent it from being run again the next time the user runs the setup program.
Note that the setup program runs all the post-install scripts after all desired packages have been installed, that is, it does not run each package's post-install script immediately after installing that package.
Post-install scripts are run in dependency order. If dependency loops exist, the order in which those package's scripts are run is undefined.
If your package requires certain commands to be executed before the files in the package are removed, include them in a file in the package called /etc/preremove/<package>.<suffix>.
Note that the setup program runs all the pre-remove scripts before any packages have been uninstalled. Note that when upgrading a package, the pre-remove script for the currently installed version will be run before it is removed, then the post-install script for the upgraded version will be run after it is installed.
Perpetual post-install and pre-remove scripts
In addition to the ordinary ("run-once") scripts described above,
the setup program supports "perpetual" post-install and pre-remove scripts.
These are run on every invocation of setup, as long as the package is still
installed. Perpetual scripts are distinguished from run-once scripts by
having names that start with "0p_" or "zp_". Those that start with "0p_" are
run before the run-once scripts, and those that start with "zp_" are run
after the run-once scripts. Examples include
postinstall/0p_000_autorebase.dash (provided by the
postinstall/0p_update-info-dir.dash (provided by the
preremove/0p_000_etckeeper_pre-install.sh (provided by the
For those package maintainers wanting to employ perpetual scripts, the first thing to keep in mind is to only use this feature for things that really can't be done with run-once scripting. Any perpetual script should minimize the resources used (use dash instead of bash for instance) and exit at the earliest possible moment if no action is required. Post-install scripts of type "0p_" must be able to run with the Base packages installed but the remaining post-install scripts not yet executed; in practical terms that rules out using bash scripts. Pre-remove scripts of type "zp_" must be able to run with the other pre-remove scripts already executed. These limitations do not apply to post-install scripts of type "zp_" and pre-remove scripts of type "0p_".
See this mailing list post for more discussion and current limitations.
The following environment variables are used to communicate information from the setup program to post-install and pre-remove scripts:
CYGWINFORALL contains "-A" if installing for "All Users" (This also
implies setup is running with elevated permissions), and is unset otherwise.
This is intended to be used as an option to
mkshortcut, or in shell conditionals such as