Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions recipes/recipes_emscripten/llguidance/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash
set -e

echo "=========================================="
echo "Building llguidance for emscripten-wasm32"
echo "=========================================="

# Add wasm32-unknown-emscripten target for Rust
rustup target add wasm32-unknown-emscripten

# Build the parser crate with WASM-appropriate features
# Disable rayon (threading not available in WASM)
# Disable wasm feature (uses instant crate which calls _emscripten_get_now,
# not available in side modules; std::time::Instant works instead)
# Keep lark (grammar syntax) and referencing (JSON $ref support)
# Use cargo rustc with --crate-type staticlib to avoid cdylib build,
# which fails on emscripten when SIDE_MODULE=2 exports Rust-mangled symbols
# (e.g. serde_json::value::Index) that contain invalid export name characters.
cargo rustc \
--target wasm32-unknown-emscripten \
--release \
--package llguidance \
--no-default-features \
--features "lark,referencing" \
--crate-type staticlib

echo "Installing library and headers..."

# Install static library
mkdir -p $PREFIX/lib
cp target/wasm32-unknown-emscripten/release/libllguidance.a $PREFIX/lib/

# Install C header (pre-generated, committed in repo)
mkdir -p $PREFIX/include
cp parser/llguidance.h $PREFIX/include/

# Install CMake config files
mkdir -p $PREFIX/lib/cmake/llguidance

# llguidanceConfigVersion.cmake
cat > $PREFIX/lib/cmake/llguidance/llguidanceConfigVersion.cmake << 'CMAKE_EOF'
set(PACKAGE_VERSION "LLG_VERSION_PLACEHOLDER")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
if(PACKAGE_VERSION MATCHES "^([0-9]+)\\.")
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
else()
set(CVF_VERSION_MAJOR "${PACKAGE_VERSION}")
endif()

if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()

if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
CMAKE_EOF
sed -i "s/LLG_VERSION_PLACEHOLDER/${PKG_VERSION}/" $PREFIX/lib/cmake/llguidance/llguidanceConfigVersion.cmake

# llguidanceConfig.cmake
cat > $PREFIX/lib/cmake/llguidance/llguidanceConfig.cmake << 'CMAKE_EOF'
include("${CMAKE_CURRENT_LIST_DIR}/llguidanceTargets.cmake")
CMAKE_EOF

# llguidanceTargets.cmake
cat > $PREFIX/lib/cmake/llguidance/llguidanceTargets.cmake << 'CMAKE_EOF'
if(NOT TARGET llguidance::llguidance)
add_library(llguidance::llguidance STATIC IMPORTED)
set_target_properties(llguidance::llguidance PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/../../libllguidance.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/../../../include"
)
endif()
CMAKE_EOF

echo "=========================================="
echo "llguidance build complete"
echo "=========================================="
24 changes: 24 additions & 0 deletions recipes/recipes_emscripten/llguidance/build_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
set -e

echo "=========================================="
echo "Building llguidance tests..."
echo "=========================================="

mkdir -p build_tests
cd build_tests

emcmake cmake ../tests \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=$PREFIX \
-DCMAKE_FIND_ROOT_PATH=$PREFIX

emmake ninja

echo "Running llguidance tests..."
node test_llguidance.js

echo "=========================================="
echo "All llguidance tests passed!"
echo "=========================================="
59 changes: 59 additions & 0 deletions recipes/recipes_emscripten/llguidance/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
context:
version: 1.7.5
name: llguidance-cpp

package:
name: ${{ name }}
version: ${{ version }}

source:
url: https://github.com/guidance-ai/llguidance/archive/refs/tags/v${{ version }}.tar.gz
sha256: 45791cba890ea8e2109de30a26634ad2f5645d63fcba354b98787ae9294ba5cd

build:
number: 0

requirements:
build:
- rust-nightly
- ${{ compiler('c') }}
- ${{ compiler('cxx') }}

tests:
- package_contents:
lib:
- libllguidance.a
include:
- llguidance.h
files:
- lib/cmake/llguidance/llguidanceConfig.cmake
- lib/cmake/llguidance/llguidanceConfigVersion.cmake
- script:
- bash build_tests.sh
requirements:
build:
- ${{ compiler('cxx') }}
- cmake
- ninja
files:
recipe:
- build_tests.sh
- tests/

about:
homepage: https://github.com/guidance-ai/llguidance
license: MIT
license_family: MIT
license_file: LICENSE
summary: Low-level guidance library for constrained LLM token generation
description: |
llguidance is a low-level library for constrained LLM token generation.
It provides a C API for guiding LLM output through grammars, regex,
JSON schemas, and Lark grammars. Includes an Earley parser for efficient
token mask computation.
documentation: https://github.com/guidance-ai/llguidance
repository: https://github.com/guidance-ai/llguidance

extra:
recipe-maintainers:
- Alex-PLACET
17 changes: 17 additions & 0 deletions recipes/recipes_emscripten/llguidance/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.20)
project(llguidance_test CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(llguidance REQUIRED)

add_executable(test_llguidance test_llguidance.cpp)
target_link_libraries(test_llguidance PRIVATE llguidance::llguidance)

if(EMSCRIPTEN)
target_link_options(test_llguidance PRIVATE
-sALLOW_MEMORY_GROWTH=1
-sINITIAL_MEMORY=64MB
)
endif()
Loading