This tutorial is meant to help you get started writing your own packages in Pacman 3. As an example, we'll go through the process of writing a package to install Python version 2.3.4 and its documentation.
Start by setting up Pacman in the usual way. Make a subdirectory cache/ to hold the Pacman source code and work/ to test the installation. Edit a file cache/Python.pacman so it contains
# # Sample Python 2.3.4 installation # # author: {you} # date: {date} #In the work/ directory, do
% pacman -get ../cache:Python % pacman -l -d src [*] Python, source cache [../cache]to get started.
In writing a package, you'll have a good point of view if you imagine that you have been blindfolded and lead to a terminal session on an unknown computer running some unknown version of Unix. Your job is to define all of the conditions necessary to insure that Python version 2.3.4 is correctly installed and setup on your unknown computer. By taking this point of view, you will make your package nice and robustly self-contained.
Before getting to the actual business of installing Python, let's add the following to Python.pacman.
packageName('Python') url('Python','http://www.python.org') version('2.3.4')The packageName atom fixes the name of the package to be "Python" even if you change the filename to something like Python-2.3.4.pacman later on. This lets you have different versions of Python described in different files in the same cache directory. The url atom is used to provide a convenient pointer for the installer when Pacman generates web pages. The version('2.3.4') atom sets the version string of this package to '2.3.4'. This allows the package to be conveniently selected among other possible Python installations. To try this, in the work area do:
% pacman -remove % pacman -lc ../cache -d version [ ] Python, in cache [../cache] version = 2.3.4 % pacman -get "../cache:Python | version('2.3.4')" % pacman -l -d src [*] Python, source cache [../cache] [src] # [src] # Sample Python 2.3.4 installation [src] # [src] # author: {you} [src] # date: {date} [src] # [src] packageName('Python') [src] url('Python','http://www.python.org') [src] [src] version('2.3.4')to see that you have successfully selected a particular version.
In this particular case, we're planning to install Python from it's sources taken from a tarball from www.python.org. This is a procedure that might work on any Unix platform as long as basic utilities like make, ld and gcc are available and as long as, say 30 Megs of disk space is available. To make sure that this is true, add
# # -- Basic system requirements # platformGE('unix') which('gcc'); which('ld'); which('make') freeMegsMinimum(30)to Python.pacman. To test what we've got so far, you can do -remove and -get as before or just do
% pacman -update % pacman -lTo update to the newly modified version.
It may sometimes be helpful to do
% pacman -l -d cmp [*] Python, in cache [/home/youssef/Pacman/work] [*] AND [*] setcwd /home/youssef/Pacman/work [*] setenv temporary PACMAN_INSTALLATION => /home/youssef/Pacman/work [*] packageName Python [*] cache of origin ../cache [*] pacman source code Python.pacman [*] Python [*] version = 2.3.4 [*] platform >= unix [*] which gcc [*] which ld [*] which make [*] freeMegsMinimum 30 free Megabytes at . [*] setcwd /home/youssef/Pacman/workto view the compiled environmental conditions. You will see "[*]" wherever the defined condition is satisfied.
Now let's begin the actual installation by downloading the tarball from www.python.org. To do this, just add
# # -- Prepare to do the installation # mkdir('python-2.3.4') cd('python-2.3.4') downloadUntarzip('http://www.python.org/ftp/python/2.3.4/Python-2.3.4.tgz','PYTHON_TAR') mkdir('python') # directory which will contain the installed package setenvTemp('PYTHON_LOCATION','$PWD/python') # define a temporary environment variableto Python.pacman. This code creates a working directory for the package and a directory which will hold the files created by the Python make procedure (python/). The setenvTemp atom defines a temporary environment variable which is available only during the package installation and is not defined as part of the setup scripts. The downloadUntarzip atom is a handy combined download/untar which also sets a temporary environment variable $PYTHON_TAR to the path of the location of the top directory of the untarred tarball. Now we are ready to configure and install Python by adding
# # -- Install as usual # cd('$PYTHON_TAR') shell('./configure --prefix="$PYTHON_LOCATION"') # configure Python to install into the prepared directory shell('make') shell('make install') cd()the shell atoms execute shell commands. You should note a couple of things about shell commands: the shell atom does not send the shell output to the installer's terminal. This means that if you want to execute shell commands that ask questions, you should use shellDialogue. Also, keep in mind that shell commands cannot affect the environment of the Pacman process that is doing the installation. Setting environment variables in a shell script, for example, will not have an effect for the rest of the installation. For more details about shell commands, see the shell section of the language description.
This time, let's install step by step so that we can see the effect of each Pacman action. To do this, do
% pacman -remove % pacman -ask action -get ../cache:Pythonin your work area. You will be asked permission before each Pacman action is taken.
Assuming that you have gotten Python to install correctly, you only have to add
# # -- setup the user's environment # path('python/bin')to add the bin/ area to the user/installer's path. If your package is dependent on other packages, you just use the package or configure atoms as explained in the language syntax. To try this out, add Python documentation to your package by adding.
# # -- add Python standard documentation # package('Demo:PythonDocs | versionGE("2.3.4")')If you install this, you will see that the csh/sh/py/pl scripts now adjust your PATH variable to use the installed Python.
The complete package now reads
# # Sample Python 2.3.4 installation # # author: {you} # date: {date} # packageName('Python') url('Python','http://www.python.org') version('2.3.4') # # -- Basic system requirements # platformGE('unix') which('gcc'); which('ld'); which('make') freeMegsMinimum(30) # # -- Prepare to do the installation # mkdir('python-2.3.4') cd('python-2.3.4') downloadUntarzip('http://www.python.org/ftp/python/2.3.4/Python-2.3.4.tgz','PYTHON_TAR') mkdir('python') # directory which will contain the installed package setenvTemp('PYTHON_LOCATION','$PWD/python') # define a temporary environment variable # # -- Install as usual # cd('$PYTHON_TAR') shell('./configure --prefix="$PYTHON_LOCATION"') # configure Python to install into the prepared directory shell('make') shell('make install') cd() # # -- Add the python binary directory to the users's path both during installation and in setup # path('python/bin') # # -- add Python standard documentation # package('Demo:PythonDocs | versionGE("2.3.4")')
When you're finished writing a package, it is a good practice to confirm that it removes itself correctly if you do % pacman -remove. Pacman guarantees this for Pacman operations, but if a package uses a script, you are responsible for making sure that this is cleaned up when your package is uninstalled. You may occasionally need the uninstallShell atom to do this.
The basic philosophy of Pacman is to guarantee all of the conditions that you desribe above over time. For instance if you define an environment variable with setenv Pacman will make sure that this is not overwritten by some other package. In this case, for example, you have put some binaries in the user's path. If some other package puts other binaries with the same name in the user's path (a different version of Python, for example), then Pacman will complain and refuse to create setup scripts for the installation.