Skip to content

MinGW cross pkg is a simple package management tool for cross-compiled mingw packages from a unix system.

License

Notifications You must be signed in to change notification settings

johan-boule/mingw-cross-pkg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MinGW cross pkg is a simple package management tool for cross-compiled mingw packages from a unix system.

This packaging tool makes it easy to install and remove packages at will in an install tree,
It handles the building and downloading of package sources, and also the dependencies between packages.

The tool uses three directories to manage the packages:
	- a directory of package recipes,
	- a directory where packages are built,
	- a directory where packages are installed.
	
By default, the build directory and the install directory are created as
subdirectories of the directory where the mingw-cross-pkg command is invoked,
and are name respectively ++build and ++install.

Following the Usage chapter below, are some explanations of the directory structures,
and on how to write package recipes.
Using the tool does not require you read all of this.

========
0. Usage
========

The tool is self documented, by using the --help option.

Usage: ./mingw-cross-pkg <command> [args]
  where <command> is one of: help, version, list, show, install, remove, need-rebuild, reverse-depends, clean-build.

Usage: <help | --help> [command]
or   : <command> --help
  gives help on command, or on all commands.

Usage: <version | --version>
  prints the version of this tool.

Usage: list
  gives a list of all packages, with state information.

Usage: show <package...>
  shows the details of the packages.

Usage: install [--continue | --rebuild | --no-download | --no-act] <package...>
  installs the packages, and their dependencies.
  Packages given as arguments will be marked as user,
  unless the --rebuild option is present and the package was already installed.

  --no-act         do not really install, just show what would be done.
  --skip-download  skip the download step.
  --rebuild        rebuild the packages given as arguments.
  --continue       continue after a build failure.

Usage: remove [--verbose | --no-act] <package...>
  removes the packages, dependent packages, and packages marked auto that become no longer needed.

  --no-act   do not really remove, just show what would be done.
  --verbose  show what files and dirs are removed.

Usage: need-rebuild
  gives a list of all packages that may need to be rebuilt.
  This lists the packages for which the installed versions of the packages they depend on (recursively)
  are no longer the same as the ones they were built with.

Usage: reverse-depends [--installed-only] <package...>
  shows the reverse dependencies of the packages.

  --installed-only  only show installed packages.

Usage: clean-build [--download | --destdir | --all] <package...>
  cleans the build dirs of packages.

  --dest-dir  also clean the dest dir.
  --download  also clean the downloaded files.
  --all       wipe out the whole build dir altogether (same effect as --dest-dir --download).

==================
1. Package recipes
==================

Each package recipe is an arbitrary executable file (shell script, makefile, whatever), or a python module,
that contains instructions to download and build a package, and also defines the dependencies of a package.

Package recipes are files stored under the "package-recipes" directory in the same directory where
the mingw-cross-pkg command is. So, the package recipe for package "foo" is looked for in package-recipes/foo.

------------------------------------------
1.3 Methods/Variables available in recipes
------------------------------------------

The base recipe class provide the following methods (and environment variables) for use in recipes.
Recipes should not override these methods, just use them.

- TARGET / def target(self) -> string:
	This method/variable returns the target triplet used for cross compilation.
	For example: i386-mingw32msvc.
	For autoconf-based packages, you would pass this path to the configure's --target option.

- PREFIX / def prefix(self) -> path
	This method/variable returns the absolute path to the final installation tree, xxx/++install/prefix.
	For autoconf-based packages, you would pass either
	self.prefix() or self.prefix() + self.target() to the configure's --prefix option,
	depending on whether you're building a cross-build tool or a normal software.

- DESTDIR / def dest_dir(self) -> path:
	This method/variable returns the path were the package should put all the files to install.
	For automake-based packages, you would pass this path to the "make install DESTDIR=" command.
	For a package "foo", dest dir would be an absolute path to xxx/++build/foo/dest/.

- GMAKE, MAKE / def gmake(self):
	returns the the name or path to the GNU make command ('gmake' instead of 'make' on *bsd systems)

- GSED, SED / def gsed(self):
	returns the the name or path to the GNU sed ('gsed' instead of 'sed' on *bsd systems)

- RECIPES:
	returns the the path to the directory where recipees are stored

---------------------------------------------------
1.4 Methods to define/override in each recipe class
---------------------------------------------------

1.4.1 The version method
------------------------

def version(self) -> string

