Building Julia (Detailed)

Downloading the Julia source code

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

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

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

Building Julia

When compiled the first time, the build will automatically download pre-built external dependencies. If you prefer to build all the dependencies on your own, or are building on a system that cannot access the network during the build process, add the following in 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= ( $path $cwd ) ), или

  • добавьте директорию julia в ваш исполняемый путь навсегда (например, в .bash_profile), или
  • напишите prefix=/path/to/install/folder в Make.user, а затем выполните make install. Если в этой папке уже установлена версия Julia, вы должны удалить её перед выполнением make install.

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

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

$ make print-JULIA_PRECOMPILE
JULIA_PRECOMPILE=1

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

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

julia

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

Updating an existing source tree

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

cd julia
git pull && make

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

General troubleshooting

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

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

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

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

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

    b. Чтобы удалить существующие бинарные файлы 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 могут быть полезны:

    sh git reset --hard #Forcibly remove any changes to any files under version control git clean -x -f -d #Forcibly remove any file or directory not under version control

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

Platform-Specific Notes

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

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

Required Build Tools and External Libraries

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

  • [GNU make] — создание зависимостей.
  • [gcc & g++][gcc] (>= 7.1) или [Clang][clang] (>= 5.0, >= 9.3 для Apple Clang) — компиляция и линковка C, C++.
  • [libatomic][gcc] — предоставляется [gcc] и необходим для поддержки атомарных операций.
  • [python] (>=2.7) — необходим для сборки LLVM.
  • [gfortran] — компиляция и линковка библиотек Fortran.
  • [perl] — предварительная обработка заголовочных файлов библиотек.
  • [wget], [curl], или [fetch] (FreeBSD) — для автоматической загрузки внешних библиотек.
  • [m4] — необходимо для сборки GMP.
  • [awk] — вспомогательный инструмент для Makefile.
  • [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) — инфраструктура компилятора (см. note below).
  • [FemtoLisp] — упакован с исходным кодом Julia и используется для реализации фронтенда компилятора.
  • [libuv] (кастомный форк) — портируемая, высокопроизводительная библиотека ввода-вывода на основе событий.
  • [OpenLibm] — портируемая библиотека libm, содержащая элементарные математические функции.
  • [DSFMT] — быстрая библиотека генератора псевдослучайных чисел Mersenne Twister.
  • [OpenBLAS] — быстрые, открытые и поддерживаемые [базовые подпрограммы линейной алгебры (BLAS)]
  • [LAPACK] — библиотека рутин линейной алгебры для решения систем одновременных линейных уравнений, решений наименьших квадратов линейных систем уравнений, задач собственных значений и задач сингулярных значений.
  • [MKL] (необязательно) – 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] — форк [libunwind] от LLVM, библиотеки, которая определяет цепочку вызовов программы.
  • [ITTAPI] — Технология инструментирования и трассировки Intel и API "своевременной" компиляции.

[GNU make]: https://www.gnu.org/software/make [patch]: https://www.gnu.org/software/patch [wget]: https://www.gnu.org/software/wget [m4]: https://www.gnu.org/software/m4 [awk]: https://www.gnu.org/software/gawk [gcc]: https://gcc.gnu.org [clang]: https://clang.llvm.org [python]: https://www.python.org/ [gfortran]: https://gcc.gnu.org/fortran/ [curl]: https://curl.haxx.se [fetch]: https://www.freebsd.org/cgi/man.cgi?fetch(1) [perl]: https://www.perl.org [cmake]: https://www.cmake.org [OpenLibm]: https://github.com/JuliaLang/openlibm [DSFMT]: https://github.com/MersenneTwister-Lab/dSFMT [OpenBLAS]: https://github.com/xianyi/OpenBLAS [LAPACK]: https://www.netlib.org/lapack [MKL]: https://software.intel.com/en-us/articles/intel-mkl [SuiteSparse]: https://people.engr.tamu.edu/davis/suitesparse.html [PCRE]: https://www.pcre.org [LLVM]: https://www.llvm.org [LLVM libunwind]: https://github.com/llvm/llvm-project/tree/main/libunwind [FemtoLisp]: https://github.com/JeffBezanson/femtolisp [GMP]: https://gmplib.org [MPFR]: https://www.mpfr.org [libuv]: https://github.com/JuliaLang/libuv [libgit2]: https://libgit2.org/ [utf8proc]: https://julialang.org/utf8proc/ [libunwind]: https://www.nongnu.org/libunwind [libssh2]: https://www.libssh2.org [mbedtls]: https://tls.mbed.org/ [pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ [powershell]: https://docs.microsoft.com/en-us/powershell/scripting/wmf/overview [which]: https://carlowood.github.io/which/ [ITTAPI]: https://github.com/intel/ittapi

Build dependencies

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

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

LLVM

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

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

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

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

    • Полный список патчей доступен по адресу Github, смотрите ветку julia-release/15.x.
    • Единственный патч, специфичный для Julia, — это переименование библиотеки (llvm7-symver-jlprefix.patch), который не должен применяться к системному LLVM.
    • Оставшиеся патчи — это все исправления ошибок в upstream, которые были внесены в upstream 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, поддержка этого должна рассматриваться как экспериментальная и не подходит для упаковки.

libuv

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

BLAS and LAPACK

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

Source distributions of releases

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

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

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

Building Julia from source with a Git checkout of a stdlib

Если вам нужно собрать Julia из исходников с помощью Git-клона стандартной библиотеки, используйте make DEPS_GIT=NAME_OF_STDLIB при сборке Julia.

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

Если вам нужно собрать Julia из исходников с Git-клонами более одной стандартной библиотеки, то DEPS_GIT должен быть списком имен стандартных библиотек, разделенных пробелами. Например, если вам нужно собрать Julia из исходников с Git-клоном Pkg, Tar и Downloads, то используйте make DEPS_GIT='Pkg Tar Downloads' при сборке Julia.

Building an "assert build" of Julia

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

FORCE_ASSERTIONS=1
LLVM_ASSERTIONS=1

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

Building 32-bit Julia on a 64-bit machine

Иногда могут возникать ошибки, специфичные для 32-битных архитектур, и когда это происходит, полезно иметь возможность отладить проблему на вашем локальном компьютере. Поскольку большинство современных 64-битных систем поддерживают запуск программ, созданных для 32-битных, если вам не нужно перекомпилировать Julia из исходников (например, вам в основном нужно проверить поведение 32-битной Julia, не трогая C-код), вы, вероятно, сможете использовать 32-битную сборку Julia для вашей системы, которую можно получить из official downloads page. Однако, если вам действительно нужно перекомпилировать Julia из исходников, одним из вариантов является использование контейнера Docker 32-битной системы. По крайней мере, на данный момент создание 32-битной версии Julia относительно просто с использованием ubuntu 32-bit docker images. Вкратце, после настройки 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 во всех командах.)

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

Update the version number of a dependency

Существует два типа сборок

  1. Соберите все (deps/ и src/) из исходного кода. (Добавьте USE_BINARYBUILDER=0 в Make.user, см. Building Julia)
  2. Собрать из исходников (src/) с предкомпилированными зависимостями (по умолчанию)

Когда вы хотите обновить номер версии зависимости в deps/, вам может понадобиться использовать следующий контрольный список:

### Check list

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`

Примечание:

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

Example: 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).