I am compiling some project with dependency so i won't have to recompile each time, but when i am adding -Dsome_flags to my CFLAGS, it is not recompiling.
dep: $(CPPS)
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
i add to my CFLAS -DDEBUG_FLAG and it forces me to do make clean and make instead of make.
It won't recompile because you don't have the makefile itself listed as a dependency.
dep: $(CPPS) Makefile
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
That said, if you're feeding in make flags from the command line (e.g. CFLAGS=-O3 make all), make has no way of detecting that you've changed those and forcing a full build.
The simplest, in my opinion, would be to do a make clean and then a make. This is of course assuming that you want all source files to be recompiled due to the change in compiler flags. But you seem to not like this method.
If you want to modify the makefile, you can add the name of your makefile to every rule for compiling source files, for example:
somefile.o : somefile.cpp <makefile_name>
$(CC) -c $(CFLAGS) somefile.cpp -o somefile.o
or
%.o : %.c <makefile_name>
$(CC) -c $(CFLAGS) somefile.cpp -o somefile.o
Given the size of the project, and the number of rules involved, doing a make clean; make may be the easiest and fastest method. However, as always, you mileage my vary.
Just my $0.02 worth, hope it helps
T.
Makefile looks for changes based on the data it has. Your Makefile states the only dependencies are defined under $(CPPS).
dep: $(CPPS)
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
So the make tracks the changes only within the given list, i.e., $(CPPS). So the resolution is:
dep: $(CPPS) Makefile
$(CC) $(CFLAGS) $(INC) -M $(CPPS) > dep
For complete but non-complex example, here is my Makefile for a helloworld program:
OBJS = helloworld.o
default: hw
%.o: %.c Makefile
gcc -c $< -o $#
hw: $(OBJS)
gcc $(OBJS) -o $#
clean:
-rm -f $(OBJS) hw
Everytime I change my makefile it gets recompile! :)
Related
I'm developing a parallel project with a Main.cpp and a set of .hpp files. I've found the Makefile below suitable to compile, deploy and execute my project on a Xeon Phi. The problem here is that if I edit only one of the .hpp (so not Main.cpp) then when I execute make compile obviously nothing happens (so I have to execute make clean before). Can you help me to change it so if I edit file.hpp then it will compile it? Thanks!
FF_ROOT = /home/luca/fastflow
BOOST_ROOT = /home/luca/boost_1_59_0
CC = icpc -mmic
CXX = $(CC) -std=c++11 -DNO_DEFAULT_MAPPING
INCLUDES = -I $(BOOST_ROOT) -I $(FF_ROOT)
CXXFLAGS =
LDFLAGS = -pthread
OPTFLAGS = -O3 -finline-functions -DNDEBUG -g -O0
TARGETS = \
Main \
.PHONY: all clean copy exec cleanall
.SUFFIXES: .cpp
%: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) $(OPTFLAGS) -o $# $< $(LDFLAGS)
all: compile
compile: $(TARGETS)
copy:
scp $(TARGETS) mic0:
exec:
ssh mic0 './$(TARGETS) $(ARGS)'
clean:
rm -f $(TARGETS)
cleanall : clean
\rm -f *.o *~
Your Makefile is blatantly not sufficient. At the moment it only contains the commands to translate from one input to the next, but it's missing the crucial ingredient of any build system: Dependencies.
Dependencies are hard to maintain by hand. You could add main: a.hpp b.hpp etc by hand, but that doesn't scale and you forget to update it when you refactor. That's why make is not usually something the user should use directly. make is a bit like assembler: it's the final level at which build rules are expressed, but creating the build rules is best left to a higher-level system (e.g. automake or cmake or any of the other competitors in the field; or even the old makedepend).
As a side note, you really don't want to build the binary directly from source, that defeats almost all points of having a Makefile. You really want to break your project into separately compiled translation units, so that you only rebuild the minimal amount after a change.
OBJS := a.o b.o c.o
main: $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $#
.cc.o:
$(CXX) $(CXXFLAGS) -c $< -o $#
# Dependencies! This is in addition to the implied "foo.o: foo.cc" above.
a.o: a.h b.h tools.h
b.o: b.h tools.h
c.o: c.h b.h weirdstuff.h
Many tutorials explain all this.
Add a rule for the source file where it depends on all (local, not system) header files.
Like
Main.cpp: SomeHeaderFile.hpp SomeOtherHeaderFile.hpp
As a follow-up question from here: My Makefile will do the linking, even if nothing is changed in the code. Why? How can I avoid that behaviour, so that make won't do anything if the code has not changed?
OBJS = main_no_mkl.o
SOURCE = main_no_mkl.cpp
HEADER = IO.h
OUT = test
CXX = ../../mpich-install/bin/mpic++
CXXFLAGS = -I../../intel/mkl/include -Wl,--start-group -Wl,--end-group -lpthread -lm -ldl -Wall
LDFLAGS = ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a -Wl,--start-group ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a ../../intel/mkl/lib/intel64/libmkl_sequential.a -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread -lm -ldl
all: $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
# create/compile the individual files >>separately<<
main_no_mkl.o: main_no_mkl.cpp
$(CXX) -c main_no_mkl.cpp $(CXXFLAGS)
.PHONY : all
The problem is your all target. It doesn't generate an all (and is marked .PHONY as well) file. Check this answer for a reminder about .PHONY. (You are violating the second Rule of Makefiles.)
So the second/etc time you run make (assume the .PHONY marking wasn't present) make would look for an all file, not find it, and assume it must need to create it again.
With .PHONY you short-circuit that file-finding logic and make just always assumes it needs to run the recipe again.
So, essentially, you've told make to always run the linking step so make does that.
Use this instead to fix that problem.
all: $(OUT)
$(OUT): $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
For the record running make -d and reading through the output would have pointed this out to you.
The objects are really the dependencies of your output, and your "all" target should depend on the output(s). So you should do something like this instead:
all: $(OUT)
$(OUT): $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
My make file is failing to find my include directory when it tries to remake object files. For example, when I call make tests I get the output:
g++ -c -o sdl_class.o sdl_class.cpp
sdl_class.cpp:9:23: fatal error: sdl_class.h: No such file or directory
#include <sdl_class.h>
^
compilation terminated.
make: *** [sdl_class.o] Error 1
My Makefile is this:
#Originally from: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
#But will be heavily modified
IDIR =../include
CC=g++
CFLAGS=-w -I$(IDIR)
#ODIR=obj
LDIR =../lib
LIBS=-lSDL2
_DEPS = sdl_class.h SDL_image.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
OBJ = sdl_class.o tests.o
#OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
%.o: %.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS) $(LIBS)
tests: sdl_class.o tests.o
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
all: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f *.o *~ core $(IDIR)/*~
My understanding is that when I call make tests, that it should attempt to remake the sdl_class.o file. This should then call the %.o rule, which should try to make the object file by calling something like:
g++ -c -o sdl_class.o sdl_class.cpp -w -I../include -lSDL2
However, this is not the case as it looks like it is calling $(CC) -c -o $# $< $(CFLAGS) $(LIBS), as you can see from above.
Do I have a fundamental misunderstanding about how make builds its rules? Seems likely, this is my first Makefile. Perhaps I am confused on how compilation works in general, as I'm somewhat new to that as well.
I would say that the problem is that one or more of the files ../include/sdl_class.h or ../include/SDL_image.h does not exist. Because of that, make is deciding that your pattern rule does not match (because not all the prerequisites can be found or made) and it defaults to the built-in rule to create object files from .cpp files.
The built-in rules use the make variables CXX for the C++ compiler and CXXFLAGS for the C++ flags: the CC and CFLAGS variables are used for the C compiler. That's why your settings for CFLAGS are being ignored.
If you run make -d sdl_class.o you'll see which file make is looking for and why it decides to not use your pattern rule.
If you rewrite your rules like this it will work better:
%.o: %.cpp
$(CC) -c -o $# $< $(CFLAGS)
sdl_class.o tests.o: $(DEPS)
because make will now complain that the relevant files can't be found or created.
There are other issues, of course. You shouldn't be passing $(LIBS) to your compile command; that belongs only in your link line. And, you should probably stick to the standard variables CXX for the C++ compiler, CPPFLAGS for preprocessor flags like -I and -D, and CXXFLAGS for C++ compiler flags. Also, linker library flags like -L../lib go in LDFLAGS and linker libraries like -lSDL2 go in LDLIBS.
CC/CCFLAGS are for C compilation. You should use CXX and CXXFLAGS for C++. They are used in built-in rules and in the LINK.cc macro, making the Makefile much simpler, and thus less error prone.
CXXFLAGS = -Wall ...
prog : foo.o bar.o
$(LINK.cc) -o $# $^
see Default linker setting in Makefile for linking C++ object files
I would like to try to establish a very small system of Makefiles. I have the following set up, but something is not quite right (this has been pieced together from reading a few SO posts about the topic, though somewhat project-specific, and some websites. I must not be catching something fundamental in having a "Makefile" call sub-makefiles.
This is even simpler than having the main Makefile call files in different subdirectories. Here are the following files I have prepared:
Makefile:
all:
$(MAKE) -f ./make_system.mk
$(MAKE) -f ./make_crc.mk
make_system.mk:
G = -g ## debug option
CC = gcc ## compiler
SRCS = source.c sink.c gateway.c
EXES = source sink gateway
OBJS = source.o sink.o gateway.o
CFLG =
LFLG =
LIB = #-lsocket -lnsl -lpthread
all: $(EXES)
%.o: %.c %.h
$(CC) -c $G $(CFLG) $<
source: source.o
$(CC) -o source source.o $(LIB) $(LFLG)
sink: sink.o
$(CC) -o sink sink.o $(LIB) $(LFLG)
gateway: gateway.o
$(CC) -o gateway gateway.o $(LIB) $(LFLG)
clean:
/bin/rm -f core *.o $(EXES) *~
make_crc.mk:
CC = gcc
CFLAGS = -g
LFLAGS =
HDR = crcmode.h
SRC = crcmodel.c crctest.c
OBJ = crcmodel.o crctest.o
EXE = crctest
all: $(EXE)
%.o: %.c %.h
$(CC) -c $(CLFAGS) $<
$(EXE): $(OBJ)
$(CC) $(LFLAGS) $(OBJ) -o $(EXE)
clean:
/bin/rm -f *.o *~ core $(EXE)
How would I set up Makefile to call the smaller sub-makefiles (of type *.mk)? This is a basic but important first step towards working with larger scale makefile systems (there is the manual to consult, though I do not think it has explicit basic examples). If someone who has done this could show me a small Makefile vignette, this would be greatly appreciated (again, this makefile system can exist within the same local directory).
Note: The individual makefiles "make_system" and "make_crc" work fine when they are themselves named "Makefile", but I want to try to call them as separate sub-makefiles with one single overall Makefile.
ADDENDUM (to solution below):
Once I implemented Carl's solution shown below, I realized that you need to always include some form of "make clean" or at least enter at in the command line before calling your Makefile. Otherwise, you see the appropriate output "nothing to be done". This was something I knew before, but neglected to do this time around (easy check: just look at your directory and you will see you have executables in the environment/directory).
I you want to "forward" the target, you'll need to do it explicitly. Something like this example should work (though I can't test easily right now, sorry):
default: all
%:
$(MAKE) -f ./make_system.mk $#
$(MAKE) -f ./make_crc.mk $#
I was looking for a solution on this site and also tried google for some time now, but somehow I can't get it to work.
My source should be in the src directory and the object files would be in the obj directory. Now I try to create a simple makefie but I either get an error that there is no rule, or I can't make it work to use the directories.
CC = /usr/bin/gcc
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
SRC:= nohupshd.cpp \
task.cpp
OBJ:= nohupshd.o \
task.o
OBJDIR:= obj
SRCDIR:= src
DEP:= src/task.h
LIBS:=
TARGET:= nohupshd
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(LIBS)
clean:
rm -f $(OBJ) $(TARGET)
Variant 1:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
Variant 1a:
%.o: %.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
When I use this pattern I always get an error that there is no rule for nohupshd.o to build.
Variant 2:
$(OBJ) : $(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $(SRCDIR)/$< -o $(OBJDIR)/$#
$(CC) -c $(SRCDIR)/$< -o $(OBJDIR)/$#
When I use this variant, I can see that it tries to build, but I get errors saying that "file".o doesn't fit the target pattern.
Another issue is that "$<" doesn't give me the source name. According to several sites it should, but I can see in the output that there is nothing, so how can I fix this?
Update:
In the meantime my newest version looks like this:
$(OBJDIR)/$(OBJ) : $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) -S $< -o $(OBJDIR)/`basename $# .o`.asm
$(CC) -c $< -o $#
This now manages to compile the first objectfile (nohupshd.o) but when make tries to do the second file it fails again saying: target 'task.o' doesn't match a pattern.
You actually have a couple if incorrect things above.
First you write My error was, that I was assuming that the pattern %.o matches ANY pattern ending with .o which it doesn't; that's not true. The pattern does match any string ending in .o. However, the pattern character % that is matched on the target side is replaced on the prerequisite side with the identical string. So if you have a target obj/task.o and it matches the pattern %.o then the stem (what the manual calls it) will be obj/task, and when the prerequisite is %.c that means that make will look for a prerequisite obj/task.c. Since there isn't one, and make doesn't know how to build one, that rule is discarded as not applying. When writing pattern rules you must write them so ONLY the identical parts of the names match the pattern character (%). ALL non-identical parts, including directories, must be specified explicitly.
Second, the rule $(OBJ) : $(SRC) is really not right. That line says that each object file depends on all the source files, so whenever any single source file changes all the object files will be recompiled. That's really not what you want (if that IS what you want you don't need make: you can just write a simple shell script). I don't know what you mean by since the rules is empty it invokes the pattern rule; you don't need this to invoke the pattern rule. The target depends on $(OBJ), and each object file depends on its source file (due to the pattern). You don't need this line at all.
Third, I don't know why you are trying to construct .asm files rather than just compiling directly from source to object, but if you really want them it would be cleaner and more "make-like" to create a separate pattern rule to build them: create a pattern rule $(OBJDIR)/%.o : $(OBJDIR)/%.asm and a rule $(OBJDIR)/%.asm : $(SRCDIR)/%.c. If you want the ASM files to be products of the build you should declare them as a prerequisite of all or similar, otherwise they'll be deleted as intermediate files.
Fourth, using things like basename is unnecessary. There are lots of automatic make variables that can be used instead. For example, $* expands to the stem, so you could write $(OBJDIR)/$*.asm. Of course if you make a separate pattern rule for ASM files you can just use $# or $< directly. There are various make functions that can also be used; see the manual.
Fifth, you define a variable containing a header file, DEP, but then never use it. Because it's not used, if you change that file nothing would be rebuilt. If you know that all the source files include every header you can use $(OBJ) : $(DEP) to define that; but it does mean (as in the second point above) that any change to any header causes all objects to recompile. You would be better off auto-generating the prerequisites; since you're using GCC this is quite simple.
Sixth, you're using C++ files (xxx.cpp) but you're using the C compiler. This will not work (the link line will fail: although the compiler can see you're compiling a C++ file and do the right thing, even if you call gcc, when you link a bunch of objects together it has no idea if those were C objects or C++ objects (or FORTRAN or whatever) so you MUST use the C++ front-end to link or it won't pull in the right C++ libraries). You should be using the make variable CXX to build C++ code, not CC, and setting it to g++ not gcc.
Seventh, you don't need .SUFFIXES: .c .o to use pattern rules. They are only needed for suffix rules, which you don't have here. You can keep the plain .SUFFIXES: though to disable built-in pattern matching which is a slight performance improvement.
Finally, you'll note you don't actually need the $(SRC) variable because make can infer it from the pattern rules. However, if you wanted to have your makefile less onerous to change, you could construct the contents of the OBJ variable from the SRC variable, like SRC = nohupshd.cpp task.cpp then OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(SRC)).
So, all-in, this is how I would recommend you write your makefile (I don't include the auto-generated dependencies here though):
.SUFFIXES:
CXX := g++
CXXFLAGS := -O2 -g -Wall -fmessage-length=0
OBJDIR := obj
SRCDIR := src
TARGET := nohupshd
SRC := nohupshd.cpp task.cpp
DEP := src/task.h
LIBS :=
# ----
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SRC))
ASM := $(patsubst %.cpp,$(OBJDIR)/%.asm,$(SRC))
.PHONY: all clean
all: $(TARGET) $(ASM)
$(TARGET): $(OBJ)
$(CXX) -o $# $^ $(LIBS)
clean:
rm -f $(OBJDIR)/* $(TARGET)
$(OBJDIR)/%.o : $(SRCDIR)/%.asm
$(CXX) $(CXXFLAGS) -c -x assembler-with-cpp $< -o $#
$(OBJDIR)/%.asm : $(SRCDIR)/%.cpp
$(CXX) $(CPPFLAGS) -S $< -o $#
Don't repeat the directory names in the compiler line. $< and $# already have the directory names.
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -S $< -o $#
$(CC) -c $< -o $#
So finally I found the answer on how to write this makefile, for an exaplanation of my mistakes look at the posting I marked as correct answer:
The resulting makefile looks like this, and for completeness I post it here including dependencies for header files (remove the ASM parts if you don't need 'em):
.SUFFIXES:
.SUFFIXES: .o .cpp
.SUFFIXES: .o .d
CC := g++
LNK:= ar
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJDIR:= obj
SRCDIR:= src
HDIR:= include
INCLUDE_PATHS:= -Iinclude -Iinclude/interfaces -Iinclude/support
CPP_FILES := propertyfile/propertyfile.cpp \
propertyfile/propertyitem.cpp \
propertyfile/propertyfactory.cpp
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC := $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))
ASM := $(patsubst %.cpp, $(OBJDIR)/$*.asm, $(CPP_FILES))
LIBS:=
TARGET:= libsupport.a
all: $(TARGET)
$(TARGET): $(OBJ)
#echo "Linking..."
#$(LNK) rvs $(TARGET) $(OBJ)
#cp $(TARGET) ../lib
#cp -r include ..
clean:
rm -f $(OBJ) $(ASM) $(TARGET)
-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -S $< -o $(OBJDIR)/$*.asm $(INCLUDE_PATHS)
$(CC) $(CXXFLAGS) -c $< -o $# $(INCLUDE_PATHS)
$(OBJDIR)/%.d: $(SRCDIR)/%.cpp
$(CC) $(CXXFLAGS) -MM -MT $# -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)
I hope this helps other user. All examples that I found were either extremly simple and listed multiple files individually and not part of a rule, but didn't really explain how it works, or were so complicated that I couldn't find out how it can help me.