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
Related
Currently the shell script checks for the existence of intended object directory right before each compiler call. How do I modify my Makefile so that the code checks only once before it moves on to compiling all the prerequisites?
Here is my Makefile:
#########################################################
## BUILD TASKS ##
#########################################################
HDIR := hdr
SDIR := src
ODIR := obj
EXET := a
OBJS := main.o mainhdr.o testcode.o
OSRC := $(addprefix $(ODIR)/, $(OBJS))
CXX := g++
CXXFLAGS := -I$(HDIR) -g -Wall -std=c++17
## BUILD DIRECTIVE:
all: $(EXET)
$(EXET): $(OSRC)
$(CXX) $(CXXFLAGS) $^ -o $#
$(ODIR)/%.o: $(SDIR)/%.cpp
if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
$(CXX) -c $(CXXFLAGS) $^ -o $#
## foo.bak: foo.bar
## if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
#########################################################
## CLEAN TASK ##
#########################################################
.PHONY: clean
clean:
rm -r $(EXET) $(ODIR)
I have tried putting:
foo.bak: foo.bar
if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
as suggested here right before the clean task, but that doesn't seem to work. I could be understanding it wrong, but isn't that the Makefile is executed recursively so by putting that block of code at the end it should be at the tip of recursion and thus executed before everything else?
On newer gnu-make, you can use 'order-only-prerequisites`. This eliminate the timestamp checking, and only required that the prerequisite will exists. This works well to ensure that directories will be created before files are stored into them, and can significantly speedup build jobs
$(ODIR):
mkdir $(ODIR)
# Note pipe '|' to separate order only prereq.
$(ODIR)/%.o: $(SDIR)/%.cpp | $(ODIR)
$(CXX) -c $(CXXFLAGS) $^ -o $#
See: https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types
I've installed alljoyn on my raspberry pi and i'm trying to compile the sample code for its basic services. I used the following makefile that i found online with small changes.
# Copyright 2010-2011, Qualcomm Innovation Center, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# returns current working directory
TOP := $(dir $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
ALLJOYN_DIST := /home/pi/work/alljoyn/core/build/linux/arm/debug/dist/cpp
# for use by AllJoyn developers. Code built from alljoyn_core
#ALLJOYN_DIST := ../../build/linux/x86/debug/dist
#ALLJOYN_DIST := ../../build/linux/x86/release/dist
#ALLJOYN_DIST := ../../build/linux/x86_64/debug/dist
#ALLJOYN_DIST := ../../build/linux/x86_64/release/dist
# for use by AllJoyn developers. Code built from master
#ALLJOYN_DIST := ../../../build/linux/x86/debug/dist
#ALLJOYN_DIST := ../../../build/linux/x86/release/dist
#ALLJOYN_DIST := ../../../build/linux/x86_64/debug/dist
#ALLJOYN_DIST := ../../../build/linux/x86_64/release/dist
OBJ_DIR := obj
BIN_DIR := bin
ALLJOYN_LIB := /home/pi/work/alljoyn/core/build/linux/arm/debug/dist/cpp/lib/liballjoyn.a
CXXFLAGS = -Wall -pipe -std=c++98 -fno-rtti -fno-exceptions -Wno-long-long -Wno-deprecated -g -DQCC_OS_LINUX -DQCC_OS_GROUP_POSIX -DQCC_CPU_X86
LIBS = -lstdc++ -lcrypto -lpthread -lrt
.PHONY: default clean
default: all
all: basic_client basic_service nameChange_client signal_service signalConsumer_client
basic_client: basic_client.o $(ALLJOYN_LIB)
mkdir -p $(BIN_DIR)
$(CXX) -o $(BIN_DIR)/$# $(OBJ_DIR)/basic_client.o $(TOP)$(ALLJOYN_LIB) $(LIBS)
basic_client.o: basic_client.cc $(ALLJOYN_LIB)
mkdir -p $(OBJ_DIR)
$(CXX) -c $(CXXFLAGS) -I$(ALLJOYN_DIST)/inc -o $(OBJ_DIR)/$# basic_client.cc
basic_service: basic_service.o $(ALLJOYN_LIB)
$(CXX) -o $(BIN_DIR)/$# $(OBJ_DIR)/basic_service.o $(TOP)$(ALLJOYN_LIB) $(LIBS)
basic_service.o: basic_service.cc $(ALLJOYN_LIB)
$(CXX) -c $(CXXFLAGS) -I$(ALLJOYN_DIST)/inc -o $(OBJ_DIR)/$# basic_service.cc
nameChange_client: nameChange_client.o $(ALLJOYN_LIB)
$(CXX) -o $(BIN_DIR)/$# $(OBJ_DIR)/nameChange_client.o $(TOP)$(ALLJOYN_LIB) $(LIBS)
nameChange_client.o: nameChange_client.cc $(ALLJOYN_LIB)
$(CXX) -c $(CXXFLAGS) -I$(ALLJOYN_DIST)/inc -o $(OBJ_DIR)/$# nameChange_client.cc
signal_service: signal_service.o $(ALLJOYN_LIB)
$(CXX) -o $(BIN_DIR)/$# $(OBJ_DIR)/signal_service.o $(TOP)$(ALLJOYN_LIB) $(LIBS)
signal_service.o: signal_service.cc $(ALLJOYN_LIB)
$(CXX) -c $(CXXFLAGS) -I$(ALLJOYN_DIST)/inc -o $(OBJ_DIR)/$# signal_service.cc
signalConsumer_client: signalConsumer_client.o $(ALLJOYN_LIB)
$(CXX) -o $(BIN_DIR)/$# $(OBJ_DIR)/signalConsumer_client.o $(TOP)$(ALLJOYN_LIB) $(LIBS)
signalConsumer_client.o: signalConsumer_client.cc $(ALLJOYN_LIB)
$(CXX) -c $(CXXFLAGS) -I$(ALLJOYN_DIST)/inc -o $(OBJ_DIR)/$# signalConsumer_client.cc
clean: clean_basic_client clean_basic_service clean_nameChange_client clean_signal_service clean_signalConsumer_client
rmdir $(OBJ_DIR)
rmdir $(BIN_DIR)
clean_basic_client:
rm -f $(OBJ_DIR)/basic_client.o $(BIN_DIR)/basic_client
clean_basic_service:
rm -f $(OBJ_DIR)/basic_service.o $(BIN_DIR)/basic_service
clean_nameChange_client:
rm -f $(OBJ_DIR)/nameChange_client.o $(BIN_DIR)/nameChange_client
clean_signal_service:
rm -f $(OBJ_DIR)/signal_service.o $(BIN_DIR)/signal_service
clean_signalConsumer_client:
rm -f $(OBJ_DIR)/signalConsumer_client.o $(BIN_DIR)/signalConsumer_client
The problem is that i get the following error:
g++: error: /home/pi/work/alljoyn/core/build/linux/arm/debug/dist/cpp/samples/basic/ /home/pi/work/alljoyn/core/build/linux/arm/debug/dist/cpp/lib/liballjoyn.a: No such file or directory"
So my compiler can't find liballjoyn.a but i don't understand why. The path to the library is the correct one and i also tried
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/home/pi/work/alljoyn/core/build/linux/arm/debug/dist/cpp/lib/'
Can anyone help me?
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.
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
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
...