'Undefined symbols for architecture x86_64: "RtMidiIn::RtMidiIn

I'm trying to connect to a MIDI device from an existing program. RtMidi is a popular library for this. As I understand, all I should have to do is drop RtMidi.cpp and RtMidi.h in the directory with the rest of the source, and build as usual. I've done so, and added to one of the main classes that get loaded:

#include "RtMidi.h"

And only this in the constructor:

RtMidiIn *midiin = new RtMidiIn();

Just to see if that much compiles. But I'm getting the following:

Undefined symbols for architecture x86_64:
  "RtMidiIn::RtMidiIn(RtMidi::Api, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int)", referenced from:
      spotify::playback::AudioDecompressorProcess::AudioDecompressorProcess(spotify::playback::AudioSinkChain const&, std::__1::function<std::__1::unique_ptr<spotify::playback::AudioDecompressor, std::__1::default_delete<spotify::playback::AudioDecompressor> > (spotify::tl::span<unsigned char const>)> const&, bool, spotify::playback::PlaybackInstrumentation&, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> >, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> >) in libplayback.a(audio_decompressor_process.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **


The following build commands failed:
    Ld /Users/acheong/src/spotify/client-web/desktop/shell/build/desktop/Debug/Spotify.app/Contents/MacOS/Spotify normal (in target 'Spotify' from project 'spotify')

I found this thread which suggested defining __MACOSX_CORE__. I tried this in 2 ways. First, using a #define right before the include:

#define __MACOSX_CORE__
#include "RtMidi.h"

Same error. Second, by adding this to the xcodebuild command line:

GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS __MACOSX_CORE__'

Same error still. (These are definitely doing something though, because when I accidentally tried both the above simultaneously, I got an error that the macro was already defined.)

I'm not super familiar with C++ build chains, so I'm not sure whether I'm just doing something stupid—like, do I need to update some Makefiles or something for the compiler to "see" RtMidi.cpp/h—or is this some kind of compatibility issue as I've read in some threads.



Solution 1:[1]

@AdrianMole was right—I had to explicitly instruct CMake to build the RtMidi files. I added the files in the relevant CMakeLists.txt under SOURCES:

sp_add_sources(TARGET playback
  FOLDER "src"
  ROOT "src"
  SOURCES
    RtMidi.cpp
    RtMidi.h
    audio_buffered_sink.cpp
    audio_buffered_sink.h
    audio_container_format.cpp
    ...

And also added this:

target_link_libraries(playback PRIVATE "-framework CoreMIDI")

Then I was able to include "RtMidi.h" in my existing program, and add the example code, i.e.

RtMidiIn *midiin = new RtMidiIn();
// Check available ports.
unsigned int nPorts = midiin->getPortCount();
...

and have everything build successfully, not even needing the __MACOSX_CORE__ anywhere.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 slackwing