Beginner: Ways of including source subfolders?

Can CMake be used to dynamically pull in source file folders? I’m not talking about using libraries per se.

Say for example I have a top level CMakeLists.txt file. I know I can explicitly include subfolder content like this:

file(GLOB other_SRCS 
    other_src/*.cpp
)
add_executable(MyTarget ${other_SRCS})

But how can I tell the top CMakeLists.txt to include “whatever” is in the other_src folder as defined by an other_src/CMakeLists.txt?

Would I do it like this?
include(${CMAKE_CURRENT_SOURCE_DIR}/other_src/CMakeLists.txt)

Now the bit I’m struggling with - if I don’t want to generate a library, what would I put in the other_src/CMakeLists.txt file?

file(GLOB other_SRCS 
    *.cpp
)

what else?

The important function you are looking for is target_sources.

Top level CMakeLists.txt would have something like

add_executable(MyTarget)
add_subdirectory(other_src)

Content in the other_src CMakeLists.txt

file(GLOB other_SRCS *.cpp)
target_sources(MyTarget PRIVATE ${other_SRC})

I try to use add_subdirectory if I’m referencing a CMakeLists.txt and use include when I’m pulling in a *.cmake file. There is a difference between include and add_subdirectory, so it would depend on your use case which would be better.

As an aside, be aware of the pitfalls of file(GLOB) for defining source files. See file glob documentation. Be sure to understand the tradeoffs when trying to use it that way.

1 Like

@dnglaze thanks for that - would “MyTarget” in target_sources() be “OtherSourcesTarget” - ie - a target name local to the other_SRC files?

In this situation where you aren’t looking to create another library, you can just use the target defined in the parent CMakeLists.txt, the executable MyTarget in this case. As long as the target has been defined, you can add additional sources to it with target_sources. So no, there’s no local target you have to worry about.

You likely could define a separate target to contain the sources if you wanted, but I would imagine that’s only interesting in situations where you want to apply those sources to multiple targets. This is likely more complicated than what you’re looking for, but leverages the same target_sources command.

If instead you are looking to organize files and are using a generator that supports filters, such as Visual Studio, you can always use a source_group to group stuff in other_src into a separate filter.

1 Like

Thanks @dnglaze . This should help me a little in accepting what the “normal” way would be for doing what we’re talking about.

I used to use Visual Studio 2010 (and earlier) all the time so yes, the concept of a filter (or “folder” as I preferred to call them) made sense under the main source tree. So source_group may be worth reading about.

It’s actually or the IDF ESP32 environment that I’m wanting to understand CMake with. IDF has a few concepts of it’s own (they call them “components”) but I figured it would be best that I understand vanilla CMake first - especially when I see it being used increasingly in all aspects of work and hobbies that I’m exposed to these days.

You may find my blog post on target_sources() to be a helpful read. It covers similar use cases to yours. Enhanced source file handling with target_sources() - Crascit

1 Like

beware: the answer of @dnglaze has just a little bug: the ${other_SRC} is missing an “S” at the end, it should be: ${other_SRCS} to match the variable declaration on the previous line.
:wink: