As I am learning about VST development I wanted to share my notes, first as a way to document my own understanding for the future and second as a way to help others following a similar path.

This is not meant to be generic for all platforms and is only focusing on macOS.

Configuration

At the time of this writing (March 2018) I am using:

  • Hardware: MacBook Pro (Mid 2014) / 2.8Ghz Intel Core i7 / 16GB
  • macOS High Sierra 10.13.3
  • Xcode 9.2
  • CLion 2017.3.3

Notes

Install

Version VST 3 / 369 (vstsdk369_01_03_2018_build_132) downloaded from Steinberg (shasum 256 => 7c6c2a5f0bcbf8a7a0d6a42b782f0d3c00ec8eafa4226bbf2f5554e8cd764964).

After unpacking, run

./copy_vst2_to_vst3_sdk.sh

to make sure that we can build VST2 wrappers as well (VST3 is very poorly supported, ex: Maschine by Native Instruments or Reason by Propellerhead do not support it)

Documentation

Documentation starts with VST3_SDK/index.html and is not really beginner friendly.

Building the SDK and examples

The VST3 SDK uses cmake as its built tool. This lets you build the project on various platforms as well as use Xcode or Visual Studio (altough I do not recommend this approach if you want to build cross plaform). The section “How to use cmake for Building VST 3 Plug-in” describes the various steps.

New in version 3.6.9, the ability to build your own plugins. There is actually a brand new documentation page explaining how to do that.

I investigated 2 ways of building the SDK and examples: one with Xcode and one with CLion/Makefiles

Building the SDK, samples and helloworld (with Xcode)

Generate Xcode project
  • Run cmake-gui (version 3.9.4 installed from CMake download) from anywhere.
  • In the Where is the source code: field, point to the VST3_SDK folder.
  • In the Where to build the binaries: field, point to any folder you want
  • Click Configure (and approve creation of the output folder if it does not exist).
  • Select Xcode for the generator for this project.
  • Once the configuration completes, the Name/Value section will have some default values. Check the SMTG_CREATE_VST2_VERSION option because we want to build VST2 plugins as well. Note how the SMTG_MYPLUGINS_SRC_PATH is pointing to the my_plugins folder contained with the distribution, but oustide the actual SDK. More on this later.
  • Click Generate
Build the again example
All this is relative to the Where to build the binaries: folder previously set.
  • Under the output folder previously selected there is now a Xcode project called vstsdk. Double click to open in Xcode.
  • In the Scheme selection dropdown (on the right of the buttons that look like play & stop), select again / My Mac
  • Now select menu Product/Build to build again plugin
  • The result of the build will be stored under VST3/Debug/again.vst3
  • As a side effect of this build, some libraries were generated (under lib/Debug) and a validator tool (bin/Debug/validator)
  • Run the validator tool:
./bin/Debug/validator VST3/Debug/again.vst3
...
* Scanning classes...

  Factory Info:
	vendor = Steinberg Media Technologies
	url = http://www.steinberg.net
	email = mailto:info@steinberg.de

  Class Info 0:
	name = AGain VST3
	category = Audio Module Class
	cid = 84E8DE5F92554F5396FAE4133C935A18

  Class Info 1:
	name = AGain VST3Controller
	category = Component Controller Class
	cid = D39D5B65D7AF42FA843F4AC841EB04F0

  Class Info 2:
	name = AGain SideChain VST3
	category = Audio Module Class
	cid = 41347FD6FED64094AFBB12B7DBA1D441
...
-------------------------------------------------------------
Result: 78 tests passed, 0 tests failed
-------------------------------------------------------------
Note that the validator tool is actually run automatically part of the build (it is an option in the cmake build file which is ON by default).
  • Copy the plugin as a VST2 plugin for local testing
    cp -r VST3/Debug/again.vst3 ~/Library/Audio/Plug-Ins/VST/again.vst
Note that since 3.6.9, a link into the VST3 folder is automatically created as part of the build (variable SMTG_VST3_TARGET_PATH in cmake-gui).
  • Open a DAW application (Maschine in my example) and assign the plugin to a sound (the plugin is under Steinberg Media Technologies)
Build the helloworld example

This is easy and just a matter of selecting another Scheme: helloworldWithVSTGUI > Mac under the drowdown and building it.

This example is not a VST2 plugin!

Building the SDK, samples and helloworld (on the CLI)

The reason why I do not like to use Xcode (or Visual Studio) is that the source of truth is the CMakeLists.txt file. If you generate an Xcode project, then the Xcode project becomes the source of truth: if you add source files to the project or resources (like images), then they only get added to the Xcode project. So you then would have to backport your changes to the CMakeLists.txt in order to compile on a different platform.

SDK 3.6.9 is actually broken when it comes to command line (see post). A workaround is to disable the validator to run automatically.
Generate the project

The first step is to generate the project (this assumes that the sdk has been installed under /Applications/VST_SDK.369):

mkdir -p /tmp/vst369.sdk/Debug
cd /tmp/vst369.sdk/Debug

# enable VST2 and disable automatic run of validator (workaround)
cmake -DSMTG_RUN_VST_VALIDATOR=OFF -DSMTG_CREATE_VST2_VERSION=ON /Applications/VST_SDK.369/VST3_SDK
Build the again sample

After running the previous command, you can run this commands to generate the again sample:

cmake --build . --target again

Since the validator was disabled, let’s build it first:

cmake --build . --target validator

And run it to verify that the again sample was built properly:

