Makefile target gets called twice - makefile

I have the following Makefile:
VERSION = 0.1.1
CC = g++
CFLAGS = -Wall -g -DVERSION=\"$(VERSION)\"
LDFLAGS = -lm
DEPFILE = .dep
SOURCES := ${wildcard *.cpp}
HEADERS := ${wildcard *.h}
OBJECTS := ${SOURCES:.cpp=.o}
BINARY = main.exe
.PHONY: all dep clean
all: $(BINARY)
$(BINARY): $(DEPFILE) $(OBJECTS)
$(CC) $(CFLAGS) -o $(BINARY) $(OBJECTS) $(LDFLAGS)
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
dep: $(DEPFILE)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $(DEPFILE)
-include $(DEPFILE)
clean:
rm -vf $(BINARY) $(OBJECTS) $(DEPFILE)
When I run make dep I get
g++ -MM Monomial.cpp main.cpp Variable.cpp > .dep
make: Nothing to be done for 'dep'.
It seems as if dep is called twice. Why is that?
I am using GNU Make 4.2.1 under Cygwin.
Also it would be great if you could give me some best practises for this Makefile if you spot some bad design patterns (other than the double call of dep).

Your makefile contains an include directive:
-include $(DEPFILE)
So when Make starts, before it even considers the target(s) you've asked it to build, it tries to rebuild the file that is to be included in the makefile. Once it's done rebuilding .dep, it gets to work on the file you asked for... which is .dep.
You probably don't have to explicitly make dep, ever.
And you can simplify a couple of your rules in light of this fact, and the useful nature of automatic variables:
$(BINARY): $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $#

Related

How to compile source objects into another directory and then build an executable?

