# Компиляция Manticore из исходных кодов

Компиляция Manticore Search из исходных кодов позволяет настраивать сборку, например, отключать определенные функции или добавлять патчи для тестирования. Например, вы можете захотеть скомпилировать из исходных кодов и отключить встроенную ICU, чтобы использовать другую версию, установленную в вашей системе, которую можно обновлять независимо от Manticore. Это также полезно, если вы заинтересованы в участии в проекте Manticore Search.

## Сборка с использованием Docker CI
Для подготовки [официальных релизных и development-пакетов](https://repo.manticoresearch.com/) мы используем Docker и специальный образ для сборки. Этот образ включает в себя необходимый инструментарий и предназначен для работы с внешними sysroot, поэтому один контейнер может собирать пакеты для всех операционных систем. Вы можете собрать образ, используя [Dockerfile](https://github.com/manticoresoftware/manticoresearch/blob/main/dist/build_dockers/cross/external_toolchain/Dockerfile) и [README](https://github.com/manticoresoftware/manticoresearch/blob/main/dist/build_dockers/README.md), или использовать образ из [Docker Hub](https://hub.docker.com/r/manticoresearch/external_toolchain/tags). Это самый простой способ создания бинарных файлов для любой поддерживаемой операционной системы и архитектуры. Вам также потребуется указать следующие переменные окружения при запуске контейнера:

* `DISTR`: целевая платформа: `bionic`, `focal`, `jammy`, `buster`, `bullseye`, `bookworm`, `rhel8`, `rhel9`, `rhel10`, `macos`, `windows`, `freebsd13`
* `arch`: архитектура: `x86_64`, `x64` (для Windows), `aarch64`, `arm64` (для Macos)
* `SYSROOT_URL`: URL-адрес архивов системных корней. Вы можете использовать https://repo.manticoresearch.com/repository/sysroots, если не собираете sysroot самостоятельно (инструкции можно найти [здесь](https://github.com/manticoresoftware/manticoresearch/tree/main/dist/build_dockers/cross/sysroots)).
* Используйте файлы рабочих процессов CI в качестве справочника, чтобы найти другие переменные окружения, которые могут вам понадобиться:
  - https://github.com/manticoresoftware/manticoresearch/blob/main/.github/workflows/pack_publish.yml
  - https://github.com/manticoresoftware/manticoresearch/blob/main/.github/workflows/build_template.yml

Чтобы найти возможные значения для `DISTR` и `arch`, вы можете использовать каталог https://repo.manticoresearch.com/repository/sysroots/roots_with_zstd/ в качестве справочника, так как он включает системные корни для всех поддерживаемых комбинаций.

После этого сборка пакетов внутри Docker-контейнера так же проста, как вызов:

```bash
cmake -DPACK=1 /path/to/sources
cmake --build .
```

Например, чтобы создать пакет для Ubuntu Jammy, аналогичный официальной версии, предоставляемой командой Manticore Core, вы должны выполнить следующие команды в каталоге, содержащем исходные коды Manticore Search. Этот каталог является корнем клонированного репозитория из https://github.com/manticoresoftware/manticoresearch:

```bash
docker run -it --rm \
-e CACHEB="../cache" \
-e DIAGNOSTIC=1 \
-e PACK_ICUDATA=0 \
-e NO_TESTS=1 \
-e DISTR=jammy \
-e boost=boost_nov22 \
-e sysroot=roots_nov22 \
-e arch=x86_64 \
-e CTEST_CMAKE_GENERATOR=Ninja \
-e CTEST_CONFIGURATION_TYPE=RelWithDebInfo \
-e WITH_COVERAGE=0 \
-e SYSROOT_URL="https://repo.manticoresearch.com/repository/sysroots" \
-e HOMEBREW_PREFIX="" \
-e PACK_GALERA=0 \
-e UNITY_BUILD=1 \
-v $(pwd):/manticore_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
manticoresearch/external_toolchain:vcpkg331_20260310 bash

# following is to be run inside docker shell
cd /manticore_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/
mkdir build && cd build
cmake -DPACK=1 ..
cmake --build .
# or if you want to build packages:
# cmake --build . --target package
```
Длинный путь к исходному каталогу требуется, иначе в некоторых случаях (например, в Centos) сборка исходных кодов может завершиться неудачей.

Таким же образом вы можете собирать бинарные файлы или пакеты не только для популярных дистрибутивов Linux, но и для FreeBSD, Windows и macOS.

#### Сборка SRPM с использованием Docker

Вы также можете использовать тот же специальный образ Docker для сборки SRPM:

```bash
docker run -it --rm \
-e CACHEB="../cache" \
-e DIAGNOSTIC=1 \
-e PACK_ICUDATA=0 \
-e NO_TESTS=1 \
-e DISTR=rhel8 \
-e boost=boost_rhel_feb17 \
-e sysroot=roots_nov22 \
-e arch=x86_64 \
-e CTEST_CMAKE_GENERATOR=Ninja \
-e CTEST_CONFIGURATION_TYPE=RelWithDebInfo \
-e WITH_COVERAGE=0 \
-e SYSROOT_URL="https://repo.manticoresearch.com/repository/sysroots" \
-e HOMEBREW_PREFIX="" \
-e PACK_GALERA=0 \
-e UNITY_BUILD=1 \
-v $(pwd):/manticore_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
manticoresearch/external_toolchain:vcpkg331_20260310 bash

# following is to be run inside docker shell
cd /manticore_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/
mkdir build && cd build
cmake -DPACK=1 ..
# The CPackSourceConfig.cmake file is now generated in the build directory
cpack -G RPM --config ./CPackSourceConfig.cmake
```

Это сгенерирует RPM с исходным кодом (`.src.rpm` файл), содержащий весь исходный код.

#### Сборка бинарных RPM из SRPM

После того как вы сгенерировали SRPM, вы можете использовать его для сборки полного набора бинарных RPM-пакетов:

```bash
# Install build tools and dependencies
dnf install -y rpm-build cmake gcc-c++ boost-devel epel-release

# Install SRPM dependencies automatically
dnf builddep -y manticore-*.src.rpm

# Build all binary RPMs from the SRPM
rpmbuild --rebuild manticore-*.src.rpm

# Find the generated packages
ls ~/rpmbuild/RPMS/*/manticore*
```

> ПРИМЕЧАНИЕ: **Для сборки RPM из SRPM необходимо убедиться, что все зависимости, перечисленные в SRPM, полностью установлены, что может быть сложной задачей.** SRPM все еще может быть полезен для:
> - Аудита процесса сборки или проверки исходных и спецификационных файлов
> - Внесения пользовательских изменений или патчей в сборку
> - Понимания того, как были созданы бинарные файлы
> - Соответствия требованиям лицензий с открытым исходным кодом

## Ручная сборка

Компиляция Manticore без использования Docker для сборки **не рекомендуется**, но если вам нужно это сделать, вот что вам может понадобиться знать:

### Необходимые инструменты

* Компилятор C++
  * В Linux - можно использовать GNU (4.7.2 и выше) или Clang
  * В Windows - Microsoft Visual Studio 2019 и выше (достаточно Community Edition)
  * На macOS - Clang (из инструментов командной строки XCode, используйте `xcode-select --install` для установки).
* Bison, Flex - в большинстве систем они доступны в виде пакетов, в Windows они доступны в рамках cygwin.
* Cmake - используется на всех платформах (требуется версия 3.19 или выше)

### Получение исходных кодов

#### Из git

Исходный код Manticore [размещен на GitHub](https://github.com/manticoresoftware/manticoresearch).
Чтобы получить исходный код, клонируйте репозиторий, а затем переключитесь на нужную ветку или тег. Ветка `main` представляет основную ветку разработки. При выпуске релиза создаётся версионный тег, например `3.6.0`, и начинается новая ветка для текущего релиза, в данном случае `manticore-3.6.0`. Голова версионной ветки после всех изменений используется в качестве источника для сборки всех бинарных релизов. Например, чтобы взять исходники версии 3.6.0, вы можете выполнить:

```bash
git clone --recurse-submodules https://github.com/manticoresoftware/manticoresearch.git
cd manticoresearch
git checkout manticore-3.6.0
git submodule update --init --recursive
```

#### Из архива

Git — рекомендуемый способ получить исходники, потому что Manticore зависит от подмодуля `mcl`. Архивы .zip и .tar.gz, созданные GitHub, не содержат содержимое подмодулей, поэтому настройка из такого архива завершится ошибкой, если только вы не заполните каталог `mcl` соответствующей ревизией [MCL](https://github.com/manticoresoftware/columnar).

```bash
wget -c https://github.com/manticoresoftware/manticoresearch/archive/refs/tags/3.6.0.tar.gz
tar -zxf 3.6.0.tar.gz
cd manticoresearch-3.6.0
# Populate ./mcl with the matching columnar/MCL revision before running cmake.
```

### Конфигурация

Manticore использует CMake. Предполагая, что вы находитесь в корневом каталоге клонированного репозитория:

```bash
mkdir build && cd build
cmake -DMCL_LOCAL_RUNTIME=OFF ..
```

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

Дерево исходников MCL берется из git-подмодуля `mcl`. Команда выше использует заголовки MCL API из этого подмодуля, но не собирает локальные модули выполнения MCL. Если подмодуль отсутствует, CMake остановится с ошибкой и предложит выполнить `git submodule update --init --recursive mcl`.

Чтобы также собрать локальные модули выполнения MCL из подмодуля, настройте сборку так:

```bash
cmake -DMCL_LOCAL_RUNTIME=ON ..
```

Это собирает `columnar_lib`, `secondary_index`, `knn_lib` и библиотеку embeddings вместе с Manticore. В Windows эти цели видны в сгенерированном решении Visual Studio. Этот режим требует Rust и Cargo для библиотеки embeddings, если только вы не укажете уже существующую библиотеку embeddings с `-DMANTICORE_KNN_EMBEDDINGS_LIB=/path/to/lib_manticore_knn_embeddings.so` (или `.dll` в Windows).

Вы также можете явно настроить сборку с помощью флагов и опций. Чтобы включить функцию `FOO`, добавьте `-DFOO=1` к вызову CMake.
Чтобы отключить её, используйте `-DFOO=0`. Если не указано явно, включение функции, которая недоступна (например, `WITH_GALERA` в сборке для MS Windows), приведет к ошибке конфигурации. Отключение функции, помимо исключения её из сборки, также отключает её проверку в системе и отключает загрузку/сборку любых связанных внешних библиотек.

#### Флаги и опции конфигурации

- **USE_SYSLOG** - позволяет использовать `syslog` в [логировании запросов](../Logging/Query_logging.md).
- **WITH_GALERA** -Включает поддержку репликации в демоне поиска. Поддержка будет настроена при сборке, а исходники библиотеки Galera будут загружены, собраны, и включены в дистрибутив/установку. Обычно безопасно собирать с Galera, но не распространять саму библиотеку (т.е. без модуля Galera, без репликации). Однако иногда может потребоваться явное отключение, например если нужно собрать статичный бинарник, который по замыслу не может загружать никакие библиотеки, так что даже присутствие вызова функции 'dlopen' внутри демона приведёт к ошибке на этапе линковки.
- **WITH_RE2** - Сборка с использованием библиотеки регулярных выражений RE2. Это необходимо для функций вроде [REGEX()](../Functions/String_functions.md#REGEX%28%29), и для [regexp_filter](../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#regexp_filter)
  функциональности.
- **WITH_RE2_FORCE_STATIC** - Загружает исходники RE2, компилирует их и статически линкует, так что итоговые бинарные файлы не будут зависеть от наличия общей `RE2` библиотеки в вашей системе.
- **WITH_STEMMER** - Сборка с использованием библиотеки Snowball для стемминга.
- **WITH_STEMMER_FORCE_STATIC** - Загружает исходники Snowball, компилирует их и статически линкует, так что итоговые бинарные файлы не будут зависеть от наличия общей `libstemmer` библиотеки в вашей системе.
- **WITH_ICU** -  Сборка с библиотекой ICU (International Components for Unicode). Она используется для сегментации китайского текста. Применяется при установке morphology=`icu_chinese`.
- **WITH_JIEBA** -  Сборка с использованием инструмента сегментации китайского текста Jieba. Он используется для сегментации китайского текста. Применяется при установке morphology=`jieba_chinese`.
- **WITH_ICU_FORCE_STATIC** - Загружает исходники ICU, компилирует их и статически линкует, так что итоговые бинарные файлы не будут зависеть от наличия общей `icu` библиотеки в вашей системе. Также включает файл данных ICU в установку/дистрибутив. Цель статической связи ICU — иметь библиотеку известной версии, чтобы поведение было определено и не зависело от системных библиотек. Скорее всего, вы предпочтёте использовать системную ICU, так как она может обновляться со временем без необходимости перекомпиляции демона Manticore. В этом случае нужно явно отключить эту опцию. Это также сэкономит место, занимаемое файлом данных ICU (примерно 30M), так как он не будет включён в дистрибутив.
- **WITH_SSL** - Используется для поддержки HTTPS, а также зашифрованных подключений MySQL к демону. Системная библиотека OpenSSL будет связана с демоном. Это означает, что для запуска демона потребуется OpenSSL. Это обязательно для поддержки HTTPS, но не строго обязательно для сервера (т.е. отсутствие SSL означает невозможность подключения по HTTPS, но остальные протоколы будут работать). Библиотеки SSL версий от 1.0.2 до 1.1.1 могут использоваться Manticore, однако обратите внимание, что **ради безопасности настоятельно рекомендуется использовать самую свежую SSL
  библиотеку**. Пока что поддерживается только v1.1.1, остальные устарели (
  см. [стратегию выпусков openssl](https://www.openssl.org/policies/releasestrat.html)
- **WITH_ZLIB** - используется индексером для работы с сжатыми столбцами из MySQL. Используется демоном для поддержки сжатого протокола MySQL.
- **WITH_ODBC** - используется индексером для поддержки индексирования источников из провайдеров ODBC (обычно это UnixODBC и iODBC). В MS Windows ODBC является правильным способом работы с источниками MS SQL, поэтому индексирование `MSSQL` также подразумевает этот флаг.
- **DL_ODBC** - не линкуется с библиотекой ODBC. Если ODBC связана, но недоступна, вы не сможете запустить инструмент indexer даже если хотите обработать что-то не связанное с ODBC. Этот параметр заставляет indexer загружать библиотеку во время выполнения только тогда, когда вы хотите работать с источником ODBC.
- **ODBC_LIB** - имя файла библиотеки ODBC. Indexer будет пытаться загрузить этот файл, когда вы захотите обработать источник ODBC. Этот параметр автоматически определяется на основе исследования доступных общих библиотек ODBC. Вы также можете переопределить это имя во время выполнения, задав переменную окружения `ODBC_LIB` с правильным путем к альтернативной библиотеке перед запуском indexer.
- **WITH_EXPAT** - используется индексером для поддержки индексирования источников xmlpipe.
- **DL_EXPAT** - не линкуется с библиотекой EXPAT. Если EXPAT связана, но недоступна, вы не сможете запустить инструмент `indexer` даже если хотите обработать что-то не связанное с xmlpipe. Этот параметр заставляет indexer загружать библиотеку во время выполнения только тогда, когда вы хотите работать с источником xmlpipe.
- **EXPAT_LIB** - имя файла библиотеки EXPAT. Indexer попытается загрузить этот файл, когда вы захотите обработать источник xmlpipe. Этот параметр автоматически определяется из анализа доступных общих библиотек EXPAT. Вы также можете переопределить это имя во время выполнения, задав переменную окружения EXPAT_LIB с правильным путем к альтернативной библиотеке перед запуском indexer.
- **WITH_ICONV** - для поддержки различных кодировок при индексировании источников xmlpipe с помощью indexer.
- **DL_ICONV** - не линкуется с библиотекой iconv. Если iconv связана, но недоступна, вы не сможете запустить инструмент `indexer` даже если хотите обработать что-то не связанное с xmlpipe. Этот параметр заставляет indexer загружать библиотеку во время выполнения только тогда, когда вы хотите работать с источником xmlpipe.
- **ICONV_LIB** - имя файла библиотеки iconv. Indexer попытается загрузить этот файл, когда вы захотите обработать источник xmlpipe. Этот параметр автоматически определяется из анализа доступных общих библиотек iconv. Вы также можете переопределить это имя во время выполнения, задав переменную окружения `ICONV_LIB` с правильным путем к альтернативной библиотеке перед запуском indexer.
- **WITH_MYSQL** - используется индексером для поддержки индексирования источников MySQL.
- **DL_MYSQL** - не линкуется с библиотекой MySQL. Если MySQL связана, но недоступна, вы не сможете запустить инструмент`indexer` даже если хотите обработать что-то не связанное с MySQL. Этот параметр заставляет indexer загружать библиотеку во время выполнения только тогда, когда вы хотите работать с источником MySQL.
- **MYSQL_LIB** -- имя файла библиотеки MySQL. Indexer будет пытаться загрузить этот файл, когда вы захотите обработать источник MySQL. Этот параметр автоматически определяется из анализа доступных общих библиотек MySQL. Вы также можете переопределить это имя во время выполнения, задав переменную окружения `MYSQL_LIB` с правильным путем к альтернативной библиотеке перед запуском indexer.
- **WITH_POSTGRESQL** - используется индексером для поддержки индексирования источников PostgreSQL.
- **DL_POSTGRESQL** - не линкуется с библиотекой PostgreSQL. Если PostgreSQL связана, но недоступна, вы не сможете запустить инструмент `indexer` ool даже если хотите обработать что-то не связанное с PostgreSQL. Этот параметр заставляет indexer загружать библиотеку во время выполнения только тогда, когда вы хотите работать с источником PostgreSQL.
- **POSTGRESQL_LIB** - имя файла библиотеки postgresql. Indexer будет пытаться загрузить указанный файл библиотеки postgresql при обработке источника postgresql. Этот параметр автоматически определяется из анализа доступных общих библиотек postgresql. Вы также можете переопределить это имя во время выполнения, задав переменную окружения  `POSTGRESQL_LIB` с правильным путем к альтернативной библиотеке перед запуском indexer.
- **LOCALDATADIR** - путь по умолчанию, где демон хранит binlogs. Если этот путь не задан или явно отключен в runtime-конфигурации демона (т.е. файл `manticore.conf`, который не связан с этой конфигурацией сборки), binlogs будут помещены в этот путь. Обычно это абсолютный путь, однако он не обязан быть таковым, допускаются и относительные пути. Скорее всего, вам не потребуется изменять значение по умолчанию, определённое конфигурацией, которое, в зависимости от целевой системы, может быть чем-то вроде `/var/data`, `/var/lib/manticore/data` или `/usr/local/var/lib/manticore/data`.
- **FULL_SHARE_DIR** - путь по умолчанию, где хранятся все ресурсы. Он может быть переопределён переменной окружения `FULL_SHARE_DIR` перед запуском любого инструмента, использующего файлы из этой папки. Это важный путь, так как там по умолчанию ожидается найти множество вещей. Сюда входят предопределённые таблицы кодировок, стоп-слова, модули manticore и файлы данных icu, все помещённые в эту папку. Скрипт конфигурации обычно определяет этот путь как что-то вроде `/usr/share/manticore` или `/usr/local/share/manticore`.
- **DISTR_BUILD** - ярлык для опций создания пакетов. Это строковое значение с названием целевой платформы. Оно может использоваться вместо ручной настройки всех опций. В Debian и Redhat Linux значение по умолчанию может быть определено путём лёгкой инспекции и установлено как обобщённое 'Debian' или 'RHEL'. В противном случае значение не определяется.
- **PACK** - ещё более удобный ярлык. Он читает переменную окружения `DISTR`, присваивает её параметру **DISTR_BUILD** и затем работает как обычно. Это очень полезно при сборке в подготовленных системах сборки, таких как контейнеры Docker, где переменная `DISTR` задаётся на уровне системы и отражает целевую систему, для которой предназначен контейнер.
- **MCL_LOCAL_RUNTIME** - управляет тем, будут ли при локальной немакетной сборке также собираться модули выполнения MCL из подмодуля `mcl`. Установите `OFF` для базовой сборки демона, описанной выше, или `ON`, если нужно также собирать локальные модули выполнения MCL.
- **MCL_RUNTIME_ARTIFACT_DIR** - путь к каталогу с заранее собранными модулями выполнения MCL. Это в основном используется в CI-тестах, которые собирают или восстанавливают артефакты MCL с точным SHA, а затем запускают против них тесты демона.
- **BUILD_EMBEDDINGS_LOCALLY** - управляет тем, будет ли библиотека embeddings MCL собираться локально. Для локальных сборок runtime по умолчанию имеет значение `ON`, если только `MANTICORE_KNN_EMBEDDINGS_LIB` уже не задана.
- **MANTICORE_KNN_EMBEDDINGS_LIB** - путь к существующей библиотеке embeddings. Используйте его, когда хотите переиспользовать заранее собранную библиотеку `lib_manticore_knn_embeddings` вместо того, чтобы собирать ее через Cargo.
- **CMAKE_INSTALL_PREFIX** (path) - путь, куда предполагается установить Manticore. Сборка не выполняет установку, но подготавливает правила установки, которые выполняются при запуске команды `cmake --install` или при создании пакета и последующей его установке. Префикс может быть изменён в любой момент, даже во время установки, вызовом
  `cmake --install . --prefix /path/to/installation`. Однако на этапе конфигурирования эта переменная используется для инициализации значений по умолчанию для `LOCALDATADIR` и `FULL_SHARE_DIR`. Например, установка её в `/my/custom` на этапе конфигурирования
  приведёт к тому, что `LOCALDATADIR` будет жёстко задан как `/my/custom/var/lib/manticore/data`, а `FULL_SHARE_DIR` как
  `/my/custom/usr/share/manticore`.
- **BUILD_TESTING** (bool) нужна ли поддержка тестирования. Если включено, после сборки вы можете запустить 'ctest' и протестировать сборку. Обратите внимание, что тестирование подразумевает дополнительные зависимости, такие как наличие PHP cli, Python и доступного сервера MySQL с тестовой базой. По умолчанию этот параметр включён. Поэтому для 'просто сборки' вы можете отключить опцию, явно указав значение 'off'.
- **BUILD_SRPMS** (bool) показывать ли инструкции по сборке Source RPMs (SRPMs). Из-за ограничений CPack при компонентном упаковке SRPMs не могут быть сгенерированы напрямую вместе с бинарными RPM. При включении система сборки будет выводить инструкции по правильной генерации SRPM с использованием метода конфигурирования исходников. По умолчанию этот параметр выключен.
- **LIBS_BUNDLE** - путь к папке с различными библиотеками. Это в основном актуально для сборки в Windows, но может быть полезно и в других случаях, чтобы не загружать сторонние исходники каждый раз. По умолчанию этот путь не меняется скриптом конфигурации; вы должны вручную помещать всё туда. Когда, скажем, нужна поддержка стеммера, исходники будут загружены с сайта Snowball, затем распакованы, сконфигурированы, собраны и т.д. Вместо этого вы можете поместить оригинальный архив исходников (который имеет имя `libstemmer_c.tgz`) в эту папку. В следующий раз при сборке с нуля скрипт конфигурации сначала проверит бандл, и если найдёт там стеммер, он не загрузит его снова из интернета.
- **CACHEB** - путь к папке со сохранёнными сборками сторонних библиотек. Обычно такие компоненты, как galera, re2, icu и т.д., сначала загружаются или берутся из бандла, затем распаковываются, собираются и устанавливаются во временную внутреннюю папку. При сборке manticore эта папка затем используется как место, где располагаются необходимые для поддержки запрошенной функции элементы. В конце они либо линкуются с manticore (если это библиотека), либо идут прямо в дистрибутив/установку (например, galera или данные icu). Когда **CACHEB** задана либо как параметр конфигурации cmake, либо как переменная окружения, она используется в качестве целевой папки для этих сборок. Эту папку можно сохранять между сборками, чтобы расположенные там библиотеки больше не пересобирались, что значительно сокращает время всей сборки.


Обратите внимание, что некоторые опции организованы в тройки: `WITH_XXX`, `DL_XXX` и `XXX_LIB` — например, поддержка mysql, odbc и т.д. `WITH_XXX` определяет, будут ли действовать следующие две. Т.е., если вы установите `WITH_ODBC` в `0` — нет смысла указывать `DL_ODBC` и `ODBC_LIB`, и эти две опции не будут иметь эффекта, если вся функция отключена. Также `XXX_LIB` не имеет смысла без `DL_XXX`, потому что если вам не нужна опция `DL_XXX`, динамическая загрузка использоваться не будет, и имя, указанное в `XXX_LIB`, бесполезно. Это используется при интроспекции по умолчанию.

Также, использование библиотеки `iconv` предполагает наличие `expat` и бесполезно, если последний отключен.

Кроме того, некоторые библиотеки могут быть всегда доступны, и поэтому нет смысла избегать линковки с ними. Например, в Windows это ODBC. В macOS это Expat, iconv и, возможно, другие. Интроспекция по умолчанию определяет такие библиотеки и фактически выдает только `WITH_XXX` для них, без `DL_XXX` и `XXX_LIB`, что упрощает ситуацию.

При использовании некоторых опций конфигурация может выглядеть так:

```bash
mkdir build && cd build
cmake -DWITH_MYSQL=1 -DWITH_RE2=1 ..
```

Помимо общих значений конфигурации, вы также можете изучить файл `CMakeCache.txt`, который остается в папке сборки сразу после запуска конфигурации. Любые значения, определенные там, могут быть переопределены явно при запуске cmake. Например, вы можете запустить `cmake -DHAVE_GETADDRINFO_A=FALSE ...`, и эта конфигурация не будет использовать исследованное значение этой переменной, а будет использовать предоставленное вами.

#### Специфичные переменные окружения

Переменные окружения полезны для предоставления некоторых глобальных настроек, которые хранятся отдельно от конфигурации сборки и всегда присутствуют. Для постоянства их можно установить глобально в системе разными способами — например, добавив их в файл `.bashrc`, или встроив в Dockerfile, если вы создаете систему сборки на основе Docker, или записав их в переменные окружения системных настроек в Windows. Также вы можете установить их на короткое время, используя `export VAR=value` в оболочке. Или даже короче, добавив значения перед вызовом cmake, например, `CACHEB=/my/cache cmake ...` — таким образом, это будет работать только при этом вызове и не будет видно при следующем.

Некоторые из таких переменных, как известно, используются в целом cmake и некоторыми другими инструментами. Это такие вещи, как `CXX`, который определяет текущий компилятор C++, или `CXX_FLAGS` для предоставления флагов компилятора и т.д.

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

- **CACHEB** — то же, что опция конфигурации **CACHEB**
- **LIBS_BUNDLE** — то же, что опция конфигурации **LIBS_BUNDLE**
- **DISTR** — используется для инициализации опции `DISTR_BUILD`, когда используется `-DPACK=1`.
- **DIAGNOSTIC** — делает вывод конфигурации cmake гораздо более подробным, объясняя все происходящее
- **WRITEB** — предполагает **LIBS_BUNDLE** и, если установлено, будет загружать архивные файлы исходного кода для различных инструментов в папку LIBS_BUNDLE. То есть, если выходит новая версия стеммера — вы можете вручную удалить libstemmer_c.tgz из бандла, а затем запустить одноразовый `WRITEB=1 cmake ...` — он не найдет исходники стеммера в бандле и затем загрузит их с сайта поставщика в бандл (без WRITEB он загрузит их во временную папку внутри сборки, и они исчезнут, когда вы очистите папку сборки).

В конце конфигурации вы можете увидеть, что доступно и будет использовано, в списке, подобном этому:

```
-- Enabled features compiled in:
* Galera, replication of tables
* re2, a regular expression library
* stemmer, stemming library (Snowball)
* icu, International Components for Unicode
* OpenSSL, for encrypted networking
* ZLIB, for compressed data and networking
* ODBC, for indexing MSSQL (windows) and generic ODBC sources with indexer
* EXPAT, for indexing xmlpipe sources with indexer
* Iconv, for support of different encodings when indexing xmlpipe sources with indexer
* MySQL, for indexing MySQL sources with indexer
* PostgreSQL, for indexing PostgreSQL sources with indexer
```

### Сборка

```bash
cmake --build . --config RelWithDebInfo
```

### Установка

Для установки выполните:

```bash
cmake --install . --config RelWithDebInfo
```

чтобы установить в пользовательскую (не по умолчанию) папку, выполните

```bash
cmake --install . --prefix path/to/build --config RelWithDebInfo
```

### Сборка пакетов

Для сборки пакета используйте цель `package`. Она соберет пакет в соответствии с выбором, предоставленным опцией `-DDISTR_BUILD`. По умолчанию это будет простой архив .zip или .tgz со всеми бинарными файлами и дополнительными файлами.

```bash
cmake --build . --target package --config RelWithDebInfo
```

## Некоторые продвинутые вещи о сборке

### Перекомпиляция (обновление) при одноконфигурационной сборке

Если вы не меняли путь к исходникам и сборке, просто перейдите в папку сборки и выполните:

```bash
cmake .
cmake --build . --clean-first --config RelWithDebInfo
```

Если по какой-либо причине это не работает, вы можете удалить файл `CMakeCache.txt`, расположенный в папке сборки. После этого шага вам придется снова запустить cmake, указав папку с исходниками и настроив опции.

Если это тоже не помогает, просто очистите папку сборки и начните с нуля.

### Типы сборки

Кратко — просто используйте `--config RelWithDebInfo`, как написано выше. Это не даст ошибиться.

Мы используем два типа сборки. Для разработки это `Debug` — он назначает флаги компилятора для оптимизации и другие вещи таким образом, что это очень удобно для разработки, подразумевая отладку с пошаговым выполнением. Однако полученные бинарные файлы довольно большие и медленные для производства.

Для выпуска релизов мы используем другой тип — `RelWithDebInfo` — что означает 'сборка релиза с отладочной информацией'. Он производит бинарные файлы для производства со встроенной отладочной информацией. Последняя затем отделяется в отдельные пакеты debuginfo, которые хранятся отдельно от релизных пакетов и могут быть использованы в случае некоторых проблем, таких как сбои — для расследования и исправления ошибок. Cmake также предоставляет `Release` и `MinSizeRel`, но мы их не используем. Если тип сборки недоступен, cmake выполнит сборку `noconfig`.

#### Генераторы системы сборки

Существует два типа генераторов: одноконфигурационные и многоконфигурационные.

- Одноконфигурационным требуется тип сборки, предоставленный во время конфигурации, через параметр `CMAKE_BUILD_TYPE`. Если он не определен, сборка вернется к типу `RelWithDebInfo`, который подходит, если вы просто хотите собрать Manticore из исходников и не участвовать в разработке. Для явных сборок вы должны предоставить тип сборки, например, `-DCMAKE_BUILD_TYPE=Debug`.
- Многоконфигурационный выбирает тип сборки во время сборки. Он должен быть предоставлен с опцией `--config`, иначе он соберет что-то вроде `noconfig`, что нежелательно. Поэтому вы всегда должны указывать тип сборки, например, `--config Debug`.

Если вы хотите указать тип сборки, но не хотите заботиться о том, является генератор 'single' или 'multi' config - просто предоставьте необходимые ключи в обоих местах. То есть, конфигурируйте с `-DCMAKE_BUILD_TYPE=Debug`, а затем собирайте с `--config Debug`. Убедитесь, что обе значения одинаковы. Если целевой сборщик одноконфигурационный, он будет использовать параметр конфигурации. Если он многоконфигурационный, параметр конфигурации будет игнорироваться, но правильная конфигурация сборки будет выбрана ключом `--config`.

Если вам нужен `RelWithDebInfo` (то есть просто сборка для производства) и вы знаете, что работаете на одноконфигурационной платформе (это все, кроме Windows) - вы можете опустить флаг `--config` при вызове cmake. Тогда будет настроен и использован стандартный `CMAKE_BUILD_TYPE=RelWithDebInfo`. Все команды для 'сборки', 'установки' и 'сборки пакета' станут тогда более короткими.

#### Явный выбор генераторов системы сборки

CMake это инструмент, который не выполняет сборку самостоятельно, но генерирует правила для локальной системы сборки.
Обычно он хорошо определяет доступную систему сборки, но иногда вам может потребоваться явно указать генератор.
Вы можете запустить `cmake -G` и просмотреть список доступных генераторов.

- На Windows, если у вас установлено более одной версии Visual Studio, вам может потребоваться указать, которую использовать,
например:
```bash
cmake -G "Visual Studio 16 2019" ....
  ```
- На всех других платформах - обычно используются Unix Makefiles, но можно указать другой, например Ninja или Ninja Multi-Config, как:
  Multi-Config`, как:
```bash
  cmake -GNinja ...
  ```
  или
```bash
  cmake -G"Ninja Multi-Config" ...
```
Ninja Multi-Config весьма полезен, так как он действительно 'multi-config' и доступен на Linux/macOS/BSD. С этим генератором вы можете перенести выбор типа конфигурации на момент сборки и также можете собирать несколько конфигураций в одной и той же директории сборки, меняя только параметр `--config`.

### Предостережения

1. Если вы хотите окончательно собрать полнофункциональный RPM пакет, путь к директории сборки должен быть достаточно длинным для корректной сборки символов отладки.
Как `/manticore012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789`, например. Это потому что инструменты RPM изменяют путь над скомпилированными бинарниками при сборке информации отладки, и они могут просто записать в существующее пространство, не выделяя дополнительного. Упомянутый длинный путь имеет 100 символов и это вполне достаточно для такого случая.

## Внешние зависимости

Некоторые библиотеки должны быть доступны, если вы хотите их использовать.
- Для индексации (инструмент `indexer`): `expat`, `iconv`, `mysql`, `odbc`, `postgresql`. Без них можно обрабатывать только источники `tsv` и `csv`.
- Для обработки запросов (демон `searchd`): может потребоваться `openssl`.
- Для всех (обязательных!) нужна библиотека Boost. Минимальная версия 1.61.0, но мы собираем бинарники с более свежей версией 1.75.0. Даже более новые версии (например 1.76) также должны работать. На Windows можно скачать предварительно собранный Boost с их сайта (boost.org) и установить в стандартный предлагаемый путь (например `C:\\boost...`). На MacOs версия из brew подходит. На Linux можно проверить доступную версию в официальных репозиториях, и если она не соответствует требованиям, можно собрать из исходников. Нужна компонента 'context', также можно собрать компоненты 'system' и 'program_options', они будут необходимы, если вы хотите также собрать библиотеку Galera из исходников. Посмотрите на `dist/build_dockers/xxx/boost_175/Dockerfile` для короткого самодокументирующего скрипта/инструкции, как это сделать.

На системе сборки нужны версии 'dev' или 'devel' этих пакетов (например - libmysqlclient-devel, unixodbc-devel, etc. Посмотрите на наши dockerfiles для имен конкретных пакетов).

На системах выполнения эти пакеты должны присутствовать хотя бы в конечных (не-dev) вариантах. (devel варианты обычно больше, так как включают не только целевые бинарники, но и различные средства разработки, такие как заголовочные файлы, etc.).

### Сборка на Windows

Помимо необходимых условий, могут потребоваться предварительно собранные библиотеки клиента `expat`, `iconv`, `mysql` и `postgresql`. Вы должны либо собрать их самостоятельно, либо обратиться к нам для получения нашего пакета сборки (простой zip архив, где находится папка с этими целевыми файлами).

- ODBC не нужен, так как это системная библиотека.
- OpenSSL можно собрать из исходников или скачать предварительно собранный с https://slproweb.com/products/Win32OpenSSL.html (как указано в внутреннем скрипте cmake FindOpenSSL).
- Boost можно скачать предварительно собранный с https://www.boost.org/ релизов.

### Посмотреть что собрано

Запустите `indexer -h`. Это покажет какие функции были настроены и собраны (не важно, были они явно указаны или обнаружены):

```
Built on Linux x86_64 by GNU 8.3.1 compiler.

Configured with these definitions: -DDISTR_BUILD=rhel8 -DUSE_SYSLOG=1 -DWITH_GALERA=1 -DWITH_RE2=1 -DWITH_RE2_FORCE_STATIC=1
-DWITH_STEMMER=1 -DWITH_STEMMER_FORCE_STATIC=1 -DWITH_ICU=1 -DWITH_ICU_FORCE_STATIC=1 -DWITH_SSL=1 -DWITH_ZLIB=1 -DWITH_ODBC=1 -DDL_ODBC=1
-DODBC_LIB=libodbc.so.2 -DWITH_EXPAT=1 -DDL_EXPAT=1 -DEXPAT_LIB=libexpat.so.1 -DWITH_ICONV=1 -DWITH_MYSQL=1 -DDL_MYSQL=1
-DMYSQL_LIB=libmariadb.so.3 -DWITH_POSTGRESQL=1 -DDL_POSTGRESQL=1 -DPOSTGRESQL_LIB=libpq.so.5 -DLOCALDATADIR=/var/lib/manticore/data
-DFULL_SHARE_DIR=/usr/share/manticore
```
<!-- proofread -->
