Forking FluCoMa for fun and to experiment

I have a question about the ergonomics of creating a new package that might use FluCoMa as a dependency. I’d like to leverage the already implemented buffer framework to create a package in Max that deals with processing and manipulating buffer content. In my mind, the way I would do this now is to fork the flucoma-max package, rip out all the clients and then start creating my own. I suppose the other path is to also fork flucoma-core and create a better separation of algorithm and client as is already the case with the existing packages. Ideally, I’d avoid this kind of duopoly and just have a single repo that consumes the core as a dependency.

@weefuzzy, do you have any guidance on such matters. Of course the alternative to all of this is to build a new project from scratch, implementing my own CMake routines etc. etc. but that seems like a waste of valuable time which I could avoid by just forking a repo. Do you have any thoughts on the simplest path forward to reach a stage where I can compile some externals?

1 Like

You can either fork or use flucoma-core + flucoma-max as dependencies.

I think the latter’s doable, because I’ve just been fiddling with the experimental fluid.graph<X> stuff Gerard did for dafx a couple of years ago to get it working with the updated build system.

Summary:

  • You’ll want a CMakeLists to manage the dependencies and build stuff
  • Use FetchContent to pull in -core and -max

Here shit gets a bit more irritating (IOW, I should make it easier), but to use the max stuff without having to reproduce all our externals. It involves duplicatng some CMake to pull in the max wrapper, so as to avoid inheriting all the old targets.

Below is how the graph-stuff CMake currently looks on my local branch

cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/release-packaging" CACHE PATH "")

################################################################################
# Paths
set(MAX_SDK_PATH "" CACHE PATH "Path to the Max SDK")
if(NOT MAX_SDK_PATH)
  message(FATAL_ERROR "Max SDK Path is not set")
endif()

set(FLUID_PATH "" CACHE PATH "Optional path to the flucoma-core repo")# TODO: set to FLUCOMA_CORE_PATh

if (APPLE)
  set(CMAKE_XCODE_GENERATE_SCHEME ON)
  set(CMAKE_XCODE_SCHEME_EXECUTABLE "/Applications/Max.app")
  set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "")
endif()

################################################################################
project (graph-loop-grain LANGUAGES CXX)

set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY ON)
set(AUTHOR_DOMAIN "org.flucoma")
string(TIMESTAMP "%Y" THISYEAR)
set(COPYRIGHT_STRING "Copyright (c) 2017-${THISYEAR} University of Huddersfield")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
################################################################################
include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)

FetchContent_Declare(
  flucoma-core
  GIT_REPOSITORY https://github.com/flucoma/flucoma-core.git
  GIT_PROGRESS TRUE
  GIT_TAG origin/main
)

if(FLUID_PATH)
  get_filename_component(
    FETCHCONTENT_SOURCE_DIR_FLUCOMA-CORE ${FLUID_PATH} ABSOLUTE
  )
endif()

FetchContent_Declare(
  flucoma-max
  GIT_REPOSITORY https://github.com/flucoma/flucoma-max.git
  GIT_PROGRESS TRUE
  GIT_TAG origin/main
)

FetchContent_MakeAvailable(flucoma-core)

# Do this the long way to avoid getting all the flucoma-max targets
FetchContent_GetProperties(flucoma-max)
if(NOT flucoma-max_POPULATED)
  FetchContent_Populate(flucoma-max)
endif()

include(flucoma_version)
include(flucoma-buildtools)
include(flucoma-buildtype)

# Max Wrapper target
add_library( FLUID_MAX INTERFACE )
target_sources(
	FLUID_MAX INTERFACE
	"${flucoma-max_SOURCE_DIR}/source/include/FluidMaxWrapper.hpp"
	"${flucoma-max_SOURCE_DIR}/source/include/MaxBufferAdaptor.hpp"
)

target_include_directories(FLUID_MAX INTERFACE
"${flucoma-max_SOURCE_DIR}/source/include/"
)

# Pull in client machinery from flucoma-max repo
include("${flucoma-max_SOURCE_DIR}/source/script/MakeMaxSources.cmake")
include("${flucoma-max_SOURCE_DIR}/source/script/SetupMaxSDK.cmake")

# Make targets for local externs. Note that if the objects end with ~, the generated target name will end with _tilde
foreach(extern grain;loop;play)
  add_max_external(fluid.graph${extern}~ "${CMAKE_CURRENT_SOURCE_DIR}/fluid.graph${extern}_tilde/fluid.graph${extern}_tilde.cpp")
  target_include_directories(fluid.graph${extern}_tilde PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../include")
  target_link_libraries(fluid.graph${extern}_tilde PRIVATE FLUID_MAX)
  get_target_property(target_out fluid.graph${extern}_tilde OUTPUT_NAME)
  message(STATUS Generated ${target_out} )
endforeach()

install(TARGETS fluid.graphgrain_tilde fluid.graphloop_tilde fluid.graphplay_tilde
        DESTINATION ${CMAKE_BINARY_DIR}/dist/externals
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/help
        DESTINATION ${CMAKE_BINARY_DIR}/dist/
)
1 Like

Though this still uses hand rolled .cpp stubs, rather than generated ones. That’s manageable for a small number of objects, but more CMake acrobatics might be involved if you want to generate as well (or maybe not: perhaps generate_source will Just Work)