./bin/validator VST3/again.vst3
* Loading module...

	/tmp/vst369.sdk/Debug/VST3/again.vst3

* Scanning classes...

  Factory Info:
	vendor = Steinberg Media Technologies
	url = http://www.steinberg.net
	email = mailto:info@steinberg.de

  Class Info 0:
	name = AGain VST3
	category = Audio Module Class
	cid = 84E8DE5F92554F5396FAE4133C935A18

  Class Info 1:
	name = AGain VST3Controller
	category = Component Controller Class
	cid = D39D5B65D7AF42FA843F4AC841EB04F0

  Class Info 2:
	name = AGain SideChain VST3
	category = Audio Module Class
	cid = 41347FD6FED64094AFBB12B7DBA1D441

...

-------------------------------------------------------------
Result: 78 tests passed, 0 tests failed
-------------------------------------------------------------
The SDK is also broken when it comes to building a VST2 plugin on the command line! The reason being that the C function VSTPluginMain is not exported properly as proven by this output
mrswatson64 --display-info -p VST3/again.vst3
- 00000000 000000 MrsWatson version 0.9.8 initialized, build 20150122
- 00000000 000000 Plugin 'VST3/again.vst3' is of type VST2.x
- 00000000 000000 Opening VST2.x plugin 'VST3/again.vst3'
E 00000000 000005 Couldn't get a pointer to plugin's main()
E 00000000 000005 Could not load VST2.x plugin '/Volumes/Vault/tmp/blog/VST3/again.vst3'
E 00000000 000005 Plugin 'VST3/again.vst3' could not be opened
E 00000000 000005 Plugin 'VST3/again.vst3' could not be added to the chain
E 00000000 000005 Plugin chain could not be constructed, exiting

In order to fix this issue you need to modify the SDK :(

  • add a file public.sdk/source/main/macexport_vst2.exp with the following content (exporting the VST3 specific symbols + the VST2 specific one to make the plugin work either as a VST3 or VST2 plugin)
    _GetPluginFactory
    _bundleEntry
    _bundleExit
    _VSTPluginMain
  • change the again/CMakeLists.txt section to use it
if (SMTG_CREATE_VST2_VERSION)
  message(STATUS "SMTG_CREATE_VST2_VERSION is set for ${target}. A VST 2 version of the plug-in will be created (just rename the generated file from .vst3 to .vst).")
  if(MAC)
  # fix missing VSTPluginMain symbol when also building VST 2 version
    smtg_set_exported_symbols(${target} "${SDK_ROOT}/public.sdk/source/main/macexport_vst2.exp")
  endif()
  if (WIN)
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
  endif()
endif()

Then you need to regenerate the Makfiles (first cmake command) and then rebuild again.

Building your own VST plugin(s)

I spent a lot of time trying to figure out how to build my own VST plugin since I started with 3.6.8 which did not provide any means or instructions. This has changed with 3.6.9 which now provides an example plugins folder (my_plugins) and the necessary CMake changes in order to build an outside the SDK project.

Although this is a serious improvement since 3.6.8, I am still not thrilled with the end result:

  • instead of having your project depends on the SDK, it is the other way around: you create a project and then you tell the SDK (via SMTG_VST3_TARGET_PATH) where your project is located. This makes it very hard to work with CLion for example, because the root of the project is always the SDK not your project (you are still building vstsdk, not MyPlugin).
  • the build location of your project is hardcoded to be build in the source tree of your project
  • also note that none of the helloworld examples provided use VST2 (you can use the again sample for that).
  • the SDK is actually broken in a couple of places when not using Xcode (validator and VST2)

For this reason I created a project which addresses the shorcomings of the SDK and is a fully self contained project: the idea is that the CMakeLists.txt of the project includes (a modified version of) the one coming with the SDK and relies on its location (VST3_SDK_ROOT). The full source code is available on github vst3-again-sample

Note that this project includes:

* the proper fix for VST2 so there is no need to patch the SDK
* fix to the validator issue

It is probably not the best solution but that is the best I could do. It does achieve the fact that it is a self contained, properly version controlled project, which depends on the SDK. I just wished Steinberg was distributing the SDK with a native/tested/bullet proof way to do this.

Using CLion

Clion can actually work directly with CMake thus making the process more straightforward and cleaner as you are only dealing with the original project: CLion shows the original project and use CMake directly, so as a result if you add a resource to the project it will be added to the CMake world.

Using the vst3-again-sample as an example

  • simply open the project with CLion. Initially, CLion tries to build the project and it will fail because it does not know where the SDK root is located
  • under the menu Preferences / Build,Execution,Deployment / CMake add the CMake options:
    -DVST3_SDK_ROOT=/Applications/VST_SDK.369/VST3_SDK -DSMTG_CREATE_VST2_VERSION=ON
  • Note that you can change the Generation path: so that it is outside the source folder (which I personally prefer)
  • Select the again | Debug configuration (similar to Xcode scheme) and select the menu item Run / Build
  • The outcome will be under VST3 (relative to Generation Path)

Testing with validator and deploying to a DAW are the same as the Xcode section with the difference that there is no Debug subfolders (if you use the default Generation Path, the debug concept is part of the directory name).

Note that the validator tool is actually run automatically part of the build (it is an option in the cmake build file which is ON by default).

Next

Now that we know how to build any VST 3 plugin (as well as VST 2) while depending on the SDK, it is time to build your own. This is the point of Part 2.

Last edited: 2018/03/14