diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml new file mode 100644 index 0000000..82b6240 --- /dev/null +++ b/.github/workflows/build-macos.yml @@ -0,0 +1,47 @@ +name: build-macos + +# Builds the native components as universal (x86_64 + arm64) macOS .dylib files. +# Lets the project ship macOS support without anyone owning a Mac: +# the dylib artifacts are produced here, then dropped into the processing's +# Template.bin and the .epf is re-saved in Designer (any OS) — exactly like the +# Linux .so workflow. +# +# ScreenCapture is intentionally excluded: it relies on the Windows GDI API and +# has no non-Windows code path. + +on: + push: + branches: [main] + paths: + - 'native_components/**' + - '.github/workflows/build-macos.yml' + pull_request: + paths: + - 'native_components/**' + - '.github/workflows/build-macos.yml' + workflow_dispatch: + +jobs: + build: + runs-on: macos-14 # Apple Silicon runner; cross-builds the x86_64 slice too + strategy: + fail-fast: false + matrix: + component: + - MCPHttpTransport + - QueryLineageAnalyzer + - RegexHelper + - SyntaxHelpReader + - ToonConverter + steps: + - uses: actions/checkout@v4 + + - name: Build ${{ matrix.component }} (universal) + run: bash "native_components/${{ matrix.component }}/build_macos.sh" + + - name: Upload ${{ matrix.component }} dylib + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.component }}-macos-universal + path: native_components/${{ matrix.component }}/build_macos/${{ matrix.component }}.dylib + if-no-files-found: error diff --git a/README.md b/README.md index 3f37810..9a2ca35 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,12 @@ HTTP-сервер запускается прямо внутри обработ 3. Нажмите «Запустить сервер» 4. Настройте AI-агент на `http://:6003/mcp` +> **macOS:** встроенный сервер работает и на macOS нативно (без Python). Нужно +> собрать нативные компоненты как universal (x86_64 + arm64) — см. +> [`native_components/BUILDING_MACOS.md`](native_components/BUILDING_MACOS.md). +> Сборку автоматизирует CI (`.github/workflows/build-macos.yml`), Mac для этого +> иметь не обязательно. + ### Вариант 1: Docker Hub (режим Прокси) Запуск прокси-сервера из готового образа на Docker Hub: diff --git a/native_components/BUILDING_MACOS.md b/native_components/BUILDING_MACOS.md new file mode 100644 index 0000000..aa8dd01 --- /dev/null +++ b/native_components/BUILDING_MACOS.md @@ -0,0 +1,73 @@ +# Сборка нативных компонент под macOS + +Встроенный HTTP-сервер (`MCPHttpTransport`) и остальные нативные компоненты +работают на macOS нативно — Python-прокси не нужен. Требуется только собрать +библиотеки под macOS как **universal (x86_64 + arm64)**. + +## TL;DR + +```bash +# по одной компоненте +bash native_components/MCPHttpTransport/build_macos.sh +# → native_components/MCPHttpTransport/build_macos/MCPHttpTransport.dylib (universal, ad-hoc signed) +``` + +Готовые `.dylib` для всех компонент также собирает CI +(`.github/workflows/build-macos.yml`, раннер `macos-14`) и публикует артефактами — +**физический Mac для этого не нужен**. + +Требования для локальной сборки: CMake 3.16+, Xcode Command Line Tools +(`xcode-select --install`). Docker/Python не нужны. + +## Два критичных момента (иначе компонента/обработка не заведётся) + +### 1. Только universal или x86_64 — НЕ arm64-only + +Клиент 1С:Предприятие под macOS поставляется как **x86_64** и на Apple Silicon +работает через Rosetta 2. arm64-only библиотека не загрузится в x86_64-процесс: + +``` +Тип не определен (AddIn.MCPHttp.MCPHttpTransport) +``` + +Поэтому `build_macos.sh` собирает с `-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"`. +Проверить клиент: `lipo -archs /opt/1cv8/<версия>/1cv8` → должно быть `x86_64`. + +### 2. .epf пересохранять Конфигуратором НЕ новее рантайма + +Если собрать `.epf` Конфигуратором версии новее, чем платформа, на которой его +открывают, при открытии будет: + +``` +ошибка формата потока +``` + +Собирайте `.epf` самой старой из используемых версий платформы. + +## Встраивание в обработку + +Как и для Windows/Linux, библиотека кладётся сырым бинарником в макет +(одна разрядность на `.epf`): + +```bash +cp native_components/MCPHttpTransport/build_macos/MCPHttpTransport.dylib \ + 1c/MCPToolkit/MCPToolkit/Templates/MCPHttpTransport/Ext/Template.bin +``` + +Аналогично для `QueryLineageAnalyzer`, `RegexHelper`, `SyntaxHelpReader`, +`ToonConverter`. После замены `Template.bin` пересохраните `.epf` в Конфигураторе +(на любой ОС — `.epf` кроссплатформенный, маковый только встроенный бинарник): + +```bash +1cv8 DESIGNER /F \ + /LoadExternalDataProcessorOrReportFromFiles \ + 1c/MCPToolkit/MCPToolkit.xml build/MCP_Toolkit_mac.epf +``` + +## ScreenCapture + +`ScreenCapture` не переносится на macOS (использует Windows GDI, нет +не-Windows ветки), поэтому в CI и `build_macos.sh` не входит. На macOS его макет +остаётся Windows-DLL — обработка при старте выдаёт одно предупреждение, а +`get_screenshot` недоступен. Остальной функционал (`execute_query`, +`execute_code`, навигация, TOON, regex, справка по синтаксису) работает. diff --git a/native_components/MCPHttpTransport/build_macos.sh b/native_components/MCPHttpTransport/build_macos.sh new file mode 100755 index 0000000..0b459ca --- /dev/null +++ b/native_components/MCPHttpTransport/build_macos.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Build a 1C Native API component for macOS as a universal (x86_64 + arm64) .dylib. +# +# Why universal: the 1C:Enterprise client on macOS ships as an x86_64 binary and +# runs under Rosetta 2 on Apple Silicon. An arm64-only library cannot be loaded +# into that x86_64 process and fails with "Тип не определен (AddIn.*.*)". +# A universal binary works both natively and under Rosetta. +# +# Requirements: CMake 3.16+, Apple clang (Xcode Command Line Tools). +# No Docker, no Python — just the native toolchain. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NAME="$(basename "$SCRIPT_DIR")" +cd "$SCRIPT_DIR" + +rm -rf build_macos +cmake -B build_macos -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" +cmake --build build_macos -j"$(sysctl -n hw.ncpu)" + +DYLIB="build_macos/${NAME}.dylib" + +echo '--- Verify architectures ---' +lipo -archs "$DYLIB" +lipo -archs "$DYLIB" | grep -q x86_64 || { echo '[ERROR] x86_64 slice missing'; exit 1; } +lipo -archs "$DYLIB" | grep -q arm64 || { echo '[ERROR] arm64 slice missing'; exit 1; } + +echo '--- Verify exports ---' +EXPORTS=$(nm -gU "$DYLIB" | grep -cE 'GetClassNames|GetClassObject|DestroyObject|SetPlatformCapabilities' || true) +echo "Exports found: ${EXPORTS}/4" +[ "$EXPORTS" -eq 4 ] || { echo '[ERROR] Not all 4 required 1C Native API exports found'; exit 1; } + +echo '--- Ad-hoc code signing (avoids hardened-runtime load rejection) ---' +codesign --force --sign - "$DYLIB" + +echo "Done: ${SCRIPT_DIR}/${DYLIB}" diff --git a/native_components/QueryLineageAnalyzer/build_macos.sh b/native_components/QueryLineageAnalyzer/build_macos.sh new file mode 100755 index 0000000..0b459ca --- /dev/null +++ b/native_components/QueryLineageAnalyzer/build_macos.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Build a 1C Native API component for macOS as a universal (x86_64 + arm64) .dylib. +# +# Why universal: the 1C:Enterprise client on macOS ships as an x86_64 binary and +# runs under Rosetta 2 on Apple Silicon. An arm64-only library cannot be loaded +# into that x86_64 process and fails with "Тип не определен (AddIn.*.*)". +# A universal binary works both natively and under Rosetta. +# +# Requirements: CMake 3.16+, Apple clang (Xcode Command Line Tools). +# No Docker, no Python — just the native toolchain. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NAME="$(basename "$SCRIPT_DIR")" +cd "$SCRIPT_DIR" + +rm -rf build_macos +cmake -B build_macos -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" +cmake --build build_macos -j"$(sysctl -n hw.ncpu)" + +DYLIB="build_macos/${NAME}.dylib" + +echo '--- Verify architectures ---' +lipo -archs "$DYLIB" +lipo -archs "$DYLIB" | grep -q x86_64 || { echo '[ERROR] x86_64 slice missing'; exit 1; } +lipo -archs "$DYLIB" | grep -q arm64 || { echo '[ERROR] arm64 slice missing'; exit 1; } + +echo '--- Verify exports ---' +EXPORTS=$(nm -gU "$DYLIB" | grep -cE 'GetClassNames|GetClassObject|DestroyObject|SetPlatformCapabilities' || true) +echo "Exports found: ${EXPORTS}/4" +[ "$EXPORTS" -eq 4 ] || { echo '[ERROR] Not all 4 required 1C Native API exports found'; exit 1; } + +echo '--- Ad-hoc code signing (avoids hardened-runtime load rejection) ---' +codesign --force --sign - "$DYLIB" + +echo "Done: ${SCRIPT_DIR}/${DYLIB}" diff --git a/native_components/RegexHelper/build_macos.sh b/native_components/RegexHelper/build_macos.sh new file mode 100755 index 0000000..0b459ca --- /dev/null +++ b/native_components/RegexHelper/build_macos.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Build a 1C Native API component for macOS as a universal (x86_64 + arm64) .dylib. +# +# Why universal: the 1C:Enterprise client on macOS ships as an x86_64 binary and +# runs under Rosetta 2 on Apple Silicon. An arm64-only library cannot be loaded +# into that x86_64 process and fails with "Тип не определен (AddIn.*.*)". +# A universal binary works both natively and under Rosetta. +# +# Requirements: CMake 3.16+, Apple clang (Xcode Command Line Tools). +# No Docker, no Python — just the native toolchain. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NAME="$(basename "$SCRIPT_DIR")" +cd "$SCRIPT_DIR" + +rm -rf build_macos +cmake -B build_macos -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" +cmake --build build_macos -j"$(sysctl -n hw.ncpu)" + +DYLIB="build_macos/${NAME}.dylib" + +echo '--- Verify architectures ---' +lipo -archs "$DYLIB" +lipo -archs "$DYLIB" | grep -q x86_64 || { echo '[ERROR] x86_64 slice missing'; exit 1; } +lipo -archs "$DYLIB" | grep -q arm64 || { echo '[ERROR] arm64 slice missing'; exit 1; } + +echo '--- Verify exports ---' +EXPORTS=$(nm -gU "$DYLIB" | grep -cE 'GetClassNames|GetClassObject|DestroyObject|SetPlatformCapabilities' || true) +echo "Exports found: ${EXPORTS}/4" +[ "$EXPORTS" -eq 4 ] || { echo '[ERROR] Not all 4 required 1C Native API exports found'; exit 1; } + +echo '--- Ad-hoc code signing (avoids hardened-runtime load rejection) ---' +codesign --force --sign - "$DYLIB" + +echo "Done: ${SCRIPT_DIR}/${DYLIB}" diff --git a/native_components/SyntaxHelpReader/build_macos.sh b/native_components/SyntaxHelpReader/build_macos.sh new file mode 100755 index 0000000..0b459ca --- /dev/null +++ b/native_components/SyntaxHelpReader/build_macos.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Build a 1C Native API component for macOS as a universal (x86_64 + arm64) .dylib. +# +# Why universal: the 1C:Enterprise client on macOS ships as an x86_64 binary and +# runs under Rosetta 2 on Apple Silicon. An arm64-only library cannot be loaded +# into that x86_64 process and fails with "Тип не определен (AddIn.*.*)". +# A universal binary works both natively and under Rosetta. +# +# Requirements: CMake 3.16+, Apple clang (Xcode Command Line Tools). +# No Docker, no Python — just the native toolchain. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NAME="$(basename "$SCRIPT_DIR")" +cd "$SCRIPT_DIR" + +rm -rf build_macos +cmake -B build_macos -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" +cmake --build build_macos -j"$(sysctl -n hw.ncpu)" + +DYLIB="build_macos/${NAME}.dylib" + +echo '--- Verify architectures ---' +lipo -archs "$DYLIB" +lipo -archs "$DYLIB" | grep -q x86_64 || { echo '[ERROR] x86_64 slice missing'; exit 1; } +lipo -archs "$DYLIB" | grep -q arm64 || { echo '[ERROR] arm64 slice missing'; exit 1; } + +echo '--- Verify exports ---' +EXPORTS=$(nm -gU "$DYLIB" | grep -cE 'GetClassNames|GetClassObject|DestroyObject|SetPlatformCapabilities' || true) +echo "Exports found: ${EXPORTS}/4" +[ "$EXPORTS" -eq 4 ] || { echo '[ERROR] Not all 4 required 1C Native API exports found'; exit 1; } + +echo '--- Ad-hoc code signing (avoids hardened-runtime load rejection) ---' +codesign --force --sign - "$DYLIB" + +echo "Done: ${SCRIPT_DIR}/${DYLIB}" diff --git a/native_components/ToonConverter/build_macos.sh b/native_components/ToonConverter/build_macos.sh new file mode 100755 index 0000000..0b459ca --- /dev/null +++ b/native_components/ToonConverter/build_macos.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Build a 1C Native API component for macOS as a universal (x86_64 + arm64) .dylib. +# +# Why universal: the 1C:Enterprise client on macOS ships as an x86_64 binary and +# runs under Rosetta 2 on Apple Silicon. An arm64-only library cannot be loaded +# into that x86_64 process and fails with "Тип не определен (AddIn.*.*)". +# A universal binary works both natively and under Rosetta. +# +# Requirements: CMake 3.16+, Apple clang (Xcode Command Line Tools). +# No Docker, no Python — just the native toolchain. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NAME="$(basename "$SCRIPT_DIR")" +cd "$SCRIPT_DIR" + +rm -rf build_macos +cmake -B build_macos -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" +cmake --build build_macos -j"$(sysctl -n hw.ncpu)" + +DYLIB="build_macos/${NAME}.dylib" + +echo '--- Verify architectures ---' +lipo -archs "$DYLIB" +lipo -archs "$DYLIB" | grep -q x86_64 || { echo '[ERROR] x86_64 slice missing'; exit 1; } +lipo -archs "$DYLIB" | grep -q arm64 || { echo '[ERROR] arm64 slice missing'; exit 1; } + +echo '--- Verify exports ---' +EXPORTS=$(nm -gU "$DYLIB" | grep -cE 'GetClassNames|GetClassObject|DestroyObject|SetPlatformCapabilities' || true) +echo "Exports found: ${EXPORTS}/4" +[ "$EXPORTS" -eq 4 ] || { echo '[ERROR] Not all 4 required 1C Native API exports found'; exit 1; } + +echo '--- Ad-hoc code signing (avoids hardened-runtime load rejection) ---' +codesign --force --sign - "$DYLIB" + +echo "Done: ${SCRIPT_DIR}/${DYLIB}"