Skip to content

Commit

Permalink
Allow building external plugins as built-in, for simulator
Browse files Browse the repository at this point in the history
Simulator builds assets image using firmware assets plus ext plugin assets

Modify internal plugin manager to build Venom

Ext plugin brand and path can be different

Firmware ignores ext builtin plugins
  • Loading branch information
danngreen committed Dec 23, 2024
1 parent 4115595 commit 878449c
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 5 deletions.
2 changes: 1 addition & 1 deletion firmware/vcv_plugin/export/src/plugin/Plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Plugin::~Plugin() {
// In VCV Rack: don't delete model because it's allocated once and referenced by a global.

// In MetaModule: we need to delete the models when the Plugin is removed
pr_dbg("Deleting Model %s\n", model->slug.c_str());
pr_trace("Deleting Model %s\n", model->slug.c_str());
delete model;

MetaModule::ModuleFactory::unregisterBrand(slug);
Expand Down
6 changes: 5 additions & 1 deletion firmware/vcv_ports/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ target_include_directories(vcv_ports INTERFACE
${CMAKE_CURRENT_LIST_DIR}/glue
)

if (NOT TARGET simulator)
target_include_directories(vcv_ports INTERFACE ${CMAKE_CURRENT_LIST_DIR}/glue/ext_plugin)
endif()

# Get list of brands
include(${CMAKE_CURRENT_LIST_DIR}/brands.cmake)

Expand Down Expand Up @@ -72,7 +76,7 @@ foreach(brand ${brands})

target_link_libraries(_vcv_ports_internal PUBLIC ${brand}Library)

endif()
endif()

endforeach()

3 changes: 3 additions & 0 deletions firmware/vcv_ports/glue/ext_plugin/ext_plugin_builtin.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// do nothing in firmware:
inline void load_ext_builtin_plugins(auto &internal_plugins) {
}
2 changes: 2 additions & 0 deletions firmware/vcv_ports/internal_plugin_manager.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "convert_plugins.hh"
#include "ext_plugin_builtin.hh"
#include "fat_file_io.hh"
#include "fs/asset_drive/asset_fs.hh"
#include "fs/asset_drive/untar.hh"
Expand Down Expand Up @@ -27,6 +28,7 @@ struct InternalPluginManager {
prepare_ramdisk();
load_internal_assets();
load_internal_plugins();
load_ext_builtin_plugins(internal_plugins);
}

void prepare_ramdisk() {
Expand Down
5 changes: 3 additions & 2 deletions simulator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Ap
set(DEBUG_COMMAND ${CMAKE_DEBUGGER_BINARY} $<TARGET_FILE:simulator> --
--sdcarddir ${CMAKE_CURRENT_LIST_DIR}/patches
--flashdir ${CMAKE_CURRENT_LIST_DIR}/../patches/default
--assets ${CMAKE_CURRENT_LIST_DIR}/../firmware/build/assets.uimg
--assets ${CMAKE_CURRENT_LIST_DIR}/build/assets.uimg
)


Expand All @@ -178,7 +178,7 @@ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
--args $<TARGET_FILE:simulator>
--sdcarddir ${CMAKE_CURRENT_LIST_DIR}/patches
--flashdir ${CMAKE_CURRENT_LIST_DIR}/../shared/patch/default
--assets ${CMAKE_CURRENT_LIST_DIR}/../firmware/build/assets.uimg
--assets ${CMAKE_CURRENT_LIST_DIR}/build/assets.uimg
)
else ()
set(DEBUG_COMMAND echo "Compiler is ${CMAKE_CXX_COMPILER_ID}, but must be Clang, AppleClang, or GNU to debug")
Expand All @@ -191,3 +191,4 @@ add_custom_target(
USES_TERMINAL
)

include(ext-plugins.cmake)
65 changes: 65 additions & 0 deletions simulator/ext-plugins.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Two steps to build an external plugin into the simulator:
#
# 1. Copy/paste the two `list APPEND commands` below, puttting in the path to the
# plugin (where the CMakeLists.txt lives), and the plugin cmake library name
#
# 2. In the plugin, find the file where init(rack::Plugin*) is defined, and rename it to init_Brand
# You can use #if defined(METAMODULE_BUILTIN) so that it's still called init() when building as a plugin for Rack or MM.
# `Brand` in init_Brand must match the plugin cmake library name you used in step 1.

# Example with Venom:
# list(APPEND ext_builtin_brand_paths "${CMAKE_CURRENT_LIST_DIR}/../../metamodule-plugin-examples/Venom")
# list(APPEND ext_builtin_brand_libname "Venom")


#
# Asset dir
#

cmake_path(SET ASSET_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets")
set(ASSET_IMG_FILENAME assets.uimg)
cmake_path(APPEND ASSET_IMG_PATH "${CMAKE_CURRENT_BINARY_DIR}" "${ASSET_IMG_FILENAME}")

message("set ASSET_DIR to ${ASSET_DIR}")
message("set ASSET_IMG_PATH to ${ASSET_IMG_PATH}")

add_custom_command(
OUTPUT ${ASSET_DIR}
COMMAND ${CMAKE_COMMAND} -E echo Copying "${FWDIR}/assets" to "${ASSET_DIR}"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${FWDIR}/assets" "${ASSET_DIR}"
COMMENT "Copying assets/ dir from ${FWDIR}/assets to ${ASSET_DIR}"
VERBATIM USES_TERMINAL
)

add_custom_command(
OUTPUT ${ASSET_IMG_PATH}
COMMAND cd ${ASSET_DIR} && ${CMAKE_COMMAND} -E tar -cf ${ASSET_IMG_PATH}.tar .
COMMAND cd ${FWDIR} && flashing/uimg_header.py --name Assets ${ASSET_IMG_PATH}.tar ${ASSET_IMG_PATH}
COMMENT "Creating assets uimg file at ${ASSET_IMG_PATH}"
DEPENDS ${ASSET_DIR}
VERBATIM USES_TERMINAL
)

add_custom_target(asset-image ALL
DEPENDS ${ASSET_IMG_PATH}
)

set(EXT_PLUGIN_INIT_CALLS "")

foreach(branddir brand IN ZIP_LISTS ext_builtin_brand_paths ext_builtin_brand_libname)
set(METAMODULE_SDK_DIR ${CMAKE_CURRENT_LIST_DIR})
add_subdirectory(${branddir} ${CMAKE_CURRENT_BINARY_DIR}/builtins/${brand})

target_link_libraries(${brand} PRIVATE metamodule::vcv-plugin-interface)
target_link_libraries(${brand} PRIVATE cpputil::cpputil)
target_compile_definitions(${brand} PRIVATE METAMODULE METAMODULE_BUILTIN)

target_link_libraries(_vcv_ports_internal PUBLIC ${brand})
add_dependencies(asset-image ${brand}-assets)

string(APPEND EXT_PLUGIN_INIT_CALLS "\textern void init_${brand}(rack::plugin::Plugin *);\n\tinit_${brand}(&internal_plugins.emplace_back(\"${brand}\"));")
endforeach()

configure_file(src/ext_plugin_builtin.hh.in ${CMAKE_CURRENT_BINARY_DIR}/ext_plugin/ext_plugin_builtin.hh)
target_include_directories(simulator PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/ext_plugin)

41 changes: 41 additions & 0 deletions simulator/plugin.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# TODO: Get cmake to copy the source file that contains init() and rename that function to init_BRAND()
# Also see if Cmake can generate the calls to init (currently manually written into simulator/src/ext_plugin_builtin.hh)

# file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake"
# [=[
# file(READ "${SOURCE}" TEXT)
# string(REPLACE "foo" "bar" TEXT "${TEXT}")
# file(WRITE "${TARGET}" "${TEXT}")
# ]=])

# add_custom_command(
# OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp"
# COMMAND "${CMAKE_COMMAND}"
# "-DSOURCE=${CMAKE_CURRENT_SOURCE_DIR}/plugin.cpp"
# "-DTARGET=${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp"
# -P "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake"
# DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/plugin.cpp" "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake"
# )


function(create_plugin)
message("Building ${brand} as built-in plugin (create_plugin)")

# target_sources(${PLUGIN_OPTIONS_SOURCE_LIB} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp)

set(oneValueArgs SOURCE_LIB SOURCE_ASSETS DESTINATION PLUGIN_NAME PLUGIN_JSON)
cmake_parse_arguments(PLUGIN_OPTIONS "" "${oneValueArgs}" "" ${ARGN} )

add_custom_command(
OUTPUT "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${PLUGIN_OPTIONS_SOURCE_ASSETS}" "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}"
COMMENT "Copying ${PLUGIN_OPTIONS_SOURCE_ASSETS} to ${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}"
VERBATIM
)

add_custom_target(${PLUGIN_OPTIONS_SOURCE_LIB}-assets
DEPENDS "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}"
)


endfunction()
3 changes: 3 additions & 0 deletions simulator/src/ext_plugin_builtin.hh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
inline void load_ext_builtin_plugins(auto &internal_plugins) {
${EXT_PLUGIN_INIT_CALLS}
}
2 changes: 1 addition & 1 deletion simulator/src/settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct Settings {
unsigned zoom = 100;
std::string sdcard_path = "patches/";
std::string flash_path = "../patches/default/";
std::string asset_file = "../firmware/build/assets.uimg";
std::string asset_file = "build/assets.uimg";
int audioout_dev = 0;

void parse(int argc, char *argv[]) {
Expand Down

0 comments on commit 878449c

Please sign in to comment.