Trouble creating a makefile - makefile

I'm having some trouble making a Makefile. Write now I just compile everything every time. Although, the professor is ok with that, I do want to get it working faster and to avoid unnecessary compiling.
Here's what I have.
FILES= p6.cpp SetIter.cpp Node.cpp Set.cpp
CFLAGS= -ansi -pendantic -Wall -Wextra
CC= g++
MakePg6: p6.cpp SetIter.cpp Node.cpp Set.cpp
$(CC) $(CFLAGS) $(FILES) -o pg6
Node.cpp - node class
Set.cpp - uses nodes. Friend of Node.
SetIter.cpp - gets a set and uses a pointer to iterator through
I'm confused with some of the depencies arising from the friends thing and the point of lib.o being included in the Makefile as some sites have.
Any help is greatly appreciated. Thanks in advance.

You can simplify you make file, but using the $(FILES) in the dependency of MakePg6 thus:
MakePg6: $(FILES)
$(CC) $(CFLAGS) $(FILES) -o pg6
The friend part is resolved by each c++ is compiled independently, and the header files define all the information need to compile that one file. The compiler enforces the friend rules. The linker weaves the resulting object together to make the resulting executable.
The lib.o is include because people are making use of standard code provided by the base library. You get linking error's if you missing stuff.

What about trying to separate the making of files, so as to rebuild each one only if needed.
OBJECTS= p6.o SetIter.o Set.o Node.o
.cpp.o: $*.cpp
$(CC) $(CFLAGS) -cpp $*.cpp
p6.o: p6.cpp SetIter.cpp // any file that it depends on
SetIter.o: SetIter.cpp Set.cpp //etc
Set.o: Set.cpp Node.cpp
Node.o: Node.cpp
p6: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o
MakePg6: p6
In doing that, it will build each object file only if the .o file is older than the .cpp file, and I think that's what you are trying to accomplish.

If your Makefile works as written, then you must have the header files (e.g. Node.h) set up correctly. So the different files can be compiled separately and linked, but whether you do that or not you must account for dependencies on the header files.
OBJECTS= p6.o SetIter.o Node.o Set.o
CFLAGS= -ansi -pendantic -Wall -Wextra
CC= g++
# This will compile any object file (something.o) that is called for
# Note that I am using automatic variables-- "$<" means the first prerequisite
# (the .cpp file), "$^" means all the prerequisites, and "$#" means the target.
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
# If A.cpp (or A.h) includes B.h, then if you change B.h you must recompile A.o,
# So A.o depends on B.h.
# I will make some educated guesses about how you include header files:
SetIter.o Node.o Set.o: Node.h
Set.o: Set.h
SetIter.o p6.o: Set.h SetIter.h
# This will link the object files together to make pg6.
# Notice that the target is the name of thing actually made, a good practice.
pg6: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#
You have to work out those .h dependencies by looking at the code. There are ways to have g++ and Make do it automatically, but that's an advanced technique.

Related

Makefile - recompile

