In the last month my work is somewhat related to Solaris and since I really got used to tmux I kind of miss it. Unfortunately it turns out Solaris is not the happy Linux land I am used to. One does not simply dowload, ./configure and make install stuff in Solaris. Not without the proper spells 🙂 So here is an attempt to document my experience to build static tmux binary, that doesn’t require libevent or ncurses shared libraries. I used a VM I had with gcc installed from openCSW.
First thing libevent, download and unpack it. Then:
1 2 3 |
$ cd libevent-2.0.21-stable $ ./configure --prefix=/tmp/tmux-install $ make && make install |
Next goes ncurses, download and unpack. Then:
1 2 3 |
$ export AR=gar $ ./configure --prefix=/tmp/tmux-install --without-cxx-binding $ make && make install |
And finally we can compile tmux itself. This is abit trickier , as it seems tmux doesn’t directly support Solaris. Download and unpack. You need to apply the following patch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
diff -ur tmux-1.8/client.c tmux-1.8-patched/client.c --- tmux-1.8/client.c Sun Mar 17 16:03:37 2013 +++ tmux-1.8-patched/client.c Mon Nov 18 22:29:59 2013 @@ -33,6 +33,39 @@ #include "tmux.h" +/* BEGIN SOLARIS 11 FIX */ +#ifndef LOCK_SH +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* don’t block when locking */ +#define LOCK_UN 8 /* unlock */ +#endif +int flock(int fd, int cmd); +void cfmakeraw(struct termios *termios_p); +int +flock(int fd, int cmd) +{ + struct flock f; + memset(&f, 0, sizeof (f)); + if (cmd & LOCK_UN) + f.l_type = F_UNLCK; + if (cmd & LOCK_SH) + f.l_type = F_RDLCK; + if (cmd & LOCK_EX) + f.l_type = F_WRLCK; + return fcntl(fd, (cmd & LOCK_NB) ? F_SETLK : F_SETLKW, &f); +} +void +cfmakeraw(struct termios *termios_p) +{ + termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + termios_p->c_oflag &= ~OPOST; + termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + termios_p->c_cflag &= ~(CSIZE|PARENB); + termios_p->c_cflag |= CS8; +} +/* END SOLARIS 11 FIX */ + struct imsgbuf client_ibuf; struct event client_event; struct event client_stdin; diff -ur tmux-1.8/server-client.c tmux-1.8-patched/server-client.c --- tmux-1.8/server-client.c Tue Mar 26 21:22:31 2013 +++ tmux-1.8-patched/server-client.c Mon Nov 18 22:34:13 2013 @@ -25,7 +25,20 @@ #include #include #include +#include +#ifndef timersub +# define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + #include "tmux.h" void server_client_check_focus(struct window_pane *); |
Use gpatch, obviuosly patch in Solaris carries some braindead Unix legacy which I don’t even want to know about:
1 |
$ gpatch -p1 < ../tmux-1.8-solaris.patch |
Then we setup the CPP/LDFLAGS, ./configure and make:
1 2 3 4 |
$ export LIBEVENT_CFLAGS=-I/tmp/tmux-install/include $ export LIBEVENT_LIBS="-lsendfile /tmp/tmux-install/lib/libevent.a -L/tmp/tmux-install/include" $ CPPFLAGS="-D_XPG6" LDFLAGS="-D_XPG6" ./configure --prefix=/tmp/tmux-install/ $ make |
Thats it 🙂 In the tmux source directory we have a tmux binary that depends only on system libraries so you can copy it to other Solaris boxes and use it there.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ ldd tmux libxnet.so.1 => /lib/libxnet.so.1 libsocket.so.1 => /lib/libsocket.so.1 libnsl.so.1 => /lib/libnsl.so.1 libcurses.so.1 => /lib/libcurses.so.1 libsendfile.so.1 => /lib/libsendfile.so.1 librt.so.1 => /lib/librt.so.1 libresolv.so.2 => /lib/libresolv.so.2 libc.so.1 => /lib/libc.so.1 libmp.so.2 => /lib/libmp.so.2 libmd.so.1 => /lib/libmd.so.1 libscf.so.1 => /lib/libscf.so.1 libaio.so.1 => /lib/libaio.so.1 libdoor.so.1 => /lib/libdoor.so.1 libuutil.so.1 => /lib/libuutil.so.1 libgen.so.1 => /lib/libgen.so.1 libm.so.2 => /lib/libm.so.2 |