Problems linking static library using CMake

Hello everyone, I’m on Windows trying to add FFTW as a static library to my plug-in. I’m mostly doing this for academic purposes as a fun exercise.

However, I’m having an issue where the project won’t build correctly and I’ll get a bunch of linker errors. Namely a lot of

C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: The command "setlocal [C:
\Path\to\Project\build\JuceTestPlugin_VST3.vcxproj]

They’re all MSB3073.

I’m thinking this is probably something I’m doing wrong when I’m linking FFTW, but I can’t figure out what it is. My CMakeLists.txt file looks like this:



cmake_minimum_required(VERSION 3.22)

project(JUCETEST VERSION 0.0.1)

include_directories(${CMAKE_SOURCE_DIR}/include)
link_directories(${CMAKE_SOURCE_DIR}/lib)

add_subdirectory(JUCE) 

juce_add_plugin(JuceTestPlugin
    COMPANY_NAME Test                   
    IS_SYNTH FALSE            
    NEEDS_MIDI_INPUT FALSE     
    NEEDS_MIDI_OUTPUT FALSE      
    IS_MIDI_EFFECT FALSE     
    EDITOR_WANTS_KEYBOARD_FOCUS FALSE   
    COPY_PLUGIN_AFTER_BUILD TRUE
    PLUGIN_MANUFACTURER_CODE Test 
    PLUGIN_CODE Test                           
    FORMATS AU VST3 Standalone                
    PRODUCT_NAME "JuceTestPlugin")       

juce_generate_juce_header(JuceTestPlugin)

target_sources(JuceTestPlugin
    PRIVATE
        source/PluginEditor.cpp
        source/PluginProcessor.cpp
        source/Oscillator.cpp
        source/AnalyzerComponent.cpp)

target_compile_definitions(JuceTestPlugin
    PUBLIC
        # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them.
        JUCE_WEB_BROWSER=0  # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call
        JUCE_USE_CURL=0     # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call
        JUCE_VST3_CAN_REPLACE_VST2=0)

target_link_libraries(JuceTestPlugin
    PRIVATE
        # AudioPluginData           # If we'd created a binary data target, we'd link to it here
        juce::juce_audio_utils
    PUBLIC
        fftw3
        juce::juce_recommended_config_flags
        juce::juce_recommended_lto_flags
        juce::juce_recommended_warning_flags)

And my FFTW installation followed the steps on the official documentation, using the precompiled .dll files to build .lib files using Visual Studio.

Intellisense recognises the fftw3.h header, and I can even access the enums and their respective values, but any time I try to use any of the actual functionality of the library, I get dozens of those errors when building the project. I’m not sure what else I’m supposed to do now. I feel like I’ve tried all possible combinations including rebuilding FFTW’s lib files, clearing the CMake build, changing the function placements in the CMakeLists.txt and nothing seems to work.

Would need to see more of the error messages to debug this - but this is usually triggered by a post-build step failing, such as an xcopy failing, or whatever.

Does your project have a path with spaces in the names anywhere? This can trip up post-build steps mightily - never do it! Always have as short and succinct names in your paths for everything.

I statically link with fftw in my projects “SharedCode” targets, fwiw.

Just as a followup, I found the following related to my own use of fftw:

# Third-party FFTW library
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON")
add_subdirectory (../thirdPartyLibs/fftw3 fftw3)