This method should return the version of the package.

1.4.2 The description method
-----------------------------

def description(self) -> string

This method should return a one-line description of the package.

1.4.3 The deps method
---------------------

def deps(self) -> list

This method should return the list of packages this package depends on.

1.4.4 The download method
-------------------------

def download(self)

This method is responsible for downloading the source code.
Source code can be obtained is whatever way the recipe wants.
It can be a tarball obtained via wget, or a checkout/update from a source code repository.

This method should avoid downloading the files again if there are already there.

1.4.5 The unpack method
-----------------------

def unpack(self)

This method is responsible for unpacking the downloaded source code.

1.4.6 The build method
----------------------

def build(self)

Then the method should perform all the build steps needed to configure, build, and install the package.
The package must be installed in the stage-install directory (DESTDIR in automake).
This installation destination directory is obtained with the dest dir method inherited from the base class.

1.4.7 The continue_build method
-------------------------------

def continue_build(self)

This method can optionally be defined to allow the user to continue building a package,
instead of redoing the build from scratch.

For packages that follow the usual configure/make process, this means performing only the make step.

If the method is not defined, it inherits the default implementation,
which performs both the download and build steps again, effectively redoing a full rebuild.

1.4.8 The clean_build method
----------------------------

def clean_build(self)

This method should remove the files that were built, but keep the downloaded files.
For example, in the case of a package obtained by downloading a source tarball,
you would delete the unpacked directory of the tarball, but leave the tarball itself.

========================
2. Building of a package
========================

Building a package is implicitely done with the install command.

Before building a package, the tool first checks whether it needs to build and/or install the package's dependencies.

Each package is built in its own directory. For package "foo", the build directory is ++build/foo/.
A build directory ++build/foo/ contains the following files and subdirectories:

	++build/foo/build/:
		where source files are downloaded, and the build takes place.

	++build/foo/dest/:
		stage-installation directory.

	++build/foo/built:
		empty file whose existence indicates the package was successfully built.

	++build/foo/version:
		version of the built package.
		
	++build/foo/description:
		description of the built package.

	++build/foo/direct-dependencies:
		direct dependencies of the built package.
		Each dependency also contains the version that was installed at the time of the build.
		
	++build/foo/recursed-dependencies:
		direct + deep dependencies of the built package.
		Each dependency also contains the version that was installed at the time of the build.

If the build exists and is complete (++build/foo/built exists), the tool will not rebuild it, and will simply copy the existing built
files to the ++install tree.

If the build does not exist or is incomplete (++build/foo/built does not exist), the tool will create (if needed) the build directory,
remove the ++build/foo/built file, enter the ++build/foo/build subdirectory, and call the package recipe's download and build methods.

After a successful build, the tool will write the information files in the package's build
directory: ++build/foo/{built,version,direct-dependencies,recursed-dependencies}.

============================
3. Installation of a package
============================

Installing a package named "foo", is done by invoking the command:
	mingw-cross-pkg install foo

Before installing a package, the tool first checks whether it needs to install the package's dependencies.

The tool first checks whether the package is already installed.
Install information for a package named "foo", is stored in the ++install/package-states/foo/ directory.
If such a directory exists, the tool will not do anything for this package.

If no ++install/package-states/foo/ directory exists, the tool checks whether it already has
a built directory for the "foo" package, and builds it if not.

Before installing a package that was already installed, the tool first removes the installed package.

Then, the tool lists the content of the ++build/foo/dest/ directory,
and stores the list in ++install/package-states/foo/files.
It then copies these files from ++build/foo/dest/ to ++install/prefix/,

Then, package information ++build/foo/{version,direct-dependencies,recursed-dependencies}
is copied to ++install/package-states/foo/,

Finally, the tool writes whether the package is marked "auto" or "user" (as debian's aptitude does)
in ++install/package-states/foo/installed.

=======================
3. Removal of a package
=======================

Removing (deinstalling) a package named "foo", is done by invoking the command:
	mingw-cross-pkg remove foo

Before removing a package, the tool first removes all packages that depend on it.

The tool removes all files listed in ++install/package-states/foo/files,
and then removes the directory ++install/package-states/foo/ itself.

The tool is also able to remove all packages that are marked "auto" and no longer-needed after
the removal of a package (as debian's aptitude does).

About

MinGW cross pkg is a simple package management tool for cross-compiled mingw packages from a unix system.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published