#use g++ for everything
CC= g++
# include debugging symbols in object files,
# and enable all warnings
FLAGS= -g -Wall -std=c++11
BSTHPP= BST.hpp BSTNode.hpp BSTIterator.hpp
all: main
bst: testBST.o $(BSTHPP)
$(CC) $(FLAGS) -o bst testBST.o $(BSTHPP)
main: main.o $(BSTHPP)
$(CC) $(FLAGS) -o main main.o $(BSTHPP)
main.o: $(BSTHPP)
$(CC) $(FLAGS) -c main.cpp
testBST.o: testBST.cpp
$(CC) $(FLAGS) -c testBST.cpp
clean:
$(RM) main bst *.o
I changed the BST.hpp file and then run make bst. But I debug for several times and find out firstly I need to make clean, then recompile. But why? Could anyone explain it to me?
It's the .o files that need to depend on the .hpp, not the executable (which should also not mention them in its recipe).
Related
I have this C++ program in Clion, however, I need to create a makefile for it to be run on text editors and not IDEs, it is for a university, they do not use IDEs.
When I run my program trough the run button on CLion, it works perfectly but when I run it trough the makefile, it displays multiple errors that don't even make sense.
When is the issue occurring from? Please tell me if you need more information or images.
Project structure:
Errors with makefile:
Run without the makefile:
Makefile:
OBJS = main.o HastTable.o Book.o
SOURCE = main.cpp HastTable.cpp Book.cpp
HEADER = HashTable.h Book.h
OUT = book
CC = g++
FLAGS = -g -c -Wall -Wextra
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT) $(LFLAGS)
main.o: main.cpp
$(CC) $(FLAGS) main.cpp
HastTable.o: HastTable.cpp
$(CC) $(FLAGS) HastTable.cpp
Book.o: Book.cpp
$(CC) $(FLAGS) Book.cpp
clean:
rm -f $(OBJS) $(OUT)
I'm not sure if there is some built-in variable or rule that I don't know about, or if something is wrong with make, or if I'm just crazy.
For one of my projects, I have a makefile as follows:
CC=g++
CFLAGS=-O3 `libpng-config --cflags`
LFLAGS=-lm `libpng-config --ldflags`
OBJS=basic_render.o render.o mandel.o
BINS=basic_render
.PHONY: all clean
all: $(BINS)
clean:
rm -f $(BINS) $(OBJS)
%.o: %.cpp
$(CC) $(CFLAGS) -c -o $# $<
%: $(OBJS)
$(CC) $(LFLAGS) -o $# $(OBJS)
When building, I want to simply be able to run
make clean
make
to build everything in the BINS list.
This works all right at first, but for some reason, the behaviour changes after I edit a source file.
Before editing source file:
$ make clean
rm -f basic_render basic_render.o render.o mandel.o
$ make
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o basic_render basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
I can do this over and over again and it works just fine. After I make changes to basic_render.cpp (literally just changing a couple of constants), it suddenly changes to this:
$ make clean
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o makefile basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
makefile:1: warning: NUL character seen; rest of line ignored
makefile:1: *** missing separator. Stop.
not only did make clean just try to compile the program, it compiled basic_render with the output set in Makefile, overwriting the Makefile itself.
After editing basic_render.cpp, I looked in Makefile, and it hadn't changed, so it's not like my editor is changing the makefile or something.
So, what am I doing wrong here?
Here is an MCVE of your problem:
$ ls -R
.:
bar.c main.c Makefile
$ cat main.c
extern int bar(void);
int main(void)
{
bar();
return 0;
}
$ cat bar.c
int bar(void)
{
return 42;
}
$ cat Makefile
OBJS := main.o bar.o
BINS := prog
.PHONY: all clean
all: $(BINS)
%: $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BINS)
Make first time:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog main.o bar.o
rm bar.o main.o
Pause to notice the undesired consequence of 10.4 Chains of Implicit Rules:
rm bar.o main.o
All of the object files are auto-deleted after the program is linked, defeating the purpose
of Make. The implicit rules to blame for that are our own implicit rule:
%: $(OBJS)
$(CC) -o $# $(OBJS)
plus the built-in implicit rule1:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
which together make an implicit rule chain that results in all of the object files
becoming intermediate files.
Moving on, let's update a source file:
$ touch main.c
and make a second time:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o Makefile main.o bar.o
rm bar.o main.o
Makefile:1: warning: NUL character seen; rest of line ignored
Makefile:1: *** missing separator. Stop.
There is our Makefile clobbered by the linkage:
cc -o Makefile main.o bar.o
This snafu is explained in the manual 3.5 How Makefiles Are Remade:
Sometimes makefiles can be remade from other files, such as RCS or SCCS files.
If a makefile can be remade from other files, you probably want make to get an
up-to-date version of the makefile to read in.
To this end, after reading in all makefiles, make will consider each as a goal
target and attempt to update it. If a makefile has a rule which says how to update it
(found either in that very makefile or in another one) or if an implicit rule applies to it
(see Using Implicit Rules), it will be updated if necessary.
After all makefiles have been checked, if any have actually been changed,
make starts with a clean slate and reads all the makefiles over again.
(It will also attempt to update each of them over again, but normally this will
not change them again, since they are already up to date.)
(Emphasis mine). Is there an implicit rule that is applicable to Makefile considered
as a target? Yes, it is:
%: $(OBJS)
$(CC) -o $# $(OBJS)
since the target pattern % matches any file whatever. If we restore our clobbered
Makefile and try the same experiment thing again, this time with debugging:
make -d >debug.log 2>&1
the output will show us:
...
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Considering target file 'Makefile'.
Looking for an implicit rule for 'Makefile'.
...
...
Found an implicit rule for 'Makefile'.
...
...
Finished prerequisites of target file 'Makefile'.
Prerequisite 'main.o' is newer than target 'Makefile'.
Prerequisite 'bar.o' is newer than target 'Makefile'.
Must remake target 'Makefile'.
cc -o Makefile main.o bar.o
...
We can avoid this upshot, and also the self-defeating auto-deletion of
our object files, by not using a match-anything implicit rule to perform our
linkage. The customary thing is to make a program from its object files by
an explicit rule, e.g.
Makefile (2)
OBJS := main.o bar.o
BIN := prog
.PHONY: all clean
all: $(BIN)
$(BIN): $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
It appears that you cherish the option to have BINS be a list of multiple
programs:
I want to simply be able to run
make clean
make
to build everything in the BINS list.
But consider that with:
BINS := prog1 prog2
and the recipe:
%: $(OBJS)
$(CC) $(LFLAGS) -o $# $(OBJS)
as your way of making everything in the BINS list, you will just make the same program
twice, with two different names. And even if you wanted to do this, the way to do
it would be:
Makefile (3)
OBJS := main.o bar.o
BINS := prog1 prog2
.PHONY: all clean
all: $(BINS)
$(BINS): $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
which runs like:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog1 main.o bar.o
cc -o prog2 main.o bar.o
[1] You can get GNU Make to show you all its builtin-rules, and all the rest
of its rules for a particular build, with make --print-data-base ...
I would suggest that the % target is somehow matching the makefile file and therefore using it as the target(1).
My advice would be to change that line to:
$(BINS): $(OBJS)
and that should hopefully prevent make from thinking it should create a new makefile when the objects change.
(1) Apart from the explicit rules you provide, make also has quite a lot of implicit rules.
If even one of those rules decides that it depends on makefile (this is often configured since a change to the makefile usually means that a full rebuild should be done, as the rules may well have changed), then the % target may then be used for the makefile.
And, since the objects have changed, the makefile that depends on them will be rebuilt.
I personally have never seen a % target since I believe that means the rule may match any target, including source files which you probably don't want overwritten.
If you're interested in seeing all those implicit rules, make -d should give you quite a bit of information such as the rules used and conditions checked for whether files need to be rebuilt - just be prepared to wade through a lot of output.
I have a assign4a.cpp, list.h, and list.cpp file. I compiled them with my make file but don't know what command I would use to run the program.
What I tried to run have tried
a.out and ./a.out
both of them give me "Command not found"
Makefile
CFLAGS = -c -Wall -g
LFLAGS = -g -o assign4a
assign4a: assign4a.o list.o
g++ assign4a.o list.o $(LFLAGS)
assign4a.o: assign4a.cpp list.h
g++ $(CFLAGS) assign4a.cpp
list.o: list.cpp list.h
g++ $(CFLAGS) list.cpp
clean:
rm -f assign4a *.o *~ *#
./assign4a.
Your makefile will build the program and put a executable assign4a to the working folder.
And, your makefile is wrong.
It should be g++ $(CFLAGS) assign4a.cpp -o assign4a.o and g++ $(CFLAGS) list.cpp -o list.o.
You need to call
./assign4a
Makefile defines targets and dependencies between them. Here:
assign4a: assign4a.o list.o
g++ assign4a.o list.o $(LFLAGS)
assign4a is a target, that depends on files assign4a.o, list.o, and to build target is needed to run g++ assign4a.o list.o $(LFLAGS).
I am trying to avoid relative paths in header declaration of C++ files. So, I had used the makefile by following an online example. But I am getting error. Please check the code and help me to resolve this
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
CFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
(---- I had also used CFLAGS instead of CXXFLAGS below but the same result###)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c main.cpp
factorial.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c factorial.cpp
hello.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c hello.cpp
Error:
make: * No rule to make target 'include / functions.h "
required by "main.o" to create. Closing.
Directory Structure is
- main.cpp
- factorial.cpp
- hello.cpp
- MakeFile.mk
- +include (dir)
----->functions.h
main.cpp contains ----include "functions.h"---- in the header declaration
You are not using h files as a source files.
there should only be:
main.o: main.cpp
$(COMPILER) $(CXXFLAGS) -c main.cpp
edited:
I copy your folder content and write simple application where hello.cpp have a simple void function, factorial.cpp have simple int-returning function ane main.cpp have int main() and uses this functions, include.h hafe declarations of these two dummy functions.
Now. My makefile looks:
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp factorial.o hello.o
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
factorial.o: factorial.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
hello.o: hello.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
download for my sample
That should help You!
This is a pure make error message. The error is not related to the content of any .cpp or .h file. The error actually can come only from the content of the Makefile, and of the presence or absence of the files named in it.
As per this error message, make states that it cannot find the file include/functions.h. Double check it actually is here, with correct name and matching case.
For debugging purpose you can add the following lines to your Makefile:
./include/functions.h:
touch $#
It will instruct make to create an empty include/functions.h file if it's missing.
I am unable to figure out what is causing this error that I keep getting upon making my project:
i686-apple-darwin11-llvm-g++-4.2: -lncurses: linker input file unused because linking not done
And my make file looks like this:
CC = g++
LIB_FLAGS = -l ncurses
FLAGS = $(LIB_FLAGS)
DEPENDENCIES = window.o element.o
# FINAL OUTPUTS
main: main.cpp $(DEPENDENCIES)
$(CC) $(FLAGS) -o main.out main.cpp $(DEPENDENCIES)
# MODULES
window.o: main.h classes/window.cpp
$(CC) $(FLAGS) -c classes/window.cpp
element.o: main.h classes/element.cpp
$(CC) $(FLAGS) -c classes/element.cpp
# CLEAN
clean:
rm -rf *.o
rm main.out
Everything compiles okay, but I'm just curious what is causing this error message and what it means..
You are passing linker options to a compiler invocation together with -c, which means that linking is not performed and thereby -l options are unused. In your case, your LIB_FLAGS should not be in FLAGS, but instead specified in the the main: ... rule:
main: main.cpp
$(CC) $(FLAGS) $(LIB_FLAGS) ...
Do not give link flags when you compile (-c flag) your source files. Take a look for this example makefile (very similar as in makefile docs)
CPP = g++
CPPFLAGS =-Wall -g
OBJECTS = main.o net.o
PREFIX = /usr/local
.SUFFIXES: .cpp .o
.cpp.o:
$(CPP) $(CPPFLAGS) -c $<
.o:
$(CPP) $(CPPFLAGS) $^ -o $#
main: $(OBJECTS)
main.o: main.cpp
net.o: net.cpp net.h
.PHONY:
install: main
mkdir -p $(PREFIX)/bin
rm -f $(PREFIX)/bin/main
cp main $(PREFIX)/bin/main
clean:
rm -f *.o main
As has been mentioned already you're passing linker-related flags at the compile stage. Usually you want different flags for compiling and linking, e.g.
CC = g++
CPPFLAGS = -Wall -g -c -o $#
LDFLAGS = -l ncurses -o $#
DEPENDENCIES = main.o window.o element.o
# FINAL OUTPUTS
main: $(DEPENDENCIES)
$(CC) $(LDFLAGS) $(DEPENDENCIES)
# MODULES
main.o: main.h main.cpp
$(CC) $(CPPFLAGS) main.cpp
window.o: main.h classes/window.cpp
$(CC) $(CPPFLAGS) classes/window.cpp
element.o: main.h classes/element.cpp
$(CC) $(CPPFLAGS) classes/element.cpp
# CLEAN
clean:
-rm main $(DEPENDENCIES)