user6933051 user6933051 - 1 month ago 6
C Question

Makefile that only recompiles changed objects?

Alright, new user here, and I've got a problem. I'm a new c++ student, and I have no prior experience in this language (before about 3 months ago). My assignment is as follows:

Write a program that declares an array darray of 50 elements of type double. Initialize the array so that the first 25 elements are equal to the square of the index variable, and the last 25 elements are equal to three times the index variable. Output the array so that 10 elements per line are printed.
The program should have two functions: a function, initArray(), which initializes the array elements, and a function, prArray(), which prints the elements.

I have that, it's as follows

#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
double initArray();
double prArray(double arrayone[50]);
double * dArray;
int main() {
dArray[50] = initArray();
system("PAUSE");
prArray(dArray);
system("PAUSE");
return 0;
}

#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <iostream>
#include <string>
using namespace std;
double prArray(double arraytwo[50])
{
for (int x = 0; x < 50; x++) {
cout << arraytwo[x];
if (x = 9 || 19 || 29 || 39 || 49) {
cout << endl;
}
}
return 0;
}

#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <iostream>
#include <string>
int x = 0;
double arrayone[50];
double initArray()
{
for (x = 0; x < 25; x++) {
arrayone[x] = (x*x);
}
for (x = 25; x <= 50; x++) {
arrayone[x] = (x * 3);
}
return arrayone[50];
}


Now my problem is that the assignment goes on to say

Write a Makefile to compile the program above that minimizes recompiling items upon changes. (e.g., if one function file gets updated, only the necessary file(s) are recompiled.) Include a clean target that removes compiled objects if invoked.

I have a basic makefile:

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=Main.cpp initializeArray.cpp printArray.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=Main
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@


Now, what I need help with is turning this into a makefile that satisfies the assignment conditions - preferably with step-by-step instructions so that I can learn from this.

Answer

Modified your Makefile to:

  1. Automatically generate header dependencies.
  2. Re-build and re-link when Makefile changes.

CXX := g++
LD := ${CXX}
CXXFLAGS := -Wall -Wextra -std=gnu++14 -pthread
LDFLAGS := -pthread

exes :=

# Specify EXEs here begin.

Main.SOURCES := Main.cpp initializeArray.cpp printArray.cpp
exes += Main

# Specify EXEs here end.

all: $(exes)

.SECONDEXPANSION:

get_objects = $(patsubst %.cpp,%.o,${${1}.SOURCES})
get_deps = $(patsubst %.cpp,%.d,${${1}.SOURCES})

# Links executables.
${exes} : % : $$(call get_objects,$$*) Makefile
    ${LD} -o $@ $(filter-out Makefile,$^) ${LDFLAGS}

# Compiles C++ and generates dependencies.
%.o : %.cpp Makefile
    ${CXX} -o $@ -c ${CPPFLAGS} ${CXXFLAGS} -MP -MD $<

# Include the dependencies generated on a previous build.
-include $(foreach exe,${exes},$(call get_deps,${exe}))

.PHONY: all
Comments