Skip to content

Commit d7ab16c

Browse files
committed
add extension for loading metacall*.json
1 parent 7ff9515 commit d7ab16c

File tree

5 files changed

+287
-0
lines changed

5 files changed

+287
-0
lines changed

source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ add_subdirectory(serial)
111111
add_subdirectory(configuration)
112112
add_subdirectory(loader)
113113
add_subdirectory(metacall)
114+
add_subdirectory(extensions)
114115

115116
# Loaders
116117
set(IDE_FOLDER "Loaders")

source/extensions/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#Check if extension loader is enabled
2+
if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_EXT)
3+
return()
4+
endif()
5+
6+
#
7+
# Sub-projects
8+
#
9+
10+
add_subdirectory(load_extensions)
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Target name
2+
set(target load_extensions)
3+
4+
# Exit here if required dependencies are not met
5+
message(STATUS "Script ${target}")
6+
7+
# Set API export file and macro
8+
string(TOUPPER ${target} target_upper)
9+
set(feature_file "include/${target}/${target}_features.h")
10+
set(export_file "include/${target}/${target}_api.h")
11+
set(export_macro "${target_upper}_API")
12+
13+
#
14+
# Compiler warnings
15+
#
16+
17+
include(Warnings)
18+
19+
#
20+
# Compiler security
21+
#
22+
23+
include(SecurityFlags)
24+
25+
#
26+
# Sources
27+
#
28+
29+
set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}")
30+
set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source")
31+
32+
set(headers
33+
${include_path}/load_extensions.h
34+
)
35+
36+
set(sources
37+
${source_path}/load_extensions.cpp
38+
)
39+
40+
# Group source files
41+
set(header_group "Header Files (API)")
42+
set(source_group "Source Files")
43+
source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$"
44+
${header_group} ${headers})
45+
source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$"
46+
${source_group} ${sources})
47+
48+
#
49+
# Create library
50+
#
51+
52+
# Build library
53+
add_library(${target} MODULE
54+
${sources}
55+
${headers}
56+
)
57+
58+
# Create namespaced alias
59+
add_library(${META_PROJECT_NAME}::${target} ALIAS ${target})
60+
61+
# Export library for downstream projects
62+
export(TARGETS ${target} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake)
63+
64+
# Create feature detection header
65+
# Compilers: https://cmake.org/cmake/help/v3.1/variable/CMAKE_LANG_COMPILER_ID.html#variable:CMAKE_%3CLANG%3E_COMPILER_ID
66+
# Feature: https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
67+
68+
# Check for availability of module; use pre-generated version if not found
69+
if (WriterCompilerDetectionHeaderFound)
70+
write_compiler_detection_header(
71+
FILE ${feature_file}
72+
PREFIX ${target_upper}
73+
COMPILERS AppleClang Clang GNU MSVC
74+
FEATURES cxx_alignas cxx_alignof cxx_constexpr cxx_final cxx_noexcept cxx_nullptr cxx_sizeof_member cxx_thread_local
75+
VERSION 3.2
76+
)
77+
else()
78+
file(
79+
COPY ${PROJECT_SOURCE_DIR}/codegeneration/${target}_features.h
80+
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/${target}
81+
USE_SOURCE_PERMISSIONS
82+
)
83+
endif()
84+
85+
# Create API export header
86+
generate_export_header(${target}
87+
EXPORT_FILE_NAME ${export_file}
88+
EXPORT_MACRO_NAME ${export_macro}
89+
)
90+
91+
#
92+
# Project options
93+
#
94+
95+
set_target_properties(${target}
96+
PROPERTIES
97+
${DEFAULT_PROJECT_OPTIONS}
98+
FOLDER "${IDE_FOLDER}"
99+
BUNDLE $<$<BOOL:${APPLE}>:$<$<VERSION_GREATER:${PROJECT_OS_VERSION},8>>>
100+
)
101+
102+
#
103+
# Include directories
104+
#
105+
106+
target_include_directories(${target}
107+
PRIVATE
108+
${PROJECT_BINARY_DIR}/source/include
109+
${CMAKE_CURRENT_SOURCE_DIR}/include
110+
${CMAKE_CURRENT_BINARY_DIR}/include
111+
112+
$<TARGET_PROPERTY:${META_PROJECT_NAME}::metacall,INCLUDE_DIRECTORIES> # MetaCall includes
113+
114+
PUBLIC
115+
${DEFAULT_INCLUDE_DIRECTORIES}
116+
117+
INTERFACE
118+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
119+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
120+
$<INSTALL_INTERFACE:include>
121+
)
122+
123+
#
124+
# Libraries
125+
#
126+
127+
target_link_libraries(${target}
128+
PRIVATE
129+
${META_PROJECT_NAME}::metacall # MetaCall library
130+
131+
PUBLIC
132+
${DEFAULT_LIBRARIES}
133+
134+
INTERFACE
135+
)
136+
137+
#
138+
# Compile definitions
139+
#
140+
141+
target_compile_definitions(${target}
142+
PRIVATE
143+
144+
PUBLIC
145+
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:${target_upper}_STATIC_DEFINE>
146+
${DEFAULT_COMPILE_DEFINITIONS}
147+
148+
INTERFACE
149+
)
150+
151+
#
152+
# Compile options
153+
#
154+
155+
target_compile_options(${target}
156+
PRIVATE
157+
158+
PUBLIC
159+
${DEFAULT_COMPILE_OPTIONS}
160+
161+
INTERFACE
162+
)
163+
164+
#
165+
# Linker options
166+
#
167+
168+
target_link_libraries(${target}
169+
PRIVATE
170+
171+
PUBLIC
172+
${DEFAULT_LINKER_OPTIONS}
173+
174+
INTERFACE
175+
)
176+
177+
set_property(TARGET ${target} PROPERTY CXX_STANDARD 17)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef LOAD_EXTENSIONS_H
2+
#define LOAD_EXTENSIONS_H 1
3+
4+
#include <dynlink/dynlink.h>
5+
#include <load_extensions/load_extensions_api.h>
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
LOAD_EXTENSIONS_API void load_extensions(void *loader, void *context);
12+
13+
DYNLINK_SYMBOL_EXPORT(load_extensions);
14+
15+
#ifdef __cplusplus
16+
}
17+
#endif
18+
19+
#endif //extension.h
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include <load_extensions/load_extensions.h>
2+
3+
#include <environment/environment_variable_path.h>
4+
#include <log/log.h>
5+
#include <metacall/metacall.h>
6+
7+
#include <assert.h>
8+
9+
#include <filesystem>
10+
#include <regex>
11+
#include <string>
12+
13+
#define METACALL_EXTENSIONS_PATH "METACALL_EXTENSIONS_PATH" /*ENV Variable for plugin path*/
14+
15+
namespace fs = std::filesystem;
16+
17+
std::string get_ext_path()
18+
{
19+
/* Initialize the library path */
20+
const char name[] = "metacall"
21+
#if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__))
22+
"d"
23+
#endif
24+
;
25+
26+
dynlink_library_path_str path;
27+
size_t length = 0;
28+
29+
/* The order of precedence is:
30+
* 1) Environment variable
31+
* 2) Dynamic link library path of the host library
32+
*/
33+
dynlink_library_path(name, path, &length); //TODO: check return value
34+
35+
char *lib_path = environment_variable_path_create(METACALL_EXTENSIONS_PATH, path, length + 1, NULL);
36+
if (!lib_path)
37+
{
38+
return "";
39+
}
40+
41+
fs::path tmp(lib_path);
42+
environment_variable_path_destroy(lib_path);
43+
tmp /= "extensions";
44+
return tmp.string();
45+
}
46+
47+
void load_extensions(void *loader, void *context)
48+
{
49+
std::regex metacall_json{ R"(metacall(-.+)?\.json$)" };
50+
std::string ext_path = get_ext_path();
51+
if (ext_path.empty())
52+
{
53+
/*TODO: log*/
54+
assert(!"Failed to get metacall lib path");
55+
}
56+
57+
struct metacall_allocator_std_type std_ctx = { &std::malloc, &std::realloc, &std::free };
58+
void *config_allocator = metacall_allocator_create(METACALL_ALLOCATOR_STD, (void *)&std_ctx);
59+
60+
auto i = fs::recursive_directory_iterator(ext_path);
61+
while (i != fs::recursive_directory_iterator())
62+
{
63+
if (i.depth() == 2)
64+
i.disable_recursion_pending();
65+
66+
fs::directory_entry dir(*i);
67+
if (dir.is_regular_file())
68+
{
69+
if (std::regex_match(dir.path().filename().c_str(), metacall_json))
70+
{
71+
metacall_load_from_configuration(dir.path().c_str(), NULL, config_allocator);
72+
i.pop();
73+
continue;
74+
}
75+
}
76+
i++;
77+
}
78+
79+
metacall_allocator_destroy(config_allocator);
80+
}

0 commit comments

Comments
 (0)