(→Implementation) |
(→Step 3: The New Makefile) |
||
Line 125: | Line 125: | ||
Note that we are assuming that the appropriate changes have been made to the code in the C++ files to allow for a single interface (the function is now called simply "fact") and multiple implementations. | Note that we are assuming that the appropriate changes have been made to the code in the C++ files to allow for a single interface (the function is now called simply "fact") and multiple implementations. | ||
+ | |||
+ | Regarding CVS, only updates and commits are needed at this stage (new versions of the files will be sent to the repository). |
Considere quatro ficheiros recurs.cpp (contendo a função factrecurs), recurs.h (contendo a declaração da função factrecurs), iter.cpp (contendo a função factiter ), iter.h (contendo a declaração da função factiter) e main.cpp (contendo a função main que invoca sequencialmente ambas as funções anteriores e que inclui recurs.h e iter.h).
The following sections present possible implementations.
All shell commands are prefixed with prompt% (their output is presented for explanation purposes only and is not required to answer the problem).
It is assumed that the CVSROOT variable has been defined: <bash>
export CVSROOT=/cvs
</bash>
Assuming that all files are in directory /some/temporary/directory, the following commands may be used to create the factorial project ().
prompt% cd /some/temporary/directory prompt% cvs import factorial david initial N factorial/recurs.cpp N factorial/recurs.h N factorial/iter.cpp N factorial/iter.h N factorial/main.cpp
Then, after import is complete, we can check-out a fresh copy of the project and change to that directory:
prompt% cvs co factorial U factorial/iter.cpp U factorial/iter.h U factorial/main.cpp U factorial/recurs.cpp U factorial/recurs.h prompt% cd factorial
The following is a simple Makefile for building the executable. <text> fact: main.o iter.o recurs.o
recurs.o: recurs.cpp
g++ -c recurs.cpp
iter.o: iter.cpp
g++ -c iter.cpp
main.o: main.cpp iter.h recurs.h
g++ -c main.cpp
</text>
The following is a slightly more complex Makefile for doing exactly the same thing. The possible advanytage of using this version is that it automates a few error-prone tasks (such as keeping dependencies up to date). <text> .PHONY: all depend
CXXFILES = $(wildcard *.cpp) CXXHEADS = $(wildcard *.h) OFILES = $(CXXFILES:%.cpp=%.o) PROG = fact
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
all: depend $(PROG)
$(PROG): $(OFILES)
$(CXX) -o $@ $^
depend: .makedeps
.makedeps: $(CXXFILES) $(CXXHEADS)
$(CXX) $(CXXFLAGS) -MM $(CXXFILES) > .makedeps
-include .makedeps </text>
.PHONY indicates targets that do not correspond to actual files and attempts should not be made to build them (e.g. from implicit rules). all depends on depend to force the Makefile to keep its dependencies updated without explicitly calling "make depend".
Finally, to put the Makefile under CVS control, the following two commands would be needed:
prompt% cvs add Makefile cvs add: use `cvs commit' to add this file permanently
prompt% cvs commit /cvs/factorial/Makefile,v <-- Makefile initial revision: 1.1
The following Makefile (a straightforward adaptation of the previous one) would solve the problem: <text> .PHONY: all depend
CXXFILES = $(wildcard *.cpp) CXXHEADS = $(wildcard *.h) ITER = iter RECURS = recurs
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
all: depend $(ITER) $(RECURS)
$(ITER): main.o iter.o
$(CXX) -o $@ $^
$(RECURS): main.o recurs.o
$(CXX) -o $@ $^
depend: .makedeps
.makedeps: $(CXXFILES) $(CXXHEADS)
$(CXX) $(CXXFLAGS) -MM $(CXXFILES) > .makedeps
-include .makedeps </text>
Note that we are assuming that the appropriate changes have been made to the code in the C++ files to allow for a single interface (the function is now called simply "fact") and multiple implementations.
Regarding CVS, only updates and commits are needed at this stage (new versions of the files will be sent to the repository).