
Ask HN: Why do Makefiles typically not include an uninstall script? - codebeaker
I'm typically a package manager guy, once you start screwing with the status-quo especially on distributions like Ubuntu, things get strange really quickly.<p>Case in point, Redis, the Makefile is so simple, and the code/project so clean and with so few dependencies, there's not even a `./configure` stage, why doesn't it include a `make uninstall`.<p>`make install` must generate a file list to perform the uninstallation, it should be trivial to uninstall those files.<p>Am I missing a trick, is there some way to snatch the file list from `install` and feed it to `rm`, or do they not include an `uninstall` task incase that try to uninstall something that's running (but, even that is a small portion of things which are installed, and surely 9/10 times it would keep running until stopped/rebooted??)<p>Thanks HN!
======
e12e
As for answering the first question, maybe this might be a hint:

[http://sources.redhat.com/autobook/autobook/autobook_109.htm...](http://sources.redhat.com/autobook/autobook/autobook_109.html)

    
    
      "In our experience, uninstall is not a very useful feature. Automake implements it because it is mandated by the GNU Standards, but it doesn't work reliably across packages. Maintainers who write install hooks typically neglect to write uninstall hooks. Also, since it can't reliably uninstall a previously installed version of a package, it isn't useful for what most people would want to use it for anyway. We recommend using a real packaging system, several of which are freely available. In particular, GNU Stow, RPM, and the Debian packaging system seem like good choices."
    

Note this refers to GNU Stow[1] which is implemented in perl \-- I much prefer
the xstow variant[2] as it is more self contained. YMMV.

[1] <http://www.gnu.org/software/stow/> [2] <http://xstow.sourceforge.net/>

------
joe_bleau
Debian has checkinstall, maybe it'd work for you? (<http://www.debian-
administration.org/articles/147>)

~~~
codebeaker
> checkinstall

Thats a half-decent idea, nice smart move, and it looks like the authors
motivations weren't dissimilar to my starting point for this query.

I do wonder however if it isn't slightly over-killed, `make install` _must_
generate a list of commands to run, or there should have been some way to
stream the output of `make install` to a text file, that it might be undoable
?

------
eric_bullington
The clean way to use projects like Redis is to unpack them into an "/opt"
directory (either in your home directory or the root file system). Then just
`make` without the install and add that directory to your system path. In that
case of Redis, you have to add the Redis `src` subdirectory to the system path
in order to be able to use the `redis-server` command. You probably know all
this already, but it's really the easiest way to keep track of projects you
build yourself.

I think there is no `uninstall` command included usually because most packages
that are installed using `make install` are system libraries that other
packages depend upon. And so just uninstalling that one package could result
in a broken system. There may be some other historical reason, but that's my
guess.

EDIT: Yes, `checkinstall` is a really cool idea, but I've had a hard time
getting it to work reliably in practice. Building a deb is a complicated
process, so it's not surprising that attempting to automatic that process is
not 100% reliable. But you should try it out, maybe you'll have better luck
that I did.

~~~
e12e
I highly recommend using stow/xstow[1]. Pick a place to "stow" your "out-of-
band" programs, then:

    
    
      cd <awsome-src-distribution>
      ./configure --prefix=/usr/local/ && make
      make install prefix=/usr/local/opt/<awsome-1.2.3>
      cd /usr/local/opt
      xstow <awsome-1.2.3>
    

(aptitude install xstow on Debian & Ubuntu)

Xstow is also small enough to fit it into eg: ${HOME}/opt -- and it is able to
"unstow".

[1] <http://xstow.sourceforge.net/>

edit: formatting

~~~
e12e
To clarify; what (x) stow does, is manage a set of symlinks from/in eg: /usr
or /usr/local to a similar tree under eg: /usr/local/<program-version/, so
that for instance:

/usr/local/bin/<program> -> /usr/local/<program-version>/bin/<program>

Similarly for man, lib etc. If you don't put stuff under /usr or /usr/local
(but, say under /opt or ${HOME}/opt) -- you need to update your paths (PATH,
MANPATH, USER_LD..).

Uninstalling just means removing the symlinks (unstow) and deleting the tree
under /wherever/<program-version>.

This is what I do in my bashrc (which I use across a range of systems, some of
which are mine, some of which I only have a user accounts -- some on Solaris,
most on a flavour of Linux):

    
    
      # set PATH so it includes user's private bin if it exists
      for dir in "${HOME}" "${HOME}/opt" "${HOME}/opt/${unps}"
      do
        if [ -d "${dir}/bin" ]
        then
          PATH="$dir/bin":"${PATH}"
        fi
    
        # For python binaries, in "default" virtenv:
        if [ -d "${dir}/pybin" ]
        then
    	PATH="$dir/pybin":"${PATH}"
        fi
    
        # do the same with MANPATH
        if [ -d "${dir}/man" ]
        then
    	MANPATH="${dir}/man":"${MANPATH}"
        fi
    
        if [ -d "${dir}/lib" ]
        then
          USER_LD_LIBRARY_PATH="${dir}/lib":"${USER_LD_LIBRARY_PATH}"
        fi
    
        if [ -d "${dir}/include" ]
        then
          USER_LD_RUN_PATH="${dir}/include":"${USER_LD_RUN_PATH}"
        fi
    
      done
    
      #Then later:
      export PATH MANPATH USER_LD_LIBRARY_PATH USER_LD_RUN_PATH
    
    

The part about "pybin" is just becaus I do:

    
    
      cd ~/opt
      mkdir python-venvs
      virtualenv --no-site-packages python-venvs/misc
      ln -s python-venvs/misc/bin pybin
    

And can then pip install stuff and have it available without having to worry
about activating a virtualenv etc. I generally keep large packages in separate
venvs -- but install stuff like mercurial in the "misc" one.

Note that the structure of my opt-folder mirrors that of eg. /usr/local, so:

    
    
      mkdir -p ~/opt/{bin,include,lib,man,share}
    

(I also have src and xstow in there -- src for source packages I want to keep
around, xstow for xstow-installed packages.)

And to repeat, if you put your xstow tree under /usr/local or somewhere most
likely already in your path, it should "just work" without having to set any
extra variables -- and is more useful for eg: installing a system wide service
(like Redis for production use).

edit: forgot to add export of environment variables to the .bashrc snippet

edit: the "${HOME}/opt/${unps}" points to a directory that contains
architecture specific binaries; the unps-variable, is set to be `uname -ps`
(with some trickery) -- and is then used for finding local binaries and
setting some options like PAGER.

~~~
codebeaker
Stow seems to have a flavor of Mac homebrew about it (more likely the other
way around) everything is compiled and installed into `/Library/Cellar` and
then symlinked into the system path, you can `brew unlink readline`, for
example and it goes away, link it back and it's available to the system again.

The `brew` executable knows about the correct flags to give to `--configure`
within it's own context, so it rarely goes wrong.

