49

The CMake doc says about the command file GLOB:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.

Several discussion threads in the web second that globbing source files is evil.

However, to make the build system know that a source has been added or removed, it's sufficient to say

touch CMakeLists.txt

Right?

Then that's less effort than editing CMakeLists.txt to insert or delete a source file name. Nor is it more difficult to remember. So I don't see any good reason to advise against file GLOB.

What's wrong with this argument?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
Joachim W
  • 7,290
  • 5
  • 31
  • 59
  • 1
    See also the discussion [here](http://stackoverflow.com/questions/30949452/cmake-ninja-attempting-to-compile-deleted-cpp-file/31183245). As described in my answer there I'm using a mixed approach: listing all source files in the `CMakeLists.txt` files (also because sometimes I handpick source files for different build configurations) and globing for the header files (out of convenience to have them in the VS projects). And I suggested a workaround for e.g. `git` with something like `configure_file(${CMAKE_SOURCE_DIR}/.git/index ${PROJECT_BINARY_DIR}/git_index.tmp)`. – Florian Sep 07 '15 at 07:36
  • Does this answer your question? [Is it better to specify source files with GLOB or each file individually in CMake?](https://stackoverflow.com/questions/1027247/is-it-better-to-specify-source-files-with-glob-or-each-file-individually-in-cmak) – starball Oct 21 '22 at 04:27

4 Answers4

49

The problem is when you're not alone working on a project.

Let's say project has developer A and B.

A adds a new source file x.c. He doesn't changes CMakeLists.txt and commits after he's finished implementing x.c.

Now B does a git pull, and since there have been no modifications to the CMakeLists.txt, CMake isn't run again and B causes linker errors when compiling, because x.c has not been added to its source files list.

2020 Edit: CMake 3.12 introduces the CONFIGURE_DEPENDS argument to file(GLOB which makes globbing scan for new files: https://cmake.org/cmake/help/v3.12/command/file.html#filesystem

This is however not portable (as Visual Studio or Xcode solutions don't support the feature) so please only use that as a first approximation, else other people can have trouble building your CMake files under their IDE of choice!

mrexodia
  • 648
  • 12
  • 20
Jean-Michaël Celerier
  • 7,412
  • 3
  • 54
  • 75
  • Good point, thanks. Before I accept this answer (and possibly start to think about a workaround) let me please wait and see whether some more problems are brought up. – Joachim W Sep 05 '15 at 12:15
  • Sure, I think that this is a quite open question and that multiple people would have experiences to share relating to globbing. I sadly don't know of a workaround, I had a somewhat large project (>500 source files) that I migrated back to file lists from globbing because other developers would always complain that the build broke on their machine even if it didn't break on the CI server. – Jean-Michaël Celerier Sep 05 '15 at 12:48
  • 3
    @Jean-MichaëlCelerier workaround#1: run cmake after git pull (seriously), workaround#2: in the `CMakeLists`, write the result of the globbing into a file (conditionally, if it doesn't exist) and put it under source control. Make the `CMakeLists` include that file. On adding a new file, delete globresult file. – tamas.kenez Sep 07 '15 at 20:02
  • 3
    I disagree with these workarounds : the first incurs work on the people other that the one who added the file (and by experience this doesn't work for >3 people). The second adds more mental overhead to the developer (between adding a file in my CMakeLists and remembering creating /deleting a file...) . – Jean-Michaël Celerier Sep 08 '15 at 08:35
  • 2
    @Jean-MichaëlCelerier : well, it's the no-free-lunch thing. I think sw devs are smart people, can be trusted to remember #1 or do mental leap #2. But of course the choice should depend on the project, audience and taste. Each alternative (including the manual edit of `CMakeList`) have their drawbacks. – tamas.kenez Sep 09 '15 at 12:00
  • But can't you force the inclusion of the touched CMakeLists.txt in your commit? – einpoklum Feb 15 '16 at 16:19
  • > "if you have a file with manual list of all project files you must do a clean build for each new file you add... " uh ? no, I add new files to my project every other day and don't remember ever having to do a whole rebuild. The only thing it changes iswhere the list of files passed to cmake comes from, but add_executable / add_library will work just the same – Jean-Michaël Celerier Jan 16 '18 at 20:23
  • @IsaacPascual: I don't include a file, I just put them in here: https://github.com/OSSIA/score/blob/master/base/plugins/score-plugin-curve/CMakeLists.txt – Jean-Michaël Celerier Jan 17 '18 at 14:18
  • Is there a workaround? What about make time globbing? When I used GNU makefile, I used ```sources = $(wildcard *.c)```, and then, a rule of the form: ```target: $(sources)```. Can I do something like this - preferably in a portable way - in cmake? – Uri London Apr 11 '20 at 13:44
  • 2
    @Uri: No because the concept of globbing itself is not portable to all the build kinds that CMake supports - how would it work for instance in a Visual Studio solution or XCode project ? – Jean-Michaël Celerier Apr 11 '20 at 15:50
  • CONFIGURE_DEPENDS was actually introduced in CMake 3.12 – mrexodia Jul 03 '20 at 13:59
9

It's not inherently evil - it has advantanges and disadvantages, covered relatively well in this answer here on StackOverflow. But if you use it carelessly, you could end up ignoring dependency changes and requiring clean rebuilds of large parts of your codebase.

I'm personally in favor of using it - in smaller projects, or on certain subdirectories in larger ones - to avoid having to enter every file manually into the build files. Edit: My preference has changed and I currently tend to avoid it.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    There are many subtle cases that in some cases you have to do clean build as the only rescue. I don't think it good for large projects – Fei Feb 24 '16 at 08:25
  • @Fei: This depends on what you're building. In a large project, you might have globs for small parts of it for which it makes sense, but certainly not for the whole project. – einpoklum Feb 24 '16 at 08:59
  • My preference has also changed, but from avoiding globbing to using it everywhere, at least where colleagues allow me to. I bet you will change your preference again and write some scripts to make globbing safer. – Patrick Fromberg Jun 10 '18 at 12:02
  • @PatrickFromberg: So, that part of the answer talks about a personal preference; the general part stands whether I prefer to glob more, less or not at all.. – einpoklum Jun 10 '18 at 12:15
  • I support your point of view, it sucks to add tones of files manually. Don't tell me about aux_source_directory. – Alen Wesker Feb 08 '22 at 09:51
6

On top of the reasons other people here posted, imho the worst issue with glob is that it can yield DIFFERENT file lists on different platforms. As I see it, that's a bug. In OSX glob ignores case sensitivity and in a ubuntu box it doesn't.

Albino Cordeiro
  • 1,554
  • 1
  • 17
  • 25
  • 3
    That sounds worrying - could you possibly bring it up at the CMake developers mailing list? – Joachim W Mar 06 '19 at 19:18
  • 2
    I followed your advice and tried to open issue, however, I found out that somebody already did that 3 years ago :-) https://gitlab.kitware.com/cmake/cmake/issues/15941 – Albino Cordeiro Mar 06 '19 at 19:42
  • This is property of filesystem on given system (only Linux uses filesystem, where path is case sensitive). Anyway having files different case only is a trouble with or without use `file(GLOB` and file naming should be fixed. – Marek R Aug 17 '23 at 11:47
2

Globbing breaks all code inspection in things like CLion that otherwise understand limited subsets of CMakeLists.txt and do not and never will support globbing as it is unsafe.

Write script to dump the globbed list and paste it in, its very simple, and then CLion can actually find the referenced files and infer them as useful. Maybe even put such script into the tree so that the other devs can either run it without being a moron OR set git hooks to make it happen.

In no case should some random file dropped into some directory ever get automatically linked that's how trojans happen.

Also CLion without context jumping to known definitions and what not, is like hiking barefoot /// why bother.

Tony Butler
  • 356
  • 2
  • 7