Документация Engee

Сборка Julia (подробное описание)

Скачивание исходного кода Julia

Если вы находитесь за брандмауэром, вам может потребоваться использовать протокол https вместо протокола git.

git config --global url."https://".insteadOf git://

Обязательно настройте в системе соответствующие параметры прокси-сервера, например задав переменные https_proxy и http_proxy.

Сборка Julia

При первой компиляции сборка автоматически скачает предварительно собранные внешние зависимости. Если вы предпочитаете собирать все зависимости самостоятельно или выполняете сборку в системе без доступа к сети во время процесса сборки, добавьте следующее в файл Make.user.

USE_BINARYBUILDER=0

Для сборки Julia требуется 5 Гб, если собираются все зависимости, и около 4 Гб виртуальной памяти.

Чтобы выполнить параллельную сборку, используйте make -j N и укажите максимальное количество параллельных процессов. Если настройки по умолчанию в сборке вам не подходят и нужно задать конкретные параметры (make), вы можете сохранить их в файл Make.user и поместить этот файл в корень исходного кода Julia. Сборка автоматически проверит существование файла Make.user и будет использовать его, если он существует.

Можно создавать сборки Julia вне дерева, указав make O=<build-directory> configure в командной строке. Будет создано зеркало каталога со всеми файлами Makefile, необходимыми для сборки Julia, в указанном каталоге. Эти сборки будут совместно использовать файлы исходного кода в Julia и deps/srccache. Каждый каталог сборки вне дерева может иметь собственный файл Make.user, переопределяющий глобальный файл Make.user в папке верхнего уровня.

Если все работает правильно, вы увидите баннер Julia и интерактивное окно, в которое можно вводить выражения для вычисления. (Ошибки, связанные с библиотеками, могут быть вызваны наличием старых, несовместимых библиотек в переменной PATH. В этом случае попробуйте переместить каталог julia ближе к началу PATH.) Учтите, что большинство приведенных выше инструкций относятся к системам Unix.

Чтобы запустить julia из любого места, вы можете:

  • добавить псевдоним (в bash: echo "alias julia='/path/to/install/folder/bin/julia'" >> ~/.bashrc && source ~/.bashrc), или

  • добавить гибкую ссылку на исполняемый файл julia в каталоге julia на /usr/local/bin (или любой подходящий каталог, который уже есть в пути), или

  • добавить каталог julia в путь к исполняемым файлам для этого сеанса оболочки (в bash: export PATH="$(pwd):$PATH"; в csh или tcsh: set path= ( cwd )), или

  • навсегда добавить каталог julia в путь к исполняемым файлам (например, в .bash_profile), или

  • записать prefix=/path/to/install/folder в файл Make.user, а затем запустить make install. Если в этой папке уже установлена версия Julia, перед запуском make install ее следует удалить.

Некоторые параметры, которые можно задать для управления сборкой Julia, перечислены и задокументированы в начале файла Make.inc. Но его ни в коем случае не следует редактировать для этой цели. Вместе него используйте Make.user.

Файлы Makefile в Julia определяют удобные автоматические правила print-<VARNAME> для вывода значений переменных, заменяя <VARNAME> именем переменной, значение которой нужно вывести. Например:

$ make print-JULIA_PRECOMPILE
JULIA_PRECOMPILE=1

Эти правила полезны для отладки.

Теперь вы должны иметь возможность запускать Julia следующим образом.

julia

Если вы собираете пакет Julia для распространения в ОС Linux, macOS или Windows, ознакомьтесь с подробными примечаниями в файле distributing.md.

Обновление существующего дерева исходного кода

Если вы ранее скачали julia с помощью git clone, можно обновить существующее дерево исходного кода с помощью git pull, а не начинать заново.

cd julia
git pull && make

Если предположить, что вы не внесли никаких изменений в дерево исходного кода, которые могли бы конфликтовать с обновлениями из вышестоящего репозитория, эти команды запустят обновление сборки до последней версии.

