Тестовый стенд: tmux-1.8, libevent-2.0.21
Сборка tmux’a под Solaris ещё тот квест с правкой исходников. И так, качаем свежую версию tmux’a, а так же libevent (как зависимость). libevent ставится без проблем:
root@skeletor:/export/home/skeletor/libevent-2.0.21-stable# CFLAGS="-m64 -O2" CPPFLAGS="-m64 -O2" CCASFLAGS="-m64 -O2" CXXFLAGS="-m64 -O2" LDFLAGS="-m64 -O2" ./configure --prefix=/usr --libdir=/lib/64 && gmake && gmake install && gmake clean
А теперь соберём tmux:
root@skeletor:/export/home/skeletor/tmux-1.8# CFLAGS="-m64 -O2" CPPFLAGS="-m64 -O2" CCASFLAGS="-m64 -O2" CXXFLAGS="-m64 -O2" LDFLAGS="-m64 -O2" ./configure --prefix=/usr --libdir=/lib/64 && gmake && gmake install && gmake clean
и сразу же получаем ошибку:
In file included from /usr/include/sys/types.h:12:0,
from arguments.c:19:
/usr/include/sys/feature_tests.h:354:2: error: #error "Compiler or options invalid for pre-UNIX 03 X/Open applications and pre-2001 POSIX applications"
gmake: *** [arguments.o] Error 1
Решение простое: в Makefile меняем
am__append_2 = -std=gnu99
(или там может быть -std=с99)
на
am__append_2 = -std=gnu89
Объяснение человека, который к этому пришёл очень забавное
This is a bit of a hack, and I probably don’t understand the nuances of what I’m doing here, but I edited the Makefile, and changed
Запускаем ещё раз сборку и натыкаемся на следующую ошибку:
client.c: In function ‘client_get_lock’:
client.c:81:20: error: ‘LOCK_EX’ undeclared (first use in this function)
client.c:81:20: note: each undeclared identifier is reported only once for each function it appears in
client.c:81:28: error: ‘LOCK_NB’ undeclared (first use in this function)
gmake: *** [client.o] Error 1
Эта ошибка уже интересная и требует переписки части функции client_get_lock. Дело в том, что в Solaris-подобных ОСях (Solaris, illumos, SmartOS, …) вместо функции flock() используется fcntl(). И так, привожу diff файл (в создании патча очень помогло это пособие):
# diff -u client.c client.c_diff --- client.c Sun Mar 17 14:03:37 2013 +++ client.c_diff Fri Feb 14 11:40:38 2014 @@ -33,6 +33,15 @@ #include "tmux.h" +#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 */ + +#define F_GETLK 7 /* get record locking information */ +#define F_SETLK 8 /* set record locking information */ +#define F_SETLKW 9 /* F_SETLK; wait if blocked */ + struct imsgbuf client_ibuf; struct event client_event; struct event client_stdin; @@ -75,11 +84,20 @@ { int lockfd; + struct flock lock; + + lock.l_start = 0; + lock.l_len = 0; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) fatal("open failed"); - if (flock(lockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) { - while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR) +// if (flock(lockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) { +// while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR) + if (fcntl(lockfd, F_SETLK, &lock) == -1 && errno == EAGAIN) { + while (fcntl(lockfd, F_SETLKW, &lock) == -1 && errno == EINTR) /* nothing */; close(lockfd); return (-1);
Патчим и снова запускаем сборку и получаем ошибку:
server-client.c: In function ‘server_client_check_resize’:
server-client.c:544:7: error: ‘errno’ undeclared (first use in this function)
server-client.c:544:7: note: each undeclared identifier is reported only once for each function it appears in
server-client.c:544:16: error: ‘EINVAL’ undeclared (first use in this function)
gmake: *** [server-client.o] Error 1
Добавляем
#include <errno.h>
в файл server-client.c и снова запускаем сборку и опять получаем ошибку:
Undefined first referenced symbol in file cfmakeraw client.o ld: fatal: symbol referencing errors. No output written to tmux collect2: ld returned 1 exit status gmake: *** [tmux] Error 1
Всё дело в функции cfmakeraw(). Вот описание:
cfmakeraw() sets the terminal to something like the “raw” mode of the old Version 7 terminal driver: input is available character by character, echoing is disabled, and all special processing of terminal input and output characters is disabled.
Учитывая описание (а можно послушаться совета отсюда), просто закоментируем вызов данной функции в файле client.c:
strerror(errno)); return (1); } // cfmakeraw(&tio); tio.c_iflag = ICRNL|IXANY; tio.c_oflag = OPOST|ONLCR;
Теперь очищаем и пересобираем заново:
# gmake clean && gmake
Вот теперь всё ок. Проверяем все ли либы на месте:
# ldd ./tmux libxnet.so.1 => /lib/64/libxnet.so.1 libsocket.so.1 => /lib/64/libsocket.so.1 libnsl.so.1 => /lib/64/libnsl.so.1 libcurses.so.1 => /lib/64/libcurses.so.1 libevent-2.0.so.5 => /lib/64/libevent-2.0.so.5 libresolv.so.2 => /lib/64/libresolv.so.2 libc.so.1 => /lib/64/libc.so.1 libmp.so.2 => /lib/64/libmp.so.2 libmd.so.1 => /lib/64/libmd.so.1 libsendfile.so.1 => /lib/64/libsendfile.so.1 libgcc_s.so.1 => /usr/lib/64/libgcc_s.so.1 libsoftcrypto.so.1 => /lib/64/libsoftcrypto.so.1 libelf.so.1 => /lib/64/libelf.so.1 libcryptoutil.so.1 => /lib/64/libcryptoutil.so.1 libm.so.2 => /lib/64/libm.so.2
Квест закончен ))
Так же неплохой квест прошли ребята здесь