0

I'm new to Makefiles. I've been making a simple C++ library using WiringPi for my RaspberyPi related projects. So far its very simple with things like an LED class, DuelLED, Motor, Button, etc (both .h and .cpp). I was able to piece together a Makefile but I am getting an error "No rule to make target RumPi.o needed by RumPi". (Note: The name of my library is called RumPi)

Thanks for all the help, Here is the final fix:

CXX = g++
CXXFLAGS = -std=c++11
LDLIBS = -lwiringPi

HEADERS = Components/Headers/RumPi.h ./Common.h Components/Headers/Component.h Components/Headers/Vehicle.h Components/Headers/Motor.h Components/Headers/Receiver.h Components/Headers/DualLED.h Components/Headers/LED.h Components/Headers/RGBLED.h Components/Headers/Relay.h 
OBJECTS = RumPi.o Vehicle.o Motor.o Receiver.o DualLED.o LED.o RGBLED.o Relay.o

default: RumPi

RumPi: $(OBJECTS)
        $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@

%.o: Components/Implementations/%.cpp
        $(CXX) $(CXXFLAGS) -c -o $@ $<

$(OBJECTS): $(HEADERS)

clean:
        -rm -f $(OBJECTS)
        -rm -f RumPi
Katianie
  • 589
  • 1
  • 9
  • 38

1 Answers1

2

That message means make can't figure out how to build that target (RumPi.o). Do you have a Components/Implementations/RumPi.cpp file? Do all the header files you've listed in the $(HEADERS) variable actually exist? If either of those is not true, then your pattern rule will not match. If your pattern rule doesn't match (and the default rule doesn't match) then make can't figure out how to build the object file.

If you want full details you can run make -d and examine the debug output. You might want to redirect it to a file so you can look at it with less or a text editor since there's a lot of output.

By the way, you should not add the -lwiringPi option to your compile line. Libraries are only used at link time, not compile time.

ETA

Something else you should consider is rewriting your pattern rule so that only the source file is listed as a prerequisite and moving the headers to a separate line:

%.o: Components/Implementations/%.cpp
        gcc -c $< -o $@ -lwiringPi

$(OBJECTS): $(HEADERS)

The advantage to this is you'll get a clearer error message if one of the headers is not found. When you use a pattern rule, make will try to match all the patterns it can and if none match it tells you it doesn't know how to build the target. Since there are usually many different ways to build a target, make doesn't show an error for every one that doesn't match.

But if you declare a direct explicit prerequisite relationship between two files, rather than using a pattern that may or may not match, then if there is a missing file make will tell you directly.

ETA2

In your original makefile you had a rule like this:

RumPi: $(OBJECTS)
        gcc $(OBJECTS) -o $@ -lwiringPi

but then later you removed it. Why did you take this out? You need this rule to tell make how to link your executable file RumPi.

Also, you shouldn't be using gcc as the compiler/linker for C++ code; gcc is for C, not C++. You should use g++ for C++ code. And it's best to contain this information in variables so it's easy to find and modify (even from the command line if you like). The standard variable names for the C++ compiler is CXX etc.

Your makefile should look something like this:

CXX = g++
CXXFLAGS = -std=c++11
LDLIBS = -lwiringPi

HEADERS = Components/Headers/RumPi.h ./Common.h Components/Headers/Component.h \
    Components/Headers/Vehicle.h Components/Headers/Motor.h Components/Headers/Receiver.h \
    Components/Headers/DualLED.h Components/Headers/LED.h Components/Headers/RGBLED.h \
    Components/Headers/Relay.h 
OBJECTS = RumPi.o Vehicle.o Motor.o Receiver.o DualLED.o LED.o RGBLED.o Relay.o

default: RumPi

RumPi: $(OBJECTS)
        $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@

%.o: Components/Implementations/%.cpp
        $(CXX) $(CXXFLAGS) -c -o $@ $<

$(OBJECTS): $(HEADERS)

clean:
        -rm -f $(OBJECTS)
        -rm -f RumPi
MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • how would I add my library that needs to be ran like that with gcc? – Katianie Nov 12 '17 at 04:47
  • Yes I have a RumPi.cpp and yes they all exist. I ran make-d and it did not help just said it could not make RumPi.o – Katianie Nov 12 '17 at 05:17
  • You keep the library in the link line (the command tha builds the executable `RumPi`). But you should remove it from the compile line (the command that builds the object files (`.o` files)). – MadScientist Nov 12 '17 at 15:16
  • If you run `make -d` it will generate a ton of output, describing exactly how make thinks about building the targets. In there will be a set of decisions made to build the `RumPi.o` target. In that set of decisions will be the reason make decided it couldn't build that target. You have to look at the output and determine which file make was looking for but could not find. – MadScientist Nov 12 '17 at 15:22
  • I made the change you suggested and tried to run it again. It looks better but the only problem I have is "Common.h". Common.h is a simple interface I use for inheritance but it does not have a Common.cpp since it is a simple header. How should I include the "Components/Headers/Common.h" to the Makefile? – Katianie Nov 12 '17 at 20:00
  • Since it's a header, why not just include it with the other headers? – MadScientist Nov 12 '17 at 20:06
  • I get "No rule to make target Components/Headers/Common.h" – Katianie Nov 12 '17 at 20:08
  • That doesn't mean it's looking for a corresponding `Common.cpp`. In the makefile you've provided here there's no way it would be trying to build `Common.cpp`. That error means make can't find the file `Components/Headers/Common.h`. I can't explain this from here: you'll have to look very carefully at your system. If you run the command `ls Components/Headers/Common.h` from the same directory as you run make, using cut and paste to make sure it's the _identical_ path make printed, what happens? – MadScientist Nov 12 '17 at 20:13
  • Ok I think I fixed that issue, the problem I'm getting now is that I need to specify C++11 somehow "std=c++11" and wiringPi. Currently with what I have (I updated the post) I'm getting an error saying it cant find the wiringPi functions ("undefined reference to wiringPiSetupGPIO()"). – Katianie Nov 12 '17 at 20:28
  • Why did you remove the link rule? You need that. As I said above, you should remove the `-lwiringPi` option from the _COMPILE_ line (you've left it there in the `%.o` rule) and keep it in the _LINK_ line (which you seem to have removed completely from your makefile, which is wrong). – MadScientist Nov 12 '17 at 20:32
  • I made the modification exactly as you wrote, I'm not sure what you are referring to or what exactly I should put back in. I don't understand what you mean since this is my first makefile I have made. Can you please provide the correction? – Katianie Nov 12 '17 at 22:05
  • Thanks! This is very helpful. I'm getting an issue related to it not finding some functions but I'll look into it. I'll reply back here with my status shortly. – Katianie Nov 12 '17 at 22:20