Home > Mobile >  Preprocessing multiple source files with one command using g
Preprocessing multiple source files with one command using g

Time:06-02

Question

I have three files in my current working directory:

  • hello.cpp
  • goodbye.cpp
  • prog.cpp

I would like to only preprocess hello.cpp and goodbye.cpp and dump the output in files hello.i and goodbye.i. Is there a way to achieve this using g in a Ubuntu Linux command line using one command? The reason I would like to call g only once is because I would eventually like to include this command in my own Makefile.

What I've tried

I basically did the following:

g -E -o goodbye.i hello.i goodbye.cpp hello.cpp

Which, unsurprisingly, failed with the following error:

g : fatal error: cannot specify '-o' with '-c', '-S' or '-E' with multiple files compilation terminated

I also tried g -E goodbye.cpp hello.cpp, which only reminded me that the preprocessor dumps to stdout by default. I do, for the purposes of this exercise, need for g to dump the result into an actual *.i file...

What I'm trying to avoid

From the comments, it seems to me that I can provide a further clarification. I'm trying to avoid having multiple commands in my Makefile, as each separate .cpp file would generate a separate command:

all: preprocess_hello preprocess_goodbye

preprocess_hello:
    g   -E -o hello.i hello.cpp

preprocess_hello:
    g   -E -o goodbye.i goodbye.cpp

Obviously, this is not ideal, because every new file I add would require adding a new command and updating the all target.

CodePudding user response:

You can use a pattern rule so Make knows how to generate a .i file from a .c file:

%.i: %.cpp
    g   -E -o $@ $<

and then if your makefile ever requires hello.i, Make will know that it can use the command g -E -o hello.i hello.cpp

E.g. if you have all: hello.i goodbye.i and run make all it will know that it needs hello.i and goodbye.i and it will make them.


If you have a list of .cpp files and you need to convert it to a list of .i files (e.g. if you want to do all: $(CPPFILES) but it doesn't work because those are the .cpp files and not the .i files) you can use patsubst:

all: $(patsubst %.cpp,%.i,$(CPPFILES))

You can even use wildcard to get the list of cpp files. To make all depend on all the .i files for all the .cpp files in the current directory, you could use

all: $(patsubst %.cpp,%.i,$(wildcard *.cpp))
  • Related