pr1v8.ca

FL Studio 2026 on Linux with Windows plugins and iLok Cloud

· 13 min read · winefl-studioaudiolinux

FL Studio has no Linux version, and most of the plugins people own are Windows-only. Rebooting into Windows to make music works, but it gets old. This guide gets FL Studio 2026 and a typical commercial plugin collection running under Wine on a current Linux desktop, including plugins licensed through iLok Cloud.

It is written for someone who already uses FL Studio on Windows, owns their plugins, and is comfortable building software from source. Everything here was done on an Arch-based distribution with KDE Plasma on Wayland, PipeWire, and an NVIDIA card. Other distributions need the same steps with their own package names.

Where things stand at the end:

Why not yabridge#

yabridge is the usual answer to “Windows plugins on Linux”, but it exists so a native Linux DAW can host Windows plugins. FL Studio is itself a Windows program, so its plugins load in the same Wine process exactly as they do on Windows. No bridge is needed. yabridge also stopped working properly with Wine releases after 9.21, which makes it a dead end for a current Wine anyway.

The plan#

One Wine prefix for FL Studio and its plugins, run by a private build of Wine that carries a few fixes, installed under your home directory so the system Wine stays untouched. The fixes:

Patch Fixes Source
crypt32 signature order FL Studio refusing to start: “The validity of the program could not be verified” WineHQ merge request !11824
01 dxgi WaitForVBlank JUCE 7 plugin interfaces frozen after the first frame mine
02 dcomp Staging series DirectComposition for JUCE 8 plugins Wine Staging (CodeWeavers)
03 dxgi composition swapchains the swapchain type JUCE 8 presents to mine
04 dcomp compositor flicker, missing functions and stale frames in 02 mine

If you only need FL Studio and JUCE 7 plugins, the first two are enough. 02 to 04 only matter for plugins built on JUCE 8 or anything else that draws through DirectComposition.

1. Audio plumbing#

FL Studio talks to audio hardware through ASIO. The cleanest route is PipeASIO, an ASIO driver that talks to PipeWire directly. If your distribution pulled in jack2 as a dependency of something, replace it with PipeWire’s JACK so nothing ends up talking to a JACK server that isn’t running:

sudo pacman -S pipewire-jack

Pacman offers to remove jack2; accept.

2. Build the private Wine#

You need Wine’s build dependencies and the MinGW cross-compiler (mingw-w64-gcc on Arch). Download the four patches from the table above into ~/Downloads, then:

mkdir -p ~/src && cd ~/src
git clone --depth 1 --branch wine-11.19 https://gitlab.winehq.org/wine/wine.git wine-fl
cd wine-fl
curl -fL https://gitlab.winehq.org/wine/wine/-/merge_requests/11824.diff | git apply
for p in ~/Downloads/0[1-4]-*.patch; do git apply "$p"; done
mkdir ../wine-fl-build && cd ../wine-fl-build
../wine-fl/configure --prefix="$HOME/.local/opt/wine-fl" \
  --enable-archs=x86_64,i386 --disable-tests
make -j"$(nproc)" && make install

--enable-archs=x86_64,i386 gives the new WoW64 mode, so 32-bit plugins work without 32-bit host libraries. The patches are written against 11.19; on a newer Wine, check whether !11824 has been merged and drop it if so.

What the signature fix is about#

FL Studio checks its own Authenticode signature at startup. Its signature stores the signed attributes in an order that isn’t the canonical DER order. Windows hashes them exactly as stored. Wine re-sorts them before hashing, so the hash no longer matches and a valid signature is rejected. The merge request makes Wine hash the attributes as stored when verifying. It does not skip or weaken the check; a damaged signature is still rejected.

Copying Windows’ own crypt32.dll and wintrust.dll into the prefix does not work around this. I tried; FL either shows the same message or quits silently.

3. Create the prefix#

