#!/bin/sh # Проверка платформенных ветвей БЕЗ самих платформ (Windows и macOS). # # Зачем. Кросс-RTL обычно не установлен, поэтому ветки {$IFDEF WINDOWS} и # {$IFDEF DARWIN} на Linux не компилируются ВООБЩЕ — ошибка в них всплывает # только на сборочной машине, через полчаса после коммита. Так и вышло: модуль # Windows, добавленный ради QueryPerformanceCounter, перекрыл однопараметрический # SysUtils.GetEnvironmentVariable, и win64-сборка легла на трёх вызовах. # # Как. Копии файлов переписываются так, чтобы платформенные условия читались как # наши собственные (-dSIMWIN / -dSIMMAC), и компилируются БЕЗ ЛИНКОВКИ (-Cn): # системных функций на Linux нет, но синтаксис, типы и — главное — разрешение # имён проверяются по-настоящему. Для Windows подкладываются заглушки модулей # Windows и Serial (win_stub/) с теми же объявлениями, что у настоящих. # # Чего проверка НЕ делает: живых вызовов системных функций. Их правильность # доказывает только прогон на самой платформе. set -e cd "$(dirname "$0")" HERE=$(pwd) ROOT=../.. FILES="PlatformUtils.pas SerialPort.pas" WORK=$(mktemp -d) trap 'rm -rf "$WORK"' EXIT FAILED=0 COUNT=0 sim_build() { # $1 = win|mac MODE=$1 DIR="$WORK/$MODE" mkdir -p "$DIR" if [ "$MODE" = win ]; then cp win_stub/*.pas "$DIR/" DEF=-dSIMWIN else DEF=-dSIMMAC fi for F in $FILES; do if [ "$MODE" = win ]; then sed -e 's/{\$IFDEF WINDOWS}/{$IFDEF SIMWIN}/g' \ -e 's/{\$IFNDEF WINDOWS}/{$IFNDEF SIMWIN}/g' \ -e 's/{\$IF DEFINED(WINDOWS)}/{$IF DEFINED(SIMWIN)}/g' \ "$ROOT/$F" > "$DIR/$F" else sed -e 's/{\$IFDEF LINUX}/{$IFDEF SIMLINUX}/g' \ -e 's/{\$IFDEF DARWIN}/{$IFDEF SIMMAC}/g' \ -e 's/{\$ELSEIF DEFINED(DARWIN)}/{$ELSEIF DEFINED(SIMMAC)}/g' \ -e 's/{\$IF DEFINED(DARWIN) AND NOT DEFINED(HEADLESS)}/{$IF DEFINED(SIMMAC) AND NOT DEFINED(HEADLESS)}/g' \ "$ROOT/$F" > "$DIR/$F" fi COUNT=$((COUNT + 1)) if ( cd "$DIR" && fpc -B -Mobjfpc -dHEADLESS $DEF -Fu. -FU. -Cn "$F" >"$DIR/$F.log" 2>&1 ); then echo " ok $F: ветка $MODE компилируется" else echo " FAIL $F: ветка $MODE НЕ компилируется" cat "$DIR/$F.log" FAILED=$((FAILED + 1)) fi done } sim_build win sim_build mac # ── Прогон WINDOWS-ветки, а не только её компиляция ────────────────────────── # ★Заглушка модуля Serial — чистый Паскаль, поэтому ветку можно не только # собрать, но и ЗАПУСТИТЬ: проверяются перевод нулевого хендла RTL в # SER_INVALID_HANDLE, ответ SerValid (под Windows ноль негоден — в отличие от # Unix) и правило имени COM10+. cp win_probe/winprobe.pas "$WORK/win/" COUNT=$((COUNT + 1)) if ( cd "$WORK/win" && fpc -B -Mobjfpc -dHEADLESS -dSIMWIN -Fu. -FU. \ -o./winprobe winprobe.pas >"$WORK/win/probe.log" 2>&1 && ./winprobe ); then echo " ok SerialPort.pas: ветка win ведёт себя как надо (прогон на заглушке)" else echo " FAIL SerialPort.pas: прогон windows-ветки провалился" cat "$WORK/win/probe.log" FAILED=$((FAILED + 1)) fi echo echo "Итого: $COUNT проверок, провалено $FAILED" [ "$FAILED" -eq 0 ]