My makefile always recompiles everything in directory if one header is changed. It's not a problem now but since I'm adding more to my program this is becoming and issue. I don't want to wait for a whole recompile if I add a new variable to a header of a separate class object.
Here is my makefile:
CXX = g++
CPPFLAGS = -I -lm -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system
OBJ = CR_Main.o CarRental.o CR_Button.o CR_LoginMenu.o CR_TextBox.o CR_UserCreation.o CR_CheckBox.o
DEPS = CarRental.hpp CR_Button.hpp CR_LoginMenu.hpp CR_TextBox.hpp CR_UserCreation.hpp CR_CheckBox.hpp
%.o: %.cpp $(DEPS)
$(CXX) -c -o $# $< $(CPPFLAGS)
CRC.exe: $(OBJ)
$(CXX) -o $# $^ $(CPPFLAGS)
.PHONY: clean
clean:
del *.o *.exe
Thanks in advance!
EDIT:
I was wondering why is it compiling everything in my directory if only 1 out 6 .hpp files are modified on one line? Is something wrong with my makefile or is that how it is?
why is it compiling everything in my directory if only 1 out 6 .hpp files are modified on one line? Is something wrong with my makefile or is that how it is?
"Wrong" might be too strong a word, but yes, the behavior you describe is a consequence of how your makefile is written.
This rule ...
%.o: %.cpp $(DEPS)
$(CXX) -c -o $# $< $(CPPFLAGS)
... says, roughly, that you can build .o files from corresponding .cpp files plus all the files named in variable DEPS. This implies that if that's the rule make selects for building a given .o file, and any of those prerequisites is newer than the target, then the target is out of date and needs to be rebuilt. You have named all your headers in DEPS and you have not provided any other rules for building .o files, so yes, if any of your headers changes, all of the .o files will be rebuilt.
The most simple-minded alternative would be to write a separate rule for each .o, naming the prerequisites of that file only. That is, the corresponding .cpp file and whichever headers it #includes, directly or indirectly.
But you can save yourself a little typing by instead removing the $(DEPS) part from your existing rule, and adding an additional rule for each .o that does not have a recipe but names all the header prerequisites for that file.
Or if, as it appears, you have consistent relationships between source file names and header names, you might do something like this:
CXX = g++
CPPFLAGS = -I.
LIBS = -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -lm
MAIN_OBJ = CR_Main.o
MODULE_OBJS = CarRental.o CR_Button.o CR_LoginMenu.o CR_TextBox.o CR_UserCreation.o CR_CheckBox.o
$(MAIN_OBJ): CR_Main.cpp $(MODULE_OBJS:.o=.h)
$(CXX) $(CPPFLAGS) -c -o $# $<
%.o: %.cpp %.h
$(CXX) $(CPPFLAGS) -c -o $# $<
CRC.exe: $(MAIN_OBJ) $(MODULE_OBJS)
$(CXX) -o $# $^ $(LIBS)
# Extra dependencies (guesses for the sake of example):
CarRental.o CR_LoginMenu.o CR_UserCreation.o: CR_TextBox.h CR_CheckBox.h
# No recipe here
.PHONY: clean
clean:
del $(MAIN_OBJ) $(MODULE_OBJS) CRC.exe
Ultimately, though, what you would really like to do is generate all the header dependencies automatically. That makes the project much easier to maintain once you get it initially set up. You can find lots of information about that on the web, some of it in the GNU make manual.

How to configure a dynamic library using a macro / variable in a makefile?

