No JUCE classes found with CMake

I have my custom JUCE installed in a sister directory to my project, and I include it with:

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../JUCE-for-Rationale ${CMAKE_CURRENT_BINARY_DIR}/JUCE-for-Rationale)

Then
Cmake -Bbuild

runs without complaints, but:
cmake --build build

exits unable to find JUCE classes:

chuckk@debian:~/Coding/Rationale/RatEngine$ cmake --build build
[  5%] Generating RatEngine_ConsoleApp_artefacts/JuceLibraryCode/JuceHeader.h
Scanning dependencies of target RatEngine_ConsoleApp
[ 11%] Building CXX object CMakeFiles/RatEngine_ConsoleApp.dir/Source/Main.cpp.o
In file included from /home/chuckk/Coding/Rationale/RatEngine/Source/RatNote.h:22,
                 from /home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:30,
                 from /home/chuckk/Coding/Rationale/RatEngine/Source/Main.cpp:27:
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiMessage.h:37:48: error: expected class-name before ‘,’ token
   37 | s RatMidiMessage : public juce::MidiMessage, public RatEvent
      |                                            ^

/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiMessage.h:47:11: error: ‘MidiMessage’ in namespace ‘juce’ does not name a type
   47 |     juce::MidiMessage* getPreMessage();
      |           ^~~~~~~~~~~
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiMessage.h:61:27: error: ‘MidiMessage’ is not a member of ‘juce’
   61 |     std::shared_ptr<juce::MidiMessage> preMessage;
      |                           ^~~~~~~~~~~
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiMessage.h:61:27: error: ‘MidiMessage’ is not a member of ‘juce’
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiMessage.h:61:38: error: template argument 1 is invalid
   61 |     std::shared_ptr<juce::MidiMessage> preMessage;
      |                                      ^
In file included from /home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiManager.h:23,
                 from /home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:32,
                 from /home/chuckk/Coding/Rationale/RatEngine/Source/Main.cpp:27:
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiInputCallback.h:22:1: error: expected class-name before ‘{’ token
   22 | {
      | ^
/home/chuckk/Coding/Rationale/RatEngine/Source/RatMidiInputCallback.h:23:39: error: ‘juce::MidiInput’ has not been declared
...

And a lot more like those.
It’s hard to know what’s wrong, because the ConsoleApp example on github doesn’t actually have working code; there are commented out lines with explanations of how to include JUCE, but running them as-is does not work.
Does anyone see where I’m going wrong?
I’ve been working on this same source tree and compiling it for months using VS 2019 (exported from Projucer).
I do not have JUCE as a submodule; I link to it as out-of-tree. I prefer not to change that because, like I said, I’m already using it as-is with VS.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)

project(RAT_ENGINE_CONSOLE_APP VERSION 0.0.1)

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/…/…/JUCE-for-Rationale ${CMAKE_CURRENT_BINARY_DIR}/JUCE-for-Rationale)

juce_add_console_app(RatEngine_ConsoleApp
PRODUCT_NAME “RatEngine”) # The name of the final executable, which can differ from the target name

juce_generate_juce_header(RatEngine_ConsoleApp)

target_sources(RatEngine_ConsoleApp
PRIVATE
Source/Main.cpp Source/RatEngine.cpp Source/RatEvent.cpp Source/RatIO.cpp Source/RatIOManager.cpp Source/RatMidiInputCallback.cpp Source/RatMidiManager.cpp Source/RatMidiMessage.cpp Source/RatMidiOut.cpp Source/RatNote.cpp Source/RatNoteOff.cpp Source/RatNoteOn.cpp Source/RatRegion.cpp)

target_compile_definitions(RatEngine_ConsoleApp
PRIVATE
JUCE_WEB_BROWSER=0 # If you remove this, add NEEDS_WEB_BROWSER TRUE to the juce_add_console_app call
JUCE_USE_CURL=0) # If you remove this, add NEEDS_CURL TRUE to the juce_add_console_app call

target_link_libraries(RatEngine_ConsoleApp
PRIVATE
# ConsoleAppData # If you’d created a binary data target, you’d link to it here
juce::juce_core
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_warning_flags)

You’re only linking to juce_core. You need to link to all the modules you use.

Thank you! Corrected.

Now:

