-
Notifications
You must be signed in to change notification settings - Fork 9
Embedding OmegaEdit Core
Ωedit™ core is already structured to be embedded directly into another native project. This page documents the three supported integration patterns and the runtime tradeoffs to think through before you ship.
Use one of these patterns depending on how much of the Ωedit™ repository you want to bring into your build:
-
add_subdirectory(<omega-edit-repo>)Best when you vendor the full repository and want Ωedit™ to behave like a lean subproject.
-
add_subdirectory(<omega-edit-repo>/core)Best when you only want the native core library and do not need the packaging layer at all.
-
find_package(omega_edit CONFIG REQUIRED)Best when Ωedit™ has already been installed to a prefix and you want consumers to link against the installed package.
In all three cases, the primary target is the same:
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)That target already carries the public include path, so consumers can include headers like:
#include "omega_edit/edit.h"
#include "omega_edit/session.h"The repo root supports an embedding mode specifically for downstream native projects:
set(OMEGA_EDIT_EMBED_MODE ON CACHE BOOL "" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) # or ON
add_subdirectory(extern/omega-edit)
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)Why this mode exists:
- disables Ωedit™ tests
- disables docs generation
- disables examples
- disables coverage instrumentation
- skips the packaging layer that is only needed for install/export workflows
Use this path when you vendor the full repo but want the embedded build to stay small and predictable.
If you only need the native editing library, you can consume the core/ directory directly:
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) # or ON
add_subdirectory(extern/omega-edit/core)
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)This is the smallest CMake integration path. core/CMakeLists.txt intentionally duplicates the key options from the repo root so that core/ can stand on its own as a subproject.
Good fit for:
- embedding Ωedit™ beneath another native engine
- monorepos that already own their packaging story
- projects that do not want the repo-root packaging/install targets
If Ωedit™ has already been installed to a prefix, use the exported package config:
find_package(omega_edit CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)If you want to force a specific linkage style, request the package component explicitly:
find_package(omega_edit CONFIG REQUIRED COMPONENTS static)
# or
find_package(omega_edit CONFIG REQUIRED COMPONENTS shared)
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)Ωedit™'s installed package config understands static and shared components and loads the matching exported target file for you.
Typical install flow from this repo:
cmake -S . -B _build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
cmake --build _build --config Release
cmake --install _build --config Release --prefix _installThen point your downstream project at that prefix using CMAKE_PREFIX_PATH or your normal toolchain/package-manager mechanism.
Ωedit™ supports both shared and static builds. The right choice depends mostly on deployment constraints, not on API shape.
Best when you want:
- the simplest runtime deployment
- no separate Ωedit™ DLL /
.so/.dylib - easier shipping inside a single native executable or tightly controlled plugin package
Tradeoffs:
- larger binaries
- slower relinks during development
- less flexibility if multiple processes/plugins should share one runtime copy
Best when you want:
- smaller application binaries
- a separable Ωedit™ runtime artifact
- easier replacement of the core library without relinking the embedding app
Tradeoffs:
- the shared library must be deployed where the runtime loader can find it
- Windows packaging is usually a little more explicit than static linking
If you build Ωedit™ as a shared library on Windows, make sure omega_edit.dll is deployed beside your executable, or otherwise available on PATH.
The usual "works everywhere" rule is:
- put
omega_edit.dllnext tomy_app.exe
If you are packaging with CMake, a post-build copy step is a practical default:
add_custom_command(TARGET my_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:omega_edit::omega_edit>
$<TARGET_FILE_DIR:my_app>
)If you are using modern CMake and multiple shared dependencies, you can also use runtime-DLL copying on Windows:
add_custom_command(TARGET my_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_RUNTIME_DLLS:my_app>
$<TARGET_FILE_DIR:my_app>
COMMAND_EXPAND_LISTS
)Notes:
- when Ωedit™ is built statically, no separate Ωedit™ DLL is needed at runtime
- your C/C++ runtime deployment still follows your toolchain choice (
/MDvs/MT, vcpkg triplet, etc.); Ωedit™ does not add a separate runtime policy beyond the one your build already uses
For most embedding scenarios, the minimal requirement is just:
target_link_libraries(my_app PRIVATE omega_edit::omega_edit)You do not need to manually add the public include directory when you link the exported target.
Typical headers:
-
omega_edit/edit.hfor session lifecycle and edit operations -
omega_edit/session.hfor reading computed session state -
omega_edit/segment.hfor working with retrieved byte segments -
omega_edit/search.hif you want direct search contexts -
omega_edit/viewport.hif your host application wants viewport-style reads
Ωedit™ works well underneath another workflow engine, parser, editor shell, or rewrite system. A common pattern looks like this:
- Open a session from a file or in-memory bytes.
- Translate your engine's logical operations into Ωedit™ inserts, deletes, and overwrites.
- Read computed data back through
omega_session_get_segmentwhen you need materialized bytes. - Save to disk with
omega_edit_saveor keep working in-memory until your host decides to persist. - Destroy the session when the workflow is complete.
Minimal native flow:
#include "omega_edit/edit.h"
#include "omega_edit/segment.h"
#include "omega_edit/session.h"
int main(void) {
omega_session_t *session =
omega_edit_create_session("input.dat", NULL, NULL, NO_EVENTS, NULL);
if (!session) return 1;
omega_edit_insert(session, 0, "HDR", 3);
omega_segment_t *segment = omega_segment_create(16);
if (segment) {
if (omega_session_get_segment(session, segment, 0) == 0) {
/* consume the computed bytes here */
}
omega_segment_destroy(segment);
}
omega_edit_save(session, "output.dat", IO_FLG_OVERWRITE, NULL);
omega_edit_destroy_session(session);
return 0;
}Why this pattern is useful:
- Ωedit™ gives your host system undo/redo, checkpointing, and large-file-safe edits without forcing you to design those primitives yourself.
- Your application can keep its own higher-level transaction or workflow model while delegating byte-accurate edit bookkeeping to Ωedit™.
- You can adopt only the core session/edit APIs first and add search, viewports, profiling, or transforms later.
If you are choosing quickly:
- use repo-root
OMEGA_EDIT_EMBED_MODE=ONwhen vendoring the whole repository - use
core/directly when you only want the native library as a subproject - use
find_package(omega_edit CONFIG REQUIRED COMPONENTS static)when you want the simplest installed-package deployment story - prefer static linking first for embedded tools, plugins, and internal engines unless you have a strong reason to ship a shared runtime
- prefer shared linking when multiple packaged components need to reuse the same Ωedit™ binary or when swapping the runtime independently matters