FL Studio 2026 on Linux with Windows plugins and iLok Cloud
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:
- FL Studio 2026 (26.1.7) starts, logs in, and its browser and FL Cloud panes render.
- Audio goes through an ASIO driver that talks straight to PipeWire.
- iLok License Manager signs in and runs a Cloud Session; an iLok plugin (Slate Fresh Air) loads licensed and processes audio.
- JUCE 7 plugins whose interfaces froze after the first frame (Trackspacer, Wider, ShaperBox 3, Kickstart 2) redraw normally.
- A JUCE 8 plugin that showed an empty grey box (soothe3) draws its full interface.
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:
winetricks vcrun2022currently installs nothing. Microsoft’s redistributable names the files inside its cabinetsmsvcp140.dll_amd64andmsvcp140.dll_x86, so thecabextract -F msvcp140.dllstep in winetricks matches nothing, and Microsoft’s installer then leaves Wine’s copy alone.- Whenever Wine updates a prefix (the first run after a Wine upgrade, or after
make installchangeswine.inf), it can put its ownmsvcp140.dllback.
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.
- Snapshot the prefix first, because PACE installs services:
cp -a --reflink=always "$WINEPREFIX" "$WINEPREFIX.pre-ilok"(on btrfs or XFS this costs almost nothing). - Download iLok License Support from ilok.com and run
License Support Win64.exewith 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. - 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). - 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:
SetOffsetYandSetClip, which soothe3’s renderer needs, were missing.- Staging starts one compositor thread per device. Two layers on one window then race, and about half the frames came out black. 04 uses one compositor per process that draws all of a window’s targets together, bottom to top.
- Wine’s built-in Direct3D rotates swapchain buffers on every present, so the newest frame is in the last buffer. Staging reads buffer 0, which is right for DXVK only.
- JUCE presents only the changed rectangles and relies on the rest of the previous frame being kept, as Windows does. 03 keeps it.
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#
- iLok machine activation and dongles: not tried.
- Whether a Cloud Session survives the prefix shutting down, or has to be restarted in License Manager each time: not checked yet.
- Vendor apps that manage plugins (Native Access, Splice, the Minimal Audio hub): not tried. They are the most likely to fail.
- Only one JUCE 8 plugin was tested. A JUCE 8 plugin that draws everything through Direct2D may still hit gaps in Wine’s Direct2D.
- The four patches above apply cleanly to Wine 11.19 with !11824, but the build I run also carries two patches from the Audion project (an OpenGL flicker fix and a guard for FL’s Effectrix plugin). The JUCE 7 investigation showed the OpenGL patch makes no difference to the freezes. I haven’t built and run the four-patch set without them.
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.