diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97df633..9d7257b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: push: env: - CACHE_VERSION: 7 + CACHE_VERSION: 8 DEBIAN_FRONTEND: noninteractive HOMEBREW_NO_AUTO_UPDATE: 1 LIBGL_ALWAYS_SOFTWARE: 'true' @@ -45,7 +45,7 @@ jobs: run: | pushd deps/PawPaw; source local.env linux-aarch64; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) make unzipfx - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true @@ -111,7 +111,7 @@ jobs: run: | pushd deps/PawPaw; source local.env linux-armhf; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) make unzipfx - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true @@ -173,7 +173,7 @@ jobs: run: | pushd deps/PawPaw; source local.env linux-i686; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) make unzipfx - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true @@ -227,7 +227,7 @@ jobs: run: | pushd deps/PawPaw; source local.env linux; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) make unzipfx - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true @@ -340,18 +340,18 @@ jobs: run: | pushd deps/PawPaw; source local.env macos-universal; popd make features - make NOOPT=true WITH_LTO=true -j $(sysctl -n hw.logicalcpu) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(sysctl -n hw.logicalcpu) - name: Build macOS universal (AU using juce) run: | pushd deps/PawPaw; source local.env macos-universal; popd git clone --depth=1 -b master https://github.com/juce-framework/JUCE.git jucewrapper/JUCE mkdir jucewrapper/build - pushd jucewrapper/build; cmake .. && make -j $(sysctl -n hw.logicalcpu); popd - mv jucewrapper/build/*_artefacts/AU/*.component bin/ + pushd jucewrapper/build; cmake -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DCMAKE_BUILD_TYPE=Release .. && make -j $(sysctl -n hw.logicalcpu); popd + mv jucewrapper/build/*_artefacts/Release/AU/*.component bin/ - name: Build macOS universal (packaging) run: | pushd deps/PawPaw; source local.env macos-universal; popd - ./dpf/utils/package-osx-bundles.sh + ./utils/create-macos-installer.sh - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true id: slug1 @@ -519,15 +519,27 @@ jobs: run: | sudo dpkg --add-architecture i386 sudo apt-get update -qq - sudo apt-get install -yqq binutils-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64 wine-stable:i386 + sudo apt-get install -yqq binutils-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64 wine-stable:i386 xvfb - name: Build extra dependencies run: | ./deps/PawPaw/bootstrap-cardinal.sh win32 - - name: Build win32 cross-compiled + - name: Build win32 cross-compiled (base) run: | pushd deps/PawPaw; source local.env win32; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) + - name: Build win64 cross-compiled (carla) + run: | + pushd deps/PawPaw; source local.env win32; popd + make distclean -C carla + make -C carla EXTERNAL_PLUGINS=true HAVE_DGL=false HAVE_HYLIA=false HAVE_JACK=false HAVE_LIBLO=false HAVE_ZYN_DEPS=false HAVE_ZYN_UI_DEPS=false USING_JUCE=false USING_JUCE_AUDIO_DEVICES=false USING_JUCE_GUI_EXTRA=false USING_RTAUDIO=false -j $(nproc) + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + - name: Build win64 cross-compiled (packaging) + run: | + pushd deps/PawPaw; source local.env win32; popd + xvfb-run ./utils/create-windows-installer.sh 32 - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true id: slug1 @@ -546,6 +558,7 @@ jobs: with: name: ${{ github.event.repository.name }}-win32-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} path: | + *.exe *.zip - uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') @@ -555,6 +568,7 @@ jobs: draft: false prerelease: false files: | + *.exe *.zip win64: @@ -576,16 +590,29 @@ jobs: sudo apt-get install -yqq --allow-downgrades libpcre2-8-0/focal libpcre2-16-0/focal libpcre2-32-0/focal libpcre2-posix2/focal - name: Set up dependencies run: | + sudo dpkg --add-architecture i386 sudo apt-get update -qq - sudo apt-get install -yqq binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64 wine-stable + sudo apt-get install -yqq binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64 wine-stable xvfb - name: Build extra dependencies run: | ./deps/PawPaw/bootstrap-cardinal.sh win64 - - name: Build win64 cross-compiled + - name: Build win64 cross-compiled (base) run: | pushd deps/PawPaw; source local.env win64; popd make features - make NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) + - name: Build win64 cross-compiled (carla) + run: | + pushd deps/PawPaw; source local.env win64; popd + make distclean -C carla + make -C carla EXTERNAL_PLUGINS=true HAVE_DGL=false HAVE_HYLIA=false HAVE_JACK=false HAVE_LIBLO=false HAVE_ZYN_DEPS=false HAVE_ZYN_UI_DEPS=false USING_JUCE=false USING_JUCE_AUDIO_DEVICES=false USING_JUCE_GUI_EXTRA=false USING_RTAUDIO=false all win32r -j $(nproc) + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + make -C carla TESTING=true _CARLA_LV2_PLUGIN_FILES= _CARLA_VST2_PLUGIN_FILES= dist + - name: Build win64 cross-compiled (packaging) + run: | + pushd deps/PawPaw; source local.env win64; popd + xvfb-run ./utils/create-windows-installer.sh 64 - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true id: slug1 @@ -604,6 +631,7 @@ jobs: with: name: ${{ github.event.repository.name }}-win64-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} path: | + *.exe *.zip - uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') @@ -613,6 +641,7 @@ jobs: draft: false prerelease: false files: | + *.exe *.zip source-tarball: @@ -672,17 +701,17 @@ jobs: sudo dpkg -i kxstudio-repos_10.0.3_all.deb sudo apt-get update -qq # build-deps - sudo apt-get install -yqq libgl1-mesa-dev liblo-dev libx11-dev libxcursor-dev libxext-dev libxrandr-dev + sudo apt-get install -yqq liblo-dev # runtime testing sudo apt-get install -yqq carla-git lilv-utils lv2-dev lv2lint valgrind - - name: Build plugins + - name: Build Cardinal env: CFLAGS: -g CXXFLAGS: -g -DDPF_ABORT_ON_ERROR LDFLAGS: -static-libgcc -static-libstdc++ run: | - make features - make NOOPT=true SKIP_STRIPPING=true -j $(nproc) + make HEADLESS=true features + make HEADLESS=true NOOPT=true NOPLUGINS=true STATIC_BUILD=true SKIP_STRIPPING=true -j $(nproc) - name: Validate LV2 ttl syntax run: | lv2_validate \ @@ -691,14 +720,14 @@ jobs: /usr/lib/lv2/kx-control-input-port-change-request.lv2/*.ttl \ /usr/lib/lv2/kx-programs.lv2/*.ttl \ ./bin/*.lv2/*.ttl - #- name: Validate LV2 metadata and binaries - #run: | - #export LV2_PATH=/tmp/lv2-path - #mkdir ${LV2_PATH} - #cp -r bin/*.lv2 \ - #/usr/lib/lv2/{atom,buf-size,core,data-access,kx-control-input-port-change-request,kx-programs,instance-access,midi,parameters,port-groups,port-props,options,patch,presets,resize-port,state,time,ui,units,urid,worker}.lv2 \ - #${LV2_PATH} - #lv2lint -s lv2_generate_ttl -l ld-linux-x86-64.so.2 -M nopack $(lv2ls) + - name: Validate LV2 metadata and binaries + run: | + export LV2_PATH=/tmp/lv2-path + mkdir ${LV2_PATH} + cp -r bin/CardinalFX.lv2 bin/CardinalSynth.lv2 \ + /usr/lib/lv2/{atom,buf-size,core,data-access,kx-control-input-port-change-request,kx-programs,instance-access,midi,mod,parameters,port-groups,port-props,options,patch,presets,resize-port,state,time,ui,units,urid,worker}.lv2 \ + ${LV2_PATH} + lv2lint -s lv2_generate_ttl -l ld-linux-x86-64.so.2 -M nopack $(lv2ls) - name: Test LV2 plugin run: | export LV2_PATH=/tmp/lv2-path @@ -711,27 +740,25 @@ jobs: --suppressions=./dpf/utils/valgrind-dpf.supp \ /usr/lib/carla/carla-bridge-native lv2 "" ${p} 1>/dev/null; \ done - # - name: Test VST2 plugin - # env: - # CARLA_DO_NOT_USE_JUCE_FOR_VST2: 1 - # run: | - # for p in $(ls bin/*.vst/*.so); do \ - # env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ - # valgrind \ - # --error-exitcode=255 \ - # --leak-check=no \ - # --track-origins=yes \ - # --suppressions=./dpf/utils/valgrind-dpf.supp \ - # /usr/lib/carla/carla-bridge-native vst2 ./${p} "" 1>/dev/null; \ - # done - # - name: Test VST3 plugin - # run: | - # for p in $(ls bin/ | grep vst3); do \ - # env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ - # valgrind \ - # --error-exitcode=255 \ - # --leak-check=no \ - # --track-origins=yes \ - # --suppressions=./dpf/utils/valgrind-dpf.supp \ - # /usr/lib/carla/carla-bridge-native vst3 ./bin/${p} "" 1>/dev/null; \ - # done + - name: Test VST2 plugin + run: | + for p in $(ls bin/*.vst/*.so); do \ + env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ + valgrind \ + --error-exitcode=255 \ + --leak-check=no \ + --track-origins=yes \ + --suppressions=./dpf/utils/valgrind-dpf.supp \ + /usr/lib/carla/carla-bridge-native vst2 ./${p} "" 1>/dev/null; \ + done + - name: Test VST3 plugin + run: | + for p in $(ls bin/ | grep vst3); do \ + env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ + valgrind \ + --error-exitcode=255 \ + --leak-check=no \ + --track-origins=yes \ + --suppressions=./dpf/utils/valgrind-dpf.supp \ + /usr/lib/carla/carla-bridge-native vst3 ./bin/${p} "" 1>/dev/null; \ + done diff --git a/.gitignore b/.gitignore index 135e906..9e15837 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ bin/ build/ documentation.pdf +utils/inno/resources.iss +utils/inno/version.iss diff --git a/Makefile b/Makefile index 125123d..adb5822 100644 --- a/Makefile +++ b/Makefile @@ -404,6 +404,9 @@ tarball+deps: download rm -f ../cardinal+deps-$(VERSION).tar.xz tar -c --lzma $(TAR_ARGS) -f ../cardinal+deps-$(VERSION).tar.xz . +version: + @echo $(VERSION) + # -------------------------------------------------------------- .PHONY: carla deps plugins diff --git a/README.md b/README.md index be8c9d0..c30bfc7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ *Cardinal, the Rack!* Cardinal is a free and open-source virtual modular synthesizer plugin, -available as JACK standalone and LV2, VST2 and VST3 audio plugin for FreeBSD, Linux, macOS and Windows. +available as JACK standalone and AU, LV2, VST2 and VST3 audio plugin for FreeBSD, Linux, macOS and Windows. It is based on the popular [VCV Rack](https://vcvrack.com/) but with a focus on being a fully self-contained plugin version. More specifically, this is a [DPF-based](https://github.com/DISTRHO/DPF/) @@ -19,7 +19,6 @@ All "Core" modules from Rack have been replaced by Cardinal equivalents, simplif Cardinal does not load external modules and does not connect to the official Rack library/store. All VCV branding has been removed (to the best of our knowledge) in order to avoid any trademark issues. -Because it is using DPF, Cardinal already supports LV2 and VST2 with an extra JACK standalone mode for some systems. The VST3 version is in progress, already part of the build but still experimental. @@ -36,7 +35,7 @@ All variants have MIDI input and output support. This variant provides 8 audio inputs and outputs and 10 CV inputs and outputs. -NOTE: Due to VST2 format not supporting CV ports, this variant is not available for VST2. +NOTE: Due to AU and VST2 formats not supporting CV ports, this variant is not available for those formats. ### Synth diff --git a/deps/PawPaw b/deps/PawPaw index cc20186..4834b2e 160000 --- a/deps/PawPaw +++ b/deps/PawPaw @@ -1 +1 @@ -Subproject commit cc201866d35449bce0d9e02a85f641aa071437b8 +Subproject commit 4834b2e078af3d47dde45cab88bbdfe33ec90738 diff --git a/docs/DIFFERENCES.md b/docs/DIFFERENCES.md index 60e4047..7f402a9 100644 --- a/docs/DIFFERENCES.md +++ b/docs/DIFFERENCES.md @@ -21,6 +21,7 @@ Bellow follows a list of features comparing the official plugin to Cardinal. | Loads external modules | Yes | No | | | Supports closed-source modules | Yes | No | | | Supports physical devices | Yes | No | Audio + MIDI only through the DAW/Host or via JACK in standalone | +| Plugin in AU format | No | Yes | | | Plugin in LV2 format | No | Yes | | | Plugin in VST2 format | Yes | Yes | | | Plugin in VST3 format | No | WIP | | @@ -42,7 +43,6 @@ Bellow follows a list of features comparing the official plugin to Cardinal. Additionally, Cardinal contains the following built-in modules not present in the official plugin or standalone: - * Amalgamated Harmonics * Aria Salvatrice modules (except Arcane related modules, due to their online requirement) * Mog (never updated to v2) * mscHack (never updated to v2) diff --git a/dpf b/dpf index 215fc23..7cd27b1 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit 215fc2317efe822abf5eb545f422eedbb473693d +Subproject commit 7cd27b17fbbd196beff8c1fcc209f10e9c24f274 diff --git a/plugins/Cardinal/src/Carla.cpp b/plugins/Cardinal/src/Carla.cpp index cdd3256..f5d726f 100644 --- a/plugins/Cardinal/src/Carla.cpp +++ b/plugins/Cardinal/src/Carla.cpp @@ -99,6 +99,11 @@ struct CarlaModule : Module { CardinalExpanderFromCarlaMIDIToCV* midiOutExpander = nullptr; std::string patchStorage; +#ifdef CARLA_OS_WIN + // must keep string pointer valid + std::string winResourceDir; +#endif + CarlaModule() : pcontext(static_cast(APP)) { @@ -138,10 +143,14 @@ struct CarlaModule : Module { binaryDir = "/Applications/Carla.app/Contents/MacOS"; resourceDir = "/Applications/Carla.app/Contents/MacOS/resources"; } -#elif defined(CARLA_OS_WINDOWS) - // Carla does not support system-wide install on Windows right now - if (false) +#elif defined(CARLA_OS_WIN) + const std::string winBinaryDir = system::join(asset::systemDir, "Carla"); + + if (system::exists(winBinaryDir)) { + winResourceDir = system::join(winBinaryDir, "resources"); + binaryDir = winBinaryDir.c_str(); + resourceDir = winResourceDir.c_str(); } #else if (system::exists("/usr/local/lib/carla")) diff --git a/plugins/Cardinal/src/Ildaeil.cpp b/plugins/Cardinal/src/Ildaeil.cpp index b7d1039..3417242 100644 --- a/plugins/Cardinal/src/Ildaeil.cpp +++ b/plugins/Cardinal/src/Ildaeil.cpp @@ -209,10 +209,14 @@ struct IldaeilModule : Module { carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_BINARIES, 0, "/Applications/Carla.app/Contents/MacOS"); carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_RESOURCES, 0, "/Applications/Carla.app/Contents/MacOS/resources"); } -#elif defined(CARLA_OS_WINDOWS) - // Carla does not support system-wide install on Windows right now - if (false) +#elif defined(CARLA_OS_WIN) + const std::string winBinaryDir = system::join(asset::systemDir, "Carla"); + + if (system::exists(winBinaryDir)) { + const std::string winResourceDir = system::join(winBinaryDir, "resources"); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_BINARIES, 0, winBinaryDir.c_str()); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_RESOURCES, 0, winResourceDir.c_str()); } #else if (system::exists("/usr/local/lib/carla")) diff --git a/plugins/Makefile b/plugins/Makefile index d98f492..6a6d346 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -1051,10 +1051,8 @@ VST2_RESOURCES += $(PLUGIN_LIST:%=../bin/CardinalSynth.vst/Contents/Resources/Pl VST2_RESOURCES += $(RESOURCE_FILES:%=../bin/CardinalFX.vst/Contents/Resources/%) VST2_RESOURCES += $(RESOURCE_FILES:%=../bin/CardinalSynth.vst/Contents/Resources/%) else -VST2_RESOURCES = $(PLUGIN_LIST:%=../bin/CardinalFX.vst/resources/PluginManifests/%.json) -VST2_RESOURCES += $(PLUGIN_LIST:%=../bin/CardinalSynth.vst/resources/PluginManifests/%.json) -VST2_RESOURCES += $(RESOURCE_FILES:%=../bin/CardinalFX.vst/resources/%) -VST2_RESOURCES += $(RESOURCE_FILES:%=../bin/CardinalSynth.vst/resources/%) +VST2_RESOURCES = $(PLUGIN_LIST:%=../bin/Cardinal.vst/resources/PluginManifests/%.json) +VST2_RESOURCES += $(RESOURCE_FILES:%=../bin/Cardinal.vst/resources/%) endif VST3_RESOURCES = $(PLUGIN_LIST:%=../bin/Cardinal.vst3/Contents/Resources/PluginManifests/%.json) @@ -1138,19 +1136,11 @@ ifeq ($(MACOS),true) -@mkdir -p "$(shell dirname $@)" $(SILENT)ln -sf $(abspath $<) $@ else -../bin/CardinalFX.vst/resources/%: % +../bin/Cardinal.vst/resources/%: % -@mkdir -p "$(shell dirname $@)" $(SILENT)ln -sf $(abspath $<) $@ -../bin/CardinalSynth.vst/resources/%: % - -@mkdir -p "$(shell dirname $@)" - $(SILENT)ln -sf $(abspath $<) $@ - -../bin/CardinalFX.vst/resources/PluginManifests/%.json: %/plugin.json - -@mkdir -p "$(shell dirname $@)" - $(SILENT)ln -sf $(abspath $<) $@ - -../bin/CardinalSynth.vst/resources/PluginManifests/%.json: %/plugin.json +../bin/Cardinal.vst/resources/PluginManifests/%.json: %/plugin.json -@mkdir -p "$(shell dirname $@)" $(SILENT)ln -sf $(abspath $<) $@ endif diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index d02ed86..b7fab0f 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -138,7 +138,7 @@ struct Initializer } } - if (asset::systemDir.empty()) + if (asset::systemDir.empty() || ! system::exists(asset::systemDir)) { #ifdef CARDINAL_PLUGIN_SOURCE_DIR // Make system dir point to source code location as fallback @@ -151,11 +151,21 @@ struct Initializer // If source code dir does not exist use install target prefix as system dir else #endif - if (system::exists(CARDINAL_PLUGIN_PREFIX "/share/cardinal")) { - asset::bundlePath = CARDINAL_PLUGIN_PREFIX "/share/cardinal/PluginManifests"; + #if defined(ARCH_MAC) + asset::systemDir = "/Library/Application Support/Cardinal"; + #elif defined(ARCH_WIN) + if (const char* const commonprogfiles = std::getenv("COMMONPROGRAMFILES")) + asset::systemDir = system::join(commonprogfiles, "Cardinal"); + #else asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal"; - templatePath = system::join(asset::systemDir, "template.vcv"); + #endif + + if (! asset::systemDir.empty()) + { + asset::bundlePath = system::join(asset::systemDir, "PluginManifests"); + templatePath = system::join(asset::systemDir, "template.vcv"); + } } } diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp index 2858ab2..37f4d6a 100644 --- a/src/CardinalUI.cpp +++ b/src/CardinalUI.cpp @@ -325,7 +325,15 @@ public: } if (! errorMessage.empty()) - asyncDialog::create(errorMessage.c_str()); + { + static bool shown = false; + + if (! shown) + { + shown = true; + asyncDialog::create(errorMessage.c_str()); + } + } context->window->step(); diff --git a/src/Makefile b/src/Makefile index f5c196e..48b7d05 100644 --- a/src/Makefile +++ b/src/Makefile @@ -171,21 +171,26 @@ endif TARGET = rack.a +ifneq ($(MACOS),true) +CARDINAL_FX_ARGS = VST2_FILENAME=Cardinal.vst/CardinalFX$(LIB_EXT) +CARDINAL_SYNTH_ARGS = VST2_FILENAME=Cardinal.vst/CardinalSynth$(LIB_EXT) +endif + all: $(TARGET) ifeq ($(MOD_BUILD),true) $(MAKE) -C CardinalFX lv2 else $(MAKE) -C Cardinal - $(MAKE) -C CardinalFX - $(MAKE) -C CardinalSynth + $(MAKE) -C CardinalFX $(CARDINAL_FX_ARGS) + $(MAKE) -C CardinalSynth $(CARDINAL_SYNTH_ARGS) endif clean: rm -f $(TARGET) rm -rf $(BUILD_DIR) $(MAKE) clean -C Cardinal - $(MAKE) clean -C CardinalFX - $(MAKE) clean -C CardinalSynth + $(MAKE) clean -C CardinalFX $(CARDINAL_FX_ARGS) + $(MAKE) clean -C CardinalSynth $(CARDINAL_SYNTH_ARGS) # -------------------------------------------------------------- # Build commands diff --git a/src/Makefile.cardinal.mk b/src/Makefile.cardinal.mk index 62e2bee..8c704ca 100644 --- a/src/Makefile.cardinal.mk +++ b/src/Makefile.cardinal.mk @@ -235,6 +235,7 @@ endif # -------------------------------------------------------------- # fallback path to resource files +ifneq ($(CIBUILD),true) ifneq ($(SYSDEPS),true) ifeq ($(EXE_WRAPPER),wine) @@ -245,6 +246,7 @@ endif BUILD_CXX_FLAGS += -DCARDINAL_PLUGIN_SOURCE_DIR='"$(SOURCE_DIR)"' +endif endif # -------------------------------------------------------------- @@ -256,8 +258,12 @@ BUILD_CXX_FLAGS += -DCARDINAL_PLUGIN_PREFIX='"$(PREFIX)"' # Enable all possible plugin types and setup resources ifeq ($(CARDINAL_VARIANT),main) +ifneq ($(STATIC_BUILD),true) all: jack lv2 vst3 else +all: lv2 vst3 +endif # STATIC_BUILD +else all: lv2 vst2 vst3 static endif @@ -284,7 +290,7 @@ ifneq ($(CARDINAL_VARIANT),main) ifeq ($(MACOS),true) VST2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst/Contents/Resources/%) else -VST2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst/resources/%) +VST2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/Cardinal.vst/resources/%) endif endif @@ -294,7 +300,7 @@ vst3: $(VST3_RESOURCES) # -------------------------------------------------------------- -$(TARGET_DIR)/$(NAME).%/template.vcv: ../template.vcv +$(TARGET_DIR)/%/template.vcv: ../template.vcv -@mkdir -p "$(shell dirname $@)" $(SILENT)ln -sf $(abspath $<) $@ @@ -315,7 +321,7 @@ $(TARGET_DIR)/$(NAME).lv2/modgui/documentation.pdf: ../../docs/MODDEVICES.md $(T (cd ../../docs/ && pandoc MODDEVICES.md -f markdown+implicit_figures -o $(abspath $@)) endif -$(TARGET_DIR)/$(NAME).vst/resources/%: ../Rack/res/% +$(TARGET_DIR)/Cardinal.vst/resources/%: ../Rack/res/% -@mkdir -p "$(shell dirname $@)" $(SILENT)ln -sf $(abspath $<) $@ diff --git a/src/override/Scene.cpp b/src/override/Scene.cpp index ea6b108..82f09e3 100644 --- a/src/override/Scene.cpp +++ b/src/override/Scene.cpp @@ -46,6 +46,10 @@ # undef DEBUG #endif +#ifdef STATIC_BUILD +# undef HAVE_LIBLO +#endif + #ifdef HAVE_LIBLO # include #endif diff --git a/src/override/common.cpp b/src/override/common.cpp index f469d3e..c1c9e70 100644 --- a/src/override/common.cpp +++ b/src/override/common.cpp @@ -53,7 +53,7 @@ const std::string APP_VERSION_MAJOR = "2"; const std::string APP_VERSION = "2.1"; #if defined ARCH_WIN const std::string APP_OS = "win"; -#elif ARCH_MAC +#elif defined ARCH_MAC const std::string APP_OS = "mac"; #elif defined ARCH_LIN const std::string APP_OS = "lin"; diff --git a/utils/create-macos-installer.sh b/utils/create-macos-installer.sh new file mode 100755 index 0000000..642c40f --- /dev/null +++ b/utils/create-macos-installer.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +set -e + +if [ -d bin ]; then + cd bin +else + echo "Please run this script from the root folder" + exit +fi + +rm -rf res +rm -rf au +rm -rf lv2 +rm -rf vst2 +rm -rf vst3 + +mkdir au lv2 vst2 vst3 +mv *.component au/ +mv *.lv2 lv2/ +mv *.vst vst2/ +mv *.vst3 vst3/ +cp -RL lv2/Cardinal.lv2/resources res +rm -rf lv2/*.lv2/resources +rm -rf vst2/*.vst/Contents/Resources +rm -rf vst3/*.vst3/Contents/Resources + +pkgbuild \ + --identifier "studio.kx.distrho.cardinal.resources" \ + --install-location "/Library/Application Support/Cardinal/" \ + --root "${PWD}/res/" \ + ../dpf-cardinal-resources.pkg + +pkgbuild \ + --identifier "studio.kx.distrho.plugins.cardinal.components" \ + --install-location "/Library/Audio/Plug-Ins/Components/" \ + --root "${PWD}/au/" \ + ../dpf-cardinal-components.pkg + +pkgbuild \ + --identifier "studio.kx.distrho.plugins.cardinal.lv2bundles" \ + --install-location "/Library/Audio/Plug-Ins/LV2/" \ + --root "${PWD}/lv2/" \ + ../dpf-cardinal-lv2bundles.pkg + +pkgbuild \ + --identifier "studio.kx.distrho.plugins.cardinal.vst2bundles" \ + --install-location "/Library/Audio/Plug-Ins/VST/" \ + --root "${PWD}/vst2/" \ + ../dpf-cardinal-vst2bundles.pkg + +pkgbuild \ + --identifier "studio.kx.distrho.plugins.cardinal.vst3bundles" \ + --install-location "/Library/Audio/Plug-Ins/VST3/" \ + --root "${PWD}/vst3/" \ + ../dpf-cardinal-vst3bundles.pkg + +cd .. + +sed -e "s|@builddir@|${PWD}/build|" utils/plugin.pkg/package.xml.in > build/package.xml + +productbuild \ + --distribution build/package.xml \ + --identifier "studio.kx.distrho.cardinal" \ + --package-path "${PWD}" \ + --version 0 \ + Cardinal-macOS.pkg diff --git a/utils/create-windows-installer.sh b/utils/create-windows-installer.sh new file mode 100755 index 0000000..a8b9c58 --- /dev/null +++ b/utils/create-windows-installer.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -e + +if [ ! -d bin ]; then + echo "Please run this script from the root folder" + exit +fi + +# args +bit=${1} +bit=${bit:=64} + +# setup innosetup +dlfile="${PWD}/bin/innosetup-6.0.5.exe" +innodir="${PWD}/build/innosetup-6.0.5" +iscc="${innodir}/drive_c/InnoSetup/ISCC.exe" + +# download it +if [ ! -f "${dlfile}" ]; then + # FIXME proper dl version + curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o "${dlfile}" +fi + +# initialize wine +if [ ! -d "${innodir}"/drive_c ]; then + env WINEPREFIX="${innodir}" wineboot -u +fi + +# install innosetup in custom wineprefix +if [ ! -f "${innodir}"/drive_c/InnoSetup/ISCC.exe ]; then + env WINEPREFIX="${innodir}" wine "${dlfile}" /allusers /dir=C:\\InnoSetup /nocancel /norestart /verysilent +fi + +# generate resources +echo -n "" > utils/inno/resources.iss +IFS=' +' +for f in $(find -L bin/Cardinal.lv2/resources/ -type f); do + d=$(dirname $(echo ${f} | sed "s|bin/Cardinal.lv2/resources/||")) + echo "Source: \"..\\..\\$(echo ${f} | tr '/' '\\')\"; DestDir: \"{commoncf${bit}}\\Cardinal\\$(echo ${d} | tr '/' '\\')\"; Components: resources; Flags: ignoreversion;" >> utils/inno/resources.iss +done + +# generate version +echo "#define VERSION \"$(make version)\"" > utils/inno/version.iss + +# create the installer file +pushd "utils/inno" +env WINEPREFIX="${innodir}" wine "${iscc}" "win${bit}.iss" +popd + +# move installer file where CI expects it to be +mv utils/inno/*.exe . diff --git a/utils/inno/win32.iss b/utils/inno/win32.iss new file mode 100644 index 0000000..7255fd9 --- /dev/null +++ b/utils/inno/win32.iss @@ -0,0 +1,54 @@ +#include "version.iss" + +[Setup] +ArchitecturesInstallIn64BitMode=x64 +AppName=Cardinal +AppPublisher=DISTRHO +AppPublisherURL=https://github.com/DISTRHO/Cardinal/ +AppSupportURL=https://github.com/DISTRHO/Cardinal/issues/ +AppUpdatesURL=https://github.com/DISTRHO/Cardinal/releases/ +AppVersion={#VERSION} +DefaultDirName={commonpf32}\Cardinal +DisableDirPage=yes +DisableWelcomePage=no +LicenseFile=..\..\LICENSE +OutputBaseFilename=Cardinal-win32-{#VERSION}-installer +OutputDir=. +UsePreviousAppDir=no + +[Types] +Name: "full"; Description: "Full installation"; +Name: "custom"; Description: "Custom installation"; Flags: iscustom; + +[Components] +Name: resources; Description: "Resources"; Types: full custom; Flags: fixed; +Name: carla; Description: "Carla/Ildaeil host tools"; Types: full; +Name: lv2; Description: "LV2 plugin"; Types: full; +Name: vst2; Description: "VST2 plugin"; Types: full; +Name: vst3; Description: "VST3 plugin"; Types: full; + +[Files] +#include "resources.iss" +; carla +Source: "..\..\carla\bin\carla-bridge-*.*"; DestDir: "{commoncf32}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\bin\carla-discovery-*.exe"; DestDir: "{commoncf32}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\bin\libcarla_utils.dll"; DestDir: "{commoncf32}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\libpython3.8.dll"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\Qt5*.dll"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\iconengines\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\imageformats\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\platforms\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\styles\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\lib\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources\lib"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\lib\PyQt5\*.*"; DestDir: "{commoncf32}\Cardinal\Carla\resources\lib\PyQt5"; Components: carla; Flags: ignoreversion; +; lv2 +Source: "..\..\bin\Cardinal.lv2\*.*"; DestDir: "{commoncf32}\LV2\Cardinal.lv2"; Components: lv2; Flags: ignoreversion; +Source: "..\..\bin\CardinalFX.lv2\*.*"; DestDir: "{commoncf32}\LV2\CardinalFX.lv2"; Components: lv2; Flags: ignoreversion; +Source: "..\..\bin\CardinalSynth.lv2\*.*"; DestDir: "{commoncf32}\LV2\CardinalSynth.lv2"; Components: lv2; Flags: ignoreversion; +; vst2 +Source: "..\..\bin\Cardinal.vst\*.*"; DestDir: "{commoncf32}\VST2\Cardinal.vst"; Components: vst2; Flags: ignoreversion; +; vst3 +Source: "..\..\bin\Cardinal.vst3\Contents\x86-win\Cardinal.vst3"; DestDir: "{commoncf64}\VST3\Cardinal.vst3\Contents\x86-win"; Components: vst3; Flags: ignoreversion; +Source: "..\..\bin\CardinalFX.vst3\Contents\x86-win\CardinalFX.vst3"; DestDir: "{commoncf64}\VST3\CardinalFX.vst3\Contents\x86-win"; Components: vst3; Flags: ignoreversion; +Source: "..\..\bin\CardinalSynth.vst3\Contents\x86-win\CardinalSynth.vst3"; DestDir: "{commoncf64}\VST3\CardinalSynth.vst3\Contents\x86-win"; Components: vst3; Flags: ignoreversion; diff --git a/utils/inno/win64.iss b/utils/inno/win64.iss new file mode 100644 index 0000000..38f371d --- /dev/null +++ b/utils/inno/win64.iss @@ -0,0 +1,54 @@ +#include "version.iss" + +[Setup] +ArchitecturesInstallIn64BitMode=x64 +AppName=Cardinal +AppPublisher=DISTRHO +AppPublisherURL=https://github.com/DISTRHO/Cardinal/ +AppSupportURL=https://github.com/DISTRHO/Cardinal/issues/ +AppUpdatesURL=https://github.com/DISTRHO/Cardinal/releases/ +AppVersion={#VERSION} +DefaultDirName={commonpf64}\Cardinal +DisableDirPage=yes +DisableWelcomePage=no +LicenseFile=..\..\LICENSE +OutputBaseFilename=Cardinal-win64-{#VERSION}-installer +OutputDir=. +UsePreviousAppDir=no + +[Types] +Name: "full"; Description: "Full installation"; +Name: "custom"; Description: "Custom installation"; Flags: iscustom; + +[Components] +Name: resources; Description: "Resources"; Types: full custom; Flags: fixed; +Name: carla; Description: "Carla/Ildaeil host tools"; Types: full; +Name: lv2; Description: "LV2 plugin"; Types: full; +Name: vst2; Description: "VST2 plugin"; Types: full; +Name: vst3; Description: "VST3 plugin"; Types: full; + +[Files] +#include "resources.iss" +; carla +Source: "..\..\carla\bin\carla-bridge-*.*"; DestDir: "{commoncf64}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\bin\carla-discovery-*.exe"; DestDir: "{commoncf64}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\bin\libcarla_utils.dll"; DestDir: "{commoncf64}\Cardinal\Carla"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\libpython3.8.dll"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\Qt5*.dll"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\iconengines\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\imageformats\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\platforms\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\styles\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\lib\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources\lib"; Components: carla; Flags: ignoreversion; +Source: "..\..\carla\build\Carla\resources\lib\PyQt5\*.*"; DestDir: "{commoncf64}\Cardinal\Carla\resources\lib\PyQt5"; Components: carla; Flags: ignoreversion; +; lv2 +Source: "..\..\bin\Cardinal.lv2\*.*"; DestDir: "{commoncf64}\LV2\Cardinal.lv2"; Components: lv2; Flags: ignoreversion; +Source: "..\..\bin\CardinalFX.lv2\*.*"; DestDir: "{commoncf64}\LV2\CardinalFX.lv2"; Components: lv2; Flags: ignoreversion; +Source: "..\..\bin\CardinalSynth.lv2\*.*"; DestDir: "{commoncf64}\LV2\CardinalSynth.lv2"; Components: lv2; Flags: ignoreversion; +; vst2 +Source: "..\..\bin\Cardinal.vst\*.*"; DestDir: "{commoncf64}\VST2\Cardinal.vst"; Components: vst2; Flags: ignoreversion; +; vst3 +Source: "..\..\bin\Cardinal.vst3\Contents\x86_64-win\Cardinal.vst3"; DestDir: "{commoncf64}\VST3\Cardinal.vst3\Contents\x86_64-win"; Components: vst3; Flags: ignoreversion; +Source: "..\..\bin\CardinalFX.vst3\Contents\x86_64-win\CardinalFX.vst3"; DestDir: "{commoncf64}\VST3\CardinalFX.vst3\Contents\x86_64-win"; Components: vst3; Flags: ignoreversion; +Source: "..\..\bin\CardinalSynth.vst3\Contents\x86_64-win\CardinalSynth.vst3"; DestDir: "{commoncf64}\VST3\CardinalSynth.vst3\Contents\x86_64-win"; Components: vst3; Flags: ignoreversion; diff --git a/utils/plugin.pkg/package.xml.in b/utils/plugin.pkg/package.xml.in new file mode 100644 index 0000000..0304318 --- /dev/null +++ b/utils/plugin.pkg/package.xml.in @@ -0,0 +1,31 @@ + + + Cardinal + + + + + + + dpf-cardinal-resources.pkg + + + dpf-cardinal-components.pkg + + + dpf-cardinal-lv2bundles.pkg + + + dpf-cardinal-vst2bundles.pkg + + + dpf-cardinal-vst3bundles.pkg + + + + + + + + + diff --git a/utils/plugin.pkg/welcome.txt.in b/utils/plugin.pkg/welcome.txt.in new file mode 100644 index 0000000..3fa7d29 --- /dev/null +++ b/utils/plugin.pkg/welcome.txt.in @@ -0,0 +1,14 @@ +Cardinal is a free and open-source virtual modular synthesizer plugin. +It is based on the popular VCV Rack but with a focus on being a fully self-contained plugin version. + +Cardinal provides 3 plugin variants - "main", Synth and FX. +They are all equivalent in performance and behaviour, with only the IO and metadata that changes. + +FX and Synth variants both have 2 audio outputs, while "main" has 8. +All variants have MIDI input and output support. + +This package provides the AU, LV2, VST2 and VST3 audio plugins for macOS. + +Notes: + - Due to AU and VST2 not supporting CV ports, the main variant is not available for these formats. + - The VST3 version is in progress, already part of the build but still experimental.