2
\$\begingroup\$

I am working on creating a Makefile for my ProjectEuler solutions. I need to compile each solution into a separate binary for personal timing purposes. Is it possible to pass the name of the rule to the -o option to remove some repeated code?

CXX = g++
CXXFLAGS = -std=c++0x
INC = -Iinclude/ -I../tools/

binaries=01sum35\
     02evenfibs\
     03largestprimefactor\
     04largestpallyproduct\
     05smallestmultiple\
     06sumsquaredifference\
     07tenthousandfirstprime\
     08largestproductinseries\
     09specialpythagtriplet

all: $(binaries)

01sum35: 
    $(CXX) $(CXXFLAGS) 01sum35.cc $(INC) -o 01sum35  

02evenfibs:
    $(CXX) $(CXXFLAGS) 02evenfibs.cc $(INC) -o 02evenfibs

03largestprimefactor:
    $(CXX) $(CXXFLAGS) 03largestprimefactor.cc $(INC) -o 03largestprimefactor

04largestpallyproduct:
    $(CXX) $(CXXFLAGS) 04largestpallyproduct.cc ../tools/tools.cc $(INC) -o 04largestpallyproduct

05smallestmultiple:
    $(CXX) $(CXXFLAGS) 05smallestmultiple.cc $(INC) -o 05smallestmultiple

06sumsquaredifference:
    $(CXX) $(CXXFLAGS) 06sumsquaredifference.cc $(INC) -o 06sumsquaredifference

07tenthousandfirstprime:
    $(CXX) $(CXXFLAGS) 07tenthousandfirstprime.cc ../tools/tools.cc $(INC) -o 07tenthousandfirstprime

08largestproductinseries:
    $(CXX) $(CXXFLAGS) 08largestproductinseries.cc ../tools/tools.cc $(INC) -o 08largestproductinseries

09specialpythagtriplet:
    $(CXX) $(CXXFLAGS) 09specialpythagtriplet.cc $(INC) -o 09specialpythagtriplet

clean:
    rm -f $(binaries)
\$\endgroup\$
4
\$\begingroup\$

Yes:

CXX       = g++
#
# Notice the +=.  Use CPPFLAGS rather than INC for pre-processor rules.
#
CPPFLAGS += -Iinclude/ -I../tools/
CXXFLAGS += -std=c++0x

#
# Move the backslash
# This will stop it looking like a directory at first glance.
binaries=01sum35              \
     02evenfibs               \
     03largestprimefactor     \
     04largestpallyproduct    \
     05smallestmultiple       \
     06sumsquaredifference    \
     07tenthousandfirstprime  \
     08largestproductinseries \
     09specialpythagtriplet

all: $(binaries)

clean:
    rm -f $(binaries)

# Default rules and dependencies works for all the targets
# except the following which need one more file (dependency)

04largestpallyproduct:      04largestpallyproduct.cc    ../tools/tools.cc
07tenthousandfirstprime:    07tenthousandfirstprime.cc  ../tools/tools.cc
08largestproductinseries:   08largestproductinseries.cc ../tools/tools.cc
\$\endgroup\$
2
\$\begingroup\$

A few extra things that add to the post from @LokiAstari
In the listing below:

  1. Add some warnings, -Wall as a minimum
  2. Use VPATH to find the source files for the tools
  3. Mark targets that are not created as 'phony'. This stops make from doing some searches and prevents the makefile failing if a file called all or clean ever exists.
  4. Added some cleanup files
  5. By making the binaries that depend on the tools depend on the tools.o object file not the source file, you avoid recompiling tools.cc for every binary. Because we have a VPATH defined, the path to tools.cc need not be specified.

Here's the simplified file:

CXX       = g++
CPPFLAGS += -Iinclude/ -I../tools/
CXXFLAGS += -std=c++0x -Wall                (1)
VPATH     = ../tools                        (2)

binaries  = a b c

.PHONY : all                                (3)
all: $(binaries)

.PHONY : clean                              (3)
clean:
        rm -f $(binaries) *.o *~            (4)

b: b.c tools.o                              (5)
c: c.c tools.o                              (5)
\$\endgroup\$
  • 1
    \$\begingroup\$ The new thing I learned today is VPATH. I have used make a lot and its the first time I have heard this. \$\endgroup\$ – Martin York Jul 30 '13 at 5:04
  • \$\begingroup\$ @LokiAstari I've learnt many things from your answers to the many C++ questions, so I am glad it is now not an entirely one-way street :-) \$\endgroup\$ – William Morris Jul 30 '13 at 19:35
0
\$\begingroup\$

You could use suffix rules (the .c.o part below) to tell make how to compile a c file. Then you can just tell the dependencies for each target.

CXX = g++
CXXFLAGS = -std=c++0x
INC = -Iinclude/ -I../tools/

binaries=01sum35\
     02evenfibs\
     03largestprimefactor\
     04largestpallyproduct\
     05smallestmultiple\
     06sumsquaredifference\
     07tenthousandfirstprime\
     08largestproductinseries\
     09specialpythagtriplet

all: $(binaries)

01sum35: 01sum35.cc

02evenfibs: 02evenfibs.cc

03largestprimefactor: 03largestprimefactor.cc 

04largestpallyproduct: 04largestpallyproduct.cc ../tools/tools.cc

05smallestmultiple: 05smallestmultiple.cc

06sumsquaredifference: 06sumsquaredifference.cc

07tenthousandfirstprime: 07tenthousandfirstprime.cc ../tools/tools.cc

08largestproductinseries: 08largestproductinseries.cc ../tools/tools.cc

09specialpythagtriplet: 09specialpythagtriplet.cc 

.cc.o:
    $(CXX) $(CXXFLAGS) $< $(INC) -o $@

clean:
    rm -f $(binaries)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.