export WINEPREFIX="$HOME/.local/share/wineprefixes/flstudio"
W="$HOME/.local/opt/wine-fl/bin"
"$W/wineboot" -i
WINE="$W/wine" winetricks -q corefonts

The C++ runtime, by hand#

Most plugins need Microsoft’s Visual C++ runtime, and some (PACE-protected ones in particular) need functions that Wine’s own msvcp140.dll lacks. Two traps:

Install the files directly. Run winetricks once so it downloads the redistributables into its cache, then:

cd "$(mktemp -d)"
for arch in x64:system32:amd64 x86:syswow64:x86; do
  IFS=: read -r a dir suffix <<< "$arch"
  mkdir "$a" && cd "$a"
  cabextract -q -L ~/.cache/winetricks/vcrun2022/vc_redist.$a.exe
  for c in a*; do cabextract -q -L -d out "$c" 2>/dev/null; done
  for f in out/*_"$suffix"; do
    cp -f "$f" "$WINEPREFIX/drive_c/windows/$dir/$(basename "$f" _"$suffix")"
  done
  cd ..
done

Check it took: WINEDEBUG=+loaddll should report MSVCP140.dll ... native, not builtin. Redo this after anything that updates the prefix.

Display scaling and fonts#

Wine ignores the desktop’s scale factor. Set the prefix DPI to match it: 96 is 100 %, 120 is 125 %, 144 is 150 %.

"$W/wine" reg add 'HKCU\Control Panel\Desktop' /v LogPixels /t REG_DWORD /d 120 /f

Fonts looked off until two more changes: the real Windows fonts, and font smoothing, which Wine leaves off. If you have a Windows installation, copy the .ttf, .ttc and .otf files from its Windows\Fonts into the prefix’s drive_c/windows/Fonts; Wine loads everything in that folder. Then turn on RGB smoothing:

for kv in FontSmoothing:REG_SZ:2 FontSmoothingType:REG_DWORD:2 \
          FontSmoothingGradientOrientation:REG_DWORD:1 \
          FontSmoothingOrientation:REG_DWORD:1; do
  IFS=: read -r k t v <<< "$kv"
  "$W/wine" reg add 'HKCU\Control Panel\Desktop' /v "$k" /t "$t" /d "$v" /f
done

4. Install FL Studio#

Run the normal installer with the private Wine and log in to your Image-Line account from inside FL:

"$W/wine" flstudio_win64_26.1.7.5653.exe

5. PipeASIO#

Build PipeASIO against the private Wine so it lands in that Wine’s library folders:

cd ~/src
git clone --depth 1 --branch v1.7.0 https://github.com/M0n7y5/pipeasio.git
cd pipeasio
W="$HOME/.local/opt/wine-fl"
PATH="$W/bin:$PATH" cmake -B build -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX="$W" \
  -DWINEBUILD="$W/bin/winebuild" -DWINEGCC="$W/bin/winegcc" \
  -DWINE_INCLUDE_DIRS="$W/include/wine;$W/include/wine/windows" \
  -DBUILD_SETTINGS_PANEL=OFF -DBUILD_ARM64=OFF -DBUILD_TESTS=OFF
PATH="$W/bin:$PATH" cmake --build build -j"$(nproc)"
cmake --install build
WINE="$W/bin/wine" PIPEASIO_PREFIX="$W" "$W/bin/pipeasio-register"

In FL Studio, pick PipeASIO under Options, Audio, and turn off “Mix in buffer switch”; PipeASIO’s documentation says that option causes crackling. The buffer size lives in ~/.config/pipeasio/config.ini and changes take effect without restarting FL.

I tried WineASIO first. Its register script looks for a wine64 command, which new WoW64 builds no longer ship, and once registered by hand it failed to open in FL. With PipeASIO there is one layer fewer anyway.

6. The browser and FL Cloud panes (WebView2)#

FL’s Sounds browser and FL Cloud pane are WebView2, Microsoft’s embedded Chromium. Under Wine they stay black. A WebView2 bug report blames graphics flags the runtime appends under Wine; on this machine the actual failure is different. When Windows reports 8.1 or later, Chromium always creates a compositor that needs DirectComposition. Wine’s DCompositionCreateDevice returns E_NOTIMPL, Chromium hits a CHECK on that, and the GPU process crash-loops until the page gives up.

On Windows 8 Chromium doesn’t use DirectComposition at all, so telling only the WebView2 runtime that it runs on Windows 8 fixes it. FL itself still sees Windows 10:

"$W/wine" reg add 'HKCU\Software\Wine\AppDefaults\msedgewebview2.exe' \
  /v Version /t REG_SZ /d win8 /f

This worked on runtimes 149 and 155. Windows 8.1 does not work.

The WebView2 installer also leaves Edge’s update services running in the prefix, which keeps it alive after FL exits. Disable them, and stop the runtime from updating itself past the version you tested:

for s in edgeupdate edgeupdatem; do
  "$W/wine" reg add "HKLM\\System\\CurrentControlSet\\Services\\$s" \
    /v Start /t REG_DWORD /d 4 /f
done
"$W/wine" reg add 'HKLM\Software\Policies\Microsoft\EdgeUpdate' \
  /v UpdateDefault /t REG_DWORD /d 0 /f

7. A launcher that closes the prefix with FL#

System Wine can’t start FL (it fails the signature check), so every menu entry for this prefix has to use the private build. I also wanted the whole prefix, services included, to shut down when FL closes. ~/.local/bin/fl-studio:

#!/bin/sh
# fl-studio              start FL Studio
# fl-studio --app EXE    start another program of the prefix (Unix path)
# fl-studio URL          hand a flstudio:// link to the running FL
export WINEPREFIX="$HOME/.local/share/wineprefixes/flstudio"
export WINEDEBUG="${WINEDEBUG:--all}"
bin="$HOME/.local/opt/wine-fl/bin"
case "$1" in
    "")
        cd "$WINEPREFIX/drive_c/Program Files/Image-Line/FL Studio 2026" || exit 1
        "$bin/wine" FL64.exe ;;
    --app)
        shift; app=$1; shift
        cd "$(dirname "$app")" || exit 1
        "$bin/wine" "$app" "$@" ;;
    *)
        exec "$bin/wine" start "$@" ;;
esac
status=$?
# Once no FL is left, end every process in the prefix.
pgrep -f 'FL64\.exe' >/dev/null || "$bin/wineserver" -k
exit $status

Point the Exec= lines of the menu entries Wine created (under ~/.local/share/applications/wine/) at this script, including the flstudio:// protocol handler, which the Image-Line login uses. Then stop Wine from rewriting them on the next FL update:

"$W/wine" reg add 'HKCU\Software\Wine\DllOverrides' /v winemenubuilder.exe /d '' /f

New installers then add no menu entries; add those by hand.

8. iLok Cloud#

iLok Cloud works under Wine. I only use iLok Cloud. A USB dongle needs a kernel driver, which Wine can’t load, and I haven’t tried machine activation.

  1. Snapshot the prefix first, because PACE installs services: cp -a --reflink=always "$WINEPREFIX" "$WINEPREFIX.pre-ilok" (on btrfs or XFS this costs almost nothing).
  2. Download iLok License Support from ilok.com and run License Support Win64.exe with the private Wine. Use the normal installer window: its silent mode quits with code -3 because it wants a recorded response file, and Wine re-quotes the /v"..." argument InstallShield needs.
  3. The installer also adds Apple’s Bonjour service, which isn’t needed for Cloud sessions. Disable it the same way as the Edge services ("Bonjour Service", Start = 4).
  4. Open iLok License Manager, sign in, and start a Cloud Session. Then load an iLok plugin in FL.

PACE’s license service (LDSvc.exe) starts with the prefix and stops with it, which fits the launcher above. While Wine’s own msvcp140.dll was installed, its log showed the same missing runtime functions that broke soothe3 (section 3). Cloud Sessions worked anyway; with Microsoft’s runtime the warnings are gone.

9. Installing plugins#

Most plugin installers have silent switches, which saves a lot of clicking:

Installer Command
Inno Setup wine setup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
NSIS wine setup.exe /S
MSI wine msiexec /i package.msi /qn
InstallShield use the window

strings setup.exe | grep -m1 -E 'Inno Setup|Nullsoft|InstallShield' tells you which one you have. One NSIS installer (Xfer Dimension Expander) installed nothing silently because it needs a target folder, and passing a /D= path with spaces through Wine didn’t work for me. 7-Zip unpacks NSIS installers, so copying the plugin DLL out of the archive into Common Files\VST2 was the quicker fix.

Installers put VST2 files in three different folders (Common Files\VST2, Program Files\Vstplugins, Program Files\Steinberg\VSTPlugins). Add all three to FL’s plugin search paths, or stick to the VST3 versions.

10. Frozen JUCE 7 interfaces#

Several plugins opened, accepted a serial typed blind, and never redrew: Trackspacer, Polyverse Wider, ShaperBox 3, and Kickstart 2, whose window stayed black. Others from the same vendors worked, which made it look random.

The split follows how JUCE 7 schedules painting. It doesn’t paint when a control changes. repaint() queues the area, and the queue is flushed from onVBlank(), which only a VSyncThread calls. That thread loops on IDXGIOutput::WaitForVBlank() and sleeps 1 ms whenever the call fails. In Wine the call is a stub that always returns E_NOTIMPL, so the window paints once and never again. Every frozen plugin imports dxgi.dll and contains the VSyncThread string; none of the working ones do.

Patch 01 makes WaitForVBlank() sleep until the next refresh interval of the output’s current mode and return S_OK, the same thing DXVK does. It is Wine bug 56799. There is an open upstream merge request (!10246) that polls in a tight loop instead; in my measurements that burned a little over one CPU core per open JUCE window, against about 15 % of one core with the sleep.

DXVK fixes these plugins too, for the same reason, but it replaces Direct3D for the whole FL process and needs d3d10core overridden as well, or Wider crashes. The DirectComposition patches below also assume Wine’s built-in Direct3D, so I didn’t use it.

11. JUCE 8 and DirectComposition#

soothe3 loaded and processed audio, but its editor was an empty grey rectangle. Two renderers are involved: JUCE 8’s own window renderer (Direct2D) and the plugin’s interface renderer (Direct3D 11). Both present through IDXGIFactory2::CreateSwapChainForComposition and DirectComposition, and both calls are stubs in Wine 11.19. JUCE has no software fallback for a plugin editor’s window, so there was nothing to switch on: DirectComposition had to work.

Wine Staging carries a DirectComposition implementation by CodeWeavers that isn’t upstream yet. Patch 02 is that series, squashed for 11.19, minus a part that needs wineserver changes and only serves shared visual handles. On its own it still drew nothing for soothe3. Patches 03 and 04 fill the gaps:

Result: soothe3’s full interface, updating when a knob moves. Drawing costs about 9 % of one core while the editor is open and animating, mostly reading frames back from the GPU. Plugins that don’t use DirectComposition are unaffected.

What works and what doesn’t#

Status
FL Studio 2026, login, browser and Cloud panes works
PipeASIO audio works
iLok Cloud (License Manager, Cloud Session, Slate Fresh Air) works
soothe3 (JUCE 8, iLok) works with 02 to 04
Trackspacer, Wider, ShaperBox 3, Kickstart 2 (JUCE 7) work with 01
ShaperBox 2, Xfer OTT, Spire worked unpatched
MIDI the “PipeWire-System” and “PipeWire-RT-Event” entries always fail to open; they are PipeWire’s own sequencer clients, not devices, so disable them

Still open#

All four patches are LGPL-2.1-or-later like Wine. Patch 01 belongs upstream on bug 56799, and 03 and 04 are improvements to the Staging series.