5 min read

Compiling zsh without root

Table of Contents

This article describes how to compile zshell on a Linux machine without root, for instance when working remotely on a server on which you do not have root.

#

Step 1: Dependencies

#

ncurses

To compile zsh, you need ncurses. This needs to be compiled with the flag -fPIC. This can be achieved as follows:

Terminal window
1
# Download the ncurses gzipped tarball
2
wget ftp://ftp.invisible-island.net/ncurses/ncurses.tar.gz
3
4
# Extract gzipped tarball
5
tar -zxvf ncurses.tar.gz
6
7
# Move into root ncurses source directory
8
cd ncurses
9
10
# Set cflags and c++ flags to compile with Position Independent Code enabled
11
export CXXFLAGS=' -fPIC'
12
export CFLAGS=' -fPIC'
13
14
# Produce Makefile and config.h via config.status
15
./configure --prefix=$HOME/.local --enable-shared
16
17
# Compile
18
make
19
20
# Deduce environment information and build private terminfo tree
21
cd progs
22
./capconvert
23
cd ..

Now before installing the compiled files, you should check to make sure that ncurses has compiled correctly by running:

Terminal window
1
./test/ncurses

If this successfully opens a prompt with multiple options, then ncurses has been successfully compiled, and you can install it:

Terminal window
1
# Install ncurses to $HOME/.local
2
make install

Note that the --enable-shared configure flag ensures that libtool builds shared libraries for ncurses, needed for zsh later on.

#

icmake

Now, this may be all you need, but if you don’t have it installed, you also need the documentation builder yodl, which in turn needs icmake. If these are installed already, you can skip straight ahead to Part 2.

Firstly, icmake is installed via:

Terminal window
1
# Download icmake source from Sourcefourge
2
wget http://downloads.sourceforge.net/project/icmake/icmake/7.21.00/icmake_7.21.00.orig.tar.gz
3
4
# Unpack archive (change version as appropriate)
5
tar -zxvf icmake_7.21.00.orig.tar.gz
6
cd icmake-7.21.00

Now the INSTALL.im file needs to be altered to reflect our local installation. This means replacing all the file installation locations with local directories as such, where should be replaced with your username:

1
#define BINDIR "/home/<USER>/.local/bin"
2
#define SKELDIR "/home/<USER>/.local/share/icmake"
3
#define MANDIR "/home/<USER>/.local/share/man"
4
#define LIBDIR "/home/<USER>/.local/lib/icmake"
5
#define CONFDIR "/home/<USER>/.local/config/icmake"
6
#define DOCDIR "/home/<USER>/.local/share/doc/icmake"
7
#define DOCDOCDIR "/home/<USER>/.local/share/doc/icmake-doc"

Now run the following to compile icmake:

Terminal window
1
./icm_bootstrap /

Now, technically, this will compile all the files you actually need in tmp, but if you further want to install the files to ~/.local, then you simply run:

Terminal window
1
./icm_install strip all

If you then want to clear up the temporary compiled files, delete the directory tmp with rm -rf tmp.

#

yodl

Now to move onto yodl. Again, we need to specify that we want to install locally by putting BASE = "/home/as1423/.local" at the start of the function setLocations()located at the end ofINSTALL.im’, so that the function looks like:

1
void setLocations()
2
{
3
BASE = "/home/as1423/.local";
4
5
// make sure that BIN, STD_INCLUDE, MAN, DOC and DOCDOC all are
6
// absolute paths
7
8
BIN = BASE + "/bin";
9
DOC = BASE + "/share/doc/yodl";
10
DOCDOC = BASE + "/share/doc/yodl-doc";
11
MAN = BASE + "/share/man";
12
STD_INCLUDE = BASE + "/share/yodl";
13
14
COMPILER = "gcc";
15
}

In addition, we need to tell build to look in our local directory for icmake instead of the standard /usr/bin or /usr/local/bin. This means editing the hashbang at the top of build to look as follows, where again is replaced by your UNIX username:

