2

I have written the following makefile:

CC=g++

all: happy

happy: happy.o HappyLetter.o
        $(CC) -o happy happy.o HappyLetter.o

happy.o: happy.cpp
        $(CC) -c happy.cpp

HappyLetter.o: HappyLetter.cpp
        $(CC) -c HappyLetter.cpp

clean:
        rm -rf *.o happy

and am working with the files HappyLetter.cpp and happy.cpp (which includes the former) to create an executable named happy.

I can build the code successfully using make. However, when I modify HappyLetter.cpp and type 'make' again, the change is not reflected. It only works when I type 'make clean' and then 'make'. The update of the object file that I expect to take place is echoed to the command line:

$ make
g++ -c HappyLetter.cpp
g++ -o happy happy.o HappyLetter.o

However, the update to HappyLetter.cpp is not being reflected in happy.

The problem does not work in the other direction. That is, if I modify happy.cpp, the change is reflected immediately after I type 'make'.

I have replicated this problem with three make binaries on my Mac OS X, and also on an Ubuntu machine. So I must be doing something wrong in the coding. Here is the text of the files, which are in the same directory as the makefile:

happy.cpp

#include "HappyLetter.cpp"

int main()
{
  printf("Hello from happy.cpp!\n");
  HappyLetter *myObj = new HappyLetter();
  myObj->speak();
  return 0;
}

HappyLetter.cpp

#include <cstdio>

class HappyLetter {
  public:
    void speak()
    {
      printf("Hello from HappyLetter.cpp!\n");
    }
};

I believe the problem is something simple, but I have no more ideas about what to check. One assumption I have is that the ordering of the rules and dependencies does not matter.

Mark
  • 55
  • 1
  • 5
  • Use [remake](http://bashdb.sourceforge.net/remake/) `-x` or `make --trace`; also improve your `Makefile` like [here](http://stackoverflow.com/a/20146082/841108); try also `touch HappyLetter.cpp` before re-running `make` – Basile Starynkevitch Jan 26 '15 at 20:21
  • You should *not* `#include "HappyLetter.cpp"` near start of `happy.cpp`; you should have a `happy.h` header file, have `#include "happy.h"` in both `HappyLetter.cpp` and `happy.cpp` and modify your `Makefile` – Basile Starynkevitch Jan 26 '15 at 20:27

1 Answers1

0

As I commented:

First, you should (conventionally) not #include "HappyLetter.cpp" in your happy.cpp (even if that is doable but poor taste). You should have a separate header file (with the conventional include guard)

#ifndef HAPPY_INCLUDED
//// file happy.h
#define HAPPY_INCLUDED 
  class HappyLetter {
 public:
   void speak();
 };
#endif /*HAPPY_INCLUDED*/

(You may -or not- decide to e.g. #include <cstdio> in your happy.h before the class HappyLetter; there are good reasons to do both ways!)

Then you should have a first source file:

// file happy.cpp
 #include <cstdio>
 #include "happy.h"
int main() {
  printf("Hello from happy.cpp!\n");
  HappyLetter *myObj = new HappyLetter();
  myObj->speak();
  delete myObj;
  return 0;
}

BTW, you should use smart pointers!

Then you have your second source file:

 // file happyletter.cpp
 #include <cstdio>
 #include "happy.h"

 void HappyLetter::speak() {
  printf("Hello from HappyLetter.cpp!\n");
 }

At last, a Makefile (see here for inspiration), like:

 # file Makefile
 CXX= g++
 CXXFLAGS= -std=c++11 -Wall -Wextra -g
 RM= rm -f
 .PHONY: all clean

 all: happy-prog

 clean:
    $(RM) *.o *~ happy-prog

 happy-prog: happy.o happyletter.o

 happy.o: happy.cpp happy.h
 happyletter.o: happyletter.cpp happy.h

Notice the explicit dependency on happy.h header

As I commented, consider using remake-x or make --trace to debug your Makefile. Notice that GNU make has a lot of built-in rules, run make -p to get them.

Read more about C++11, notably a tutorial, a good programming in C++ book, have a glance into the standard (e.g. n3337 draft). Read also about make, notably GNU make.

Study the source code of some existing free software coded in C++ (see sourceforge or github etc... to find one).

(so you got both your C++ source files and your Makefile wrong!)

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547