Undefined reference to `model

I’ve made a fork of the Core MIDI-CV module that I got working through direct modification of MIDI_CV.cpp in the Rack source. I’m now trying to move this modified module into my own Plugin, in order to compile it and run inside my standard Rack installation. I’ve got two other modules that I’ve made in this Plugin that compile and run as expected, but here I’m running into problems.

  1. I copied the modified MIDI_CV.cpp into my Plugin’s folder and renamed it to XanderMIDI_CV.cpp
  2. Inside this copy, replaced all instances of “MIDI_CV” to “XanderMIDI_CV”
  3. I copied MIDI-CV.svg to my res folder and renamed to XanderMIDI-CV.svg, and adjusted to appropriate line in XanderMIDI_CV.cpp to setPanel(APP->window->loadSvg(asset::system("res/XanderMIDI-CV.svg")));
  4. In my plugin.cpp I added p->addModel(modelXanderMIDI_CV);
  5. In my plugin.hpp I added extern Model* modelXanderMIDI_CV;
  6. In my plugin.json I added { "slug": "XanderMIDIToCVInterface", "name": "XanderMIDI-CV", "description": "Converts MIDI from an external device to CV and gates, with rotating MPE mode", "tags": [ "External", "MIDI", "Polyphonic" ] }

All of this seems to match the setup for both the original MIDI-CV in Core as well as my other two modules in this Plugin. However, on attempted compilation I get this error:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build/src/plugin.cpp.o:plugin.cpp:(.rdata$.refptr.modelXanderMIDI_CV[.refptr.modelXanderMIDI_CV]+0x0): undefined reference to `modelXanderMIDI_CV'

Given that I’ve had this Plugin compiling fine with two other modules, I figure I must be missing something obvious.

Are you actually defining Model* modelXanderMIDI_CV = createModel(...); in your XanderMIDI_CV.cpp file?

should be XanderMIDI_CV

Yeah, technically that would be better but the other would work as long as plugin.json is consistent with the createModel() call. VCV MIDI-CV has that slug for legacy reasons, because it’s better to not break patches than change the slug to match the C++ class name.

Yes, after find/replace “MIDI_CV” -> “XanderMIDI_CV”, this is the line in XanderMIDI_CV.cpp:

Model* modelXanderMIDI_CV = createModel<XanderMIDI_CV, XanderMIDI_CVWidget>("XanderMIDIToCVInterface");

For good measure I changed “XanderMIDIToCVInterface” to “XanderMIDI_CV” in both plugin.json and XanderMIDI_CV, but there was no change in the result.

Have you a link to the file, or post the lot?! surrounded with ```

You might have missed a find/replace.

I’ve now uploaded here.

What is #include <map>?

Also is it seeing MidiWidget

XanderMIDI_CV.cpp defines your model within the rack::core namespace:

namespace rack {
namespace core {
   ...
   Model* modelXanderMIDI_CV = createModel...;
} // namespace core
} // namespace rack

but plugin.cpp references it with a plain name:

   p->addModel(modelXanderMIDI_CV);

You need to make them match, either by removing the namespace from the module code or adding it to the plugin code. The Rack sources for the core plugin put both within the rack::core namespace, but most third party plugins don’t. In your situation, I would remove the namespace.

1 Like

That got it to compile! Thanks very much. After that one more issue remained, which was that the panel was set using:

setPanel(APP->window->loadSvg(asset::system("res/XanderMIDI-CV.svg")));

Rather than the correct:

setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/XanderMIDI-CV.svg")));

Now everything works as expected.

1 Like

std::map is used to correlate incoming (MPE) MIDI channel to the module’s internally rotating polyphonic cable channel, so that I have the rotation of MIDI-CV’s Rotate Mode while retaining the per-channel expression of MPE Mode. I see now that I don’t actually need to #include <map> in order to use the map class.

1 Like

Personally I’d still include it, because the fact that you don’t need to is not guaranteed on different platforms, or with future versions of whatever include file is currently pulling it in.

Yep - I switch between compilers and some are more tolerant than others for sure.

I hope your aren’t adding things to a map from your module’s process call, because if you are you will be calling malloc from the audio thread, which is certain to cause occasional clicks an pops. More info here: https://github.com/squinkylabs/SquinkyVCV/blob/master/docs/efficient-plugins.md

1 Like

I see. I’ve changed it so that the rotation indices are simply stored in a fixed-length (16) integer array indexed by channel. This also seems to better fit with the existing practices within MIDI-CV. Thanks for the tip!

1 Like