Doomed to Wordpress

Serious Reflections During the Life of Jeremy Fisher

   

Subscribe
Subscribe to a syndicated feed of my weblog, brought to you by the wonders of RSS.

Flavours
There's more than one way to view this weblog; try these flavours on for size.

  • index
  • circa 1993
  • RSS
  • Links
    These are a few links to my other sites.

  • Ставропигиальныя Пластинки
  • Анкылым
  • Русское Шрифтовое Зало
  • Gopher (Proxied)
  • More about Gopher
  •        

    2020/10/06 pkgsrc

    Доведённый до отчаяния адом зависимостей в пакетных менеджерах современных Линуксов, я начал экспериментировать с pkgsrc. Впечатления на первый взгляд хорошие. Очень порадовало, что для многих программ есть выбор, какую версию поставить: так, в дереве пакетов хранятся версии gcc со 2-й по 10-ю, 5 версий emacs, perl5 вот правда почему-то единственный, а во FreeBSD несколько, и ardour тоже, а даже в Дебиане можно несколько ставить. И evince2 буквально две недели назад удалили. Но в целом это решаемо: в будущем можно будет создать свою ветку и восстановить в ней удалённые пакеты или создать отдельные пакеты для нужных мне версий. Из обнаружившихся недостатков: дерево пакетов огромное (у меня сейчас занимает 2,5 гига, включая собранные пакеты в packages/All, а без них что-то около 1,5 гигов), обновляется медленно, индексации я вообще не дождался, ищу пакеты через find . -type d -name .... Кроме того, у меня уже накопилось достаточно локальных правок, и если переносимость получаемых бинарников между разными линуксами подтвердится (ради чего я это всё и делаю), логично было бы хранить всё дерево где-то в одном месте, скажем на флэшке или в чём-то вроде nfs/sshfs, но учитывая скорость сборки (о чём далее), есть опасение таким образом ещё более всё замедлить. Кроме того, пакеты из packages/All надо бы перенести на какой-то сервер.

    Но главное, мне показалось, что это очень интеллигентная и уютная система.

    После установки (инструкции: https://opensource.com/article/19/11/pkgsrc-netbsd-linux, но более общая и для меня подходящая команда здесь: https://www.netbsd.org/docs/pkgsrc/getting.html, может также понадобиться export SH=/bin/bash перед запуском bootstrap) не забыть прописать новые пути:

    echo "PATH=/usr/pkg/sbin:/usr/pkg/bin:$PATH" >> ~/.bashrc
    echo "MANPATH=/usr/pkg/man:$MANPATH" >> ~/.bashrc
    

    После этого я попробовал в чруте собрать недавний fontforge на wheezy. Сборка в итоге продлилась неделю. Правда, в итоге было получено достаточно много готовых пакетов (установилось 175), и теперь (опять же, если переносимость подтвердится) можно их ставить уже собранными. Разумеется, я могу затем подробнее поковыряться в опциях каждого пакета (bmake show-options) и отключить кучу ненужных зависимостей; это делается куда проще, чем в deb-пакетах. Так, уже в процессе я добавил в /usr/pkg/etc/mk.conf

    PKG_DEFAULT_OPTIONS+=   -wayland
    

    — не думаю, что когда-либо в жизни поведусь на эту моду и стану им пользоваться.

    Теперь о том, что̀ же оно такое делало целую неделю.

    Для сборки какого-то пакета понадобился cmake (куда ж без него; недавно в интернете прочитал — уж не могу теперь найти — в связи с какой-то проблемой в новых версиях каких-то продуктов Мозиллы некто жалуется, что всё это оттого, что Мозилла, как и многие другие нынешние разработчики, отказалась от GNU build tools — и воистину, он прав), но не собирался, выдавая ошибку, что не может найти -lgcc_s. А оно мне поставило gcc 4.8 в /usr/pkg/gcc48. Я поначалу долго думал, что оно просто не может найти gcc из-за нестандартного расположения. К сожалению, информации по конкретным проблемам с pkgsrc довольно мало. С трудом нашёл описание аналогичной проблемы и решение: https://mail-index.netbsd.org/tech-pkg/2020/06/25/msg023446.html — оказывается, надо вместе с gcc собирать и libgcc, которое почему-то не ставится по умолчанию. В /usr/pkg/etc/mk.conf написал:

    PKG_OPTIONS.gcc48+=     always-libgcc -nls
    

    Тут — https://mail-index.netbsd.org/tech-pkg/2020/06/25/msg023445.html — предлагается сделать это для всех версий gcc сразу так:

    PKG_DEFAULT_OPTIONS+=  always-libgcc
    

    Следующий сбой случился при установке какого-то модуля питона 2.7, когда сам питон ещё не был установлен. Ничего иного от питонщиков я и не ждал, будь они хоть создателями пакетов pkgsrc. Решилось каким-то образом повторным перезапуском сборки, при котором питон уже поставился. Так и не понял, что̀ произошло, ну и ладно. Разумеется, надо было в опциях пакетов отключать сразу питон везде, где это возможно. Но это не везде возможно.

    Следующая проблема была с gcc49 и gcc5, которые тоже оказались в чьих-то зависимостях и не собирались с ошибкой типа описанной здесь: http://mail-index.netbsd.org/pkgsrc-users/2019/06/16/msg028814.html, вот пример из gcc5:

    /usr/include/i386-linux-gnu/bits/stdio2.h: In function 'void GTM::gtm_verror(const char*, va_list)':
    /usr/include/i386-linux-gnu/bits/stdio2.h:125:1: error: inlining failed in call to always_inline 'int vfprintf(FILE*, const char*, __gnuc_va_list)': function body can be overwritten at link time
     vfprintf (FILE *__restrict __stream,
     ^
    ../../../gcc-5.5.0/libitm/util.cc:35:31: error: called from here
       vfprintf (stderr, fmt, list);
                                   ^
    

    Пришлось добавить

    FORTIFY_SUPPORTED=  no
    

    в gcc49/Makefile, иначе не знаю как.

    Опять какие-то новшества всё убивают. Раньше была проблема, что старые исходники не собираются более новым компилятором, теперь наоборот — новые не собираются старым. Вот зло!

    Далее, пришлось в Makefile для textproc/icu поменять

    GCC_REQD+=              4.8
    

    на 4.9. Далее не собирается harfbuzz (кажется, fontforge с его зависимостями был слишком сложным выбором для начального тестирования системы). Там ninja, meson и прочее. Пора бы сделать операционную систему, в которой было бы строгое требование, чтобы весь софт собирался только с помощью единого стандартного, традиционного и обратно совместимого инструментария.

    ../test/api/hb-test.h:178:5: error: 'for' loop initial declarations are only allowed in C99 or C11 mode
         for (unsigned int i = 0; i < expected_length; i++)
         ^
    ../test/api/hb-test.h:178:5: note: use option -std=c99, -std=gnu99, -std=c11 or -std=gnu11 to compile your code
    

    Пришлось поменять в Makefile USE_LANGUAGES на

    USE_LANGUAGES=  c99 c++
    

    Не забыть make clean после этого!

    И то же самое понадобилось для gcc5 (это уже третий gcc, который пришлось поставить в процессе). Не понятно, если уж так нестерпимо хочется писа́ть

    for (int i=...)
    

    вместо

    int i;
    for (i=...)
    

    — то это же совершенно механическая замена, ну пиши ты как хочется и добавь в сценарии сборки обработку особым препроцессором, который твой ленивый код приведёт к нормальному виду (и тут и выясняется вся абсурдность таких «упрощений», которые сводятся к машинно выполнимой замене; хотя вот придумали же всякий TypeScript и Less и пишут как хочется, а потом компилируют в стандартный JS/CSS, почему с C так не сделать?). (В Perl вот тоже никогда не понимал добавление этого словечка state — чем сложно было то же самое делать через замыкания, как испокон веку делалось?)

    Но и на этом не всё. Gtk3 требует libexpoxy, которое требует MesaLib, которое с некоторых пор в единственном месте употребляет специфический для Linux системный вызов:

    #if defined(__linux__)
    ...
      return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2);
    

    Однако этот системный вызов появился только в ядре 3.5 (https://rdhafidh.web.id/blog/11/04/2020/Building+mesa+19.3.5+on+ancient+ubuntu). Очевидно, более старые версии ядра̀ для разработчиков не существуют. В моём случае дело осложняется тем, что моё-то ядро поддерживает данный вызов, но я собираю для более старых дистрибутивов, кое-где у меня отлично работает ядро 3.2 и я не вижу поводов его заменять. Поэтому данный код нужно убрать полностью (начиная с изменений в коммите https://github.com/mesa3d/mesa/commit/ed271a9c2f40f8ec881bf3e4568d35dbfcd9cf70, как указано по ссылке выше), а не пытаться добавлять какие-то условия, чтобы включить его для ядер >= 3.5. Кстати, глядя на историю этого кода, видно, что разработчики уже столкнулись с проблемами из-за его добавления: в последующих версиях им пришлось скопипастить кусок из linux/kcmp.h. Так что их путь без сомнения ложный, без всяких сожалений убиваем данное новшество. Это можно сделать либо удалив лишний код, либо поставив заведомо невыполнимое условие вместо #if defined(__linux__). Чтобы облегчить себе в будущем сопровождение этих патчей, выбираю путь минимальных изменений — второй.

    Применение патчей в pkgsrc

    Опять сталкиваюсь с малочисленностью документации, из которой не могу, например, понять, зачем при запуске pkgvi переходить в каталог с исходниками и обязательно ли это. Я этого не делал. В итоге я так и не понял, вполне ли правильно всё делаю, но такая последовательность у меня сработала:

    cd /usr/pkgsrc/graphics/MesaLib
    bmake fetch extract patch
    pkgvi work/mesa-20.0.6/meson.build
    pkgdiff "work/mesa-20.0.6/meson.build" # проверка
    mkpatches
    bmake makepatchsum
    

    Однако после этого сборка стала падать с ошибкой:

    src/util/libmesa_util.a(crc32.c.o): In function `util_hash_crc32':
    crc32.c:(.text+0x1c): undefined reference to `crc32'
    src/util/libmesa_util.a(disk_cache.c.o): In function `cache_put':
    disk_cache.c:(.text+0xc1c): undefined reference to `deflateInit_'
    disk_cache.c:(.text+0xca2): undefined reference to `deflate'
    disk_cache.c:(.text+0xd02): undefined reference to `deflateEnd'
    disk_cache.c:(.text+0xd51): undefined reference to `deflateEnd'
    src/util/libmesa_util.a(disk_cache.c.o): In function `disk_cache_get':
    disk_cache.c:(.text+0x1830): undefined reference to `inflateInit_'
    disk_cache.c:(.text+0x18b1): undefined reference to `inflate'
    disk_cache.c:(.text+0x18c4): undefined reference to `inflateEnd'
    disk_cache.c:(.text+0x18e2): undefined reference to `inflateEnd'
    

    Основная сложность была даже не в том, чтобы найти подлинную причину — казалось бы, ничто не мешает пробовать разные варианты, но тут оказывается, что ещё больше времени уходит на то, чтоб разобраться, как сделать то или иное в этом дебильном Мезоне. Как там добавить флаг линкеру, как убрать флаг? Где определяется порядок аргументов, передаваемых ему? Как определить, видит ли он вообще libz и какой именно — системный или из pkgsrc?

    Решилось так:

    add_project_link_arguments(
          '-Wl,--no-as-needed',
          language : ['c', 'cpp'],
    )
    

    Не знаю, насколько правильно, но работает.

    Как видим, ни одного сбоя не произошло по вине стандартных, проверенных временем технологий; все сбои из-за введения новшеств: начиная с написания кода, привязанного к определённым (новейшим) версиям gcc и ядра и жертвующего переносимостью ради синтаксического сахара, и заканчивая нелепым желанием разработчиков привнести как можно больше разных систем сборки (в основном так или иначе завязанных на питоне), взамен простых, стандартных и проверенных configure/make.

    К сожалению, данный подход делает бессмысленной всю идею свободного ПО, которое любой человек может сам собрать из исходников. Как видим, не то что любой человек, а даже профессиональный программист не всегда может собрать программу из исходников с таким инструментарием. Пользователи оказываются вынужденными устанавливать сторонние сборки, заявляемая возможность «скачать исходники и собрать самому» оказывается чисто теоретической. (Ещё раньше это произошло с браузерами — насколько я помню, уже довольно давно Мозилла официально (!) не рекомендовала (!) собирать свои браузеры из исходников, вместо этого навязывая собственные сборки. Впрочем, как видим, на моих машинах такая сборка заняла бы, наверно, месяц.) В этой ситуации пользователю становится безразлично, свободный софт у него или проприетарный, раз установка программы ничем принципиально не отличается от установки проприетарных бинарников в винде, с той разницей, что в винде программа ещё и не тянет за собой миллион зависимостей. Создатели таких инструментариев вбивают лишь гвозди в гроб свободного ПО, к сообществу которого они наивно сами себя причисляют, но на самом деле лишь вредят, и со своими модными инструментами и технологиями место им среди высокооплачиваемых сотрудников какой-либо большой корпорации, выпускающей пропритарный хлам.

    Вдогонку: сегодня, 06.10, получаю новость:

    Разработчики проекта Mesa обсуждают возможность использования языка Rust для разработки драйверов OpenGL/Vulkan и компонентов графического стека.

    Почему я не удивлён.

    #pkgsrc #gcc

    permanent link