Збірка та встановлення erlang 19.3.6.5 (Erlang/OTP) за допомогою kerl на (l)ubuntu 20.04 LTS/22.04 LTS

що робити у випадку, коли є потреба потицяти erlang код на версії,
збірки якої немає на erlang-solutions ?

відповідь наступна - беремо kerl і робимо збірку та встановлення erlang (у моєму випадку 19.3.6.5) самостійно!

upd. на debian 12 збірка erl25 відбувається успішно, без необхідності збирати openssl :)

невеличкий спойлер --
в openssl версій 1.0/1.1 наявні деякі баги (також допускаю деяку кривизну вигинів своїх рук) --
відповідно, щоб отримати успішну збірку з ок роботою функцій модуля crypto,
мені довелось перебрати 5 версій openssl

1.1.1f не ок,
1.1.1k не ок, 
1.0.2u не ок,
1.0.1u не ок,
1.0.2t ok !! ))

що ж, розпочнемо:
встановимо необхідні для збірки програми

# Required
$ sudo apt-get -y install build-essential       # assumed
$ sudo apt-get -y install make

# These will result in the build failing if they're not present.
$ sudo apt-get -y install autoconf m4           # ./otp_build: autoconf: not found
$ sudo apt-get -y install libssl-dev            # No usable OpenSSL found
$ sudo apt-get -y install libncurses5-dev       # configure: error: No curses library functions found

# Recommended
$ sudo apt-get -y install libwxgtk3.0-gtk3-dev  # wxWidgets not found, wx will NOT be usable

# Optional
# I consider these "optional", because I've never noticed them missing.
$ sudo apt-get -y install default-jdk           # jinterface     : No Java compiler found
$ sudo apt-get -y install unixodbc-dev          # odbc           : ODBC library - link check failed

# These are for the documentation.
$ sudo apt-get -y install xsltproc fop libxml2-utils

upd. на debian 12 збірка erl25 замість libwxgtk3.0-gtk3-dev потребує

sudo apt-get -y install build-essential autoconf m4 libncurses5-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop libxml2-utils libncurses-dev default-jdk libwxgtk-webview3.2-1 libwxgtk-webview3.2-dev automake

завантажимо, розархівуємо, зберемо, встановимо openssl

$ cd /usr/local/src/
$ wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2t.tar.gz
$ tar -xf openssl-1.0.2t.tar.gz
$ cd openssl-1.0.2t
$ sudo ./config -Wl,-rpath=/usr/local/ssl/lib -Wl,--enable-new-dtags shared
$ sudo make
$ sudo make test
$ sudo make install
# sudo ln -sf /usr/local/ssl/bin/openssl `which openssl`
$ openssl version -v
$ /usr/local/ssl/bin/openssl version -a

завантажимо kerl, збираємо потрібну версію erlang-а з нашою версією openssl

$ curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl
$ chmod a+x kerl

$ ./kerl list releases
$ KERL_CONFIGURE_OPTIONS="--with-ssl=/usr/local/ssl --without-odbc" ./kerl build 19.3.6.5 19.3.6.5
$ ./kerl install 19.3.6.5 /home/e/.kerl/erlangs/19.3.6.5

включимо erlang

$ . /home/e/.kerl/erlangs/19.3.6.5/activate

тепер ми можемо запустити-перевірити версію та виклик функції з модуля crypto:

$ erl
Erlang/OTP 19 [erts-8.3.5.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.3.5.4  (abort with ^G)
1> crypto:hash(sha512, <<"12345">>).
<<54,39,144,154,41,195,19,129,160,113,236,39,247,201,202,
  151,114,97,130,174,210,154,125,221,46,84,53,51,34,...>>

все працює! :)

також ми можемо:

переглянути список встановлених версій erlang-а

$ ./kerl list installations

можемо відключити (після цього знову потрібно буде включити - командою з activate)

$ kerl_deactivate

також можемо видалити встановлену версію erlang-а

$ ./kerl delete installation /home/e/.kerl/erlangs/19.3.6.5

.

.

.

у випадку помилки виконання команди kerl build (на (l)ubuntu 22.04 lts):

configure: error: cannot find required auxiliary files: config.guess config.sub

встановлюємо (робимо downgrade) autoconf 2.69 :

wget https://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar -xzf autoconf-2.69.tar.gz
cd autoconf-2.69
./configure
make
sudo make install

$ autoconf -V

пробуємо ще раз, з gcc-9

$ KERL_CONFIGURE_OPTIONS="--with-ssl=/usr/local/ssl --without-odbc" CC="gcc-9" ./kerl build 19.3.6.5 19.3.6.5

якщо ми отримуємо помилку

  281 | static unsigned long my_sigstack[SIGSTKSZ/sizeof(long)]; 
  |  ^~~~~~~~~~~ 

