File in subfolder of module is not compiled when added manually to some target

Okay, this one is a bit complicated, but I’ll try my best to explain.

The directory structure of one of our projects looks like this

project
    ext <- Everything inside this folder is a git submodule
        juce
        specific_shared_code_for_excactly_two_plugins
            src
            test
                testFileA.cpp
                testFileB.cpp
                CMakeLists.txt <- generates a list variable holding all the cpp files above as absolute paths
            specific_shared_code_for_excactly_two_plugins.h <- JUCE module header
            specific_shared_code_for_excactly_two_plugins.cpp <- includes only files in src, not in test
    src
    CMakeLists.txt           

The content of ext/specific_shared_code_for_excactly_two_plugins/test/CMakeLists.txt is

set(TEST_SOURCES
        testFileA.cpp
        testFileB.cpp)

# Let's make absolute paths from these files
list (TRANSFORM TEST_SOURCES PREPEND ${CMAKE_CURRENT_LIST_DIR}/)

set(SHARED_TEST_SOURCES ${TEST_SOURCES} PARENT_SCOPE)

In the root CMakeLists.txt there is something like

add_subdirectory (ext/juce)

juce_add_module (ext/specific_shared_code_for_excactly_two_plugins)

add_subdirectory (ext/specific_shared_code_for_excactly_two_plugins/test)

add_executable (test_executable ${SHARED_TEST_SOURCES})

The problem:

Source files specified in SHARED_TEST_SOURCES are not compiled by the test_executable target. When I deliberately change a filename to something invalid, I get a cmake error, so obviously the file list gets passed correctly to add_executable and it is processed in some way, but then CMake decides that these files don’t need to be built by the target.

But as soon as I remove line juce_add_module (ext/specific_shared_code_for_excactly_two_plugins) the files will be compiled by the target. This leads me to the conclusion, that the juce call does something to the module folder that has side-effect on all files inside it, also files that are not actually compiled by the module.

Is this a bug or expected behaviour for some reason, and if so, could someone explain what’s going on here?

2 Likes

If you’re using JUCE_ENABLE_MODULE_SOURCE_GROUPS, then this will add all of the module sources to your build (the files need to be added to the module target in order to show up in the IDE). Then, to stop non-top-level files from building, the HEADER_FILE_ONLY property is set to true on all but the top level files. I suspect that your test sources are still marked as HEADER_FILE_ONLY when they are added to test_executable, which is why they don’t build.

I’d recommend using CMakePrintHelpers to debug the properties of the nested source files and see whether they are being treated as header files.

If this turns out to be the problem, then you could consider the following options:

  • Turn off JUCE_ENABLE_MODULE_SOURCE_GROUPS.
  • Rearrange your directory structure so that test lives next to the JUCE module, rather than inside it.
2 Likes

Yes, that did it! We actually had JUCE_ENABLE_MODULE_SOURCE_GROUPS activated – although we no longer work with IDEs that actually need this, so simply disabling it solved the issue.

Wow, how couldn’t I know about these helpers – would have saved me quite a bit of headache during previous CMake debugging tasks :exploding_head: Wasn’t even aware that there are optional CMake modules like that. Thanks a lot for that hint