Trying to Figure out Makefiles - makefile

So, I am brand new to makefiles, and I am horrible on the command prompt. So I want to make sure my syntax is correct.
I have three files:
main.cpp
Blob.cpp
Blob.h
I would create a file (in notepad or something) called makefile.make and in it the text would read:
all:
g++ main.cpp Blob.cpp Blob.h -o hello
I then run in command prompt
make
and the file will be created? Is this correct? They are all in the same directory, along with some other folders that VS2012 put in there.

If you just want to rebuild the executable when every any file has changed, use
all: hello
hello: main.cpp Blob.cpp Blob.h
g++ -o hello main.cpp Blob.cpp
If you want separate compilation you do
all: hello
hello: main.o Blob.o
g++ -o hello main.o Blob.o
main.o: main.cpp Blob.h
g++ -o main.o main.cpp
Blob.o: Blob.cpp Blob.h
g++ -o Blob.o Blob.cpp
In both cases we tell make what file are dependencies (that is, if those files change we need to rebuild) in addition to specifying the work to be done.

try this
hello:main.cpp Blob.cpp
[TAB] g++ main.cpp Blob.cpp -o hello
Name it as Makefile or makefile. You can run just make to build it. Else name it anything you like, ex mymakefile and run make -f mymakefile to build it
Get fresh with basic makefile rules

Google "makefile tutorial" and you'll find plenty of sites.
The commands to run have to be preceded by a Tab character, so it should be:
all:
g++ main.cpp Blob.cpp -o hello
Make sure you're not using an editor that converts Tab characters to spaces.

Related

'make: nothing to be done for p1 and' no rule to make target 'clean''

I'm trying to create a makefile titled 'p1' for a project.
When I try the command make p1 it returns with make: nothing to be done for p1
Also, when I try the command make p1 clean it returns no rule to make p1 'clean.' Stop
Here is my makefile:
a.out: main.o P1LinkedList.o const_iterator.o iterator.o Node.o
g++ -std=c++11 main.o const_iterator.o iterator.o Node.o
main.o:
g++ -std=c++11 -c main.cpp
P1LinkedList.o:
g++ -std=c++11 -c P1LinkedList.cpp
iterator.o:
g++ -std=c++11 -c iterator.cpp
const_iterator.o:
g++ -std=c++11 -c const_iterator.cpp
Node.o:
g++ -std=c++11 -c Node.cpp
depend:
g++ -MM main.cpp > p1.dep
clean:
rm -f a.out *.o
What do I need to fix to have the makefile compile .o files from my .cpp files and how do I fix the issue with the clean command?
Edit:
Here are the commands I've used to compile manually:
Helens-Air:p1a helenade$ g++ -std=c++11 *.cpp
Helens-Air:p1a helenade$ ./a.out
^^ and this just continues with the program execution from there
We may have to take this in stages.
First, you seem to misunderstand the difference between a makefile name and a target name. This appears to have been a miscommunication between you and your teacher, but it's easy to clear up.
Suppose you have a makefile named "Makefile", containing the following:
foo:
#echo running the foo rule
bar:
#echo running the bar rule
If you make foo, you will get:
running the foo rule
The argument (foo) tells Make which target to attempt to build. And how did Make know which makefile to use? (After all, you could have a dozen makefiles in the working directory.) You can specify which makefile to use, but if you don't then by default Make will look for a makefile named Makefile (or makefile or GNUmakefile, don't worry about this for now). To specify a makefile with another name, like "Buildfile", you can use the -f flag:
make -f Buildfile
So "p1" ought to have been the name of a target, not a makefile. Within the makefile, rename your a.out rule to p1. Then rename the whole makefile to Makefile. Then
make p1
should work (or at least run).
Edit:
I'll go out on a limb. In the a.out rule (which should now be called the p1 rule), I notice that you have left P1LinkedList.o out of the list of object files to be linked. So try changing it:
p1: main.o P1LinkedList.o const_iterator.o iterator.o Node.o
g++ -std=c++11 main.o P1LinkedList.o const_iterator.o iterator.o Node.o
If that works, you can simplify it with an automatic variable:
p1: main.o P1LinkedList.o const_iterator.o iterator.o Node.o
g++ -std=c++11 $^
And there will be other small improvements you can make.
If it doesn't work, try ls *.cpp and see if you've overlooked some other source file.

Creating .o file with make

I'm trying to learn how to write makefiles. I have started reading the manual of gnu make: https://www.gnu.org/software/make/manual/html_node/Simple-Makefile.html#Simple-Makefile
I have 3 files in the same directory:
main.cpp: which creates a rectangle and prints some information. Therefor it includes Rectangle.h
Rectangle.h: header file for rectangle class
Rectangle.cpp: implementation of rectangle class
I am having troubles with the include of Rectangle.h in main.cpp. My makefile is:
main: main.o rectangle.o
g++ -o main.exe main.o rectangle.o
main.o: main.cpp
g++ main.cpp
rectangle.o: Rectangle.cpp
g++ Rectangle.cpp
clean:
rm main.exe main.o rectangle.o
I know something is missing to create main.o but I can't find out what it is. I tried adding various variations of Rectangle.h/.o/.cpp and finding something on the internet but I was unable to find something.
Help will be much appreciated :)
PS: The code is fine, I can compile it with the command:
g++ -o main.exe main.cpp Rectangle.cpp
man g++
When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage. For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler.

make is calling g++ is always re-compiles even when I do not change the source code

I am using make which calls g++ always re-compiles the code, even when I do not change the source code. That happens for all my projects, even for simple ones such as:
[code]
all: main.cpp
g++ -std=c++11 -c main.cpp
[/code]
I believe it should compare the date/time on source and object code. Could some help me with this, I am running using GNU toolchain on Ubuntu 12.04
THX
Edit: sorry guys, I do use Makefile, I edited my question accordingly.
Simplest Makefile
It was already pointed out that your Makefile is probably wrong. The 'all' target is indeed always built (although it may result in a no-op if it has no commands and all dependencies are already satisfied). All you need in your makefile is this:
all: main
Object files
If you expect to have more source file in your build, you should consider creating intermediate object files:
all: main
main: main.o
Tweak the build
Make will automatically find the main.ccp file and turn it into main which is required per the directive above. You can use special make variables to further tweak the compilation, e.g. for debug information inclusion and for warning configuration:
CXXFLAGS = -g -Wall -Werror
all: main
main: main.o
Nitpicking
If you insist on building up the compile rule yourself, you can do it like this:
%.o: %.hpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
CXX: C++ compiler
CPPFLAGS: C preprocessor flags
CXXFLAGS: C++ compiler flags
$#: Target
$<: First dependency
If you don't want to use the standard variables nor pattern matching, you can build up the whole makefile explicitly:
all: main
main: main.o
gcc -o $# $^
main.o: main.c
gcc -g -Wall -Werror -o $# -c $<
$^: Use that one if you want to include all dependencies, for example if you have multiple *.o files to build one binary.
Note: It is a bad idea to write the file names directly into the command as you might forget to update them later.
all: main.cpp
g++ -std=c++11 -c main.cpp
This seems wrong. Why does the rule for all has main.cpp as its target? Shouldn't it be something.exe or something.o? Say
all: main.exe
main.exe: main.cpp
g++ -std=c++11 main.cpp -o main.exe
clean:
del main.exe
Targets are output files and cpp files are source code which should be input to the make system.
g++ would have to "recompile" in general (what happens if you change the header but not main.cpp?)
If you are concerned about long build times, you should use something like Make (which is designed specifically to avoid recompiling when the source hasn't changed)
The compiler will always compile the code. If you want to do conditional compilation (based on file times etc) you will need to use a make system such as Make, CMake, Ant, etc. For the simplest you can set up a small "Makefile" in the directory and use the command "make" to build.
Simple Makefile for compiling "myapp.exe" from "main.cpp", "file1.cpp" and "file2.cpp"
myapp.exe: main.o file1.o file2.o
g++ -o myapp.exe main.o file1.o file2.o
(make knows to use .cpp files to build .o files)
But if you also have header files, then you will need to build dependency chains, for which you may want to look into something more sophisticated like automake, cmake, ant, etc.
---- EDIT ----
Based on your updated post, the problem is that you aren't specifying a target, so Make has to assume it needs to recompile. See my example in the above answer.

is that necessary for makefile to generate .o files for small projects

all: hello
hello: main.o
g++ -o hello main.o
main.o: main.cpp
g++ -c main.cpp
Above is a simple makefile, my question is that why we do not use the following for small project? It is no need to generate .o files. Is there any disadvantage of using the following format for small projects?
all: hello
hello:main.cpp
g++ -o hello main.cpp
No, there is no disadvantage.
[Of course, simple projects have a tendency to grow into bigger projects, so there's always an argument that you should start as you mean to go on...]

Compile C++ with Cygwin

How do I compile my C++ programs in Cygwin. I have gcc installed. What command should I use? Also, how do I run my console application when it is in a .cpp extension. I am trying to learn C++ with some little programs, but in Visual C++, I don't want to have to create a seperate project for each little .cpp file.
You need to use a command like:
g++ -o prog prog.cpp
That's a simple form that will turn a one-file C++ project into an executable. If you have multiple C++ files, you can do:
g++ -o prog prog.cpp part2.cpp part3.cpp
but eventually, you'll want to introduce makefiles for convenience so that you only have to compile the bits that have changed. Then you'll end up with a Makefile like:
prog: prog.o part2.o part3.o
g++ -o prog prog.o part2.o part3.o
prog.o: prog.cpp
g++ -c -o prog.o prog.cpp
part2.o: part2.cpp
g++ -c -o part2.o part2.cpp
part3.o: part3.cpp
g++ -c -o part3.o part3.cpp
And then, you'll start figuring how to write your makefiles to make them more flexible (such as not needing a separate rule for each C++ file), but that can be left for another question.
Regarding having a separate project for each C++ file, that's not necessary at all. If you've got them all in one directory and there's a simple mapping of C++ files to executable files, you can use the following makefile:
SRCS=$(wildcard *.cpp)
EXES=$(SRCS:.cpp=.exe)
all: $(EXES)
%.exe: %.cpp
g++ -o $# $^
Then run the make command and it will (intelligently) create all your executables. $# is the target and $^ is the list of pre-requisites.
And, if you have more complicated rules, just tack them down at the bottom. Specific rules will be chosen in preference to the pattern rules:
SRCS=$(wildcard *.cpp)
EXES=$(SRCS:.cpp=.exe)
all: $(EXES)
%.exe: %.cpp
g++ -o $# $^
xx.exe: xx.cpp xx2.cpp xx3.cpp
g++ -o $# $^
echo Made with special rule.
You will need g++. Then try g++ file.cpp -o file.exe as a start. Later you can avoid much typing by learning about Makefiles.
if you want to use cygwin you should use the normal gcc syntax
g++ -o foobar foobar.cpp
but that doesn't really play well with Visual C++. I advise you to take a look into Eclipse CDT if you prefer using GCC over the visual C++ compiler.
What I do to compile a cpp program:
g++ -Wall Test.cpp -o Test
-Wall enables warning and error messages to be shown
-o Test creates an Test.exe after compilation
If you want to compile files separately:
g++ -Wall -c File1.cpp
g++ -Wall -c File2.cpp
Now create an executable with the combined object files as:
g++ -Wall File1.o File2.o -o File.exe
This way you can compile your header files and you can include in your application programs.

Resources