Makefile errors when I change a directory name - directory

I have a Makefile that compiles, but I want to change the name of one of the directories from "release" to "objects". This is the original Makefile -
# This makefile compiles ....
INCLUDE = -I/usr/include/X11 -I/usr/local/include -I/usr/local/include/FL/images -I/usr/include/freetype2
CC=g++
CFLAGS=-w -D LINUX -O3 -fpermissive
OBJDIR=release # HERE IS THE DIRECTORY I WANT TO CHANGE
SRCDIR=src
LDFLAGS= -L/usr/X11R6/lib$(LIBSELECT) -lpthread -lfltk -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11
SOURCES_RAW= robot_driver_agent.cpp robot_driver_position.cpp robot_driver_priorityqueue.cpp main.cpp robot_driver_tree.cpp robot_driver_stack.cpp robot_driver_grid.cpp robot_driver_path.cpp grid_analyzer.cpp tcpserver.cpp tcpclient.cpp servercontrol.cpp clientcontrol.cpp robot.cpp udpserver.cpp udpclient.cpp owncontrol.cpp guiwindow.cpp rs232.cpp
TARGET:= go
TARGETD:= go_d
OBJECTS:=$(SOURCES_RAW:.cpp=.o)
OBJECTS:=$(patsubst %.o, $(OBJDIR)/%.o, $(OBJECTS))
SOURCES:=$(SOURCES_RAW)
SOURCES:=$(patsubst %.cpp, $(SRCDIR)/%.cpp, $(SOURCES))
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
release/%.o: src/%.cpp
test -d $(OBJDIR) || mkdir $(OBJDIR)
$(CC) -g -c $< $(CFLAGS) -o $#
debug: $(TARGETD)
$(TARGETD): $(OBJECTS)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
%.o: $(SRCDIR)/%.cpp
$(CC) -c -g $< $(CFLAGS)-o $#
.PHONY : clean
clean:
rm -f $(OBJDIR)/*.o
rm -f $(TARGET) $(TARGETD)
All I do is change the OBJDIR symbol to "objects" so it would just be -
OBJDIR=objects
But when I do that, I get the error -
make: *** No rule to make target `objects/robot_driver_agent.o', needed by `go'.
What am I missing? Is "objects" a word reserved for something in make so I can't use it for directories? Is it something in the make file that I need to change? Honestly, I don't know that much about makefiles so any help at all would be great. Thanks.

You have a rule:
release/%.o: src/%.cpp
...
So that when OBJDIR=release and Make wants to build release/robot_driver_agent.o, it knows just what to do. Then you try OBJDIR=objects, it wants to build objects/robot_driver_agent.o, and it doesn't know how because there's no rule that fits. Try changing the rule to:
$(OBJDIR)/%.o: src/%.cpp
...

Related

Issue generating MOC files for QT using a makefile

Hello i am trying to generate MOC files for QT using a makeifle.
The problem is a command is executing from somewhere and i can't find from where....
This is my makefile
BUILD = Build
### SOURCES ###
SRC = Src/Main\
Src/DialogBox/DialogBox
### MOC SOURCES ###
MOC_SRC = Src/DialogBox/DialogBox
### OBJECTS ###
OBJ = $(addsuffix .o, $(addprefix $(BUILD)/, $(SRC)))
OBJ += $(addsuffix .moc.o, $(addprefix $(BUILD)/, $(MOC_SRC)))
### INCLUDES ###
INC = TOO MANY INCLUDES TO PUT HERE....
### LINKER FLAGS ###
LDFLAGS = -LC:/Qt/5.15.0/mingw81_32/lib
LDLIBS = -lQt5Quick -lQt5PrintSupport -lQt5Qml -lQt5Network -lQt5Widgets -lQt5Gui -lQt5Core
### COMPILER FLAGS
CFLAGS = $(INC)
### COMPILER ###
CC = g++
### QT MOC ###
MOC = moc
all: $(BUILD)/test.exe
$(BUILD)/test.exe: $(OBJ)
#echo LINKING $^
#$(CC) $(LDFLAGS) -o $# $^ $(LDLIBS)
$(BUILD)/%.o: %.cpp
#echo COMPILING $<
#mkdir -p $(subst /,\,$(dir $#))
#$(CC) $(CFLAGS) -M -MT $# -o $(patsubst %.o, %.d, $#) $<
#$(CC) $(CFLAGS) -o $# -c $<
$(BUILD)/%.moc.cpp: %.h
#echo MOCCING $<
$(MOC) $< -o $#
#echo MOC END
-include $(OBJ:.o=.d)
.PHONY: clean
clean:
#echo CLEANING......
#rm -rf $(BUILD)/Src $(BUILD)/test.exe
This is the result:
COMPILING Src/Main.cpp
COMPILING Src/DialogBox/DialogBox.cpp
MOCCING Src/DialogBox/DialogBox.h
moc Src/DialogBox/DialogBox.h -o Build/Src/DialogBox/DialogBox.moc.cpp
MOC END
g++ -c -o Build/Src/DialogBox/DialogBox.moc.o Build/Src/DialogBox/DialogBox.moc.cpp
In file included from Build/Src/DialogBox/DialogBox.moc.cpp:10:0:
Build/Src/DialogBox/../../../Src/DialogBox/DialogBox.h:4:19: fatal error: QDialog: No such file or directory
#include "QDialog"
^
compilation terminated.
make: *** [<builtin>: Build/Src/DialogBox/DialogBox.moc.o] Error 1
rm Build/Src/DialogBox/DialogBox.moc.cpp
Basically i have only two source files: Main.cpp and DialogBox.cpp.
I want to generate MOC file from DialogBox.h.
The problem is this command:
g++ -c -o Build/Src/DialogBox/DialogBox.moc.o Build/Src/DialogBox/DialogBox.moc.cpp
I don't understand why it's executing...
EDIT:
Even after:
MOCCING Src/DialogBox/DialogBox.h
moc Src/DialogBox/DialogBox.h -o Build/Src/DialogBox/DialogBox.moc.cpp
MOC END
no such file Build/Src/DialogBox/DialogBox.moc.cpp exists.Why?
I finally fixed it.As #G.M. suggested in the comments, probably an implicit rule is executing so i decided to write my own to avoid that.
I added this:
$(BUILD)/%.moc.o: $(BUILD)/%.moc.cpp
#echo COMPILING MOC $<
#mkdir -p $(subst /,\,$(dir $#))
#$(CC) $(CFLAGS) -M -MT $# -o $(patsubst %.o, %.d, $#) $<
#$(CC) $(CFLAGS) -o $# -c $<
and everything works fine.
The complete makefile:
BUILD = Build
### SOURCES ###
SRC = Src/Main\
Src/DialogBox/DialogBox
### MOC SOURCES ###
MOC_SRC = Src/DialogBox/DialogBox
### OBJECTS ###
OBJ = $(addsuffix .o, $(addprefix $(BUILD)/, $(SRC)))
OBJ += $(addsuffix .moc.o, $(addprefix $(BUILD)/, $(MOC_SRC)))
### INCLUDES ###
INC = TOO MANY INCLUDES TO PUT HERE....
### LINKER FLAGS ###
LDFLAGS = -LC:/Qt/5.15.0/mingw81_32/lib
LDLIBS = -lQt5Quick -lQt5PrintSupport -lQt5Qml -lQt5Network -lQt5Widgets -lQt5Gui -lQt5Core
### COMPILER FLAGS
CFLAGS = $(INC)
### COMPILER ###
CC = g++
### QT MOC ###
MOC = moc
all: $(BUILD)/test.exe
$(BUILD)/test.exe: $(OBJ)
#echo LINKING $^
#$(CC) $(LDFLAGS) -o $# $^ $(LDLIBS)
$(BUILD)/%.o: %.cpp
#echo COMPILING $<
#mkdir -p $(subst /,\,$(dir $#))
#$(CC) $(CFLAGS) -M -MT $# -o $(patsubst %.o, %.d, $#) $<
#$(CC) $(CFLAGS) -o $# -c $<
$(BUILD)/%.moc.o: $(BUILD)/%.moc.cpp
#echo COMPILING MOC $<
#mkdir -p $(subst /,\,$(dir $#))
#$(CC) $(CFLAGS) -M -MT $# -o $(patsubst %.o, %.d, $#) $<
#$(CC) $(CFLAGS) -o $# -c $<
$(BUILD)/%.moc.cpp: %.h
#echo GENERATING MOC $<
#$(MOC) $< -o $#
-include $(OBJ:.o=.d)
.PHONY: clean
clean:
#echo CLEANING......
#rm -rf $(BUILD)/Src $(BUILD)/test.exe

gnu make multiple targets one object each

I have an old project for which I'm trying to create a multiple binaries, one for each object in the directory. I cannot for the life of me figure out how to deal with multiple targets in this manner. The following works, but it seems to me I should be able to have one rule to link them all, so to speak,
# compile objects, no problem
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $#
bin: bin.o
$(CC) -o $# $< ../lib/libfoo.a -lm $(ARCH)
bar: bar.o
$(CC) -o $# $< ../lib/libfoo.a -lm $(ARCH)
One approach that I did get to work is to strip off the suffix from the target name like this, and compile and link in one step, but it feels a little hackish,
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $< ../lib/libfoo.a -lm -o $(*F)
Disclaimer: I despise make
UPDATE 1: this is what I ended up with
EXECS = bin bar ...
all: $(EXECS)
%: %.c
#echo "Building $# from $<"
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $#.o
$(CC) $(CFLAGS) $(CPPFLAGS) $#.o ../lib/libfoo.a -lm -o $#
The convention is to have something like this at the top of your Makefile:
.PHONY: all
all: bin bar
Thus make all will make bin and bar, and by putting it at the top it's the default target for make without arguments. The .PHONY: documents this as a "metatarget", but also instructs Make to run it even if there happens to be a file called all with a fresh datestamp.
%: %.o
$(CC) -o $# $< ../lib/libfoo.a -lm $(ARCH)
This tells Make how to make them both.

Writing your Own Makefile

I am trying to write a Makefile but it is showing
Make: Don't know how to make cc. Stop.
what I am doing is this :-
Hello.c
#include<stdio.h>
extern int print();
int main(){
print();
return 0;
}
print.c
#include<stdio.h>
int print(){
printf("hello\n");
return 0;
}
Makefile
all: OUT
OUT: cc Hello.o print.o -o OUT
Hello.o: Hello.c\
cc -c Hello.c
print.o: print.c \
cc -c print.c
clean: rm -f *.o
clobber: rm -f OUT
when I am writing make
$>make
Make: Don't know how to make cc. Stop.
$>make clean
Make: Don't know how to make rm. Stop.
what thing I am missing..
I am newbie with this make and makefile, so please suggest me some good tutorials on this
I changed to this :-
all: OUT
OUT:; #cc Hello.o print.o -o OUT
Hello.o:; #cc -c Hello.c
print.o:; #cc -c print.c
clean:; #rm -f *.o
clobber:; #rm -f OUT
showing error:-
cc: warning 1913:Hello.o' does not exist or cannot be read
cc: warning 1913: print.o' does not exist or cannot be read
ld: I/O error, file "Hello.o": No such file or directory
Fatal error.
*** Error exit code 1
The rules must be on a different line than the targets, indented with a hard tab:
all: OUT
OUT: Hello.o print.o
cc Hello.o print.o -o OUT
Hello.o: Hello.c
cc -c Hello.c
print.o: print.c
cc -c print.c
clean:
rm -f *.o
clobber:
rm -f OUT
But this can be simplified by relying on implicit rules and generalized by using some variables:
all: OUT
OUT: Hello.o print.o
$(CC) $(CFLAGS) $^ -o $#
clean:
rm -f *.o
clobber:
rm -f OUT

GNU makefile detect header changes

I have a directory with dozens of source and header files. Is there a better or cleaner way than the following %.o target for make to detect changes to header files? When the object is compiled, g++ is invoked with both the .cc and .h files which doesn't seem right, it should find the .h file automatically.
%.o: %.cc %.h
g++ -c $^
OBJECTS=headless-driver.o config.o simplefm2.o emulator.o basis-util.o objective.o weighted-objectives.o motifs.o util.o
learnfun : $(OBJECTS) learnfun.o
g++ $^ -o $#
%.o: %.cc %.h
g++ -c $^
You are specifying $^ which expands to all dependencies. If you just want the first dependency on the Gcc command line, use $< instead.

How to include clean target in Makefile?

I have a Makefile that looks like this
CXX = g++ -O2 -Wall
all: code1 code2
code1: code1.cc utilities.cc
$(CXX) $^ -o $#
code2: code2.cc utilities.cc
$(CXX) $^ -o $#
What I want to do next is to include clean target so that every time
I run make it will automatically delete the existing binary files of code1 and code2 before creating the new ones.
I tried to put these lines at the very end of the makefile, but it doesn't work
clean:
rm -f $#
echo Clean done
What's the right way to do it?
The best thing is probably to create a variable that holds your binaries:
binaries=code1 code2
Then use that in the all-target, to avoid repeating:
all: clean $(binaries)
Now, you can use this with the clean-target, too, and just add some globs to catch object files and stuff:
.PHONY: clean
clean:
rm -f $(binaries) *.o
Note use of the .PHONY to make clean a pseudo-target. This is a GNU make feature, so if you need to be portable to other make implementations, don't use it.
In makefile language $# means "name of the target", so rm -f $# translates to rm -f clean.
You need to specify to rm what exactly you want to delete, like rm -f *.o code1 code2
By the way it is written, clean rule is invoked only if it is explicitly called:
make clean
I think it is better, than make clean every time. If you want to do this by your way, try this:
CXX = g++ -O2 -Wall
all: clean code1 code2
code1: code1.cc utilities.cc
$(CXX) $^ -o $#
code2: code2.cc utilities.cc
$(CXX) $^ -o $#
clean:
rm ...
echo Clean done

Resources