CMake: COPY_PLUGIN_AFTER_BUILD, CLion and building plugin installers with CPack

This is a two-piece question, however both parts are somewhat related.


I’m using CLion as IDE and found out that when specifying COPY_PLUGIN_AFTER_BUILD TRUE with juce_add_plugin I need to run the Install step after the build in order to run the copy step, so I added it to the run config like this as step before launch

This works, but from the command line output generated I see that beneath the plugin executables tons of stuff gets installed to /usr/local/lib/cmake/JUCE-6.0.0/ and /usr/local/include/JUCE-6.0.0/modules/ (basically the whole JUCE source files). This does not really harm but it makes builds a bit longer and it seems like a totally unnecessary thing. So first of all I’m wondering if I’m doing anything wrong here?

2. Using CPack to create plugin installers

I just discovered CPack which seems to be a quite simple way to create platform specific installers from within CMake.

With those few lines of CMake code I nearly get a basic working VST3 & AU capable installer ready

# CPack takes these paths as the locations where the plugins should be installed in the end

# This makes sure that only the two components and nothing else is part of our installer

# We want to use the native Apple GUI installer
SET (CPACK_GENERATOR productbuild)

When calling cpack now from the command line I get the following error:

CMake Error at Deployment/MacOS/cmake_install.cmake:62 (file):
  file INSTALL cannot make directory
  "/Library/Audio/Plug-Ins/Components/MYPLUGIN.component": Permission denied.

Which shows me that invoking cpack installs the plugin to the system folder before creating the installer. Running cpack with sudo fixes this issue and creates a working installer. I could also tolerate that, BUT with the modifications above added to the CMakeLists.txt the Install step triggered from CLion now attempts to install my plugin to the system folder rather than the user folder which seems somewhat logical but fails now due to permission issues.

Three questions arising from that:

  1. Am I doing everything right with adding the Install step in CLion or is there any better way to do it (e.g. manually add some script that is called to copy the plugins from the MYPLUGIN_artefacts to the user folder)?
  2. Is there any clever way of chosing a different INSTALL configuration only applied to CPack
  3. Can CPack run without installing everything to the location where the generated installer would install the binaries to so that running cpack is possible without root permissions?

Update: Seems like all this is not as simple for a non CMake-Pro like me as I thought :smiley:

Of course my goal is to create a Cross-Platform capable installer in the end with minimal effort.

First problem I encountered: Replicating the solution from above for windows with the windows specific paths lead to an error that absolute paths are not allowed as destinations. On stackoverflow someone suggested to use relative paths and set CMAKE_INSTALL_PREFIX to point to the base directory, however that leads to an installation relative to the application directory

Second problem: Both, Mac and Windows installers created this way try to install JUCE with all its sources and as Unspecified component along with the plugin components, although I specify SET (CPACK_COMPONENTS_ALL VST3 AU). Not sure why, probably I understand something wrong here due to the lack of CMake experience.

I get the feeling that although installer creation with CPack seems super easy at first, it is deeply tied into the CMake install logic and therefore dependent on how the JUCE CMake implementation uses that under the hood. @reuk, would you say that what I’m trying here is a bad idea in general or is it a good idea in general, simply done in a wrong way?

This should not be necessary. The installation is run using a POST_BUILD custom command, so it should run every time the plugin target is built. Note that it won’t run if the plugin has already been built. I’d recommend removing the Install step from your build config, and trying again with a clean build.

According to the CPack docs:

Some CPack generators do monolithic packaging by default and may be asked to do component packaging by setting CPACK_<GENNAME>_COMPONENT_INSTALL to TRUE .

It might be worth explicitly setting that variable to TRUE for whatever generators you’re using.

It’s difficult to say. I haven’t played too much with CPack, but it seems like it would be quite difficult to set up for plugin installers, for the reasons you’ve mentioned: CPack tries to run the install on the build system before packaging, which may require elevated permissions. I can imagine this would cause difficulties if two builds were being run simultaneously (e.g. on a CI machine). Some plugin types (like VST3 on Windows) require their enclosing folder structure to be installed, rather than just the VST3 target itself, so adding a VST3 to the installer may not be as simple as installing the VST3 target. Also, on Windows the install directory may not be known ahead-of-time, and instead may need to be computed using environment variables on the destination system.

I imagine it will be possible to set up CPack for a JUCE project. However, I’m uncertain whether working around CPack’s idiosyncrasies will be less effort than building platform-dependent installers from scratch.

Mhm, just tried it, when using CLion the plugin is not copied after hitting build. However when running the build from the command line the copy step works. Not sure why? Is anyone using CLion here and knows what I could be doing wrong here?

Regarding CPack: Alright, seems like my initial assumption that this would make things super easy was wrong :grin: But could you elaborate on this one

What do you mean by the enclosing folder structure? Isn’t each VST3 itself a folder and isn’t this folder simply copied to the destination directory when installing the target?


It depends on the platform. On macOS, the VST3 folder is automatically created as part of the MODULE target, and CMake knows that the TARGET_FILE for the VST3 is actually the enclosing folder. On Windows and Linux, MODULE libraries don’t conventionally live inside directories, so we have to create the correct directory structure manually and ask CMake to place the dll inside it. Unfortunately, CMake still thinks of the dll itself as the ‘target’, rather than the enclosing folders.