Устранение распространенных неполадок

  1. Со временем в базовой библиотеке может накопиться достаточно изменений, чтобы процесс начальной загрузки при сборке образа системы завершился сбоем. Если это происходит, сборка может завершиться с ошибкой, подобной следующей.

      *** This error is usually fixed by running 'make clean'. If the error persists, try 'make cleanall' ***

    Как уже говорилось, обычно достаточно выполнить make clean && make. Иногда требуется более сильная очистка, выполняемая с помощью make cleanall.

  2. Могут быть введены новые версии внешних зависимостей, которые время от времени могут вызывать конфликты с существующими сборками старых версий.

    А. Существуют специальные файлы make, помогающие очистить существующую сборку от зависимости . Например, make -C deps clean-llvm очистит существующую сборку llvm, так что llvm будет пересобрана из скачанного дистрибутива исходного кода при следующем вызове make. make -C deps distclean-llvm является более сильной очисткой, которая также удалит скачанный дистрибутив исходного кода, гарантируя, что будет скачана его свежая копия и что любые новые исправления будут применены при следующем вызове make.

    Б. Чтобы удалить существующие двоичные файлы julia и все ее зависимости, удалите каталог ./usr в дереве исходного кода.

  3. Если вы недавно обновили macOS, обязательно выполните команду xcode-select --install, чтобы обновить инструменты командной строки. В противном случае могут возникнуть ошибки отсутствия заголовков и библиотек, например ld: library not found for -lcrt1.10.6.o.

  4. Если вы переместили каталог исходного кода, могут возникать ошибки типа CMake Error: The current CMakeCache.txt directory ... is different than the directory ... where CMakeCache.txt was created.. В этом случае вы можете удалить конфликтующую зависимость в deps.

  5. В крайних случаях может потребоваться вернуть дерево исходного кода в начальное состояние. Могут быть полезны следующие команды git.

     git reset –hard #Принудительно удаляет любые изменения в любых файлах в системе управления версиями
     git clean -x -f -d #Принудительно удаляет любые файлы или каталоги вне системы управления версиями

Чтобы не потерять результаты своей работы, прежде чем выполнять эти команды, убедитесь, что знаете, что они делают. git не сможет отменить эти изменения!

Примечания по конкретным платформам

Примечания для различных операционных систем:

Примечания для различных архитектур:

Необходимые инструменты сборки и внешние библиотеки

Для сборки Julia необходимо установить следующее программное обеспечение:

  • GNU make  — создание зависимостей.

  • gcc & g++ (>= 7.1) or Clang (>= 5.0, >= 9.3 for Apple Clang) — компиляция и связывание C, C++.

  • libatomic  — предоставляется gcc и необходимо для поддержки атомарных операций.

  • python (>=2.7)  — необходимо для сборки LLVM.

  • gfortran  — компиляция и связывание библиотек Fortran.

  • perl  — преобразование заголовочных файлов библиотек.

  • wget, curl, or fetch (FreeBSD) — для автоматической загрузки внешних библиотек.

  • m4  — необходимо для сборки GMP.

  • awk  — вспомогательный инструмент для Makefiles.

  • patch  — для изменения исходного кода.

  • cmake (>= 3.4.3)  — необходимо для сборки libgit2.

  • pkg-config  — необходимо для правильной сборки libgit2, особенно для поддержки прокси.

  • powershell (>= 3.0)  — необходимо только в Windows.

  • which  — необходимо для проверки зависимостей сборки.

В дистрибутивах на базе Debian (например, Ubuntu) их можно легко установить с помощью apt-get:

sudo apt-get install build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config curl

