1

Is there a clean/portable way to descend recursively from a given directory, compiling all found .cpp files into a single output file? I'm not sure if makefiles are capable of this sort of thing, or if it's a job for some kind of build script, but I'd like to avoid maintaining various IDEs' project files along with my code.

Maxpm
  • 24,113
  • 33
  • 111
  • 170
  • My vote goes to first assembling all the `.cpp`s in a list via a script and then feed that list as an input to your favourite compiler. Since I don't know of scripts that do this reliably cross platform, I'll keep this as a commet. :) – Xeo May 31 '11 at 18:23
  • @Xeo At least that way I'll only have to write a script for each platform once. – Maxpm May 31 '11 at 18:25
  • @Xeo: You can do that directly in a makefile - see my answer below. – Nathan Osman May 31 '11 at 18:29
  • 1
    Why would you arrange your .cpp files like this in the first place? And what do you mean by "output file"? An executable, a library? –  May 31 '11 at 18:29
  • @George: Eh? "This is not recursive, " -- you even explicitly state that in your answer! – Xeo May 31 '11 at 18:33
  • @Maxpm OK, you can do it with make, with a little jiggery-pokery, but I'm not clear why you would arrange your files like that. –  May 31 '11 at 18:42
  • 4
    Here is something that might help: http://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make (specifically [this](http://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make/2483203#2483203) answer.) – Nathan Osman May 31 '11 at 18:48
  • 1
    Do you mean recurse *from* a given directory? Recursing *through one directory* doesn't make much sense. Do you mean you want to compile all .cpp files in a given directory *and all subdirectories* into a single target? Or just *all .cpp files in one directory*? – Lasse V. Karlsen May 31 '11 at 18:49
  • @Lasse All the files in the directory and its subdirectories. – Maxpm May 31 '11 at 20:21

2 Answers2

2

There's the wildcard function which can be used to match a pattern like so:

CXX_FILES = $(wildcard src/*.cpp)   # All .cpp files in the directory

This is not recursive, but will at least save you from having to manually specify the files in a certain directory. The rule for building them would look something like this:

CXX_FILES = $(wildcard src/*.cpp)   # All .cpp files in the directory
OBJ_FILES = $(CXX_FILES:src/%.cpp=$(OBJ_DIR)/%.o)   # Corresponding .o files

# Rules
all: $(OBJ_FILES)
    g++ $(OBJ_FILES) -o output_filename

$(OBJ_DIR)/%.o: src/%.cpp
    g++ -c $< -o $@

Oh, and to answer your question, this method is completely portable.

Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • If it is *completely portable*, does that mean it runs on CP/M, too? Because that operating system has no concept of *directories*. And what if you have a platform without GNU Make, which you are obviously depending on? Or a system where GCC is not installed? – Roland Illig May 31 '11 at 18:33
  • +1 because it answers the question. However, I would recommend using a more recent tool like `SConstruct`. The gain might not be obvious for this scenario, but if you suddenly need to compile all the `.cpp` **except one**, then you have all the power of python to help you :) – ereOn May 31 '11 at 18:35
  • @Roland Illig: The OP clearly states that he has directories and that he wants to compile (that is, he states he has a compiler). I don't know what CP/M is, but my guess is that neither does the OP and that he does not really care anyway. – ereOn May 31 '11 at 18:38
  • @ereOn: For the record, CP/M was an operating system for microcomputers that predates DOS. The name stands for "Control Program for Microcomputers." – greyfade May 31 '11 at 19:01
  • @Roland: CP/M does have directories. – Jay May 31 '11 at 19:01
  • @Jay: can you prove it? Wikipedia says otherwise. – Roland Illig May 31 '11 at 19:56
  • @Jay If we are talking about CP/M for the 8080/Z90. then no it doesn't. –  May 31 '11 at 20:24
  • 1
    This answer doesn't cover the recursive descent requirement. And it's absolutely not portable: makefile functions are a feature of GNU make only. – Gilles 'SO- stop being evil' May 31 '11 at 20:45
2

There are different things that you can do here. I would suggest that you use a multiplatform build system, and follow the documentation for it. I have used CMake in the past, but I wouldn't know how to tell it to compile all files in a directory.

The advantage is that the user can use CMake to generate project files for most common IDEs, so it would allow VisualStudio users to generate VS solutions, MacOSX users to generate Xcode projects, Eclipse CDK projects in pretty much any environment, Makefiles...

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489