How to do this in makefile? - makefile

Here is my makefile :
BIN = ../mylib.a
CXX = g++5
CFLAGS = -O2 -pipe -mtune=i686 -g
#################################
default:
#echo 'Compiling socket' ; $(CXX) $(CFLAGS) -c socket.c
#echo 'Compiling fdwatch'; $(CXX) $(CFLAGS) -c fdwatch.c
#echo 'Compiling signal' ; $(CXX) $(CFLAGS) -c signal.c
#echo 'Compiling heart' ; $(CXX) $(CFLAGS) -c heart.c
#echo 'Create library static'; ar cru $(BIN) *.o
#echo 'Compiling'; ranlib $(BIN)
#echo 'Delete .obj files'; rm -f *.o
So this is my question..
Let's say I have 100 files. I want to compile them.
And I make changes in a particular file.
When I run the command make all those files from 0. And it rebuilds have to wait again until all those it rebuilds.
Now I want to ask how they can change that makefile above that to recompile just that file changed me.

How about
.PHONY: all clean
BIN = ../mylib.a
CXX = g++5
CFLAGS = -O2 -pipe -mtune=i686 -g
#################################
SOURCEFILES=socket.c fdwatch.c signal.c heart.c
all: $(BIN)
clean:
#echo Delete .obj files
#rm -f *.o
%.o: %.c
#echo Compiling $*
#$(CXX) $(CFLAGS) -c $^ -o $#
$(BIN): $(SOURCEFILES:%.c=%.o)
#echo Create static library
#ar cru $(BIN) $^
#echo Compiling
#ranlib $(BIN)
?

Related

Why is Makefile relinking?

I was trying to make a more complex Makefile with a src dir and a obj dir.
But doing that the Makefile is now relinking, and I don't understand why.
NAME = program
SRC = main.cpp
SRC_DIR = src/
OBJ = $(SRC:.cpp=.o)
OBJ_DIR = obj/
CC = c++
CFLAGS = -Wall -Werror -Wextra -std=c++98 -fsanitize=address
all: $(NAME)
$(OBJ): $(OBJ_DIR)
$(CC) $(CFLAGS) -c $(SRC_DIR)$(SRC) -o $(OBJ_DIR)$(OBJ)
$(OBJ_DIR):
mkdir $(OBJ_DIR)
$(NAME): $(OBJ)
$(CC) $(CFLAGS) $(OBJ_DIR)$(OBJ) -o $(NAME)
clean:
rm -rf $(OBJ_DIR)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
OBJ = $(SRC:.cpp=.o)
This becomes main.o
$(OBJ): $(OBJ_DIR)
$(CC) $(CFLAGS) -c $(SRC_DIR)$(SRC) -o $(OBJ_DIR)$(OBJ)
and this becomes:
main.o: obj/
c++ [options] -o obj/main.o
This will result in the compiler creating obj/main.o. main.o still does not exist. So, on the next make run, make will valiantly try to build it, with the same results (not to mention that an explicit dependency on a directory will create its own set of problems, too).

How can I store my .o files in a sepparate folder?

