Header file dependancy not working - c++

I have written below Makefile and as per answer to this question added rules for header file dependencies but it is not working. I did a clean and then build. After that I modified Parse.h using touch command and ran "make all" it says Test.exe is up to date. I got same output with just "make" command too.
Can anyone please let me know where am I gone wrong.
RM := rm -rf
MKDIR := mkdir -p
FIND := find
CPIO := cpio
CD := cd
MV := mv
# Set compiler flags
ifeq ($(BUILD_TYPE),DEBUG)
COMPILE_FLAGS= -c -fpic -DDBG=1 -g -DUSE_UTLPATMAT=1 -Wall
else ifeq ($(BUILD_TYPE),RELEASE)
COMPILE_FLAGS= -c -fpic -O3 -DUSE_UTLPATMAT=1 -Wall
else ifeq ($(BUILD_TYPE),PERF)
COMPILE_FLAGS= -c -fpic -O3 -DUSE_UTLPATMAT=1 -DPERF_COMPONENT -Wall
else
COMPILE_FLAGS= -c -fpic -O3 -DUSE_UTLPATMAT=1 -Wall
endif
export STFP_HOME = $(shell cd "$(CURDIR)/.."; pwd)
STFP_LIB = $(STFP_HOME)/lib
STFP_BIN = $(STFP_HOME)/bin
$(shell mkdir -p ${STFP_LIB})
$(shell mkdir -p ${STFP_BIN})
STFP_INC = $(CURDIR)/SP
SPTEST_SRC = $(CURDIR)/SPTest
SPTEST_INC = $(CURDIR)/SPTest
STFP_SRC = $(CURDIR)/SP
STFP_INC = $(CURDIR)/SP
UTILITIES_SRC_DIR = $(CURDIR)/../utilities
LIBS= -L${CLIENT_LIB}
INCS_DIRS= -I${CLIENT_INC}
#Subdivision Publisher Test
SPTESTSRCS=\
$(SPTEST_SRC)/Parse.cpp \
$(SPTEST_SRC)/Main.cpp
SPTESTOBJS=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SPTESTSRCS)))
all := $(STFP_BIN)/Test.exe
#################### Main targets #####################################
all:$(all)
clean:
find $(STFP_SRC)/ -name "*.o" | xargs rm -rf
find $(SPTEST_SRC)/ -name "*.o" | xargs rm -rf
rm -rf $(STFP_LIB)
rm -rf $(STFP_BIN)
#######################################################################
$(STFP_BIN)/Test.exe: $(SPTESTOBJS)
$(CXX) -g $(INCS_DIRS) \
$(SPTESTOBJS) -o $# \
$(LIBS) -lmodpbase64 -lboost_regex -lboost_filesystem -lboost_system -lboost_serialization \
-lutility
%.o : %.cpp
$(CXX) -DPROVIDE_LOG_UTILITIES $(COMPILE_FLAGS) $(INCS_DIRS) -o $# $<
%.o : %.c
$(CC) -DPROVIDE_LOG_UTILITIES $(COMPILE_FLAGS) $(INCS_DIRS) -o $# $<
################# Dependencies #########################
depend: .depend
.depend: $(SPTESTSRCS)
rm -f .depend
$(CXX) -DPROVIDE_LOG_UTILITIES $(COMPILE_FLAGS) $(INCS_DIRS) -MM -$(SPTESTSRCS) > .depend
-include .depend
########################################################
Thanks