Good day. I am in a directory, where is Makefile and folders src and bin. How can I compile object files into bin folder and then build an executable file?
I read some instructions and added $(BIN) before %.o, but it didn't helped, object files appear in folder with makefile. Where is the problem?
CC = arm-linux-gnueabihf-gcc
CXX = arm-linux-gnueabihf-g++
CPPFLAGS = -I .
CFLAGS =-g -std=gnu99 -O1 -Wall
CXXFLAGS = -g -std=gnu++11 -O1 -Wall
LDFLAGS = -lrt -lpthread
SRCDIR = src
BIN = bin
SOURCES = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.c)*
...
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
#$(warning OBJECTS=$(OBJECTS))
ifeq ($(filter %.cpp,$(SOURCES)),)
LINKER = $(CC)
LDFLAGS += $(CFLAGS) $(CPPFLAGS)
else
LINKER = $(CXX)
LDFLAGS += $(CXXFLAGS) $(CPPFLAGS)
endif
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
all: $(TARGET_EXE)
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
.PHONY : dep all run copy-executable debug
dep: depend
depend: $(SOURCES) *.h
echo '# autogenerat`enter code here`ed dependencies' > depend
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) connect.gdb depend
...
It's not clear to me how this makefile can works as well as it does, given that you haven't told it where to find the source files (unless you do so in one of the elided sections).
In these rules:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
you tell the compiler to build object files, but you don't specify where to build them, and the default is to build them in the working directory. You can override that with the -o option:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $< -o $#
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
Once you have the object files where you want them (bin/), you must ensure that the linking rule:
$(TARGET_EXE):$(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
can find them. The best way to do that is to ensure that OBJECTS contains the correct paths to the object files. I'm not sure how to advise you to do that, since from the look of your makefile that variable might not contain what you think it does.
EDIT:
Let's take this in stages.
Suppose we have on source file, src/foo.c. What we want is:
src/foo.c -> bin/foo.o
bin/foo.o -> foo
This requires two rules, which we can write like this:
$(BIN)/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET_EXE): bin/foo.o
$(LINKER) $(LDFLAGS) -L. $^ -o $#
We actually have many source files, some of which are C++ files. So we must have a rule for them:
$(BIN)/%.o: src/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
and construct a longer list of objects:
OBJECTS := bin/foo.o bin/bar.o bin/baz.o bin/quartz.o...
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
(Mixing C and C++ seems unhealthy to me, but never mind.)
And how do we construct that list of objects? We must start with the list of sources which wildcard can produce:
SRC := src
C_SOURCES := $(wildcard $(SRC/*.c)
# this is src/foo.c src/bar.c
SRC := src
CPP_SOURCES := $(wildcard $(SRC/*.cpp)
# this is src/baz.cpp src/quartz.cpp
and then convert them to the object file names we actually want:
BIN := bin
OBJECTS := $(patsubst $(SRC)/%.cpp,$(BIN)/%.o, $(CPP_SOURCES))
OBJECTS += $(patsubst $(SRC)/%.c,$(BIN)/%.o, $(C_SOURCES))
# this is bin/foo.o bin/bar.o bin/baz.o bin/quartz.o
That should give you the effect you want, and if you understand it you will understan why your old makefile did not.

Why I don't need to add prerequisite ".depend" in this make file?

I have a make file I wrote which represents a simple example of auto-detecting if a header file is changed using .depend generated by gcc -MM -MF.
Consider the following makefile: We have main.c and factorial.h
CC=gcc
CFLAGS=-c -Wall
OBJECTS=main.o
SRCS=main.c
EXECUTABLE=program
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXECUTABLE)
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
sinclude .depend
#main.o: main.c factorial.h
clean:
rm -rf *.o $(EXECUTABLE) .depend
This works fine and I want to know why!
The common sense is to write
$(EXECUTABLE): $(OBJECTS) .depend
because we want to make sure the file .depend is there. However, it seems like omitting it works fine, too. Why? Also, I'd like to know what include (or sinclude in this case) actually does. I think: in our example, include .depend would be replaced by
main.o: main.c factorial.h, but again the workflow doesn't make sense. Any experts?
Make will automatically try to remake the target of an include directive
[...]after reading in all makefiles, make will consider each as a goal target and attempt to update it.
The line sinclude .depend tells make "Read in .depend, don't quit if it fails, look for any matching rules, and remake .depend if it's out of date."
In any case you should create dependencies as a side effect of compilation, there's really no need for the extra step
target := program
sources := main.c
objs := $(sources:.c=.o)
deps := $(objs:.o=.d)
CPPFLAGS := -MMD -MP
CFLAGS := -Wall
$(target): $(objs)
$(LINK.o) $^ $(LDLIBS) -o $#
clean: ; $(RM) $(target) $(objs) $(deps)
-include $(deps)

How to write a makefile for llvm IR

If I have 3 files, function.h, function.c and my_program.c which calls a method in function.h all in the same directory, what would be the best way to write a makefile so that I end up with a my_program.bc that would actually run when I type in lli my_program.bc? (I need to run a user defined pass that would insert stuff into the functions - should I run the pass on function.bc and test.bc, or should I link before running the pass?)
I've tried llvm-link function.bc my_program.bc with no luck. I feel I'm either missing something simple or going about the whole thing wrong.
Current terrible none-working makefile:
.PHONY: all clean
CC = clang
CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200809L -g -Wall
IRFLAGS = -O3 -emit-llvm
TARGET = test
DEPS = functions.h
all: $(TARGET)
bc: test2
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
%.bc: %.c $(DEPS)
$(CC) $(IRFLAGS) -c -o $# $<
test2: test.bc functions.bc
llvm-link -o test2.bc $< functions.bc
test: test.o functions.o
$(CC) $(CFLAGS) -o $# $^
clean:
$(RM) $(TARGET) *.o *.bc
Why not just write a normal Makefile to produce the desired executable,
then use wllvm?
Shameless plug for wllvm:
https://github.com/SRI-CSL/whole-program-llvm
I do not use lli, so I would be interested to hear about how it resolved
any reliance on stdlibc that your program may have.

Makefile does not work properly

I've this folder structure
project
|_src
| |_test
| |_main.cpp
|_Makefile
This is my makefile (trying to adapt from this link):
CC = g++
RM = rm
WFLAGS = -c -Wall -W
LDFLAGS =
SRCTESTD = src/test
EXECUTABLE = test
OBJD = .obj
DEPD = .dep
SRCSTEST = $(SRCTESTD)/main.cpp
OBJECTSTEST = $(patsubst %.cpp, $(OBJD)/test/%.o, $(notdir $(SRCSTEST)))
DEPDSTEST = $(patsubst %.cpp, $(DEPD)/test/%.d, $(notdir $(SRCSTEST)))
all: $(SRCSTEST) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTSTEST)
$(CC) $(LDFLAGS) $(OBJECTSTEST) -o $#
.cpp.o:
$(CC) $(WFLAGS) $< -o $#
It does not work, and I've this error
make: *** No rule to make target `.obj/test/main.o', needed by `test'. Stop.
What I'm doing wrong? Sorry for trivial question, but I'm a make newbie.
The link shows outdated methods, such as suffix rules. Making dependencies can also be done during compilation by gcc/g++.
As for the rest, here is it :
EXE := test
SRCDIR := src
OBJDIR := .obj
SRC := $(shell find $(SRCDIR) -name "*.cpp")
OBJ := $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEP := $(OBJ:.o=.d)
LDLIBS := # -l flags
LDFLAGS := # -L flags
CPPFLAGS := -MMD -MP # -I flags also
CXXFLAGS := -W -Wall # no -c flag here
.PHONY: all clean fclean re
all: $(EXE)
clean:
$(RM) -r $(OBJDIR)
fclean: clean
$(RM) $(EXE)
re: fclean all
-include $(DEP)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
#mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
No redefinition of internally defined variables, no suffix rules, correct linking step and dependencies generation.
Update: To avoid calling mkdir for every source file, one should use order-only prerequisites and the special target .SECONDEXPANSION.
Change this block:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
#mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
To this:
.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(#D)/
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
%/:
mkdir $*
The error means make can't find a correct rule to build your object files. Your tree structure lacks some informations: only one file ? Where are the others ? Anyway, here are some hints:
In the last two lines, you are using an obsolete feature of make: suffix rules. I suggest you switch to a pattern rule, which is functionaly equivalent.
Say something like:
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
Another thing (that shouldn't be a problem here): you are using the variable CC which is internally defined as the default C compiler. It's okay because you redefine it, but as your sources seem to be C++ files, why not use the variable CXX, that is internally defined as the C++ compiler ?
Lastly, to make sure your set of files are correctly defined, you can print them with a dummy show target, see here.
show:
#echo "OBJECTSTEST=$(OBJECTSTEST)"
...

Simple Makefile not taking include path

following is my makefile. but It is not taking include path during build.
SHELL = /bin/sh
CC = g++
FLAGS =
CFLAGS = -fPIC
TARGET = my_bridge.so
INC=-I/my_custom_path/include/ -I/my_custom_path/include/linux
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.cpp=.o)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(INC) $(CFLAGS) -o $(TARGET) $(OBJECTS)
When I build i get following line
g++ -c -o my_bridge.o my_bridge.cpp
Your $(TARGET): $(OBJECTS) rule tells make how to generate my_bridge.so out of my_bridge.o, but you haven't given a rule that explains how to make my_bridge.o in the first place. make relies thus on its implicit rules for that, which gives you the command that you see. You can either define your own rule to compile .cpp files, e.g.
%.o: %.cpp
$(CC) $(FLAGS) $(INC) $(CFLAGS) -o $# $<
or put your include directive in $(CXXFLAGS), which is used by make's default rule (see https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules)

Resources