chuckk@debian:~/Coding/Rationale/RatEngine$ cmake --build build
Scanning dependencies of target RatEngine_ConsoleApp
[  3%] Building CXX object CMakeFiles/RatEngine_ConsoleApp.dir/Source/Main.cpp.o
In file included from /home/chuckk/Coding/Rationale/RatEngine/Source/Main.cpp:27:
/home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:41:47: error: qualified name does not name a class before ‘:’ token
   41 |  class RatEngine::MidiScoreTimeCheckThread : public juce::Thread
      |                                            ^

/home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:41:47: error: expected ‘{’ before ‘:’ token
/home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:41:49: error: expected primary-expression before ‘public’
   41 | lass RatEngine::MidiScoreTimeCheckThread : public juce::Thread
      |                                            ^~~~~~

/home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:41:47: error: expected ‘;’ at end of member declaration
   41 |  class RatEngine::MidiScoreTimeCheckThread : public juce::Thread
      |                                            ^
      |                                             ;
/home/chuckk/Coding/Rationale/RatEngine/Source/RatEngine.h:41:55: error: expected ‘:’ before ‘juce’
   41 | atEngine::MidiScoreTimeCheckThread : public juce::Thread
      |                                            ^~~~~
      |                                            :

from RatEngine.h:

class RatEngine : public juce::InterprocessConnection
{
public:
    class RatEngine::MidiScoreTimeCheckThread : public juce::Thread
    {
    public:
        MidiScoreTimeCheckThread(RatEngine*, RatMidiManager*);
        ~MidiScoreTimeCheckThread() override;
        void keepCheckingCurrentMidiScoreTime();
        void run() override;
    private:
        RatMidiManager* midiManager;
        RatEngine* engine;
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RatEngine::MidiScoreTimeCheckThread);
    };
...

from RatEngine.cpp:

RatEngine::MidiScoreTimeCheckThread::MidiScoreTimeCheckThread(RatEngine* engine_, RatMidiManager* midiManager_)
    : juce::Thread("MIDI Score Time Check Thread")
{
    engine = engine_;
    midiManager = midiManager_;
    startThread();
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(RAT_ENGINE_CONSOLE_APP VERSION 0.0.1)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../JUCE-for-Rationale ${CMAKE_CURRENT_BINARY_DIR}/JUCE-for-Rationale)
juce_add_console_app(RatEngine_ConsoleApp
juce_generate_juce_header(RatEngine_ConsoleApp)
target_sources(RatEngine_ConsoleApp
    PRIVATE
    Source/Main.cpp
    Source/RatMidiInputCallback.cpp
    Source/RatMidiMessage.cpp
    Source/RatEvent.cpp
    Source/RatIO.cpp
    Source/RatMidiOut.cpp
p    Source/RatIOManager.cpp
    Source/RatMidiManager.cpp
    Source/RatNoteOn.cpp
    Source/RatOutputManager.cpp
    Source/RatNoteOff.cpp
    Source/RatMPEManager.cpp
    Source/RatMPEOut.cpp
    Source/RatNote.cpp
    Source/RatRegion.cpp
    Source/RatEngine.cpp)
target_compile_definitions(RatEngine_ConsoleApp
    PRIVATE
        JUCE_WEB_BROWSER=0  # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_console_app` call
        JUCE_USE_CURL=0)    # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_console_app` call

target_link_libraries(RatEngine_ConsoleApp
    PRIVATE
        # ConsoleAppData            # If you'd created a binary data target, you'd link to it here
        juce::juce_core
	juce::juce_audio_basics
	juce::juce_audio_devices
	juce::juce_audio_formats
	juce::juce_audio_processors
	juce::juce_audio_utils
	juce::juce_data_structures
	juce::juce_events
	juce::juce_graphics
	juce::juce_gui_basics
	juce::juce_gui_extra
    PUBLIC
        juce::juce_recommended_config_flags
        juce::juce_recommended_warning_flags)

Anyone??

That’s not a CMake thing, it’s just invalid C++ syntax.

When you have nested classes, you don’t need to specify the base for the nested. Remove RatEngine:: from the nested class declaration.

1 Like

Ah, Visual Studio did me the “favor” of ignoring that for months…
Thanks guys! It works!

1 Like

That’s probably because you’re using an old version of vs. When I upgraded to vs 2022 for over a year ago, it spotted some of my own misuses of class names inside the declaration. Or could be you’re not using the latest toolset or C++ version.

1 Like