You seem to expect .o files in SPTest. You could do so by using:
SPTest/%.o: SPTest/%.cpp
$(CXX) -DPROVIDE_LOG_UTILITIES $(COMPILE_FLAGS) $(INCS_DIRS) -o $# $<
OR by using (where #D is directory and #F is filename):
%.o : %.cpp
$(CXX) -DPROVIDE_LOG_UTILITIES $(COMPILE_FLAGS) $(INCS_DIRS) -o $(#D)/$(#F) $<
Let me know if you still get errors.

Related

Extend C++ project with CMakeList.txt

I'm trying to transform old project with Makefile to a modern one with CMakeLists.txt and GoogleTest framework but i can't handle the dependencies.
This is my Project structure
Project-LG
src/
app/
main.cpp
A.cpp
A.hpp
B.cpp
B.hpp
C.cpp
C.hpp
...
cpp-utils/
D.cpp
D.hpp
E.hpp
F.hpp
json/
json.hpp
hiredis/ /*Makefile project*/
orane2/ /*Makefile project*/
rmr/ /*Makefile project*/
spdlog/ /*Headers project with nested directories*/
Makefile
And this is the "Project-LG" Makefile
CC=gcc
CPP=g++
SRCDIR = .
APPDIR = $(SRCDIR)/app
UTILSDIR = $(SRCDIR)/cpp-utils
TARGETDIR =./../out
OBJDIR =./../out/obj
APP_OBJDIR =$(OBJDIR)/app
UTILS_OBJDIR =$(OBJDIR)/cpp-utils
LIBSDIR = ./../libs
INCLUDE_FILE = \
-Iapp \
-Icpp-utils \
-Irmr/si \
-Irmr/si/si95 \
-Irmr/common \
-Ijson \
-Iorane2 \
-I. \
-Ihiredis
SUBDIRS := \
$(SRCDIR)/rmr \
$(SRCDIR)/orane2 \
$(SRCDIR)/hiredis
LFLAGS =
LIBS += -pthread -static-libstdc++ \
-L$(LIBSDIR) -l:librmr.a -l:liborane2.a -l:hiredis.a
XAPP_NAME_STR := '"app-lg"'
CFLAGS += -Wall -g -O2 -DXAPP_NAME=$(XAPP_NAME_STR) $(INCLUDE_FILE)
CPPFLAGS = $(CFLAGS) -fPIC -std=c++17
APP_EXE ?= xapp
APP_SOURCES := $(shell find $(APPDIR) -maxdepth 1 -name '*.cpp' -printf '%f\n')
UTILS_SOURCES := $(shell find $(UTILSDIR) -maxdepth 1 -name '*.cpp' -printf '%f\n')
APP_OBJS := $(addprefix $(APP_OBJDIR)/, $(APP_SOURCES:%.cpp=%.o))
UTILS_OBJS := $(addprefix $(UTILS_OBJDIR)/, $(UTILS_SOURCES:%.cpp=%.o))
.SUFFIXES: .c~.o
.PHONY: all $(SUBDIRS) clean
all: $(SUBDIRS) $(APP_EXE)
$(APP_EXE): $(APP_OBJS) $(UTILS_OBJS)
#mkdir -p $(TARGETDIR)
#mkdir -p $(OBJDIR)
$(CPP) $(CFLAGS) $(LFLAGS) $(APP_OBJS) $(UTILS_OBJS) $(LIBS) -o $(TARGETDIR)/$#
$(APP_OBJDIR)/%.o : $(APPDIR)/%.cpp
#mkdir -p $(OBJDIR)
#mkdir -p $(APP_OBJDIR)
$(CPP) -c $(CPPFLAGS) $(LFLAGS) $< -o $#
$(UTILS_OBJDIR)/%.o : $(UTILSDIR)/%.cpp
#mkdir -p $(OBJDIR)
#mkdir -p $(UTILS_OBJDIR)
$(CPP) -c $(CPPFLAGS) $(LFLAGS) $< -o $#
$(SUBDIRS):
$(MAKE) -C $#
clean:
rm -rf $(TARGETDIR)
It was difficult to figure out how to call the Makefile from CMake and how to add the GoogleTest framework with all its dependencies
Please accept my thanks for your time.

Makefile to compile a list of sources to custom directory

I have this makefile:
IDIR = include
SDIR = src
ODIR = obj
BDIR = build
DEPS = $(shell find $(IDIR)/ -name '*.hpp')
SRCS = $(shell find $(SDIR)/ -name '*.cpp')
OBJS = $(patsubst %.cpp,$(ODIR)/%.o,$(notdir $(SRCS)))
BIN = main
CPPC = g++
CFLAGS = -Wall -c
all: dir $(BDIR)/$(BIN)
#echo Finished compiling $(BIN)
dir:
mkdir -p $(BDIR)
mkdir -p $(ODIR)
$(BDIR)/$(BIN): $(OBJS)
$(CPPC) $^ -o $#
$(OBJS): $(SRCS)
$(CPPC) $(CFLAGS) $^ -o $#
clean:
rm -rf $(BDIR) $(ODIR)
When I try to make, I get the following error:
mkdir -p build
mkdir -p obj
g++ -Wall -c src/sdk/tcp/Tcp.cpp src/sdk/socket/Socket.cpp src/Main.cpp -o obj/Tcp.o
g++: fatal error: cannot specify ‘-o’ with ‘-c’, ‘-S’ or ‘-E’ with multiple files
compilation terminated.
make: *** [Makefile:27: obj/Tcp.o] Error 1
My question is, is it possible to achieve what I am trying with this makefile? Going through each source file in $(SRCS), and compile the object file directly inside the obj directory with just the basename. An example of obj directory after a successful compilation:
obj
/ | \
/ | \
Tcp.o Socket.o Main.o
Your $(OBJS) rule is wrong.
There are (at least) two ways to do this.
You could write a pattern rule and use vpath to locate the sources:
vpath %.cpp $(dir $(SRCS))
$(OBJS): obj/%.o: %.cpp
$(CPPC) $(CFLAGS) $^ -o $#
Or you could generate a rule for each object:
define template
$(patsubst %,obj/%.o,$(notdir $(1))): $(addsuffix .cpp,$(1))
echo $(CPPC) $(CFLAGS) $$^ -o $$#
endef
$(foreach src,$(SRCS),$(eval $(call template,$(basename $(src)))))

Make won't recompile header file changes. Despite including .d dependency files

I have a really strange issue with the Makefile in one of my off-time projects.
I have a Makefile (shown below) that generates dependency information in .d files following https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html.
The problem is that a change in one of my header files (shader.h) does not trigger the recompilation of shader.o (out of shader.cpp).
The problem started happening recently when I re-organized the directory structure in my project so I suspect it is related to that.
The strange thing is that if I do make --print-data-base it does seem like it has found the correct prerequisites matching the shader.d file.
The diretory structure is as follows:
|-src
|-engine
|-shader.h
|-shader.cpp
|-bin
|-Debug
|-OpenGLTest
|-obj
|-Debug
|-engine
|-shader.o
|-dep
|-engine
|-shader.d
Makefile:
WORKDIR = `pwd`
CC = gcc
CXX = g++
AR = ar
LD = g++
WINDRES = windres
INC = -I/usr/local/include
CFLAGS = -Wall -Werror
CXX_FLAGS = -std=c++11
RESINC =
LIBDIR = -L/usr/local/lib
LIB = -lSDL2 -lGLEW -framework OpenGL
LDFLAGS =
DEPDIR = dep
SRCDIR = src
INC_DEBUG = $(INC)
CFLAGS_DEBUG = $(CFLAGS) -g
RESINC_DEBUG = $(RESINC)
RCFLAGS_DEBUG = $(RCFLAGS)
LIBDIR_DEBUG = $(LIBDIR)
LIB_DEBUG = $(LIB)
LDFLAGS_DEBUG = $(LDFLAGS)
OBJDIR_DEBUG = obj/Debug
DEP_DEBUG =
OUT_DEBUG = bin/Debug/OpenGLTest
CXX_SRCS = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/**/*.cpp)
CXX_REL_SRCS = $(subst $(SRCDIR)/,,$(CXX_SRCS))
OBJS = $(CXX_REL_SRCS:%.cpp=%.o)
OBJ_DEBUG = $(addprefix $(OBJDIR_DEBUG)/,$(OBJS))
# ----------------------------- debug -----------------------------
clean: clean_debug clean_release
rm -rf $(DEPDIR)
before_debug:
#test -d bin/Debug || mkdir -p bin/Debug
#test -d $(OBJDIR_DEBUG) || mkdir -p $(OBJDIR_DEBUG)
#mkdir -p $(dir $(OBJ_DEBUG))
after_debug:
debug: before_debug out_debug after_debug
out_debug: before_debug $(OBJ_DEBUG) $(DEP_DEBUG)
$(LD) $(LIBDIR_DEBUG) -o $(OUT_DEBUG) $(OBJ_DEBUG) $(LDFLAGS_DEBUG) $(LIB_DEBUG)
$(OBJDIR_DEBUG)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CFLAGS_DEBUG) $(CXX_FLAGS) $(INC_DEBUG) -c $< -o $#
clean_debug:
rm -f $(OBJ_DEBUG) $(OUT_DEBUG)
rm -rf bin/Debug
rm -rf $(OBJDIR_DEBUG)
# ----------------------------- dependencies -----------------------------
# Generate dependencies in *.d files
$(DEPDIR)/%.d: $(SRCDIR)/%.cpp
#test -d $(DEPDIR) || mkdir -p $(DEPDIR)
#mkdir -p $(dir $#)
#set -e; rm -f $#; \
$(CXX) -MM $(CFLAGS) $(CXX_FLAGS) $(INC) $< > $#.$$$$; \
sed 's,\(.*\)\.o[ :]*,$(OBJDIR_RELEASE)/\1.o $(OBJDIR_DEBUG)/\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
# Include the *.d files
include $(patsubst %,$(DEPDIR)/%.d,$(basename $(CXX_REL_SRCS)))
# ----------------------------- targets -----------------------------
.PHONY: before_debug after_debug clean_debug
all: debug
shader.d:
obj/Debug/shader.o dep/engine/shader.d : src/engine/shader.cpp src/engine/shader.h \
src/engine/transform.h src/engine/camera.h src/engine/constants.h
I'll answer this since the issue has been found by #G.M. in the comments.
Turns out that the dependency generation was flawed.
In shader.d obj/Debug/shader.o should really be obj/Debug/engine/shader.o. Modifying the sed command as shown below fixes this.
sed 's,\(.*\)\.o[ :]*,$(OBJDIR_RELEASE)/$(subst $(SRCDIR)/,,$(dir $<))\1.o $(OBJDIR_DEBUG)/$(subst $(SRCDIR)/,,$(dir $<))\1.o $# : ,g' < $#.$$$$ > $#;

