.. _cmake_api: ============= CMake helpers ============= Consume apiary from CMake via ``find_package(Apiary)`` (installed) or ``add_subdirectory`` (vendored). Both provide: - ``apiary::apiary`` — the codegen executable. - ``apiary::annotations`` — an INTERFACE target carrying the ``APIARY_*`` macro header; link it instead of hardcoding the include path. …plus the helper functions below (lifted from their in-source documentation). ``apiary_detect_toolchain`` --------------------------- :: Probe ``CMAKE_CXX_COMPILER`` (or a conda clang++) for the include paths libtooling needs and cache them as: APIARY_RESOURCE_DIR - clang -resource-dir (builtin headers) APIARY_EXTRA_ISYSTEM - active conda env's include dir (third-party) APIARY_CXX_INCLUDE_DIRS - the compiler's C++ stdlib search dirs Without these even ``#include `` fails when the build compiler is gcc (libstdc++) rather than the clang that backs the apiary binary. ``apiary_collect_usage_requirements`` ------------------------------------- :: Recursively collect BUILD_INTERFACE include directories AND INTERFACE_COMPILE_DEFINITIONS reachable from via INTERFACE_LINK_LIBRARIES. CMake has no built-in for this; the walk is reliable since usage requirements are set explicitly via target_link_libraries / target_include_directories. apiary_collect_usage_requirements( INCLUDES_OUT DEFINES_OUT ) Genex-wrapped entries are unwrapped for BUILD_INTERFACE and dropped otherwise (config-conditional values can't be evaluated at configure time). ``apiary_add_bindings`` ----------------------- :: Emit the codegen custom command(s) that run apiary on one set of headers. apiary_add_bindings( HEADERS # parsed by apiary (positional) SOURCE_INCLUDES # --source-include each REGISTER_FUNCTION # --register-function (binding TU) MODULE # --module (docs json; default "module") DEPENDS_TARGETS # usage requirements -> -I / -D OUTPUT_DIR # where generated files land OUTPUT_NAME # base filename for outputs CXX_STANDARD # default 17 MAX_DEFS_PER_TU # split binding into shard TUs of ~n .def's EXTRA_FLAGS # extra -I/-D/... after -- EXTRA_DEPENDS # extra DEPENDS (e.g. Defines.hpp) BINDING # emit the pybind TU (+ stub) DOCS_JSON # emit the docs-json OUT_BINDING OUT_STUB OUT_DOCS_JSON ) MAX_DEFS_PER_TU > 0 splits the generated binding into several smaller TUs (``_pybind.shard.cpp``) so a heavily instantiated module doesn't compile as one TU large enough to exhaust memory. The shard count is discovered at configure time by running ``apiary --plan`` (so the OUT_BINDING list and the custom-command OUTPUTs are exact). This needs the apiary binary to already exist at configure time — true under find_package(Apiary); in add_subdirectory mode the tool isn't built yet, so sharding is skipped (with a status message) and a single TU is emitted. Computes flags = APIARY_SYSTEM_FLAGS + usage-requirements(DEPENDS_TARGETS) + EXTRA_FLAGS + -std, and sets the requested OUT_* variables in the caller's scope. Requires apiary_detect_toolchain() to have run. ``apiary_aggregate_extension`` ------------------------------ :: Assemble per-module bindings into one Python extension. apiary_aggregate_extension( NAME # pybind11 module target to create MAIN # consumer's PYBIND11_MODULE source BINDINGS # per-module binding TUs (from apiary_add_bindings) MODULES # modules to register REGISTER_PREFIX

# default apiary_register_ MODULES_HEADER # generated header declaring all() MODULES_INCLUDE_DIR

# added to the target so MAIN finds the header # optional .pyi aggregation: STUBS STUBS_TARGET FRAG_DIR PKG_DIR PY_HELPERS_DIR PY_HELPER_DEPENDS # optional consumer-provided overlay for runtime-patched members the # codegen can't see (content + target-class regex are the caller's): STUB_OVERLAY STUB_OVERLAY_CLASS_REGEX # optional docs render (built on demand, not part of ALL): DOCS_JSON DOCS_TARGET DOCS_OUTDIR ) Generates the register header, creates the pybind11 module (the consumer configures output name / linkage / packaging afterward), and — when the optional groups are given — wires the stub-aggregation (ALL) and docs-render (on-demand) targets using Apiary's bundled scripts (APIARY_SCRIPTS_DIR).