Skip to content

Commit 18ea656

Browse files
Automatically generate CMake targets for plugins with no 3rd party dependency (#41)
* Improve code quality Bring back support for 1.3- plugins Rename Common.cmake functions Move 1.4 specific target generation code to its own .cmake and support post target generation common function (for example; group every target in a folder) Auto-naming change: Instead of putting underscore for every dot, remove dots and join names with uppercase Don't create target for plugins with no Source folder Use CMakeLists.txt instead of CMake/Plugin.cmake Fix rust compilation warnings Use Common.cmake for repo's common cmakedependencies Use fixed .cmake location Delete unnecessary logs Add sdk dependency field to nosplugin & better nodos info command experience Add path argument to nosman info, allowing CMake to get info of a plugin in a specific folder Detect .cmake file in directory and call its function * Fix info.rs compilation * Support multiple flatbuffers types folders defined in .nosplugin and fix sdk target compilation due to min max definition * Support flatbuffers file paths in custom_types field & improve code quality * Rename manuel target generation code file * Rename post target creation function and old module keywords to plugin or package * Don't allow more than one .nosplugin to exist in the same directory * Add plugin name argument to nos_plugin_on_post_target_generated function to allow simpler switch cases * Support defining common definitions just like common dependencies and propagate them to subdirectories * Remove unnecessary messages, define NOS_DISABLE_DEPRECATED only if NOS_FORCE_DEPRECATED is given or nodos dev gen, rename Common.cmake -> NosPluginCommon.cmake * Remove NOMINMAX definition * Support creating targets with no source code * Optimization: Do not try to process directories without nosplugin files * Fix having to define info.dependency field in nosplugin * Rewrite manifest path based plugin info query * Use new nosman cli argument structure for info based on manifest path --------- Co-authored-by: Caner <caner.coskun@nodos.dev>
1 parent a558cc4 commit 18ea656

File tree

11 files changed

+655
-75
lines changed

11 files changed

+655
-75
lines changed

Toolchain/CMake/CMakeLists.txt

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ project(${PROJECT_NAME})
1212
include(${CMAKE_CURRENT_SOURCE_DIR}/Scripts/Utils.cmake)
1313

1414
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
15+
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
16+
set(CMAKE_CXX_STANDARD 20)
1517

1618
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
1719
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23 -Wno-changes-meaning -fpermissive -fPIC")
@@ -114,6 +116,7 @@ if (NOS_SDK_END_RANGE GREATER_EQUAL 1)
114116
if (nos_version VERSION_GREATER_EQUAL "1.4.0")
115117
set(sdk_root ${nos_sdk_dir}/Plugin)
116118
set(sdk_include_dir ${nos_sdk_dir}/Plugin/Include)
119+
set(USE_AUTO_TARGET_GENERATION TRUE)
117120
else()
118121
set(sdk_root ${nos_sdk_dir})
119122
set(sdk_include_dir ${nos_sdk_dir}/include)
@@ -135,7 +138,6 @@ if (NOS_SDK_END_RANGE GREATER_EQUAL 1)
135138

136139
# Create targets
137140
add_library(${nos_plugin_sdk_target} INTERFACE)
138-
target_compile_definitions(${nos_plugin_sdk_target} INTERFACE "-DNOMINMAX")
139141
target_include_directories(${nos_plugin_sdk_target} INTERFACE ${sdk_include_dir})
140142

141143
# Exclude from all
@@ -154,7 +156,6 @@ if (NOS_SDK_END_RANGE GREATER_EQUAL 1)
154156

155157
# Create nosSubsystemSDK target
156158
add_library(${nos_subsystem_sdk_target} INTERFACE)
157-
target_compile_definitions(${nos_subsystem_sdk_target} INTERFACE "-DNOMINMAX")
158159
target_include_directories(${nos_subsystem_sdk_target} INTERFACE ${sdk_include_dir})
159160
set_target_properties(${nos_subsystem_sdk_target} PROPERTIES EXCLUDE_FROM_ALL TRUE)
160161
if (EXISTS ${natvis_file})
@@ -244,36 +245,9 @@ if(NOT DEFINED MODULE_DIRS OR MODULE_DIRS STREQUAL "")
244245
set(MODULE_DIRS "${NODOS_WORKSPACE_DIR}/Module" CACHE INTERNAL "Plugin directories" FORCE)
245246
endif()
246247

247-
function(collect_first_cmake_directories dir out_dirs)
248-
file(GLOB SUBDIRS RELATIVE ${dir} ${dir}/*)
249-
250-
if(EXISTS "${dir}/CMakeLists.txt")
251-
set(${out_dirs} ${${out_dirs}} ${dir} CACHE INTERNAL "Plugin directories" FORCE)
252-
message("Found plugin directory: ${dir}")
253-
else()
254-
foreach(subdir ${SUBDIRS})
255-
if(IS_DIRECTORY ${dir}/${subdir})
256-
collect_first_cmake_directories(${dir}/${subdir} ${out_dirs})
257-
endif()
258-
endforeach()
259-
endif()
260-
endfunction()
261-
262-
set(NOS_MODULE_DIR_INDEX 0)
263-
set(ALL_MODULE_DIRS "" CACHE INTERNAL "All plugin directories" FORCE)
264-
foreach(cur_plugin_dir ${MODULE_DIRS})
265-
# If relative, should be relative to NODOS_WORKSPACE_DIR
266-
if(NOT IS_ABSOLUTE ${cur_plugin_dir})
267-
set(cur_plugin_dir "${NODOS_WORKSPACE_DIR}/${cur_plugin_dir}")
268-
endif()
269-
nos_colored_message(COLOR GREEN "Scanning for plugins in ${cur_plugin_dir}")
270-
collect_first_cmake_directories("${cur_plugin_dir}" ALL_MODULE_DIRS)
271-
endforeach()
272-
273-
foreach(dir ${ALL_MODULE_DIRS})
274-
if(IS_DIRECTORY ${dir})
275-
nos_colored_message(COLOR GREEN "Processing plugin directory: ${dir}")
276-
add_subdirectory(${dir} "${CMAKE_CURRENT_BINARY_DIR}/PluginDir${NOS_MODULE_DIR_INDEX}")
277-
math(EXPR NOS_MODULE_DIR_INDEX "${NOS_MODULE_DIR_INDEX} + 1")
278-
endif()
279-
endforeach()
248+
# Use automatic target generation for plugins written for Nodos 1.4 and later
249+
if(USE_AUTO_TARGET_GENERATION)
250+
include(${CMAKE_CURRENT_SOURCE_DIR}/Scripts/GeneratePluginTargetsAuto.cmake)
251+
else()
252+
include(${CMAKE_CURRENT_SOURCE_DIR}/Scripts/GeneratePluginTargetsManual.cmake)
253+
endif()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright MediaZ Teknoloji A.S. All Rights Reserved.
2+
3+
function(nos_plugin_common current_dir out_target_dependencies out_target_definitions)
4+
endfunction()
5+
6+
function(nos_plugin_on_post_target_generated plugin_target plugin_name)
7+
endfunction()

Toolchain/CMake/Scripts/FindNodosSDK.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ macro(nos_find_sdk requested_version out_nos_plugin_sdk out_nos_subsystem_sdk ou
6868
else()
6969
set(${out_nos_subsystem_sdk} ${${out_nos_plugin_sdk}})
7070
endif()
71+
7172
if (${found_version} VERSION_GREATER_EQUAL "1.4.0")
7273
set(nos_sdk_dir ${nos_sdk_dir}/Plugin)
7374
set(FLATC_EXECUTABLE "${nos_sdk_dir}/Binaries/flatc" CACHE PATH "Path to the flatc executable" FORCE)
@@ -88,6 +89,7 @@ macro(nos_find_plugin_sdk requested_sdk_version out_sdk_target out_sdk_dir)
8889
get_filename_component(sdk_path "${sdk_manifest_path}" DIRECTORY)
8990
set(${out_sdk_target} ${sdk_target_name})
9091
set(${out_sdk_dir} ${sdk_path})
92+
9193
set(FLATC_EXECUTABLE "${sdk_path}/Binaries/flatc" CACHE PATH "Path to the flatc executable" FORCE)
9294
else()
9395
# For all nodos sdks, call `nodos sdk-info ${requested_sdk_version} plugin` and read the json if ret code is 0
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Copyright MediaZ Teknoloji A.S. All Rights Reserved.
2+
3+
function(_nos_get_custom_type_paths_from_json JSON_FILE OUT_LIST)
4+
if(NOT EXISTS "${JSON_FILE}")
5+
message(FATAL_ERROR "JSON file not found: ${JSON_FILE}")
6+
endif()
7+
8+
# Read file
9+
file(READ "${JSON_FILE}" _json_content)
10+
11+
# Check if field exists
12+
string(JSON _has_custom_types ERROR_VARIABLE _err
13+
GET "${_json_content}" custom_types
14+
)
15+
16+
if(_err)
17+
# Field does not exist → return empty list
18+
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Types)
19+
set(${OUT_LIST} "${CMAKE_CURRENT_SOURCE_DIR}/Types" PARENT_SCOPE)
20+
else()
21+
set(${OUT_LIST} "" PARENT_SCOPE)
22+
endif()
23+
return()
24+
endif()
25+
26+
# Get array length
27+
string(JSON _len LENGTH "${_json_content}" custom_types)
28+
29+
set(_result "")
30+
math(EXPR _last "${_len} - 1")
31+
32+
foreach(i RANGE 0 ${_last})
33+
string(JSON _value GET "${_json_content}" custom_types ${i})
34+
list(APPEND _result "${CMAKE_CURRENT_SOURCE_DIR}/${_value}")
35+
endforeach()
36+
37+
set(${OUT_LIST} "${_result}" PARENT_SCOPE)
38+
endfunction()
39+
40+
function(_nos_generate_plugin_target nos_plugin_file_path common_deps common_defs out_target_name out_plugin_name)
41+
message(STATUS "Configuring plugin ${plugin_name}")
42+
nos_get_package_info_by_path(${nos_plugin_file_path} plugin_name plugin_version out_json_info)
43+
44+
nos_normalize_plugin_name(${plugin_name} target_name)
45+
get_filename_component(PLUGIN_DIR "${nos_plugin_file_path}" DIRECTORY)
46+
47+
nos_find_plugin_sdk_version(${out_json_info} plugin_sdk_version)
48+
if ("${plugin_sdk_version}" STREQUAL "None")
49+
message(STATUS "Module is not depended on a SDK version, there is no need for a target")
50+
return()
51+
endif()
52+
53+
message(STATUS "Plugin SDK version requested: ${plugin_sdk_version}")
54+
55+
nos_find_plugin_sdk(${plugin_sdk_version} NOS_PLUGIN_SDK_TARGET NOS_SDK_DIR)
56+
if (NOT DEFINED NOS_SDK_DIR)
57+
message(FATAL_ERROR "Nodos SDK with version ${plugin_sdk_version} not found, please either install it or choose different version")
58+
endif()
59+
60+
nos_find_immediate_plugin_dependencies(${out_json_info} found_dependency_targets found_dep_dirs found_include_dirs)
61+
list(APPEND INCLUDE_FOLDERS ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/Include" "${found_include_dirs}")
62+
list(APPEND MODULE_DEPENDENCIES_TARGETS ${NOS_PLUGIN_SDK_TARGET})
63+
64+
_nos_get_custom_type_paths_from_json(${nos_plugin_file_path} TYPE_FOLDERS)
65+
if(TYPE_FOLDERS)
66+
nos_generate_flatbuffers("${TYPE_FOLDERS}" "${CMAKE_CURRENT_SOURCE_DIR}/Include/${target_name}" "cpp" "${NOS_SDK_DIR}/Types;${found_dep_dirs}" ${target_name}_generated)
67+
list(APPEND MODULE_DEPENDENCIES_TARGETS ${target_name}_generated)
68+
endif()
69+
70+
list(APPEND
71+
MODULE_DEPENDENCIES_TARGETS
72+
${found_dependency_targets}
73+
${common_deps} # dereference here
74+
)
75+
message(STATUS "Module dependencies: ${MODULE_DEPENDENCIES_TARGETS}")
76+
nos_add_plugin("${target_name}" "${MODULE_DEPENDENCIES_TARGETS}" "${INCLUDE_FOLDERS}")
77+
if(TARGET "${target_name}")
78+
message(STATUS "Successfully created target: ${target_name}")
79+
set(${out_target_name} ${target_name} PARENT_SCOPE)
80+
set(${out_plugin_name} ${plugin_name} PARENT_SCOPE)
81+
82+
get_target_property(target_type ${target_name} TYPE)
83+
if(target_type STREQUAL "INTERFACE_LIBRARY")
84+
return()
85+
endif()
86+
else()
87+
nos_fatal_error("Failed to create target: ${target_name}")
88+
endif()
89+
90+
#Helpers need C++20
91+
set_target_properties("${target_name}" PROPERTIES CXX_STANDARD 20)
92+
target_compile_definitions("${target_name}" PRIVATE ${common_defs})
93+
94+
if(NOS_FORCE_DISABLE_DEPRECATED)
95+
target_compile_definitions("${target_name}" PRIVATE NOS_DISABLE_DEPRECATED)
96+
endif()
97+
endfunction()
98+
99+
function(_nos_configure_plugin_dir dir common_dependencies common_definitions)
100+
if(NOT IS_DIRECTORY ${dir})
101+
nos_colored_message(COLOR RED "Can't process plugin because it's not folder: ${dir}")
102+
return()
103+
endif()
104+
105+
nos_colored_message(COLOR GREEN "Processing plugin directory: ${dir}")
106+
file(GLOB PLUGINS "${dir}/*.nosplugin")
107+
108+
foreach(plugin ${PLUGINS})
109+
get_filename_component(plugin_name "${plugin}" NAME_WE)
110+
111+
set(_old_cmake_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
112+
# Set current source dir to the plugin's directory for includes
113+
set(CMAKE_CURRENT_SOURCE_DIR "${dir}")
114+
115+
_nos_generate_plugin_target("${plugin}" "${common_dependencies}" "${common_definitions}" plugin_target plugin_name)
116+
if(NOT TARGET ${plugin_target})
117+
return()
118+
endif()
119+
120+
if(EXISTS "${dir}/CMakeLists.txt")
121+
nos_colored_message(COLOR GREEN "Including custom cmake file for plugin: ${plugin_name}")
122+
set(NOS_PLUGIN_TARGET ${plugin_target})
123+
add_subdirectory("${dir}" "${CMAKE_CURRENT_BINARY_DIR}/ModuleDir_${plugin_target}")
124+
endif()
125+
nos_get_vendor_name(${plugin_name} plugin_vendor)
126+
nos_group_targets(${plugin_target} "${plugin_vendor} Plugins")
127+
128+
if(COMMAND "nos_plugin_on_post_target_generated")
129+
nos_colored_message(COLOR CYAN "Calling post target generation function")
130+
cmake_language(CALL "nos_plugin_on_post_target_generated" "${plugin_target}" "${plugin_name}")
131+
endif()
132+
133+
set(CMAKE_CURRENT_SOURCE_DIR "${_old_cmake_source_dir}")
134+
endforeach()
135+
endfunction()
136+
137+
138+
function(_nos_process_plugin_directories_recursive dir common_dependencies common_definitions)
139+
get_filename_component(parent_dir "${dir}" DIRECTORY)
140+
get_filename_component(parent_name "${parent_dir}" NAME)
141+
if(parent_name STREQUAL "Downloaded")
142+
message(STATUS "Skipping directory under Downloaded: ${dir}")
143+
return()
144+
endif()
145+
146+
file(GLOB PLUGINS "${dir}/*.nosplugin")
147+
148+
if(EXISTS "${dir}/NosPluginCommon.cmake")
149+
message("Found common dependency file: ${dir}/NosPluginCommon.cmake")
150+
include("${dir}/NosPluginCommon.cmake")
151+
152+
if(COMMAND "nos_plugin_common")
153+
nos_colored_message(COLOR CYAN "Calling common dependency function")
154+
155+
set(common_deps "")
156+
set(common_defs "")
157+
cmake_language(CALL "nos_plugin_common" ${dir} common_deps common_defs)
158+
list(APPEND common_dependencies ${common_deps})
159+
list(APPEND common_definitions ${common_defs})
160+
else()
161+
nos_fatal_error("Expected function '${plugin_name}' not found in ${plugin_cmake}")
162+
endif()
163+
endif()
164+
165+
list(LENGTH PLUGINS PLUGIN_COUNT)
166+
167+
if (PLUGIN_COUNT GREATER 1)
168+
nos_fatal_error("Multiple .nosplugin files found in directory: ${dir}")
169+
elseif (PLUGIN_COUNT EQUAL 1)
170+
list(GET PLUGINS 0 plugin)
171+
get_filename_component(plugin_name "${plugin}" NAME)
172+
173+
_nos_configure_plugin_dir(${dir} "${common_dependencies}" "${common_definitions}")
174+
endif()
175+
176+
file(GLOB SUBDIRS RELATIVE ${dir} ${dir}/*)
177+
178+
foreach(subdir ${SUBDIRS})
179+
include(${CMAKE_CURRENT_SOURCE_DIR}/Scripts/DefaultNosPluginCommon.cmake)
180+
181+
# try to find a *.nosplugin, if not, skip
182+
# TODO: Ideally, this should done only at the start and only the directories containing plugins should be processed
183+
file(GLOB_RECURSE FOUND_PLUGINS RELATIVE "${dir}" "${dir}/${subdir}/*.nosplugin")
184+
if (NOT FOUND_PLUGINS)
185+
continue()
186+
endif()
187+
_nos_process_plugin_directories_recursive(
188+
"${dir}/${subdir}"
189+
"${common_dependencies}"
190+
"${common_definitions}"
191+
)
192+
193+
# Reload functions
194+
if(EXISTS "${dir}/NosPluginCommon.cmake")
195+
include("${dir}/NosPluginCommon.cmake")
196+
endif()
197+
endforeach()
198+
199+
include(${CMAKE_CURRENT_SOURCE_DIR}/Scripts/DefaultNosPluginCommon.cmake)
200+
endfunction()
201+
202+
foreach(cur_plugin_dir ${MODULE_DIRS})
203+
# If relative, should be relative to NODOS_WORKSPACE_DIR
204+
if(NOT IS_ABSOLUTE ${cur_plugin_dir})
205+
set(cur_plugin_dir "${NODOS_WORKSPACE_DIR}/${cur_plugin_dir}")
206+
endif()
207+
nos_colored_message(COLOR GREEN "Scanning for plugins in ${cur_plugin_dir}")
208+
_nos_process_plugin_directories_recursive("${cur_plugin_dir}" "" "")
209+
endforeach()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright MediaZ Teknoloji A.S. All Rights Reserved.
2+
3+
set(NOS_MODULE_DIR_INDEX 0)
4+
set(ALL_MODULE_DIRS "" CACHE INTERNAL "All module directories" FORCE)
5+
6+
function(collect_first_cmake_directories dir out_dirs)
7+
file(GLOB SUBDIRS RELATIVE ${dir} ${dir}/*)
8+
9+
if(EXISTS "${dir}/CMakeLists.txt")
10+
set(${out_dirs} ${${out_dirs}} ${dir} CACHE INTERNAL "Module directories" FORCE)
11+
message("Found module directory: ${dir}/${subdir}")
12+
else()
13+
foreach(subdir ${SUBDIRS})
14+
if(IS_DIRECTORY ${dir}/${subdir})
15+
collect_first_cmake_directories(${dir}/${subdir} ${out_dirs})
16+
endif()
17+
endforeach()
18+
endif()
19+
endfunction()
20+
21+
foreach(cur_module_dir ${MODULE_DIRS})
22+
# If relative, should be relative to NODOS_WORKSPACE_DIR
23+
if(NOT IS_ABSOLUTE ${cur_module_dir})
24+
set(cur_module_dir "${NODOS_WORKSPACE_DIR}/${cur_module_dir}")
25+
endif()
26+
nos_colored_message(COLOR GREEN "Scanning for modules in ${cur_module_dir}")
27+
collect_first_cmake_directories("${cur_module_dir}" ALL_MODULE_DIRS)
28+
endforeach()
29+
30+
foreach(dir ${ALL_MODULE_DIRS})
31+
if(IS_DIRECTORY ${dir})
32+
nos_colored_message(COLOR GREEN "Processing module directory: ${dir}")
33+
add_subdirectory(${dir} "${CMAKE_CURRENT_BINARY_DIR}/ModuleDir${NOS_MODULE_DIR_INDEX}")
34+
math(EXPR NOS_MODULE_DIR_INDEX "${NOS_MODULE_DIR_INDEX} + 1")
35+
endif()
36+
endforeach()

0 commit comments

Comments
 (0)