22

I've just read this:

CMake - Automatically add all files in a folder to a target?

With the answer suggesting a file glob, e.g.:

file(GLOB "*.h" "*.cpp")

now, what if I want my target to depend on all files of a certain type under a certain folder - which might be within multiple subfolders? I tried using

execute_process(COMMAND find src/baz/ -name "*.cpp" OUTPUT_VARIABLE BAR)

and then

add_executable(foo ${BAR}

but this gives me the error:

Cannot find source file:

  src/baz/some/file/here

src/baz/some/other_file/here

src/baz/some/other_file/here2

(yes, with that spacing.)

What am I doing wrong here?

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 4
    Maybe `file(GLOB_RECURSE ...)`? But be aware of [Why is cmake file GLOB evil?](http://stackoverflow.com/questions/32411963/why-is-cmake-file-glob-evil) and [Best way to specify sourcefiles in CMake](http://stackoverflow.com/questions/1027247/best-way-to-specify-sourcefiles-in-cmake) – Florian Feb 15 '16 at 15:48
  • Using `find` that way is a bad idea, but you could fix the issue you seem to be having with it by adding `-type f`. – bames53 Feb 15 '16 at 17:54
  • @bames53: I'll try that. About this being a bad idea - I've read the links Florian posted, and think I agree with [this answer](http://stackoverflow.com/a/1060061/1593077)the first comment on [this answer](http://stackoverflow.com/a/18538444/1593077) – einpoklum Feb 15 '16 at 22:44
  • @einpoklum I think the comment you reference is comparing the wrong things: "But isn't it true that if you don't glob, you still have to manually update CMakeLists.txt, meaning cmake is still not automatically updating the build system?" The original complaint that globing files doesn't automatically update the build system was not in comparison to a system that does automatically update the build system. Perhaps the original point wasn't made all that clearly, but the complaint was about the _failure_ mode of the two methods. – bames53 Feb 15 '16 at 23:11
  • 1
    @einpoklum The failure mode for builds based on globing are possibly difficult to diagnose, perhaps even silent, broken builds which may happen as a result of a problem that has nothing to do with the code actually in the source control system. The failure mode for builds based on explicit file lists is an explicit and reproducible failure, which can be controlled/prevented by the code actually in the source control system, regardless of whatever other garbage a developer checking out code might leave in his working directory. – bames53 Feb 15 '16 at 23:15
  • @bames53: I respect what you're saying, although I disagree. I'm not saying everything should be globbed everywhere, but that globbing can be used reasonably in many cases. At any rate, I don't think we should try to convince each other to avoid globbing or adopt globbing here in the comments... – einpoklum Feb 15 '16 at 23:26
  • 1
    @einpoklum Oh, also my comment about using `find` that way was not about the usual globing problem. The reason I'd advise against using `find` here is because it adds an additional dependency for no real reason. `file(GLOB_RECURSE ...)` seems like the correct thing here. – bames53 Feb 16 '16 at 00:39
  • 1
    It is not recommended by the authors of CMake to use in projects, but only in scripts. [presentation](https://youtu.be/bsXLMQ6WgIk) – Damian Nov 27 '17 at 23:04

1 Answers1

33

Turning my comment into an answer

If you want to add recursive searching for files use file(GLOB_RECURSE ...)

file(GLOB_RECURSE source_list "*.cpp" "*.hpp")

Your second example would translate into

file(GLOB_RECURSE BAR "src/baz/*.cpp")

References

starball
  • 20,030
  • 7
  • 43
  • 238
Florian
  • 39,996
  • 9
  • 133
  • 149
  • 5
    It might be good to add here, that it is also possible to use the built-in CMake variables to indicate the exact location of the files we wish to add recursively, i.e. - file(GLOB_RECURSE SRC "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp") - will add all C++ source files located under the src folder , which is itself within the same folder where the current CMakeList.txt file that is being processed resides. – Guy Avraham Sep 12 '17 at 21:13
  • Does this support excluding certain files ? – coin cheung Oct 24 '18 at 02:08
  • 1
    This answer is incomplete without a discussion of `CONFIGURE_DEPENDS` which restores the basic, fundamental contract on CMake builds that the generated buildsystem has everything it needs to know when to re-configure. – Alex Reinking Jul 01 '21 at 06:46
  • 1
    It must also be noted that the CMake developers [_**"do not recommend using GLOB to collect a list of source files from your source tree."**_](https://cmake.org/cmake/help/latest/command/file.html#glob) This is pretty strong language and should give one pause before doing so. If you come to the CMake developers with a bug and a glob, they'll tell you to fix that before they help you. – Alex Reinking Jul 01 '21 at 06:49