# Project Setup:
juce_add_plugin("${PROJECT_NAME}"

Not sure this is related directly to your problem, but when you finally work out the bug in your own CMake configuration, you’re also going to need that CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS option as well, I think …

Awesome! Thank you for the info. I’ll check these out and see how it goes!

I checked and the project does not have any directories or subdirectories with spaces, and it also isn’t under one either anywhere in the path. However, Visual Studio’s path does contain spaces (that’s how it installed itself by default) and of course the “Program Files” folder also contains spaces, though I’m guessing that one gets special treatment as a default folder.

Here’s more of the errors. They don’t provide any additional context that I could notice:

C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: El comand
o "setlocal [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: "C:\Progr 
am Files\CMake\bin\cmake.exe" -E echo "removing moduleinfo.json" [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\Juce 
TestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: if %error 
level% neq 0 goto :cmEnd [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: "C:\Progr 
am Files\CMake\bin\cmake.exe" -E remove -f C:/Users/usuario/Documents/Programming/CMake_Learning/Juce_test_1/build/JuceTestPlugin_artefacts/De 
bug/VST3/JuceTestPlugin.vst3/Contents/moduleinfo.json C:/Users/usuario/Documents/Programming/CMake_Learning/Juce_test_1/build/JuceTestPlugin_a 
rtefacts/Debug/VST3/JuceTestPlugin.vst3/Contents/Resources/moduleinfo.json [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\ 
build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: if %error 
level% neq 0 goto :cmEnd [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmEnd [C 
:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: endlocal  
& call :cmErrorLevel %errorlevel% & goto :cmDone [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3. 
vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmErrorL 
evel [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: exit /b % 
1 [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmDone [ 
C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: if %error 
level% neq 0 goto :VCEnd [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: setlocal  
[C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: "C:\Progr 
am Files\CMake\bin\cmake.exe" -E make_directory C:/Users/usuario/Documents/Programming/CMake_Learning/Juce_test_1/build/JuceTestPlugin_artefac 
ts/Debug/VST3/JuceTestPlugin.vst3/Contents/Resources [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_V 
ST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: if %error 
level% neq 0 goto :cmEnd [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: Debug\juc 
e_vst3_helper.exe -create -version 0.0.1 -path C:/Users/usuario/Documents/Programming/CMake_Learning/Juce_test_1/build/JuceTestPlugin_artefact 
s/Debug/VST3/JuceTestPlugin.vst3 -output C:/Users/usuario/Documents/Programming/CMake_Learning/Juce_test_1/build/JuceTestPlugin_artefacts/Debu 
g/VST3/JuceTestPlugin.vst3/Contents/Resources/moduleinfo.json [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTes 
tPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: if %error 
level% neq 0 goto :cmEnd [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmEnd [C 
:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: endlocal  
& call :cmErrorLevel %errorlevel% & goto :cmDone [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3. 
vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmErrorL 
evel [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: exit /b % 
1 [C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(159,5): error MSB3073: :cmDone [ 
C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_VST3.vcxproj]

I vaguely remember getting MSB3073 back in my windows days when not running MSVC as admin with the post build plugin copy step is enabled

This looks more like a problem with your development environment setup - are you running cmake manually, or through the IDE? I confess that I use CLion, so if you are on VSCode/Studio, ymmv.

Tried to build this manually by running cmake from within the “x64 Native Tools Command Prompt for VS”, by any chance?

Yes, I am using VSCode, actually, so no IDE on my end. Might be worth checking CLion out, just to simplify my life. I just really like VSCode due to how lightweight it is.

I’ll also check the x64 Native Tools Command Prompt option and see how it goes. Thank you for the help!

I haven’t been running it as admin, now that you mention it. One interesting thing is that the Juce project itself compiles with no problems, and I actually built a noise generator without any troubles, but the program breaks the moment I include any FFTW code, which makes me think JUCE is linked correctly, but FFTW isn’t.

Its probably juce_vst3_helper.exe crashing because it has to open your plugin for manifest generation, maybe try to run the standalone version to get more debug info?

1 Like

You’re absolutely correct. I compiled only for Standalone and there were absolutely no issues while building. The program builds, but upon trying to open the .exe, it says it can’t find fftw3-3.dll which is odd because it’s in the same folder as the .lib.

There is a fixed set of folders windows is searching for dlls.
This is a bit annoying for plugins, since the best way is usually to place dlls in the folder of the executable, but in our case the executable could be any host.

But by far the easiest fix is to just use a static version of your library.

Okay, I finally figured out where the error is coming from and what was going on. I was completely misunderstanding how FFTW’s static libraries are build, and was mistaking the .lib include libraries with actual static library files. Turned out I had to compile the static libraries by myself all along. I did that, and now the Standalone version runs without any problems! VST3 also works when I open it with reaper, however for some reason, I’m still getting the MSB3073 error during the build step, but it seemingly doesn’t affect the program from running properly, so not sure what’s going on there.

Care to share how you got FFTW built for your situation? Its a thorny and interesting subject, so your case is interesting.

Right, so here’s the initial problem:

When you’re using FFTW with Windows, the original website directs you to a precompiled version of the library, which includes a set of .dll and .def files, as well as instructions on how to build include .lib files using Visual Studio. The problem with this is that include libraries are not static libraries (normally you cannot build a static library out of dynamic libraries), but a more inexperienced developer like myself would not tell the difference and then get stuck in the loop like I did, where the program still considers the .lib files dynamic, because they are.

So to fix this, you actually need to download the .tar files from the FFTW website, uncompress them, and build the library yourself. This was actually trickier than I expected, but I found this very useful tutorial on Stack Overflow that explained in detail how to do it using Visual Studio.

I followed it, and changed my CMakeLists.txt include_directories and link_directories as such:

include_directories(${CMAKE_SOURCE_DIR}/lib/fftw/api)
link_directories(${CMAKE_SOURCE_DIR}/lib/fftw/out/build/x64-Debug/)

Which are folders included with the FFTW source code you get from the .tar file or that are created during the creation of the static library.

This is definitely still a little over my head and my own comprehension of CMake, libraries and linking, but for now the program works after building it, so at least it feels like a step in the right direction.

Nice work, and well done. :wink:

Hi, I managed to get the Standalone version up and running after recompiling the static library, but I still can’t manage to build the VST3 as I keep getting the same error.

Seemingly the errors start appearing after this line

JuceTestPlugin_VST3.vcxproj -> C:\Users\usuario\Documents\Programming\CMake_Learning\Juce_test_1\build\JuceTestPlugin_artefacts\Debug\VST3\JuceTestP
  lugin.vst3\Contents\x86_64-win\JuceTestPlugin.vst3
  removing moduleinfo.json

Leading me to believe, this really is related to the manifest generation. However, I’ve tried following the advice on the forum by making VST3_AUTO_MANIFEST FALSE and adding the juce_enable_vst3_manifest_step(JuceTestPlugin) later in the CMakeLists.txt file, but no position for it ever seems to work. The Standalone is working just fine, so this has to be related to the VST3 build at some point, but I just can’t figure out what’s wrong with it.