то нам потрібно знайти такий файл та строчку
https://github.com/erlang/otp/blob/OTP-19.3.6.5/erts/emulator/hipe/hipe_x86_signal.c#L281
і зробити отаку заміну

  //static unsigned long my_sigstack[SIGSTKSZ/sizeof(long)];
  static unsigned long my_sigstack[8192/sizeof(long)];

для цього розпакуємо архів

$ cd .kerl/archives
$ tar -xf OTP-19.3.6.5.tar.gz

після редагування - упаковуємо назад в архів

e@ee:~/.kerl/archives$ tar -czvf OTP-19.3.6.5.tar.gz otp-OTP-19.3.6.5

пробуємо (тут -j10 V=1 -- кількість ядер процесора = 10):

$ env KERL_CONFIGURE_OPTIONS="--without-odbc --with-ssl=/usr/local/ssl" CC="gcc -w" CXX="gcc -w" LDFLAGS="-Wl,--allow-multiple-definition" MAKEFLAGS="-j10 V=1" ./kerl build 19.3.6.5 19.3.6.5

якщо отримали наступну помилку

wxe_impl.cpp: In member function ‘void* WxeApp::getPtr(char*, wxeMemEnv*)’:
wxe_impl.cpp:669:55: error: ordered comparison of pointer with integer zero (‘void*’ and ‘long int’)
  669 |   if((index < memenv->next) && ((index == 0) || (temp > NULL)))
      |                                                       ^
wxe_impl.cpp: In member function ‘void WxeApp::registerPid(char*, ErlDrvTermData, wxeMemEnv*)’:
wxe_impl.cpp:681:55: error: ordered comparison of pointer with integer zero (‘void*’ and ‘long int’)
  681 |   if((index < memenv->next) && ((index == 0) || (temp > NULL))) {
      |                                                       ^

то нам потрібно знайти такий файл та строчки
https://github.com/erlang/otp/blob/OTP-19.3.6.5/lib/wx/c_src/wxe_impl.cpp#L669-L681
тут ми знаходимо строчки 669 та 681, в яких

(temp > NULL)

замінюємо на

(temp != NULL)

після редагування - упаковуємо назад в архів (див. вище) і пробуємо ще раз

$ env KERL_CONFIGURE_OPTIONS="--without-odbc --with-ssl=/usr/local/ssl" CC="gcc -w" CXX="gcc -w" LDFLAGS="-Wl,--allow-multiple-definition" MAKEFLAGS="-j10 V=1" ./kerl build 19.3.6.5 19.3.6.5
Extracting source code
Building Erlang/OTP 19.3.6.5 (19.3.6.5), please wait...
APPLICATIONS DISABLED (See: /home/e/.kerl/builds/19.3.6.5/otp_build_19.3.6.5.log)
 * jinterface     : No Java compiler found
 * odbc           : odbc disabled by user.
 * odbc           : User gave --without-odbc option

DOCUMENTATION INFORMATION (See: /home/e/.kerl/builds/19.3.6.5/otp_build_19.3.6.5.log)
 * documentation  :
 *                  xsltproc is missing.
 *                  fop is missing.
 *                  xmllint is missing.
 *                  The documentation can not be built.

Erlang/OTP 19.3.6.5 (19.3.6.5) has been successfully built


$ ./kerl install 19.3.6.5 /home/e/.kerl/erlangs/19.3.6.5
Installing Erlang/OTP 19.3.6.5 (19.3.6.5) in /home/e/.kerl/erlangs/19.3.6.5...

$ . /home/e/.kerl/erlangs/19.3.6.5/activate
$ erl
Erlang/OTP 19 [erts-8.3.5.4] [source] [64-bit] [smp:20:20] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.3.5.4
1> crypto:hash(sha512, <<"12345">>).
<<54, 39, 144, ...>>
2> q().
ok

працює! ура!

the end :)

Посилання

https://github.com/kerl/kerl
https://github.com/kerl/kerl/issues/226
https://blog.differentpla.net/blog/2019/01/30/erlang-build-prerequisites/
https://blog.differentpla.net/blog/2019/01/30/installing-erlang-with-kerl/
https://www.openssl.org/source/old/1.0.2/
https://wiki.openssl.org/index.php/Compilation_and_Installation
https://devdojo.com/howtoubuntu/how-to-install-openssl-on-ubuntu
https://www.miguelvallejo.com/tag/installing-openssl-1-0-2g-on-ubuntu/

https://github.com/asdf-vm/asdf-erlang/issues/189
https://github.com/asdf-vm/asdf-erlang/issues/278
https://github.com/kerl/kerl/issues/359
https://github.com/kerl/kerl/issues/369
https://github.com/kerl/kerl/issues/347
https://github.com/asdf-vm/asdf-erlang/issues/159
https://elixirforum.com/t/erlang-otp-22-3-4-17-released/38748/4
https://elixirforum.com/t/unable-to-install-erlang-21-3-8-17-with-asdf/33668/6

https://www.erldocs.com/19.0/crypto/crypto.html?i=14&search=crypto:#hash/2