Julia использует следующие внешние библиотеки, которые автоматически загружаются (или в некоторых случаях включаются в репозиторий исходного кода Julia), а затем компилируются из исходного кода при первом запуске make. Конкретные номера версий этих библиотек, которые использует Julia, перечислены в deps/$(libname).version:

  • LLVM (15.0 + patches) — инфраструктура компилятора (см. примечание ниже).

  • FemtoLisp  — поставляется в комплекте с исходным кодом Julia и используется для реализации фронт-энда компилятора.

  • libuv (custom fork) — переносимая высокопроизводительная библиотека ввода-вывода на основе событий.

  • OpenLibm  — переносимая библиотека libm, содержащая элементарные математические функции.

  • DSFMT  — быстрая библиотека генератора псевдослучайных чисел Mersenne Twister.

  • OpenBLAS  — быстрая, открытая и поддерживаемая [basic linear algebra subprograms (BLAS)]

  • LAPACK  — библиотека подпрограмм линейной алгебры для решения систем линейных уравнений, решений линейных систем уравнений по методу наименьших квадратов, задач о собственных значениях и задач о сингулярных значениях.

  • MKL (optional)  — OpenBLAS и LAPACK могут быть заменены библиотекой MKL от Intel.

  • SuiteSparse  — библиотека подпрограмм линейной алгебры для разреженных матриц.

  • PCRE  — библиотека регулярных выражений, совместимая с Perl.

  • GMP  — библиотека арифметики с множественной точностью GNU, необходимая для поддержки BigInt.

  • MPFR  — библиотека GNU для вычислений с плавающей запятой с множественной точностью, необходимая для поддержки плавающей запятой с произвольной точностью (BigFloat).

  • libgit2  — библиотека Git, используемая менеджером пакетов Julia.

  • curl  — libcurl обеспечивает поддержку загрузки и прокси.

  • libssh2  — библиотека для транспорта SSH, используемая libgit2 для пакетов с удаленными SSH.

  • mbedtls  — библиотека, используемая для криптографии и безопасности транспортного уровня, используемая libssh2.

  • utf8proc  — библиотека для обработки строк Unicode, закодированных в UTF-8.

  • LLVM libunwind  — форк LLVM от libunwind, библиотеки, которая определяет цепочку вызовов программы.

  • ITTAPI  — технология инструментирования и трассировки Intel и API Just-In-Time.

Зависимости сборки

Если в вашей системе уже установлен один или несколько из этих пакетов, вы можете запретить Julia компилировать дубликаты этих библиотек, передав USE_SYSTEM_...=1 в make или добавив эту строку в Make.user. Полный список возможных флагов можно найти в Make.inc.

Обратите внимание, что эта процедура официально не поддерживается, поскольку она вносит дополнительную изменчивость в установку и версионирование зависимостей, и рекомендуется только для системных администраторов. Могут возникнуть непредвиденные ошибки компиляции, поскольку система сборки не будет проводить дальнейшую проверку, чтобы убедиться, что установлены правильные пакеты.

LLVM

Самая сложная зависимость — LLVM, для которой нам требуются дополнительные патчи от разработчиков (LLVM не обратно совместим).

Для упаковки Julia с LLVM мы рекомендуем либо:

  • включить библиотеку LLVM только для Julia в пакет Julia, либо

  • добавить патчи в пакет LLVM дистрибутива.

    • Полный список патчей доступен на Github в ветке julia-release/15.x.

    • Единственный патч, специфичный для Julia, — это переименование библиотеки (llvm7-symver-jlprefix.patch), который не следует применять к системному LLVM.

    • Остальные патчи являются исправлениями ошибок в исходном коде и были переданы в исходный код LLVM.

Использование неисправленной или другой версии LLVM приведет к ошибкам и/или снижению производительности. Вы можете скомпилировать другую версию LLVM из удаленного репозитория Git с помощью следующих опций в файле Make.user:

# Force source build of LLVM
USE_BINARYBUILDER_LLVM = 0
# Use Git for fetching LLVM source code
# this is either `1` to get all of them
DEPS_GIT = 1
# or a space-separated list of specific dependencies to download with git
DEPS_GIT = llvm

# Other useful options:
#URL of the Git repository you want to obtain LLVM from:
#  LLVM_GIT_URL = ...
#Name of the alternate branch to clone from git
#  LLVM_BRANCH = julia-16.0.6-0
#SHA hash of the alterate commit to check out automatically
#  LLVM_SHA1 = $(LLVM_BRANCH)
#List of LLVM targets to build.  It is strongly recommended to keep at least all the
#default targets listed in `deps/llvm.mk`, even if you don't necessarily need all of them.
#  LLVM_TARGETS = ...
#Use ccache for faster recompilation in case you need to restart a build.
#  USECCACHE = 1
#  CMAKE_GENERATOR=Ninja
#  LLVM_ASSERTIONS=1
#  LLVM_DEBUG=Symbols

