Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have 3 files: MyLib.h MyLib.c Tester.c
I've been trying to create the makefile but it is proving difficult.
I can do it when it is only one file, like below where I am compiling Hello.c
I have seen some examples but they seem a lot more complicated than the one I am using below -- which sort of makes sense to me.
BINDIR = /usr/local/sbin
CC = gcc
CFLAGS = -O
all: Hello
Hello: Hello.o
${CC} ${CFLAGS} Hello.o ${LDFLAGS} -o Hello
Hello.o: Hello.c
${CC} ${CFLAGS} -c Hello.c
install: all
rm -f ${BINDIR}/Hello
cp Hello ${BINDIR}/Hello
clean:
rm -f Hello *.o core core.* *.core
Please help.
I been typing this every time I turn on my computer, kind of annoying by now.
gcc MyLib.c Tester.c -o Tester
Presuming MyLib.h is a dependency for both of your C files, you should have something like this:
# Variables
CC := gcc
CFLAGS := -O
# Link executable
Tester: MyLib.o Tester.o
${CC} MyLib.o Tester.o ${LDFLAGS} -o Tester
# Compile object files
MyLib.o: MyLib.c MyLib.h
${CC} ${CFLAGS} -c -o MyLib.o MyLib.c
Tester.o: Tester.c MyLib.h
${CC} ${CFLAGS} -c -o Tester.o Tester.c
and, once you've got the hang of how things work, you can use the automatic variables as your second step in reducing code duplication:
# Variables
CC := gcc
CFLAGS := -O
# Link executable
Tester: MyLib.o Tester.o
${CC} $^ ${LDFLAGS} -o $#
# Compile object files
MyLib.o: MyLib.c MyLib.h
${CC} ${CFLAGS} -c -o $# $<
Tester.o: Tester.c MyLib.h
${CC} ${CFLAGS} -c -o $# $<
where $# is the replaced by the name of the target for the current rule, $< is replaced by the first (i.e. leftmost) dependency, and $^ is replaced by the full list of dependencies.
In the above, the bits after the : are dependencies, i.e. the target to the left of the : will be made/remade if any of the dependencies are more recent than the target. For each of the dependencies, make will look for a target for it. So, for the first section, it sees that MyLib.o and Tester.o are dependencies for your overall executable, and it looks for targets for them, which are provided. Finding the targets, it builds them (if necessary) and then proceeds to build Tester.
Note that CFLAGS conventionally represents compilation flags, so you don't need to pass them when you're only linking since no compilation is being done at that point.
Also, if you're struggling with this kind of thing, then simplify, and remove all the additional targets (such as clean and install and all) until you've got the hang of what's going on.
Crude but effective:
Tester:
gcc MyLib.c Tester.c -o Tester
Better:
CC = gcc
Tester: MyLib.o Tester.o
$(CC) $^ -o $#
And I'll just make a guess about dependency:
MyLib.o Tester.o : MyLib.h
More sophisticated makefiles are possible, but this should do for now.
Related
I have designed a Makefile that compiles all the .c files individually and produces a .o respectively (I think this happens Implicitly and works perfectly fine).
The executable (.out) is not being generated from the .o files.
Makefile:
TARGET = all.out
OBJS = file1.o file2.o file3.o
CC = gcc
CFLAGS = -g -Wall
all : $(TARGET)
$(TARGET) : $(OBJS)
# gcc $^ -o $#
run : $(TARGET)
./$<
clean :
rm -rf *.o $(TARGET)
Output:
$ make
make: Circular all.out <- all dependency dropped.
gcc -g -Wall -c -o file1.o file1.c
gcc -g -Wall -c -o file2.o file2.c
gcc -g -Wall -c -o file3.o file3.c
cp file1.o all.out
Note: The Makefile works perfectly and produces the perfect results if the line no. 7 present in it is uncommented.
line no. 7:
# gcc $^ -o $#
Output when line no. 7 is uncommented (Works perfectly as intended):
gcc -g -Wall -c -o file1.o file1.c
gcc -g -Wall -c -o file2.o file2.c
gcc -g -Wall -c -o file3.o file3.c
gcc file1.o file2.o file3.o -o a.out
I am new to Makefiles.
Queries:
why does commenting line no. 7 causing this issue and uncommenting it works perfectly?
What is cp in the first output when line no.7 was commented?
What does circular - dependency dropped mean?
I can't explain how you are seeing the problem you showed to us. Either what you wrote above is not actually what you're using, or you have a buggy version of GNU make. I can't reproduce the behavior you're seeing.
But, I'm sure it's related to this: GNU make has a built-in rule that knows how to build an xx.out file from a file xx for any xx:
# make -p -f/dev/null
...
%.out: %
# recipe to execute (built-in):
#rm -f $#
cp $< $#
If you comment out your own recipe as an explicit rule, then make will search for one among the pattern rules it knows about and it will find this built-in pattern rule.
However this rule shouldn't match based on what you've shown us: in order for it to match with a target of a.out, make would have to find or know how to build a target a and that doesn't seem to be available. Also, knowing how to build a would show a circular dependency on a.out.
If your makefile was:
TARGET = all.out
THEN it would all make perfect sense because you would have:
all : all.out
all.out : file1.o file2.o file3.o
and after the implicit rule match %.out: % it would expand like this:
all : all.out
all.out : all file1.o file2.o file3.o
#rm -f all.out
cp all all.out
So I assume that when you copied the output into your question you changed it: best to not do that. You should post exactly the problem you have (and verify you still have the problem with what you posted).
This question already has an answer here:
Cannot get makefile to build each object from its corresponding source
(1 answer)
Closed 2 years ago.
So I am struggling a bit with the following Makefile:
src := $(wildcard *.c)
bin := $(src:%.c=out/%)
.PHONY: all
all: $(bin)
.PHONY: clean
clean:
rm -r out
out:
mkdir $#
$(bin): $(src) | out
$(CC) -Iincludes/ -Wall $< -o $#
Let's say I have the following directory:
$ ls
includes/ Makefile test1.c test2.c
Then I want the following to happen:
$ make
mkdir out
cc -Iincludes/ -Wall test1.c -o out/test2
cc -Iincludes/ -Wall test2.c -o out/test1
But what actually happens:
$ make
mkdir out
cc -Iincludes/ -Wall test2.c -o out/test2
cc -Iincludes/ -Wall test2.c -o out/test1
I kinda do not want to move files around what other solutions suggest
I am pretty sure this has to be easy but I am lost. Thank you for your help.
Consider changing the '$(bin)' rule:
out/%: %.c
$(CC) -Iincludes/ -Wall $< -o $#
The existing rule indicate that each program depends on ALL source files, and that each program can be built by compiling the ($<) FIRST source file. The revised rule indicate that echh programs depends on the .c with the same name
First, the makefile in question roughly looks like this (I'm writing off my memory):
CXX=g++
CXXFLAGS=-c -Wall -std=c++11 -O3
LDFLAGS=-Wall -std=c++11 -O3
all: clean car.out
clean:
rm -f *.o *.out
car.out: a.o b.o
$(CXX) -o $# $(LDFLAGS) $^
a.o: a.cpp
$(CXX) $(CXXFLAGS) $<
b.o: b.cpp
$(CXX) $(CXXFLAGS) $<
Basically this will make some object files first and then link them together. I think this is semantically unreasonable because:
As its name suggests, LDFLAGS is for ld, but there is no flags for it here. If we need some external library like OpenGL, then a flag like -LGL is passed to g++, and then g++ would pass it to the linker. In that case, it would be reasonable to put -LGL in LDFLAGS.
Even if it's the case where we put flags such as -Wall into LDFLAGS, it doesn't make much sense. This kind of flags are intuitively for the compilation process, not linking (unless I understand this process wrong).
In https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html, there is a piece of code $(CC) -c $(CFLAGS) $(CPPFLAGS), which passes -c explicitly. I think this is the better way to do this--putting all compilation flags (e.g. -Wall) into CXXFLAGS, and pass in -c explicitly for object file compilation. Of course, the web page does not say that this piece of code is definitely better or the only way to do it.
So the only reason I can think of to use LDFLAGS there is because "there's a linking step," which doesn't make much sense to me. In my opinion, the makefile above should look like:
CXX=g++
CXXFLAGS=-Wall -std=c++11 -O3
all: clean car.out
clean:
rm -f *.o *.out
car.out: a.o b.o
$(CXX) -o $# $(LDFLAGS) $^
a.o: a.cpp
$(CXX) -c $(CXXFLAGS) $<
b.o: b.cpp
$(CXX) -c $(CXXFLAGS) $<
LDFLAGS defaults to an empty string, so we can still have it there for the linking step.
However I'm not sure if I'm right.
You are right that compilation flags have nothing to do in LDFLAGS. Just define LDFLAGS explicitly so that another editor -or yourself, when some time has passed- can figure out at a glance that 1. it is empty and 2. where to modify it (like adding -s to it, which is quite common).
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
Lets say I have files:
Libs:
one.cpp, one.h
two.cpp, two.h
three.cpp, three.h
Program:
program.cpp
Is there way, to create Makefile which will compile only that *.cpp which were modified from last compilation?
Currently I have something like that:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: $(OBJS) program
.cpp.o:
g++ -Wall -c $<
program:
g++ -Wall $(OBJS) program.cpp -o program
clean:
rm -f $(OBJS) program
I works fine, but when I compile my program and then change two.cpp or two.h I need to run "make clean" first, because when I secondly run "make" I get:
Nothing to be done for 'all'.
I would like to change my Makefile in that way, it would recognize my changes and recompile that file and its dependencies (if one.cpp uses code from two.cpp which was modified, both files should be recompiled).
So if I modify two.cpp, make should do:
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
But if one.cpp uses code from two.cpp which was modified, make shold do:
g++ -Wall -c one.cpp
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
First we make the object files prerequisites of the executable. Once this is done, Make will rebuild program whenever one of the SRCS changes, so we don't need OBJS as an explicit target:
all: program
program: $(OBJS)
g++ -Wall $(OBJS) program.cpp -o program
Then we make the header files prerequisites of the objects, so that if we change three.h, Make will rebuild three.o:
$(OBJS): %.o : %.h
And finally since one.cpp uses code from two.cpp by means of two.h (I hope), we make two.h a prerequisite of one.o:
one.o: two.h
And to make things cleaner and easier to maintain we use automatic variables:
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
Put it all together and we get:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: program
$(OBJS): %.o : %.h
one.o: two.h
.cpp.o:
g++ -Wall -c $<
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
clean:
rm -f $(OBJS) program
There are a few more things we could do (like adding program.o to OBJS), but this is enough for today.
Add the files a command depends upon to run to the right of the target name.
Example:
default: hello.c
gcc -o hello.bin hello.c
install: hello.bin
cp hello.bin ../
All you need to do is tell make that the .o file depends on the .cpp file:
%.cpp.o: %.cpp
g++ -Wall -c -o $# $<