Skip to content
Merged
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
70 changes: 52 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,23 @@ if (ENABLE_COVERAGE)
add_link_options(--coverage)
endif ()

add_compile_options(-Wall -Wextra -Wpedantic)

#####################################
# External projects
#####################################
# simdjson

FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.12.0
jsoncons
GIT_REPOSITORY https://github.com/danielaparker/jsoncons.git
GIT_TAG v1.4.3
)
FetchContent_MakeAvailable(nlohmann_json)

set(JSONCONS_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(JSONCONS_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(JSONCONS_BUILD_FUZZERS OFF CACHE BOOL "" FORCE)

FetchContent_MakeAvailable(jsoncons)

if (BUILD_PYTHON_BINDINGS)
FetchContent_Declare(
Expand All @@ -66,22 +73,57 @@ if (BUILD_PYTHON_BINDINGS)
FetchContent_MakeAvailable(pybind11)
endif ()

#####################################
# Encode CAPIO-CL JSON Schemas
#####################################
set(CAPIOCL_JSON_SCHEMAS_DIRECTORY "${CMAKE_BINARY_DIR}/schemas")
set(OUTPUT_HEADER "${CAPIOCL_JSON_SCHEMAS_DIRECTORY}/capio_cl_json_schemas.hpp")
file(GLOB SCHEMA_FILES "${CMAKE_SOURCE_DIR}/schema/*.json")

set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/schema*.json")

file(WRITE ${OUTPUT_HEADER} "// Bundled CAPIO-CL encoded JSON schemas\n")
file(APPEND ${OUTPUT_HEADER} "#pragma once\n\n")

foreach (SCHEMA_FILE ${SCHEMA_FILES})
get_filename_component(SCHEMA_NAME ${SCHEMA_FILE} NAME_WE)
get_filename_component(SCHEMA_BASENAME ${SCHEMA_FILE} NAME)
message(STATUS "Bundling CAPIO-CL schema: ${SCHEMA_BASENAME}")
file(APPEND ${OUTPUT_HEADER} "// CAPIO-CL version: ${SCHEMA_NAME}\n")

execute_process(
COMMAND xxd -i ${SCHEMA_BASENAME}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/schema
OUTPUT_VARIABLE HEXDATA
RESULT_VARIABLE RES
)
if (NOT RES EQUAL 0)
message(FATAL_ERROR "xxd failed for ${SCHEMA_FILE}")
endif ()

file(APPEND ${OUTPUT_HEADER} "${HEXDATA}\n\n")
endforeach ()

message(STATUS "Generated header: ${OUTPUT_HEADER}")

#####################################
# Sources and headers
#####################################
file(GLOB_RECURSE CAPIO_SRC CONFIGURE_DEPENDS "src/*.cpp")
set(CAPIO_CL_HEADERS capiocl.hpp)

# Library target (for use with external projects)
# Library target
add_library(libcapio_cl STATIC ${CAPIO_SRC} ${CAPIO_CL_HEADERS})

target_include_directories(libcapio_cl PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src
${nlohmann_json_SOURCE_DIR}/include
${jsoncons_SOURCE_DIR}/include
${CAPIOCL_JSON_SCHEMAS_DIRECTORY}
)

# jsoncons is header-only, no linking required
target_link_libraries(libcapio_cl PUBLIC)

#####################################
# Install rules
Expand All @@ -90,22 +132,18 @@ install(TARGETS libcapio_cl
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)


#####################################
# Python bindings
#####################################
if (BUILD_PYTHON_BINDINGS)

set(PYTHON_BIND_NAME _py_capio_cl)

pybind11_add_module(${PYTHON_BIND_NAME}
bindings/python_bindings.cpp
)


# Make sure the binding sees the CAPIO CL headers & links against the core lib
target_link_libraries(${PYTHON_BIND_NAME}
PRIVATE libcapio_cl
target_link_libraries(${PYTHON_BIND_NAME} PRIVATE
libcapio_cl
)

target_include_directories(${PYTHON_BIND_NAME}
Expand All @@ -114,10 +152,8 @@ if (BUILD_PYTHON_BINDINGS)
)

install(TARGETS _py_capio_cl DESTINATION py_capio_cl)

endif ()


#####################################
# Tests (only when built standalone)
#####################################
Expand Down Expand Up @@ -161,14 +197,12 @@ if (CAPIO_CL_BUILD_TESTS)
)

#####################################
# Install rules
# Install rules for tests
#####################################
# Optionally install tests
install(TARGETS CAPIO_CL_tests
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

# Copy tests jsons
install(DIRECTORY ${TEST_JSON_DIR}
DESTINATION ${CMAKE_INSTALL_BINDIR}/jsons
FILES_MATCHING PATTERN "*.json"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ At runtime, CAPIO-CL’s parser and engine components analyze, track, and manage
### Requirements & dependencies
- C++17 or greater
- Cmake 3.15 or newer
- [nlohmann/json](https://github.com/nlohmann/json) to parse JSON config files
- [danielaparker/jsoncons](https://github.com/danielaparker/jsoncons) to parse, serialize and validate CAPIO-CL JSON config files
- [GoogleTest](https://github.com/google/googletest) for automated testing

All dependencies are fetched automatically by CMake — no manual setup required.
Expand Down
6 changes: 1 addition & 5 deletions capiocl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ constexpr char UPDATE[] = "update";
namespace commit_rules {
constexpr char ON_CLOSE[] = "on_close";
constexpr char ON_FILE[] = "on_file";
constexpr char N_FILES[] = "n_files";
constexpr char N_FILES[] = "on_n_files";
constexpr char ON_TERMINATION[] = "on_termination";
} // namespace commit_rules

Expand Down Expand Up @@ -413,10 +413,6 @@ class Engine {
*
*/
class Parser {

static std::filesystem::path resolve(std::filesystem::path path,
const std::filesystem::path &prefix);

public:
/**
* @brief Perform the parsing of the capio_server configuration file
Expand Down
220 changes: 220 additions & 0 deletions schema/v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CAPIO-CL Configuration Schema",
"type": "object",

"definitions": {
"streaming_name_rule": {
"type": "object",
"properties": {
"name": {
"type": "array",
"description": "Filenames to which the rule applies.",
"items": { "type": "string" }
},
"committed": {
"type": "string",
"description": "Commit rule associated with the file.",
"pattern": "^(on_close(:[0-9]+)?|on_file|on_termination)$"
},
"mode": {
"type": "string",
"description": "Firing rule associated with the files.",
"enum": ["update", "no_update"]
},
"file_deps": {
"type": "array",
"description": "List of dependent files required when committed = on_file.",
"items": { "type": "string" }
},
"n_files": {
"type": "integer",
"description": "Number of files expected when commit rule == n_files."
}
},
"required": ["name"],
"additionalProperties": false,

"if": {
"properties": {
"committed": { "pattern": "^on_file" }
},
"required": ["committed"]
},
"then": {
"required": ["file_deps"]
}
},

"streaming_dirname_rule": {
"type": "object",
"properties": {
"dirname": {
"type": "array",
"description": "Directory names to which the rule applies.",
"items": { "type": "string" }
},
"committed": {
"type": "string",
"description": "Commit rule associated with the directory.",
"pattern": "^(on_close(:[0-9]+)?|on_file|on_n_files|on_termination)$"
},
"mode": {
"type": "string",
"description": "Firing rule associated with the directory contents.",
"enum": ["update", "no_update"]
},
"file_deps": {
"type": "array",
"description": "List of dependent files required when committed = on_file.",
"items": { "type": "string" }
},
"n_files": {
"type": "integer",
"description": "Number of files expected when commit rule == n_files."
}
},
"required": ["dirname"],
"additionalProperties": false,

"allOf": [
{
"if": {
"properties": {
"committed": { "pattern": "^on_file" }
},
"required": ["committed"]
},
"then": {
"required": ["file_deps"]
}
},
{
"if": {
"properties": {
"committed": { "pattern": "^on_n_files" }
},
"required": ["committed"]
},
"then": {
"required": ["n_files"]
}
}
]
}
},
"properties": {
"name": {
"type": "string",
"description": "Identifies the application workflow."
},

"aliases": {
"type": "array",
"description": "Groups files or directories under a convenient name.",
"items": {
"type": "object",
"properties": {
"group_name": { "type": "string" },
"files": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["group_name", "files"],
"additionalProperties": false
}
},

"IO_Graph": {
"type": "array",
"description": "Describes file data dependencies among application modules.",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },

"input_stream": {
"type": "array",
"items": { "type": "string" }
},

"output_stream": {
"type": "array",
"items": { "type": "string" }
},

"streaming": {
"type": "array",
"items": {
"oneOf": [
{ "$ref": "#/definitions/streaming_name_rule" },
{ "$ref": "#/definitions/streaming_dirname_rule" }
]
}
}
},
"required": ["name", "input_stream", "output_stream"],
"additionalProperties": false
}
},

"permanent": {
"type": "array",
"items": { "type": "string" }
},

"exclude": {
"type": "array",
"items": { "type": "string" }
},

"home_node_policies": {
"type": "object",
"properties": {
"create": {
"type": "array",
"items": { "type": "string" }
},
"hashing": {
"type": "array",
"items": { "type": "string" }
},
"manual": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "array",
"items": { "type": "string" }
},
"app_node": { "type": "string" }
},
"required": ["name", "app_node"],
"additionalProperties": false
}
}
},
"additionalProperties": false
},

"storage": {
"type": "object",
"properties": {
"memory": {
"type": "array",
"items": { "type": "string" }
},
"fs": {
"type": "array",
"items": { "type": "string" }
}
},
"additionalProperties": false
}
},

"required": ["name", "IO_Graph"],
"additionalProperties": false
}
Loading
Loading