Error LNK2019/LNK1120 - unresolved external symbol createPluginFilter() when compiling VST3 with JUCE + CMake

I’m new to VST development and I’d like to understand why I’m getting this error.

     Criando biblioteca D:/vstdevelopment/EasyProd/EasyProd/build/EasyProd_artefacts/Release/VST3/EasyProd.lib e objeto D:/vstdevelopment/EasyProd/EasyProd/build/EasyProd_artefacts/Release/VST3/EasyProd.exp
juce_audio_plugin_client_VST3.obj : error LNK2019: símbolo externo não resolvido, "class juce::AudioProcessor * __cdecl createPluginFilter(void)" (?createPluginFilter@@YAPEAVAudioProcessor@juce@@XZ), referenciad
o na função "public: __cdecl juce::JuceVST3Component::JuceVST3Component(class juce::VSTComSmartPtr<class Steinberg::Vst::IHostApplication> const &,struct juce::RunLoop const &)" (??0JuceVST3Component@juce@@QEAA@
AEBV?$VSTComSmartPtr@VIHostApplication@Vst@Steinberg@@@1@AEBURunLoop@1@@Z) [D:\vstdevelopment\EasyProd\EasyProd\build\EasyProd_VST3.vcxproj]
D:\vstdevelopment\EasyProd\EasyProd\build\EasyProd_artefacts\Release\VST3\EasyProd.vst3\Contents\x86_64-win\EasyProd.vst3 : fatal error LNK1120: 1 externo não resolvidos [D:\vstdevelopment\EasyProd\EasyProd\buil
d\EasyProd_VST3.vcxproj]
#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
EasyProdAudioProcessor::EasyProdAudioProcessor()
    : AudioProcessor(juce::AudioProcessor::BusesProperties() // <> define estéreo I/O
#if !JucePlugin_IsMidiEffect
#if !JucePlugin_IsSynth
                         .withInput("Input", juce::AudioChannelSet::stereo(), true)
#endif
                         .withOutput("Output", juce::AudioChannelSet::stereo(), true)
#endif
                         ),
      extractor(juce::File::getSpecialLocation(juce::File::currentExecutableFile)
                    .getSiblingFile("demucs_2stems.onnx")),
      licenseManager()
{
    licenseManager.load(); // tenta restaurar a licença
}

EasyProdAudioProcessor::~EasyProdAudioProcessor() = default;

//==============================================================================
// Apenas estéreo in/out
bool EasyProdAudioProcessor::isBusesLayoutSupported(const BusesLayout &layouts) const
{
    return layouts.getMainOutputChannelSet() == juce::AudioChannelSet::stereo() && layouts.getMainInputChannelSet() == juce::AudioChannelSet::stereo();
}

void EasyProdAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    tracker.prepare(sampleRate);
    vocalsTmp.setSize(2, samplesPerBlock, false, false, true);

    // Define latência (uma vez) para o host compensar
    setLatencySamples(extractor.getLatencySamples());
}

void EasyProdAudioProcessor::releaseResources()
{
    vocalsTmp.setSize(0, 0);
}

void EasyProdAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
                                          juce::MidiBuffer &midiMessages)
{
    juce::ScopedNoDenormals _noDenormals;

    // Plugin bloqueado? silencia
    if (!licenseManager.isUnlocked())
    {
        buffer.clear();
        midiMessages.clear();
        return;
    }

    // ==== ÁUDIO → MIDI ====
    midiMessages.clear();
    notes.clear();
    tracker.analyse(buffer, params, notes);

    ep::MidiWriter::bufferFromNotes(notes, midiTmp, getSampleRate());
    midiMessages.swapWith(midiTmp);

    // ==== EXTRAÇÃO DE VOCAIS ====
    if (extractor.separate(buffer, vocalsTmp))
    {
        if (getTotalNumOutputChannels() > 1)
            buffer.copyFrom(1, 0, vocalsTmp, 0, 0, buffer.getNumSamples());
    }
}

//==============================================================================
// Editor genérico (ou troque pelo seu)
juce::AudioProcessorEditor *EasyProdAudioProcessor::createEditor()
{
    return new juce::GenericAudioProcessorEditor(*this);
}

//==============================================================================
// Salva/recupera o estado da licença
void EasyProdAudioProcessor::getStateInformation(juce::MemoryBlock &destData)
{
    auto state = licenseManager.getState();
    destData.append(state.toRawUTF8(), state.getNumBytesAsUTF8());
}

void EasyProdAudioProcessor::setStateInformation(const void *data, int sizeInBytes)
{
    auto state = juce::String::fromUTF8(static_cast<const char *>(data), sizeInBytes);
    licenseManager.applyKeyFile(state);
}

//==============================================================================
// Ponto de entrada exigido pelo módulo VST3
juce::AudioProcessor *JUCE_CALLTYPE createPluginFilter()
{
    return new EasyProdAudioProcessor();
}