-
Notifications
You must be signed in to change notification settings - Fork 99
MINIFICPP-2715 - Use symbols to check api compatibility #2105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6f2c864
d846444
f92032f
4619de4
9667386
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -17,8 +17,41 @@ | |||||
| To enable all extensions for your platform, you may use -DENABLE_ALL=TRUE OR select the option to "Enable all Extensions" in the bootstrap script. [ReadMe](https://github.com/apache/nifi-minifi-cpp/#bootstrapping) | ||||||
|
|
||||||
| # Extension internals | ||||||
| Extensions are dynamic libraries loaded at runtime by the agent. An extension makes its | ||||||
| capabilities (classes) available to the system through registrars. Registration must happen in source files, not headers. | ||||||
| Extensions are dynamic libraries loaded at runtime by the agent. | ||||||
|
|
||||||
| ## C extensions | ||||||
| You can build a shared library depending on the C capabilities of the agent as given in the `minifi-c.h` file. | ||||||
| For the shared library to be considered a valid extension, it has to have a global symbol with the name `MinifiCApiVersion` | ||||||
| with its value as a null terminated string (`const char*`) of the macro `MINIFI_API_VERSION` from `minifi-c.h`. | ||||||
|
|
||||||
| Moreover the actual resource registration (processors/controller services) has to happen during the `MinifiInitExtension` call. | ||||||
| One possible example of this is: | ||||||
|
|
||||||
| ```C++ | ||||||
| extern "C" const char* const MinifiApiVersion = MINIFI_API_VERSION; | ||||||
|
|
||||||
| extern "C" MinifiExtension* MinifiInitExtension(MinifiConfig* /*config*/) { | ||||||
| MinifiExtension* extension = nullptr; | ||||||
| minifi::api::core::useProcessorClassDescription<minifi::extensions::llamacpp::processors::RunLlamaCppInference>([&] (const MinifiProcessorClassDefinition& description) { | ||||||
| MinifiExtensionCreateInfo ext_create_info{ | ||||||
| .name = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_NAME)), | ||||||
| .version = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_VERSION)), | ||||||
| .deinit = nullptr, | ||||||
| .user_data = nullptr, | ||||||
| .processors_count = 1, | ||||||
| .processors_ptr = &description, | ||||||
| }; | ||||||
| extension = MinifiCreateExtension(&ext_create_info); | ||||||
| }); | ||||||
| return extension; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ## C++ extensions | ||||||
| You can utilize the C++ api, linking to `minifi-api` and possibly using the helpers in `extension-framework`. | ||||||
| No compatibilities are guaranteed beyond what extensions are built together with the agent at the same time. | ||||||
|
|
||||||
| An extension makes its capabilities (classes) available to the system through registrars. Registration must happen in source files, not headers. | ||||||
|
|
||||||
| ```C++ | ||||||
| // register user-facing classes as | ||||||
|
|
@@ -33,10 +66,10 @@ REGISTER_RESOURCE(RESTSender, DescriptionOnly); | |||||
| ``` | ||||||
|
|
||||||
| Some extensions (e.g. `OpenCVExtension`) require initialization before use. | ||||||
| You need to define an `InitExtension` function of type `MinifiExtension*(MinifiConfig*)` to be called. | ||||||
| You need to define an `MinifiInitCppExtension` function of type `MinifiExtension*(MinifiConfig*)` to be called. | ||||||
|
|
||||||
| ```C++ | ||||||
| extern "C" MinifiExtension* InitExtension(MinifiConfig* /*config*/) { | ||||||
| extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* /*config*/) { | ||||||
| const auto success = org::apache::nifi::minifi::utils::Environment::setEnvironmentVariable("OPENCV_FFMPEG_CAPTURE_OPTIONS", "rtsp_transport;udp", false /*overwrite*/); | ||||||
| if (!success) { | ||||||
| return nullptr; | ||||||
|
|
@@ -49,7 +82,7 @@ extern "C" MinifiExtension* InitExtension(MinifiConfig* /*config*/) { | |||||
| .processors_count = 0, | ||||||
| .processors_ptr = nullptr | ||||||
| }; | ||||||
| return MinifiCreateExtension(minifi::utils::toStringView(MINIFI_API_VERSION), &ext_create_info); | ||||||
| return MinifiCreateCppExtension(&ext_create_info); | ||||||
|
||||||
| return MinifiCreateCppExtension(&ext_create_info); | |
| return minifi::utils::MinifiCreateCppExtension(&ext_create_info); |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,29 +22,14 @@ define_property(GLOBAL PROPERTY EXTENSION-OPTIONS | |||||||
|
|
||||||||
| set_property(GLOBAL PROPERTY EXTENSION-OPTIONS "") | ||||||||
|
|
||||||||
| set(extension-build-info-file "${CMAKE_CURRENT_BINARY_DIR}/ExtensionBuildInfo.cpp") | ||||||||
| file(GENERATE OUTPUT ${extension-build-info-file} | ||||||||
| CONTENT "\ | ||||||||
| #include \"minifi-cpp/utils/Export.h\"\n\ | ||||||||
| #ifdef BUILD_ID_VARIABLE_NAME\n\ | ||||||||
| EXTENSIONAPI extern const char* const BUILD_ID_VARIABLE_NAME = \"__EXTENSION_BUILD_IDENTIFIER_BEGIN__${BUILD_IDENTIFIER}__EXTENSION_BUILD_IDENTIFIER_END__\";\n\ | ||||||||
| #else\n\ | ||||||||
| static_assert(false, \"BUILD_ID_VARIABLE_NAME is not defined\");\n\ | ||||||||
| #endif\n") | ||||||||
|
|
||||||||
| function(get_build_id_variable_name extension-name output) | ||||||||
| string(REPLACE "-" "_" result ${extension-name}) | ||||||||
| string(APPEND result "_build_identifier") | ||||||||
| set("${output}" "${result}" PARENT_SCOPE) | ||||||||
| endfunction() | ||||||||
|
|
||||||||
| macro(register_extension extension-name extension-display-name extension-guard description) | ||||||||
| set(${extension-guard} ${extension-name} PARENT_SCOPE) | ||||||||
| get_property(extensions GLOBAL PROPERTY EXTENSION-OPTIONS) | ||||||||
| set_property(GLOBAL APPEND PROPERTY EXTENSION-OPTIONS ${extension-name}) | ||||||||
| get_build_id_variable_name(${extension-name} build-id-variable-name) | ||||||||
| set_source_files_properties(${extension-build-info-file} PROPERTIES GENERATED TRUE) | ||||||||
| target_sources(${extension-name} PRIVATE ${extension-build-info-file}) | ||||||||
| get_target_property(has_custom_initializer ${extension-name} HAS_CUSTOM_INITIALIZER) | ||||||||
| if (NOT has_custom_initializer) | ||||||||
| target_sources(${extension-name} PRIVATE ${CMAKE_SOURCE_DIR}/extensions/ExtensionInitializer.cpp) | ||||||||
| endif() | ||||||||
| target_compile_definitions(${extension-name} | ||||||||
| PRIVATE "MODULE_NAME=${extension-name}" | ||||||||
| PRIVATE "BUILD_ID_VARIABLE_NAME=${build-id-variable-name}") | ||||||||
|
Comment on lines
34
to
35
|
||||||||
| PRIVATE "MODULE_NAME=${extension-name}" | |
| PRIVATE "BUILD_ID_VARIABLE_NAME=${build-id-variable-name}") | |
| PRIVATE "MODULE_NAME=${extension-name}") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /** | ||
| * | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #include "minifi-c/minifi-c.h" | ||
| #include "utils/ExtensionInitUtils.h" | ||
| #include "minifi-cpp/agent/agent_version.h" | ||
| #include "core/Resource.h" | ||
|
|
||
| namespace minifi = org::apache::nifi::minifi; | ||
|
|
||
| extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* /*config*/) { | ||
| MinifiExtensionCreateInfo ext_create_info{ | ||
| .name = minifi::utils::toStringView(MAKESTRING(MODULE_NAME)), | ||
| .version = minifi::utils::toStringView(minifi::AgentBuild::VERSION), | ||
| .deinit = nullptr, | ||
| .user_data = nullptr, | ||
| .processors_count = 0, | ||
| .processors_ptr = nullptr | ||
| }; | ||
| return minifi::utils::MinifiCreateCppExtension(&ext_create_info); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -33,7 +33,7 @@ static minifi::extensions::python::PythonCreator& getPythonCreator() { | |||||
| // the symbols of the python library | ||||||
| extern "C" const int LOAD_MODULE_AS_GLOBAL = 1; | ||||||
|
|
||||||
| extern "C" MinifiExtension* InitExtension(MinifiConfig* config) { | ||||||
| extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* config) { | ||||||
| getPythonCreator().configure([&] (std::string_view key) -> std::optional<std::string> { | ||||||
| std::optional<std::string> result; | ||||||
| MinifiConfigGet(config, minifi::utils::toStringView(key), [] (void* user_data, MinifiStringView value) { | ||||||
|
|
@@ -49,5 +49,5 @@ extern "C" MinifiExtension* InitExtension(MinifiConfig* config) { | |||||
| .processors_count = 0, | ||||||
| .processors_ptr = nullptr | ||||||
| }; | ||||||
| return MinifiCreateExtension(minifi::utils::toStringView(MINIFI_API_VERSION), &ext_create_info); | ||||||
| return minifi::utils::MinifiCreateCppExtension( &ext_create_info); | ||||||
|
||||||
| return minifi::utils::MinifiCreateCppExtension( &ext_create_info); | |
| return minifi::utils::MinifiCreateCppExtension(&ext_create_info); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states the symbol should be named
MinifiCApiVersion, but the actual code in Extension.cpp line 70 looks forMinifiApiVersion(without the "C"). The documentation should be corrected to match the implementation.