2

I have a simple makefile to help me compile some examples:

   ex104: ex104.cpp
        $(CPP) ex104.cpp $(INCS) $(LINKFLAGS) $(COMPILEFLAGS) -o ex104  

   clean:   
        rm -f *.o $(EXECUTABLE)

Now, that works fine. The problem is: I would need to explicitly write a rule for each of the examples, thus copying the following line many, many times:

   ex104: ex104.cpp
        $(CPP) ex104.cpp $(INCS) $(LINKFLAGS) $(COMPILEFLAGS) -o ex104

Is there a way to generic-ize it a bit? So that I would end up with a command line like below that would build ex252 from ex252.cpp built automatically:

make ex252

Fortunately, it's a template-only library, so I always have to build from just one cpp file, and I do not need to keep track of object files.

Michael
  • 7,407
  • 8
  • 41
  • 84
  • Possible duplicate of [Passing additional variables from command line to make](http://stackoverflow.com/questions/2826029/passing-additional-variables-from-command-line-to-make) – taskinoor Jul 19 '16 at 11:04
  • 2
    Have you tried `make ex252`? No you haven't, I can tell... ;-) Read up on [implicit rules](https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules). – DevSolar Jul 19 '16 at 13:59
  • That's interesting. I did not have an idea that this feature even exists. So I would just give standard names to the variables for compiler and flags, and make would do everything else for me? – Michael Jul 20 '16 at 09:23

4 Answers4

5

Make has a bunch of default rules and what you want should works if instead of your variables you are using the default one for flags to be given.

If your version of make does not have such default, this should add one (it correspond to GNU make default rule with some intermediary variables inlined and obsolete one removed) :

.cpp:
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@

CXX is the C++ compiler

CXXFLAGS is the flags for the C++ compiler

CPPFLAGS is the flags for the preprocessor (they are common between C and C++ in gnu make)

LDFLAGS are the flags for linking

TARGET_ARCH allows to specify a target architecture

LDLIBS is the libraries to link

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
3

Perhaps something like:

%: %.cpp
    $(CXX) $< $(INCS) $(LINKFLAGS) $(COMPILEFLAGS) -o $@

For further details about $< and $@ take a look at automatic variables.

manlio
  • 18,345
  • 14
  • 76
  • 126
  • Why make up your own variable names instead of using the conventional ones like `CPPFLAGS` ? – Jonathan Wakely Jul 19 '16 at 14:02
  • @JonathanWakely it was to reuse the original variable names, so allowing a simpler visual "pattern matching" (and a direct upgrade path from the old Makefile). Indeed you're right, the conventional names should be preferred. – manlio Jul 19 '16 at 14:19
  • Oh yes, I didn't notice that, sorry :) – Jonathan Wakely Jul 19 '16 at 14:20
2

If I understand your question correctly, you are looking for something like pattern rules. If that is correct, this makefile should compile every cpp file in the directory (taken from here):

%.o : %.cpp
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@
BЈовић
  • 62,405
  • 41
  • 173
  • 273
1

Like @AProgrammer said, use built-in rules. I just want to expand on that.

You can find built-in rules and flags by recursively grepping make's database dump. make -pq | grep %: to get the list of rules that can produce executable and make -pq | grep '%: %.cpp' -A5 to see the actual command it executes.

In your case, literally the whole makefile could look like:

all: ex104

As long as ex104 is required by the default goal and ex104.cpp exists, %: %.cpp built-in rule will be selected. You can build on that. Add more dependencies and flags.

CXXFLAGS += -Wall -Wextra -Wpedantic -std=c++14
all: ex104
ex104: common_utils.cpp

PS: In make CPP refers to C pre-processor, not C++.

Ivan Baldin
  • 3,391
  • 3
  • 22
  • 14