INCDIR=include
SRCDIR=src
SRC = $(wildcard $(SRCDIR)/*.cpp)
DEPS = $(wildcard $(INCDIR)/*.h)
OBJ = $(SRC:.cpp=.o)
CFLAGS = -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC=g++
preprocessor: $(OBJ)
$(CC) $(OBJ) -o $# $(CFLAGS)
$(SRCDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) $^ -o $#
clean:
rm $(SRCDIR)/*.o preprocessor
This is my current makefile, if I wanted to store my .o files in a sepparate directory, src/obj for example, how would I have to modify it?
Many ways to do it, but according to your own code, you could do:
INCDIR=include
SRCDIR=src
OBJDIR=obj
SRC= $(wildcard $(SRCDIR)/*.cpp)
DEPS= $(wildcard $(INCDIR)/*.h)
OBJ=$(patsubst %.cpp, $(OBJDIR)/%.o, $(notdir $(SRC)))
CFLAGS= -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC=g++
$(OBJDIR):
#if ! [ -d $(#) ]; then\
echo "==> creating dir: $(#)";\
mkdir $(#);\
fi
preprocessor: $(OBJDIR) $(OBJ)
$(CC) $(OBJ) -o $# $(CFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) $^ -o $#
clean:
rm $(OBJDIR)/*.o preprocessor
printobj: $(OBJDIR)
#echo "$(OBJ)"
will output:
$ gmake preprocessor
g++ -c -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion src/a.cpp -o obj/a.o
g++ -c -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion src/b.cpp -o obj/b.o
g++ obj/a.o obj/b.o -o preprocessor -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion
NOTE: the target printobj is just here to output what you could expect, the target $(OBJDIR) ensure your directory exist before creating object files.
The are just a few things to change:
INCDIR := include
SRCDIR := src
OBJDIR := $(SRCDIR)/obj
SRC := $(wildcard $(SRCDIR)/*.cpp)
DEPS := $(wildcard $(INCDIR)/*.h)
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRC))
CFLAGS := -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC := g++
preprocessor: $(OBJ)
$(CC) $^ -o $# $(CFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $(OBJDIR)
$(CC) -c $(CFLAGS) $< -o $#
$(OBJDIR):
mkdir -p "$#"
clean:
rm -f $(OBJ) preprocessor
Note some other minor modifications:
the | $(OBJDIR) order-only prerequisite and the $(OBJDIR): rule to ensure the objects directory exists before compiling,
:= instead of = for all make variable assignments because you don't need recursively expanded variables here,
$^ instead of $(OBJ) in the link recipe because using automatic variables in recipes makes them more generic,
$< instead of $^ in the compile recipe because you compile only the first prerequisite, not all of them,
rm -f $(OBJ) preprocessor instead of rm $(SRCDIR)/*.o preprocessor to remove only the object files of the project and avoid errors if none exists.

Why does my Makefile with pattern rules not create debugging symbols for main?

I am using this auto-generated Makefile with pattern rules, that I oviously do not understand yet. I want to create debuggins symbols and then debug main, but it doesn't work. There is a -g flag. Adding $(LDFLAGS) statement above after $(ODIR) does not print one as expcted.
IDIR =./include
CC=g++
CFLAGS = -I$(IDIR)
LDFLAGS = -g
ODIR=./
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c
$(CC) -c -o $# $< $(CFLAGS)
main: $(OBJ)
$(CC) $(LDFLAGS) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o
This is the terminal output
g++ -c -o Source.o Source.cpp
g++ -g -o Source Source.o -I./include
Your sources are C++ (.cpp) but your Makefile contains explicit instructions for building C files. Make is therefore falling back to its built in implicit rules.
Also note that by convention those rules use $(CXX) to refer to the C++ compiler, with $(CXXFLAGS) replacing $(CFLAGS), and the -I flag belongs in $(CPPFLAGS):
IDIR =./include
CPPFLAGS = -I$(IDIR)
CXXFLAGS = -g
ODIR=.
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.cpp
$(CXX) -c -o $# $(CPPFLAGS) $(CXXFLAGS) $<
main: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJ)
If you were to do away with the ODIR handling and use the conventional variable names you could do without the explicit .o: .cpp rule altogether.

How to copy target file to a sub folder in Makefile?

In this Makefile- I want to copy the $(TGT) binary file after compiled to a sub folder(test) in the same directory. How can I include the copy command of the compiled target file in the Makefile?
CC = g++
CFLAGS = -ansi -std=c++11
LIBS = -L/usr/lib -lstdc++
DEPS = foo.cpp
OBJ = foo.o
TGT+=foo
%.o: %.cc $(DEPS)
$(CC) -c $< $(CFLAGS) -o $#
all: $(TGT)
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
# TODO: Need to include the copy command for copying TGT to test folder.
clean:
rm -f *.o $(TGT)
Currently the folder structure is-
<foo>
Makefile
foo.cpp
foo.h
<test>
<..Need "foo" inside this folder>
Is there some reason you can't just change the recipe to copy the file?
Change:
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
To:
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
cp $# test
You can easily add a rule to copy a file:
all: test/$(TGT)
test/$(TGT): $(TGT)
cp $< $#

How to change gcc compile message in makefile

I am new to programming.
I need to help me with hiding a message in makefile.
Let me show you:
When compiling this set of files(grid.cc attribute.cc targa.cc) http://prntscr.com/67ack4
I see this message: gcc5 -Wall -O2 -pipe -mtune=i686 -c attribute.cc
And I want to defend me something like: Compilation targa.cc
And I want to defend me something like: Compilation attribute.cc
etc
etc ...
I hope you understand what I mean.
Here is my makefile :
BIN = ../libgame.a
CXX = gcc5
CFLAGS = -Wall -O2 -pipe -mtune=i686
OBJFILES = grid.o attribute.o targa.o
########################################################################################################
default:
$(CXX) $(CFLAGS) -c grid.cc
$(CXX) $(CFLAGS) -c attribute.cc
$(CXX) $(CFLAGS) -c targa.cc
ar cru $(BIN) $(OBJFILES)
ranlib $(BIN)
rm -f *.o
You can use an automake-style silent rules trick to control what is output for your commands.
To do this directly you would do this:
BIN = ../libgame.a
CXX = gcc5
CFLAGS = -Wall -O2 -pipe -mtune=i686
OBJFILES = grid.o attribute.o targa.o
########################################################################################################
default:
#echo 'Compiling grid.cc';$(CXX) $(CFLAGS) -c grid.cc
#echo 'Compiling attribute.cc';$(CXX) $(CFLAGS) -c attribute.cc
#echo 'Compiling targa.cc';$(CXX) $(CFLAGS) -c targa.cc
ar cru $(BIN) $(OBJFILES)
ranlib $(BIN)
rm -f *.o
Alternatively you could use my silent_rules.mk and use:
$(eval $(call vrule,Compile,Compiling $$(value 1))
$(call Compile,grid.cc);$(CXX) $(CFLAGS) -c grid.cc
$(call Compile,attribute.cc);$(CXX) $(CFLAGS) -c attribute.cc
$(call Compile,targa.cc);$(CXX) $(CFLAGS) -c targa.cc
to get Compiling grid.cc, Compiling attribute.cc and Compiling targa.cc messages instead. (If you were using proper targets for your object files you could use the default $(GEN) silent rule to get GEN xxx.o output automatically.

Resources