1
#!/home/<USER>/.local/bin/icmake -qt/tmp/yodl

Now that build knows that we want to run our locally compiled icmake, we can actually build yodl:

Terminal window
1
# In root directory of yodl source
2
./build programs
3
./build man
4
./build manual
5
./build macros

There may be a LaTeX error when running ./build manual, but just ignore this, because it’s not vital.

Now we’re ready to actually install yodl:

Terminal window
1
./build install programs /
2
./build install man /
3
./build install manual /
4
./build install macros /
5
./build install docs /

Note that the / designates that we are installing with respect to the root of our filesystem. This is fine, though, because we’ve already specified in INSTALL.im that we want everything to be installed locally into $HOME/.local$. Now yodl` should be successfully installed.

#

Step 2: Tell environment where ncurses is

Before compiling zsh, you need to tell your environment where your newly compiled files are (if you haven’t already). This can be achieved with:

Terminal window
1
INSTALL_PATH='$HOME/.local'
2
3
export PATH=$INSTALL_PATH/bin:$PATH
4
export LD_LIBRARY_PATH=$INSTALL_PATH/lib:$LD_LIBRARY_PATH
5
export CFLAGS=-I$INSTALL_PATH/include
6
export CPPFLAGS="-I$INSTALL_PATH/include" LDFLAGS="-L$INSTALL_PATH/lib"
#

Step 3: Compiling zsh

Now, we’re finally ready to move onto compiling zsh:

Terminal window
1
# Clone zsh repository from git
2
git clone git://github.com/zsh-users/zsh.git
3
4
# Move into root zsh source directory
5
cd zsh
6
7
# Produce config.h.in, needed to produce config.status from ./configure
8
autoheader
9
10
# Produce the configure file from aclocal.m4 and configure.ac
11
autoconf
12
13
# Give autotools a timestamp for recompilation
14
date < stamp-h.in
15
16
# Produce Makefile and config.h via config.status
17
./configure --prefix=$HOME/.local --enable-shared
18
19
# Compile
20
make
21
22
# Install
23
make install
#

Step 4: Enjoy zsh!

After these steps have been completed, zsh should be ready and compiled to use in your ~/.local/bin folder. If you like zsh, you’ll love ohmyzsh. This can be installed by:

Terminal window
1
curl -L http://install.ohmyz.sh | sh

Or if you don’t want o execute shell scripts from arbitrary non-https website, you can use git:

Terminal window
1
# Clone repository into local dotfiles
2
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
3
4
# Copy template file into home directory
5
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

Once you’ve done this, edit oh-my-zsh to your needs, e.g. if you want to change the theme, replace ZSH_THEME="robbyrussell" with the theme of your choice. I particularly enjoy jonathan`.

And finally, change your shell to zsh:

Terminal window
1
chsh -s $HOME/.local/bin/zsh

Now sit back and enjoy your effortless tab completion, directory movement and integrated git information.

#

Troubleshooting

If, when installing zsh, either make or make install fail despite all other programs being compiled and present, you may need to run make realclean to remove ALL compiled files, and start the compilation from autoheader. This sometimes happens if you run ./configure before installing yodl, meaning the config.h and Makefile files have been built without knowledge of yodl and need to be purged.

If zsh isn’t recognising the ncurses library when running ./configure, and instead giving the following error:

Terminal window
1
configure: error: "No terminal handling library was found on your system.
2
This is probably a library called 'curses' or 'ncurses'. You may
3
need to install a package called 'curses-devel' or 'ncurses-devel' on your
4
system."
5
See `config.log' for more details.

Then this means that you haven’t got the ncurses library in your library path. You can add it to your environment by re-running the commands in Part 2, in particular the final command exporting CPPFLAGS and LDFLAGS.

#

References

This stackoverflow post

This autotools flow chart from Wikipedia

The somewhat cryptic and involved zsh INSTALL file.