C++ Make file issue "No rule to make target ..."

I just started working with makefile.
I am getting the error with makefile of my C++ project.
make: No rule to make target 'bin/smartCart_app', needed by all.
Below is the directory structure and files associated with it.
VBOX:~BASE$ls
build src
VBOX:~BASE$cd build
VBOX:~BASE/build$ ls
bin build Makefile.sc
VBOX:~BASE/build$ cd ../src
VBOX:~BASE/src$ls
baseStation.cpp config util //config and util has header and cpp files
Here is my Make file
CC=gcc
CPP=g++
CCFLAGS=-g -Wall -std=gnu+0x -o0
CC_LDFLAGS = -g -Wl
BUILD=./build
BIN = ./bin
SC_SRC_ROOT = ../src
SC_SRC_SUBDIRS = config util
SC_SRC_RELDIRS = $(addprefix $(strip $(SC_SRC_ROOT)), $(strip $(SC_SRC_SUBDIRS)))
SC_SRCS_ = $(shell /usr/bin/find $(SC_SRC_ROOT)/config $(SC_SRC_ROOT)/util -name "*.cpp")
SC_SRCS = $(SC_SRCS_) baseStation.cpp
SC_NEW_SRCS = $(notdir $(SC_SRCS))
SPACE :=
SPACE +=
INCLUDE = $(addprefix -I, $(SRC_RELDIRS))
VPATH = $(subst $(SPACE),:,$(SRC_RELDIRS)) $(subst $(SPACE),:,$(SC_SRC_RELDIRS))
SC_INCLUDE = $(addprefix -I, $(SC_SRC_RELDIRS))
SC_OBJS = $(SC_NEW_SRCS:%.cpp=$(BUILD)/%.o)
SC_DEPS = $(SC_OBJS:%.o=%.d)
# Ensure paths exist.
$(shell [ -d "$(BIN)" ] || mkdir -p $(BIN))
$(shell [ -d "$(BUILD)" ] || mkdir -p $(BUILD))
# Explicit rules.
.PHONY: all clean $(PHONY)
all: $(BIN)/smartCart_app
clean:
#echo "Cleaning..."
-#rm -f $(BIN)/smartCart_app $(SC_OBJS)
$(SC_OBJS): $(BUILD)/%.o: %.cpp
#echo "Compiling $(notdir $<)"
#$(CPP) $(CCFLAGS) $(INCLUDE) $(SC_INCLUDE) -MD -c -o $# $<
$(MACRO_DEPS):
-#rm -f $(patsubst %_ON.d,%_OFF.d,$#) $(patsubst %_OFF.d,%_ON.d,$#) $#
#touch $#
#$(ALL_OBJS): %.o: %.d
$(DEPS): $(BUILD)/%.d: %.cpp
#$(CC) $< -MM -MF $# $(INCLUDE)

How to implement cleanall in when a common make file is used

Hi I am using common makefile.inc for my project. For my src folders, I define a makefile which sets some variables and includes makefile.inc. I can also define DIRS= variable (sample #2) which will call make -C on each one of the directories specified there. This all works. However, I cannot get a "clean" or "cleanall" to work properly. If DIRS= is defined, I need a way to go through all the directories listed and call "make -C xxx clean". Any ideas?
Sample makefile #1
TYPE = exe
SOURCES = test.cpp
INCLUDES = -I. -I/usr/local/include -I../src
LIBS = -lpcre
OUT = test
include ../../makefile.inc
Sample makefile #2
DIRS = src test
include ../makefile.inc
makefile.inc
OBJS = $(SOURCES:.cpp=.o)
ifeq ($(CFG),)
CFG=debug
endif
ifeq ($(CFG),debug)
CXXFLAGS += -g -Wall -DNDEBUG
else
CXXFLAGS += -O2 -Wall
endif
all: dirs cfgcheck $(OUT)
.PHONY: clean cleanall all
cfgcheck:
ifneq ($(CFG),release)
ifneq ($(CFG),debug)
#echo "Error: Invalid CFG '$(CFG)'' (options: debug,release)"
#exit 1
endif
endif
#echo "Making '$(CURDIR)' CFG="$(CFG)
$(OUT): $(OBJS)
ifeq ($(TYPE),lib)
$(AR) rcs $(OUT) $(OBJS)
endif
ifeq ($(TYPE),exe)
$(CXX) -o $# $^ ${LDFLAGS} $(LIBS)
endif
-include $(OBJS:.o=.d)
%.o: %.cpp
$(CXX) -c $(INCLUDES) $(CXXFLAGS) $*.cpp -o $*.o
$(CXX) -MM $(CXXFLAGS) $*.cpp > $*.d
#cp -f $*.d $*.d.tmp
#sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
#rm -f $*.d.tmp
dirs: $(DIRS)
$(DIRS):
$(MAKE) -C $#
clean:
rm -f $(OUT) *.o *.d
I'd do something like this:
DIRS = src test
clean: TARG:=clean
clean: $(DIRS)
.PHONY: $(DIRS)
$(DIRS):
#$(MAKE) -C $# $(TARG)
If you don't like using the names of directories as phony targets, there are alternatives that are slightly more complicated...