Сборка tmux’a под Solaris

Тестовый стенд: 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

Квест закончен ))

Так же неплохой квест прошли ребята здесь

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *