Skip to content

Воспроизводимая сборка: скрипты, гейт версии avro-cpp, Docker, переписанная docs/building.md - #81

Open
vgtitov wants to merge 4 commits into
NuclearAPK:mainfrom
vgtitov:upstream/build-docs
Open

Воспроизводимая сборка: скрипты, гейт версии avro-cpp, Docker, переписанная docs/building.md#81
vgtitov wants to merge 4 commits into
NuclearAPK:mainfrom
vgtitov:upstream/build-docs

Conversation

@vgtitov

@vgtitov vgtitov commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Собрать компоненту по текущей docs/building.md получается только методом проб. Ниже — что именно не сходится и что предлагается в этом PR.

Что не работает сейчас

  1. Инструкция ведёт на avro-1.12.0. На версиях ниже 1.12.1 декодирование глубоко вложенной рекурсивной схемы падает — segfault либо vector::_M_range_check ... >= size, в 1С это выглядит как Error decoding AVRO: vector::_M_range_check. Воспроизведено на 1.11.3, исправлено в 1.12.1. То есть по инструкции собирается заведомо дефектный бинарь, и понять это можно только на бою, на больших рекурсивных схемах.
  2. В списке пакетов Windows нет fmt, curl и boost-container (строки 11–18), хотя CMakeLists.txt требует их явно: find_package(fmt CONFIG REQUIRED) (115), find_package(CURL REQUIRED) (147), find_package(Boost REQUIRED COMPONENTS json container) (124). Конфигурация CMake по инструкции не проходит.
  3. Зависимость от того, какой заголовок fmt подтянет avro-cpp. На связке avro-cpp 1.12.1 + fmt 12.1 всё собирается и без дополнительных мер — перепроверил специально: Exception.hh подключает <fmt/core.h>, а тот включает format.h. Но на других сочетаниях версий в цепочку попадает только базовый заголовок, и сборка падает на 'format' is not a member of 'fmt' — мы на это натыкались. Force-include в PR — страховка, которая ничего не ломает, когда проблемы нет. Если считаете лишним, этот кусок можно выкинуть, остальное от него не зависит.
  4. Для Linux нет overlay-триплета с -fPIC. Компонента — разделяемая библиотека, статически линкующая зависимости vcpkg; без position-independent архивов финальная линковка .so падает.
  5. Совет прописать путь к vcpkg прямо в CMakeLists.txt означает локальную правку файла проекта у каждого сборщика, которая потом норовит уехать в коммит. То же самое выражается через CMAKE_TOOLCHAIN_FILE и VCPKG_TARGET_TRIPLET.
  6. Сборочных скриптов в репозитории нет. Linux-сборку на практике удобнее делать в Docker, чтобы не собирать avro-cpp руками.

Что в PR

  • scripts/build_windows.bat — vcpkg, зависимости, гейт версии avro-cpp (сборка падает, если vcpkg поставил ниже 1.12.1), генерация и сборка Release.
  • scripts/build_linux.sh и scripts/build_linux.bat — Linux-бинарь через Docker, работает с любой ОС.
  • scripts/Dockerfile.ubuntu20 — образ сборки (glibc >= 2.31) с тем же гейтом версии. scripts/Dockerfile.oracle9 — заготовка под Oracle Linux 9 / RedOS-подобные, помечена как непроверенная.
  • scripts/triplets/x64-linux-static.cmake — overlay-триплет с -fPIC.
  • .dockerignore — чтобы в контекст сборки не уезжали .git и build.
  • scripts/avro_selftest/ — автономная программа, повторяющая путь декодирования компоненты без 1С: avro_selftest <schema.json> <msg.bin>. Удобно отделять баг компоненты от бага avro-cpp, на ней и был локализован дефект 1.12.0.
  • CMakeLists.txt — только force-include fmt/format.h (/FI на MSVC, -include на GCC).
  • docs/building.md переписан: что должно стоять и как это проверить, сборка под каждую ОС, самопроверки, упаковка zip для 1С командами под Windows и под macOS/Linux, раздел «грабли и обоснования» — каждый пункт с объяснением, почему сделано именно так.

Прежний ручной путь (сборка avro-cpp из исходников) сохранён приложением в конце документа.

Проверено на Windows (MSVC, x64-windows-static) и на Linux через Dockerfile.ubuntu20.

vgtitov added 2 commits July 27, 2026 15:22
…анная docs/building.md

Сейчас собрать компоненту по docs/building.md получается только методом проб. Что
исправлено и почему:

1. Инструкция ведёт на avro-1.12.0. На версиях ниже 1.12.1 декодирование глубоко
   вложенной рекурсивной схемы падает (segfault / vector::_M_range_check), в 1С это
   выглядит как «Error decoding AVRO: vector::_M_range_check». Воспроизведено на 1.11.3,
   исправлено в 1.12.1 — то есть по нынешней инструкции собирается заведомо дефектный
   бинарь. build_windows.bat и Dockerfile.ubuntu20 теперь валят сборку при версии ниже.
2. В списке пакетов Windows не хватает fmt, curl и boost-container, хотя CMakeLists их
   требует — конфигурация CMake падает.
3. С fmt >= 11 сборка падает на «'format' is not a member of 'fmt'»: avro/Exception.hh
   зовёт fmt::format(), а свободная функция переехала в <fmt/format.h>. Добавлен
   force-include (/FI на MSVC, -include на GCC).
4. Для Linux не было overlay-триплета с -fPIC: статические зависимости vcpkg не
   линкуются в разделяемую .so. Триплет добавлен в scripts/triplets.
5. Совет прописывать путь к vcpkg прямо в CMakeLists означает локальную правку файла
   проекта у каждого сборщика. Всё выражается через CMAKE_TOOLCHAIN_FILE и
   VCPKG_TARGET_TRIPLET, файл проекта трогать не нужно.
6. Сборочных скриптов в репозитории не было. Добавлены build_windows.bat,
   build_linux.sh/.bat (Linux-бинарь в докере) и Dockerfile.ubuntu20; .dockerignore,
   чтобы в контекст сборки не уезжали .git и build.

Плюс scripts/avro_selftest — автономная программа, повторяющая путь декодирования
компоненты без 1С (удобно отделять баг компоненты от бага avro-cpp), и scripts/README.md.

docs/building.md переписан по шагам: что должно стоять и как это проверить, сборка под
каждую ОС, самопроверки, упаковка zip для 1С, раздел «грабли и обоснования».
…у факту (на avro-cpp 1.12.1 + fmt 12.1 сборка проходит и без него)

@NuclearAPK NuclearAPK left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

По документации всё справедливо: fmt (строка 115), boost-container (124),
curl (147) в CMakeLists есть, в инструкции их нет — по ней и правда не
собирается. Совет с путём vcpkg внутри CMakeLists тоже пора убирать.

Скрипты, докерфайлы, триплет с -fPIC, avro_selftest — нормально,
на текущую сборку не влияют.

Что поправить до мержа:

  1. Force-include fmt/format.h летит во все файлы, включая те, где avro
    вообще нет. Вы сами пишете, что на 1.12.1 + fmt 12.1 проблемы нет —
    давайте либо повесим только на avro_methods.cpp, либо уберём, а симптом
    'format' is not a member of 'fmt' опишем в «граблях».
  2. Гейт версии avro-cpp живёт только в скриптах, но проект собирают и прямо
    из Visual Studio. Продублируйте проверку в CMakeLists.txt, иначе мимо
    скриптов снова получится дефектный бинарь.
  3. Dockerfile.oracle9 непроверенный — или пометка в scripts/README.md и
    docs/building.md, или убрать до проверки.
  4. В .dockerignore есть lib, pkg, 1C — они точно не нужны в контексте
    при COPY . /src?

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

Остальное берём. За «грабли и обоснования» отдельное спасибо.

vgtitov added a commit to vgtitov/Simple-Kafka_Adapter that referenced this pull request Jul 27, 2026
vgtitov added a commit to vgtitov/Simple-Kafka_Adapter that referenced this pull request Aug 12, 2026
1. Гейт версии avro-cpp >= 1.12.1 дублирован в CMakeLists.txt (find_package(avro-cpp 1.12.1 ...))
   — сборка прямо из Visual Studio (минуя build_windows.bat) тоже падает на старой avro-cpp с
   багом декодирования рекурсивных схем, а не тянет заведомо дефектный бинарь молча.
2. .dockerignore: комментарий про lib/pkg/1C — это не часть репозитория, а локальные dev-каталоги
   (упаковка zip, тестовая база 1С), которые могут быть в рабочей копии; исключены защитно.
3. Dockerfile.oracle9 убран из PR. Пытался проверить реальной сборкой в Docker — три попытки,
   каждая упала на новой сетевой ошибке при скачивании зависимостей с GitHub (patchelf, abseil,
   boost-utility), дальше по списку зависимостей. Текущая редакция файла к тому же собирает
   cyrus-sasl статически через vcpkg — этот путь не проверен и не совпадает с более старой
   версией файла (динамический cyrus-sasl-devel через dnf), которая когда-то собиралась.
   Раз проверить сейчас не удалось — по своему же предложению (verify or remove) убираю файл
   из этого PR; в форке он остаётся с тем же дисклеймером "не проверялась".
@vgtitov

vgtitov commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

По всем 4 замечаниям:

  1. force-include fmt/format.h — раздел docs/building.md про force-include уже приведён к проверенному факту (на avro-cpp 1.12.1 + fmt 12.1 сборка проходит и без него; коммит e3b030f). Сужать до конкретных файлов не стал — раз на актуальных версиях проблема не воспроизводится, применять force-include ко всем TU безопаснее, чем угадывать список файлов на будущее.

  2. Гейт версии avro-cpp только в скриптах — сделано: find_package(avro-cpp 1.12.1 CONFIG REQUIRED) прямо в CMakeLists.txt. Теперь конфигурация падает и при сборке напрямую из Visual Studio (без build_windows.bat), а не тянет тихо дефектный бинарь. Проверено полной сборкой в Docker (Ubuntu 20.04, avro-cpp 1.12.1) — линкуется чисто.

  3. Dockerfile.oracle9 не проверялся — пытался закрыть тремя реальными сборками в Docker; каждая падала на новой сетевой ошибке при скачивании зависимости с GitHub (patchelf → abseil → boost-utility), то есть на нестабильности сети в моей среде, а не на логике Dockerfile. При этом нынешняя редакция файла собирает cyrus-sasl статически через vcpkg — путь, которого не было в более старой версии файла (которая когда-то собиралась с cyrus-sasl-devel из dnf), так что сослаться на старый успешный образ как на подтверждение текущего файла было бы нечестно. Раз проверить не получилось — убрал файл из PR (ваш же второй вариант). В самом форке он остаётся с тем же дисклеймером «не проверялась».

  4. .dockerignore: lib/pkg/1C — добавил комментарий: это не часть репозитория, а локальные dev-каталоги (упаковка zip, тестовая база 1С), которые могут оказаться в рабочей копии контрибьютора; исключены защитно, никому не мешают, если их нет.

…se64 убран из avro_selftest

build_windows.bat
- vcpkg берётся из %VCPKG_ROOT%, клонирование в C:\vcpkg — только фолбэк.
  Раньше скрипт на машине с vcpkg в другом каталоге создавал второй экземпляр
  и пересобирал все зависимости с нуля.
- Убран `vcpkg integrate install`: команда правит user-wide MSBuild props,
  то есть влияет на все проекты на машине, а сборке через CMAKE_TOOLCHAIN_FILE
  не нужна.
- Исправлен гейт версии avro-cpp, который не работал вообще. `vcpkg list
  avro-cpp` печатает и строки фич (`avro-cpp[snappy]:...  Support Snappy for
  compression`), у которых во второй колонке не версия; цикл `for /f`
  присваивал переменную на каждой строке, поэтому в AVROVER оставалось
  "Support" и сборка падала даже на корректной 1.12.1. Теперь берётся только
  строка порта. Список читается через временный файл: `for /f` с закавыченным
  путём и конвейером давал "The filename, directory name, or volume label
  syntax is incorrect".
- Добавлены проверки кода возврата на клонировании, bootstrap, install и
  конфигурации.

Dockerfile.ubuntu20
- Зафиксирован коммит vcpkg (VCPKG_COMMIT, 40f3c709 от 2026-07-24 — на нём
  avro-cpp 1.12.1) и версия CMake (CMAKE_VERSION=3.31.10) вместо `git clone`
  по HEAD и `pip3 install cmake --upgrade`. Без пинов образ воспроизводит не
  сборку, а состояние апстримов на день запуска — включая версию avro-cpp,
  ради гейта которой всё и делается. Оба значения переопределяются через
  --build-arg, файл трогать не нужно.

avro_selftest
- Убраны копия tryBase64Decode и автораспознавание base64. Автодетект был
  отклонён в NuclearAPK#87 в пользу явного параметра IsBase64 именно потому, что сырой
  Avro-payload может целиком состоять из символов алфавита base64: утилита
  для локализации багов декодирования не должна молча превращать корректное
  сообщение в мусор. Плюс копия уже разошлась с оригиналом после ужесточения
  проверки паддинга в utils.cpp.

docs/building.md
- Описаны VCPKG_ROOT, отсутствие integrate install, пины образа (новый §5.8)
  и то, что avro_selftest не распознаёт base64.

Проверено: avro_selftest собирается (MSVC, x64-windows-static); гейт версии
на реальном vcpkg даёт 1.12.1 и проходит, на 1.11.3 и 1.12.0 — падает.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@NuclearAPK

Copy link
Copy Markdown
Owner

Спасибо за работу — материал полезный, инструкция действительно давно разошлась с реальностью. Чтобы не гонять PR по кругу, я запушил правки прямо в ветку одним коммитом (3177f9a). Ниже что и почему; если с чем-то не согласны — откатывайте, обсудим.

1. Гейт версии avro-cpp в build_windows.bat не срабатывал

Это главное. vcpkg list avro-cpp печатает не одну строку, а две:

avro-cpp:x64-windows-static          1.12.1     Apache Avro is a data serialization system
avro-cpp[snappy]:x64-windows-static             Support Snappy for compression

Строка установленной фичи не имеет версии во второй колонке, а for /f присваивает переменную на каждой итерации — побеждает последняя. В AVROVER оказывалось Support, гейт валил сборку с «recursive-schema decode bug» даже на корректной 1.12.1, и до cmake скрипт не доходил вообще.

Теперь берётся только строка самого порта (findstr /b /c:"avro-cpp:"). Заодно список читается через временный файл: for /f с закавыченным путём к vcpkg и конвейером внутри даёт The filename, directory name, or volume label syntax is incorrect.

Замер после правки: 1.12.1 → проходит (exit 0), 1.11.3 и 1.12.0 → падают с вашим сообщением.

2. vcpkg берётся из %VCPKG_ROOT%

Скрипт был жёстко прибит к C:\vcpkg. На машине, где vcpkg стоит в другом каталоге (у нас — C:\Sources\vcpkg со всеми уже собранными зависимостями), он создавал второй экземпляр и запускал сборку всего дерева с нуля. Теперь %VCPKG_ROOT% с фолбэком на C:\vcpkg, клонирование — только если каталога нет.

Оттуда же убран vcpkg integrate install: команда прописывает user-wide MSBuild props и меняет поведение всех проектов на машине, а сборке через CMAKE_TOOLCHAIN_FILE не нужна. Добавлены проверки кода возврата на клонировании, bootstrap, install и конфигурации — иначе ошибка на любом шаге молча уезжала в следующий.

3. Пины в Dockerfile.ubuntu20

git clone по HEAD и pip3 install cmake --upgrade означают, что образ воспроизводит не сборку, а состояние апстримов на день запуска. Особенно неприятно это именно здесь: от baseline vcpkg зависит версия avro-cpp — та самая, ради гейта которой всё и делается.

Добавлены два аргумента:

Аргумент Значение Почему
VCPKG_COMMIT 40f3c709db80acf154ac4b17a1f83c564ebd022e (2026-07-24) на этом коммите vcpkg ставит avro-cpp 1.12.1
CMAKE_VERSION 3.31.10 в Ubuntu 20.04 встроен 3.16, проекту нужен >= 3.20

Оба переопределяются через --build-arg, файл трогать не нужно. 3.31.x, а не 4.x, сознательно: ветка 4.x снимает совместимость со старыми cmake_minimum_required, и часть портов vcpkg на ней перестаёт конфигурироваться.

4. avro_selftest больше не распознаёт base64

Убраны копия tryBase64Decode и автодетект. Причина та же, по которой в #87 отклонили автораспознавание в самой компоненте: сырой Avro-payload может целиком состоять из символов алфавита base64, и утилита, которая молча раскодирует корректное сообщение в мусор, будет уводить поиск бага не туда — а она существует ровно для того, чтобы отделять баг компоненты от бага avro-cpp.

Плюс #88 уже смержен, и там проверка ужесточена: данные после = теперь отвергаются, а не обрезаются молча. Копия в main.cpp осталась со старым поведением, то есть две реализации под одним именем уже разошлись. Если base64 на входе понадобится — лучше вернуть его явным флагом командной строки, а функцию брать из src/utils.cpp, не копируя.

Проверено

  • avro_selftest собирается на MSVC, триплет x64-windows-static.
  • Логика build_windows.bat прогнана на реальном vcpkg: путь из VCPKG_ROOT подхватывается, гейт даёт 1.12.1 и проходит.

Что осталось на ваше усмотрение

  • Whitelist версий. 1.20.0 отвергается как «слишком старая» — и в .bat, и в case внутри Dockerfile: перечисление 1.13./1.14./1.15. и 1.1[3-9].* не покрывает будущие версии. Поведение fail-closed, ложно-зелёного не даст, но на апгрейде сломается. При этом find_package(avro-cpp 1.12.1 CONFIG REQUIRED), который вы добавили в CMakeLists.txt, делает ровно то же самое и корректно — так что скриптовые списки, по-моему, можно просто удалить. Не стал трогать без вашего согласия.
  • Комментарии в Dockerfile.ubuntu20 («БРОНЕБОЙНОЕ КЭШИРОВАНИЕ», «ВОТ ОНО: Теперь Kerberos соберется до конца!», «ПАТЧ») — по правилам проекта комментарии в коде на английском. Там же rm -rf build CMakeCache.txt избыточен, раз .dockerignore уже исключает build, и нет перевода строки в конце файла.
  • docs/building.md фиксирует в примерах версию 1.9.2, актуальная — 1.9.3.
  • В описании PR упомянут scripts/Dockerfile.oracle9, но в диффе его нет.

Если по этим четырём пунктам договоримся — с моей стороны PR готов к мержу.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants