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))