I'm writing a small study project in C. I need to create a dynamic library and configure its use with macros. First, I create object files with the command:
$gcc -fPIC -c ../data_module/data_process.c
$gcc -fPIC -c ../data_libs/data_stat.c
Then I create a dynamic library like this:
$gcc -shared -o data_process.so data_process.o data_stat.o
And finally I build an executable file using this library:
$gcc main_executable_module.o ../data_libs/data_io.o ../yet_another_decision_module/decision.o -L. data_process.so -o test_main
It works and the executable works correctly. But there is a task to configure the library using macros:
Make the necessary changes to the code of the main_executable_module, configuring the use of the dynamic library using macros.
That is, if I understand correctly, you need to add macros to the main_executable_module.o so that you do not use the -L flags during assembly. But I can't find information anywhere on how to do it. Can you please tell me how to implement this or where can I read about it?
UPD: John Bollinger says
It is possible that the word "macros" is intended to be interpreted as makefile macros, which many people instead call (makefile) "variables". That would make this a question about make / makefiles, not about C.
My Makefile:
CC=gcc
LDFLAGS=
CFLAGS=-c -Wall -Wextra -Werror
SOURCES=main_executable_module.c ../data_libs/data_stat.c ../data_libs/data_io.c ../yet_another_decision_module/decision.c ../data_module/data_process.c
DYNLIB=../data_module/data_process.c
STAT=../data_libs/data_stat.c
BUILDDYN=main_executable_module.c ../data_libs/data_io.c ../yet_another_decision_module/decision.c
OBJECTS=$(SOURCES:.c=.o)
OBJBUILDDYN=$(BUILDDYN:.c=.o)
OBJDYNLIB=data_process.o
OBJDATASTAT=data_stat.o
EXECUTABLE=../../build/main
DEXECUTABLE=../../build/Quest_6
DLIBS=data_process.so
all: $(SOURCES) $(EXECUTABLE)
data_stat.a: $(OBJLIB) $(LIBS)
ar -rcs $(LIBS) $(OBJLIB)
data_process.so: $(OBJDYNLIB) $(OBJDATASTAT)
$(CC) -shared -o $(DLIBS) $(OBJDYNLIB) $(OBJDATASTAT)
$(OBJDYNLIB): $(DYNLIB)
$(CC) -fPIC -c $(DYNLIB)
$(OBJDATASTAT): $(STAT)
$(CC) -fPIC -c $(STAT)
build_with_dynamic:$(OBJECTS) $(EXECUTABLE)
$(CC) $(OBJBUILDDYN) -L. $(DLIBS) -o $(DEXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.c.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf $(EXECUTABLE) $(OBJECTS)
lclean:
rm -rf $(LEXECUTABLE) $(OBJECTS) $(LIBS) $(DEXECUTABLE)
rebuild: clean $(SOURCES) $(EXECUTABLE)
The results of the checks revealed nothing. There are two opinions about this task.
Leave everything as above. And in the file itself, add a header process.h. Then everything is assembled and working. And at the same time, if you change the code in the library, rebuild it, and do not rebuild the executable file, then the changes will be taken into account. That is, the idea of ​​a dynamic library is respected.
Implement in such a way that there is no need to include headers in the main_executable_module.c. Then a special library is used for working with dynamic libraries, which allows you to write the path to the library and take individual functions from it. More about it here.
What was meant when it was said about macros, I still did not understand ...

Makefile header dependencies

I am new to using make and have been learning the basics through this tutorial. Here is the final example makefile example from the tutorial:
IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)
ODIR=obj
LDIR =../lib
LIBS=-lm
_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
This should work fine assuming all .c files are only including hellomake.h, but it wouldn't work if each .c file was including different headers. Is it possible to write a makefile that knows what each .c file is including, so I don't have to go in and do it manually like:
foo.o: foo.c something.h
...
bar.o: bar.c somethingelse.h
...
because that seems like it would be a big waste of time.
Suppose foo.c has a line:
#include "something.h"
You'd like a line in the makefile:
foo.o: foo.c something.h
The gcc compiler can construct that line for you. The command
gcc -MMD -c -o foo.o foo.c
will build foo.o and foo.d which contains the line. (Try it.)
So just modify your makefile to produce these *.d files and include them, and you're done:
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -MMD -c -o $# $< $(CFLAGS)
-include $(ODIR)/*.d
(Further refinements are possible, like specifying where the *.d files should go.)
Traditional makes are rather limited and force you to do all that basic stuff yourself. If you rightly expect a build tool to find dependencies and know what to link, try makepp. You may not need a makefile at all, or just a minimal one like
CFLAGS = -O3
myprog: # just a default target to know what to build
The linking part would require a little help on your side, in that it is based on source-header pairs. If myprog.cpp includes a.h and b.hpp it'll look if it can build a.o and/or b.o, and if so, will link them and recursively check what their sources include.
You will only need to learn more make syntax, if you have more complex requirements. But if you do, there is no limit. Besides doing almost all that GNU make can, there are lots more useful things, and you can even extend your makefiles with some Perl programming.
Yes, the "MMD" flag will help you to generate ".d" file (dependency) files. If you include at end of your Makefile( -include *.d ) and then if you make any change in .h file, the respective .o file, will rebuild.
Take this as reference:
https://github.com/saanvijay/makefile-skeleton
There's a minor limitation to #Beta's answer which can be fixed pretty easily.
Say you have a file main.c which includes header.h. You build this, and your main.d file looks like this:
main.o: main.c header.h
Then you delete header.h and its corresponding include in main.c. The program is valid and should compile fine, but make fails due to the above rule, which has a dependency on a now-nonexistent file.
To fix this, you need main.o to depend on main.d, and a rule to create main.d.
main.d: main.c
$(CC) -MM -o main.d main.c
include main.d
This splits the generation of the .d file into a separate step, and make is smart enough to know that since it includes main.d, it should be rebuilt before it is included. This would fix the above issue. More info in the docs.
One issue with this approach is that make will rebuild the .d file when it's not needed, e.g. when running make clean. In these cases, you can just disable the include like in this answer. I'm interested to know if there is a smarter way to do this.
The complete Makefile would look something like this:
main.d: main.c
$(CC) -MM -o main.d main.c
main.o: main.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o main.o main.c
main: main.o:
$(CC) main.o -o main $(LDLIBS)
.PHONY: clean
clean:
rm main.o main.d
ifneq ($(MAKECMDGOALS),clean)
include main.d
endif

Could someone explain this make file?

I found this makefile on this site. They don't explain this example, so I was wondering if anybody new what was going on.
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
sets four variables to be constant strings. For the rest of the makefile, wherever $(CC) appears (for example), it will be replaced by g++
OBJECTS=$(SOURCES:.cpp=.o)
sets the variable OBJECTS to be the same as SOURCES, except wherever the pattern .cpp appears in a words of SOURCES, its replaced by .o
EXECUTABLE=hello
sets another constant string var
all: $(SOURCES) $(EXECUTABLE)
The first actual rule in the makefile, This tells make that to build all it must first build everything in $(SOURCES) and $(EXECUTABLE), and then do nothing. Since this is first, it becomes the default target, so running make is equivalent to make all
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
Another rule: to create $(EXECUTABLE) (which expands to hello) it must first build everything in $(OBJECTS) (equivalent to main.o hello.o factorial.o) and then run the command $(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) -o $# $<
A pattern rule: in order to build a file ending in .o, first rebuild/create/find the corresponding file ending in .cpp, and then run the command $(CC) $(CFLAGS) -o $# $<.
These last two rules contain the special variables $# and $< which are only valid in rule actions and expand to the target and first dependency respectively
So when you run make, it reads all this and then tries to build the default target (all).
Since it doesn't exist, it tries to build the files main.cpp, hello.cpp, factorial.cpp, and hello. Since the first 3 (presumably) exist, it looks for rules/dependencies for them, but doesn't find any, so decides there's nothing to do for them. If they didn't exist, make would give an error saying "no rule to make target 'main.cpp'"
In the case of "hello" it depends on main.o, hello.o and factorial.o, so it looks into them. For main.o, the pattern rule says it depends on main.cpp, so if main.o doesn't exist or if main.cpp is newer, it will run the command g++ -c -Wall -o main.o main.cpp. The same happens for hello.o and factorial.o.
Once those are done, if hello doesn't exist or is older than any of those .o files (which may have just changed, so are possibly pretty new), it will run that command to relink it. Finally, it will run the empty command (doing nothing) to 'rebuild' all.

How can I have a Makefile automatically rebuild source files that include a modified header file? (In C/C++)

I have the following makefile that I use to build a program (a kernel, actually) that I'm working on. Its from scratch and I'm learning about the process, so its not perfect, but I think its powerful enough at this point for my level of experience writing makefiles.
AS = nasm
CC = gcc
LD = ld
TARGET = core
BUILD = build
SOURCES = source
INCLUDE = include
ASM = assembly
VPATH = $(SOURCES)
CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
-nostdinc -fno-builtin -I $(INCLUDE)
ASFLAGS = -f elf
#CFILES = core.c consoleio.c system.c
CFILES = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES = assembly/start.asm
SOBJS = $(SFILES:.asm=.o)
COBJS = $(CFILES:.c=.o)
OBJS = $(SOBJS) $(COBJS)
build : $(TARGET).img
$(TARGET).img : $(TARGET).elf
c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img
$(TARGET).elf : $(OBJS)
$(LD) -T link.ld -o $# $^
$(SOBJS) : $(SFILES)
$(AS) $(ASFLAGS) $< -o $#
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
#Clean Script - Should clear out all .o files everywhere and all that.
clean:
-del *.img
-del *.o
-del assembly\*.o
-del core.elf
My main issue with this makefile is that when I modify a header file that one or more C files include, the C files aren't rebuilt. I can fix this quite easily by having all of my header files be dependencies for all of my C files, but that would effectively cause a complete rebuild of the project any time I changed/added a header file, which would not be very graceful.
What I want is for only the C files that include the header file I change to be rebuilt, and for the entire project to be linked again. I can do the linking by causing all header files to be dependencies of the target, but I cannot figure out how to make the C files be invalidated when their included header files are newer.
I've heard that GCC has some commands to make this possible (so the makefile can somehow figure out which files need to be rebuilt) but I can't for the life of me find an actual implementation example to look at. Can someone post a solution that will enable this behavior in a makefile?
EDIT: I should clarify, I'm familiar with the concept of putting the individual targets in and having each target.o require the header files. That requires me to be editing the makefile every time I include a header file somewhere, which is a bit of a pain. I'm looking for a solution that can derive the header file dependencies on its own, which I'm fairly certain I've seen in other projects.
As already pointed out elsewhere on this site, see this page:
Auto-Dependency Generation
In short, gcc can automatically create .d dependency files for you, which are mini makefile fragments containing the dependencies of the .c file you compiled.
Every time you change the .c file and compile it, the .d file will be updated.
Besides adding the -M flag to gcc, you'll need to include the .d files in the makefile (like Chris wrote above).
There are some more complicated issues in the page which are solved using sed, but you can ignore them and do a "make clean" to clear away the .d files whenever make complains about not being able to build a header file that no longer exists.
You could add a 'make depend' command as others have stated but why not get gcc to create dependencies and compile at the same time:
DEPS := $(COBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$#) -o $# $<
The '-MF' parameter specifies a file to store the dependencies in.
The dash at the start of '-include' tells Make to continue when the .d file doesn't exist (e.g. on first compilation).
Note there seems to be a bug in gcc regarding the -o option. If you set the object filename to say obj/_file__c.o then the generated _file_.d will still contain _file_.o, not obj/_file_c.o.
This is equivalent to Chris Dodd's answer, but uses a different naming convention (and coincidentally doesn't require the sed magic. Copied from a later duplicate.
If you are using a GNU compiler, the compiler can assemble a list of dependencies for you. Makefile fragment:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
include .depend
There is also the tool makedepend, but I never liked it as much as gcc -MM
You'll have to make individual targets for each C file, and then list the header file as a dependency. You can still use your generic targets, and just place the .h dependencies afterwards, like so:
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
foo.c: bar.h
# And so on...
Basically, you need to dynamically create the makefile rules to rebuild the object files when the header files change. If you use gcc and gnumake, this is fairly easy; just put something like:
$(OBJDIR)/%.d: %.c
$(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(#D)/\1.o $(#D)/\1.d:,' >$#
ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif
in your makefile.
Over and above what #mipadi said, you can also explore the use of the '-M' option to generate a record of the dependencies. You might even generate those into a separate file (perhaps 'depend.mk') which you then include in the makefile. Or you can find a 'make depend' rule which edits the makefile with the correct dependencies (Google terms: "do not remove this line" and depend).
Simpler solution: Just use the Makefile to have the .c to .o compilation rule be dependent on the header file(s) and whatever else is relevant in your project as a dependency.
E.g., in the Makefile somewhere:
DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv
::: (your other Makefile statements like rules
::: for constructing executables or libraries)
# Compile any .c to the corresponding .o file:
%.o: %.c $(DEPENDENCIES)
$(CC) $(CFLAGS) -c -o $# $<
None of the answers worked for me. E.g. Martin Fido's answer suggests gcc can create dependency file, but when I tried that it was generating empty (zero bytes) object files for me without any warnings or errors. It might be a gcc bug. I am on
$ gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
So here's my complete Makefile that works for me; it's a combination of solutions + something that wasn't mentioned by anyone else (e.g. "suffix replacement rule" specified as .cc.o:):
CC = g++
CFLAGS = -Wall -g -std=c++0x
INCLUDES = -I./includes/
# LFLAGS = -L../lib
# LIBS = -lmylib -lm
# List of all source files
SRCS = main.cc cache.cc
# Object files defined from source files
OBJS = $(SRCS:.cc=.o)
# # define the executable file
MAIN = cache_test
#List of non-file based targets:
.PHONY: depend clean all
## .DEFAULT_GOAL := all
# List of dependencies defined from list of object files
DEPS := $(OBJS:.o=.d)
all: $(MAIN)
-include $(DEPS)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
#suffix replacement rule for building .o's from .cc's
#build dependency files first, second line actually compiles into .o
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
clean:
$(RM) *.o *~ $(MAIN) *.d
Notice I used .cc .. The above Makefile is easy to adjust for .c files.
Also notice importance of these two lines :
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
so gcc is called once to build a dependency file first, and then actually compiles a .cc file. And so on for each source file.
I believe the mkdep command is what you want. It actually scans .c files for #include lines and creates a dependency tree for them. I believe Automake/Autoconf projects use this by default.

Resources