C++ wrapper exposing the GIAC computer algebra system to Julia via CxxWrap.jl. Normally consumed through Giac.jl, which pulls a pre-built binary of this wrapper from libgiac_julia_jll (built by BinaryBuilder against GIAC_jll's runtime). This repository is what you build locally if you are contributing to the wrapper itself.
- String-based evaluation through a free function
giac_eval(expr)that routes through a process-wide thread-local default context. - Per-context evaluation via
giac_eval(expr, ctx)so distinctGiacContextinstances isolate:=bindings and per-context configuration (#3). - Pre-parsed evaluation through
Gen::eval(),Gen::simplify(),Gen::expand(),Gen::factor().
- Tier 1 direct wrappers for ~25 common operations (skip the name-lookup step):
giac_sin/cos/tan/asin/acos/atan,giac_exp/ln/log10/sqrt,giac_abs/sign/floor/ceil,giac_re/im/conj,giac_normal/evalf,giac_diff/integrate/subst/solve/limit/series,giac_gcd/lcm/pow. - Tier 2 generic dispatch by giac function name:
apply_func0/1/2/3/N— calls any giac builtin or user-registered function with 0/1/2/3/N arguments.
- Construction helpers:
Gen(string),Gen(Int64),Gen(Float64),make_identifier,make_complex,make_fraction,make_vect,make_zint_from_bytes,make_symbolic_unevaluated. - Typed accessors:
to_int64/int32/double,zint_to_bytes/sign/string,cplx_re/im,frac_num/den,vect_size/at,symb_sommet_name/feuille,idnt_name,strng_value,map_size/keys/values,type/subtype/type_name. - Value predicates:
is_zero,is_one,is_integer,is_approx. Type predicates:is_numeric,is_vector,is_symbolic,is_identifier,is_fraction,is_complex,is_string. - Operators:
+ - * /and unary-with mixed-type overloads against JuliaInt64andFloat64;==/!=. - Direct pointer plumbing for zero-copy interop with Julia:
gen_to_heap_ptr,gen_from_heap_ptr,free_gen_ptr,gen_ptr_to_string,gen_ptr_type.
- Pre-loaded command database with
init_help(path_to_aide_cas)so giac never falls back to filesystem-search paths. list_commands(),help_count(),list_builtin_functions(),builtin_function_count(),list_all_functions()for command-table inspection.
- Warning handler hooks:
set_warning_handler,clear_warning_handlerfor routing giac warnings into custom callbacks. - Config:
set_xcasroot/get_xcasroot. Per-contextset_variable/get_variable,set_timeout/get_timeout,set_precision/get_precision, andset_complex_mode/is_complex_modeare implemented. Precision and complex mode route through GIAC's per-context accessors (decimal_digits,complex_mode) so they affect subsequentgiac_evalresults — e.g.factor(x^2+1)returns(x+i)*(x-i)only in complex mode, andevalf(pi)at precision 50 yields ~50 significant digits. Timeout round-trips per context with a default of 30.0 seconds; it is stored on the wrapper but does NOT currently interrupt long-running evaluations (real enforcement is deferred — seespecs/006-wire-config-getters-setters/). - Linux and macOS in CI (Ubuntu + macOS) are fully green. Windows has a known ABI issue that affects production Julia usage, not just CI:
- In CI, Windows builds the wrapper locally under MSYS2 (currently GCC 15.2) and links against
GIAC_jll(BinaryBuilder GCC 8). The mismatch with the artifact's runtime DLLs makes the test step fail, so it runs ascontinue-on-error. - For end users on Windows, the production path is
libgiac_julia_jll(BinaryBuilder GCC 10) +GIAC_jll(BinaryBuilder GCC 8). Even though both come from BinaryBuilder, a bitfield layout difference in giac'sgenstruct still leaks across the boundary: MPFR reals come back tagged as_DOUBLE_instead of_REAL_. Surfaced while reviewing Giac.jl#22; a string-length heuristic in Giac.jl is the current workaround. A proper fix likely requires rebuildingGIAC_jllwith the samepreferred_gcc_versionaslibgiac_julia_jll.
- In CI, Windows builds the wrapper locally under MSYS2 (currently GCC 15.2) and links against
- Julia 1.10+ (LTS supported; CI runs on 1.10).
- Meson 1.2+ and Ninja as the build system.
- C++17 compiler — GCC 7+ or Clang 5+ (required by libcxxwrap-julia).
- CMake — used by Meson to discover JlCxx (libcxxwrap-julia).
- GMP and MPFR development headers (
libgmp-dev libmpfr-devon Debian/Ubuntu,gmp mpfron Homebrew,mingw-w64-x86_64-{gmp,mpfr}on MSYS2). - gettext / libintl development headers on macOS (
brew install gettext); already part of glibc on Linux. - GIAC itself — one of:
- System install:
libgiac-devon Debian/Ubuntu, or build giac from source. Default include path is/usr/include/giac. GIAC_jll(Julia binary artifact, recommended — this is what CI uses):julia -e 'using Pkg; Pkg.add("GIAC_jll")', then pass the artifact path via-Dgiac_include_dir=$(julia -e 'using GIAC_jll; print(GIAC_jll.artifact_dir)')/include/giacto Meson.
- System install:
The wrapper is tested against giac 2.0.x. The version reported at runtime by wrapper_version() is driven from meson.project_version() so it never drifts from the build (#2).
julia -e 'using Pkg; Pkg.add(["CxxWrap", "GIAC_jll"])'
CXXWRAP_PREFIX=$(julia -e 'using CxxWrap; print(CxxWrap.prefix_path())')
GIAC_ARTIFACT=$(julia -e 'using GIAC_jll; print(GIAC_jll.artifact_dir)')
meson setup builddir \
--cmake-prefix-path="$CXXWRAP_PREFIX" \
-Dgiac_include_dir="$GIAC_ARTIFACT/include/giac"
meson compile -C builddirjulia -e 'using Pkg; Pkg.add("CxxWrap")'
meson setup builddir \
--cmake-prefix-path="$(julia -e 'using CxxWrap; print(CxxWrap.prefix_path())')"
meson compile -C builddir(Defaults to /usr/include/giac; override with -Dgiac_include_dir=... if needed.)
julia -e 'using Pkg; Pkg.add("CxxWrap")'
just setup
just buildThe justfile runs the system-giac path above; for the GIAC_jll path, use the explicit meson setup command.
meson test -C builddirOr just test. This runs the C++ test suites (test_eval, test_context, test_gen, test_extraction, test_predicates, test_warnings) — 6 suites total, all green on Linux and macOS. The tests/julia/ directory contains standalone Julia integration scripts that are not currently wired into meson test; downstream coverage from Julia lives in Giac.jl.
Most consumers should use Giac.jl for an idiomatic Julia API. To talk to the wrapper directly:
# Run from the repository root after `meson compile -C builddir`.
using CxxWrap
const libgiac = joinpath(pwd(), "builddir", "src", "libgiac_wrapper")
@wrapmodule(() -> libgiac)
@initcxx
# String-based eval against the default context
r = giac_eval("sin(x)+1")
println(to_string(r)) # "sin(x)+1"
# Per-context isolation
ctx1 = GiacContext()
ctx2 = GiacContext()
giac_eval("a := 5", ctx1)
to_string(giac_eval("a", ctx1)) # "5"
to_string(giac_eval("a", ctx2)) # "a" — ctx2 never saw the binding- Giac.jl — Julia package providing the idiomatic API on top of this wrapper.
- GIAC / Xcas — the underlying CAS.
- CxxWrap.jl / libcxxwrap-julia — the C++/Julia interop layer.
GPL-3.0-or-later. See LICENSE for the full text.