Различными этапами сборки управляют конкретные файлы:

  • deps/llvm.version: измените для проверки новой версии, make get-llvm check-llvm

  • deps/srccache/llvm/source-extracted: результат выполнения make extract-llvm

  • deps/llvm/build_Release*/build-configured: результат выполнения make configure-llvm

  • deps/llvm/build_Release*/build-configured: результат выполнения make compile-llvm

  • usr-staging/llvm/build_Release*.tgz: результат выполнения make stage-llvm (повторное создание с помощью make reinstall-llvm)

  • usr/manifest/llvm: результат выполнения make install-llvm (повторное создание с помощью make uninstall-llvm)

  • make version-check-llvm: запускается каждый раз, чтобы предупредить пользователя о наличии локальных изменений

Хотя Julia можно собрать с более новыми версиями LLVM, их поддержка должна рассматриваться как экспериментальная и не подходит для упаковки.

link:@id libuv[libuv]

Julia использует пользовательскую вилку libuv. Это небольшая зависимость, и ее можно смело включать в тот же пакет, что и Julia; она не будет конфликтовать с системной библиотекой. Сборки Julia не должны использовать системную вилку libuv.

link:@id BLAS-and-LAPACK[BLAS и LAPACK]

Как высокопроизводительный язык числовых вычислений Julia должна быть связана с многопоточными BLAS и LAPACK, такими как OpenBLAS или ATLAS, которые обеспечат гораздо более высокую производительность, чем эталонные реализации libblas, которые могут использоваться по умолчанию в некоторых системах.

link:@id Source-distributions-of-releases[Дистрибутивы исходного кода для выпусков]

Каждый предварительный выпуск и выпуск Julia имеет полный дистрибутив исходного кода и облегченный дистрибутив исходного кода.

Полный дистрибутив содержит исходный код Julia и все зависимости, поэтому Julia можно собрать из исходного кода без подключения к Интернету. Облегченный дистрибутив не содержит исходного кода зависимостей.

Например, julia-1.0.0.tar.gz — это облегченный дистрибутив исходного кода для выпуска v1.0.0 Julia, а julia-1.0.0-full.tar.gz — это полный дистрибутив исходного кода.

link:@id Building-Julia-from-source-with-a-Git-checkout-of-a-stdlib[Сборка Julia из исходного кода с помощью git checkout библиотеки stdlib]

Если нужно собрать Julia из исходного кода с помощью git checkout для Pkg, Tar и Downloads, используйте при сборке make DEPS_GIT=NAME_OF_STDLIB.

Например, если нужно собрать Julia из исходного кода с помощью git checkout для Pkg, используйте при сборке make DEPS_GIT=Pkg. Репозиторий Pkg находится в stdlib/Pkg и создан изначально с отключенным HEAD. Если вы выполняете сборку из уже существующего репозитория Julia, вам может потребоваться сначала выполнить очистку (make clean).

Если нужно собрать Julia из исходного кода с помощью git checkout нескольких библиотек stdlib, DEPS_GIT должен быть списком имен библиотек stdlib, разделенных пробелами. Например, если нужно собрать Julia из исходного кода с помощью git checkout для Pkg, Tar и Downloads, используйте при сборке make DEPS_GIT='Pkg Tar Downloads'.

link:@id Building-an-[Построение сборки утверждений Julia]

Сборка утверждений Julia — это сборка, которая была создана с использованием FORCE_ASSERTIONS=1 и LLVM_ASSERTIONS=1. Чтобы построить сборку утверждений, определите обе следующие переменные в файле Make.user.

FORCE_ASSERTIONS=1
LLVM_ASSERTIONS=1

Обратите внимание, что сборки утверждений Julia будут работать медленнее, чем обычные (без утверждений) сборки.

link:@id Building-32-bit-Julia-on-a-64-bit-machine[Сборка 32-разрядной версии Julia на 64-разрядном компьютере]

Иногда могут возникать ошибки, характерные для 32-разрядных архитектур. В этом случае будет полезной возможность отладки проблемы на локальном компьютере. Большинство современных 64-разрядных систем поддерживают выполнение программ, предназначенных для 32-разрядных систем. Поэтому если вам не нужно перекомпилировать Julia из исходного кода (например, вам нужно просто проверить работу 32-разрядной версии Julia, не трогая код C), то, скорее всего, вы можете использовать 32-разрядную сборку Julia для вашей системы, которую можно получить на официальной странице файлов для загрузки. Однако если вам нужно перекомпилировать Julia из исходного кода, одним из вариантов является использование контейнера Docker с 32-разрядной системой. По крайней мере пока сборка 32-разрядной версии Julia выполняется относительно просто с помощью 32-разрядных образов Docker с Ubuntu. Если вкратце, то после настройки docker необходимо выполнить следующие действия.

$ docker pull i386/ubuntu
$ docker run –platform i386 -i -t i386/ubuntu /bin/bash

На этом этапе должна быть открыта консоль 32-разрядного компьютера (обратите внимание, что команда uname сообщает архитектуру хост-компьютера, поэтому выводиться будет 64-разрядная архитектура, однако на сборку Julia это не влияет). Вы можете добавить пакеты и код компиляции; при выполнении команды exit все изменения будут утеряны, поэтому следует завершить анализ за один сеанс либо настроить копируемый скрипт для настройки среды.

Далее следует выполнить следующую команду:

# apt update

(Обратите внимание, что программа sudo не установлена, но она и не нужна, так как вы работаете с правами пользователя root и sudo во всех командах можно опускать.)

Затем добавьте все зависимости сборки, консольный редактор на ваш выбор, программу git и все, что может еще понадобиться (например, gdb, rr и т. д.). Выберите рабочий каталог, выполните команду git clone для репозитория Julia, извлеките ветвь, которую хотите отладить, и выполните сборку Julia обычным образом.

link:@id Update-the-version-number-of-a-dependency[Обновление номера версии зависимости]

Есть два типа сборок.

  1. Сборка всех компонентов (deps/ и src/) из исходного кода. (Добавьте параметр USE_BINARYBUILDER=0 в файл Make.user; см. раздел Сборка Julia.)

  2. Сборка из исходного кода (src/) с предварительно скомпилированными зависимостями (по умолчанию).

Если вы хотите обновить номер версии зависимости в deps/, воспользуйтесь следующим контрольным списком.

### Контрольный список
Version numbers:
 - [ ] `deps/$(libname).version`: `LIBNAME_VER`, `LIBNAME_BRANCH`, `LIBNAME_SHA1` and `LIBNAME_JLL_VER`
 - [ ] `stdlib/$(LIBNAME_JLL_NAME)_jll/Project.toml`: `version`

Checksum:
 - [ ] `deps/checksums/$(libname)`
 - [ ] `deps/checksums/$(LIBNAME_JLL_NAME)-*/`: `md5` and `sha512`


Patches:
 - [ ] `deps/$(libname).mk`
 - [ ] `deps/patches/$(libname)-*.patch`

Примечание.

  • Для некоторых зависимостей те или иные элементы контрольного списка могут отсутствовать.

  • Файлом контрольной суммы может быть отдельный файл без суффикса или папка, содержащая два файла.

Пример: OpenLibm

  1. Обновление номеров версий в deps/openlibm.version

    • OPENLIBM_VER := 0.X.Y

    • OPENLIBM_BRANCH = v0.X.Y

    • OPENLIBM_SHA1 = new-sha1-hash

  2. Обновление номера версии в stdlib/OpenLibm_jll/Project.toml

    • version = "0.X.Y+0"

  3. Обновление контрольных сумм в deps/checksums/openlibm

    • make -f contrib/refresh_checksums.mk openlibm

  4. Проверка существования файлов исправлений deps/patches/openlibm-*.patch

    • если исправлений нет, действие пропускается;

    • если исправления есть, проверьте, было ли выполнено их слияние с новой версией, из-за чего их нужно удалить. При удалении исправления не забудьте изменить соответствующий файл Makefile (deps/openlibm.mk).