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.
Related
I recently tried to make a makefile and it works fine on my laptop. I was making a game in c++ and shared my code on github. One of my friends cloned
the repo and informed me that he ran into some errors. Coming to errors I must inform you that my project uses QuickCG which is based on SDL, so naturally one needs to have SDL installed. My friend did not have that initially but later downloaded it using sudo apt-get install libsdl1.2-dev. After downloading, the 'header include' error was removed but still there is linking error I suppose.
Here is my makefile
CC = g++
CFLAGS = -c -O3
CLINK_FLAGS = -lSDL
all : game
game : main.o quickcg.o
$(CC) main.o quickcg.o -o game $(CLINK_FLAGS)
main.o : main.cpp
$(CC) $(CFLAGS) main.cpp
quickcg.o : quickcg.cpp
$(CC) $(CFLAGS) quickcg.cpp
clean :
rm *.o game
My Game folder contains only 2 cpp files which are main.cpp and quickcg.cpp. It also contains 1 header file quickcg.h
Now to come to the exact error statement after executing make
g++ -c -O3 main.cpp
g++ -c -O3 quickcg.cpp
g++ main.o quickcg.o -o game -lSDL
/usr/bin/ld: cannot find -lSDL
collect2: error: ld returned 1 exit status
make: *** [game] Error 1
Please note that this worked completely fine on my laptop.
Also please note that the following command worked like a charm even on his laptop
g++ *.cpp -lSDL -O3
So clearly there seems to be a fault with makefile.
Forgive me if I have done anything stupid because I am new to makefiles but I am not able to find any errors here. Thanks in advance
You may try
CLINK_FLAGS = `sdl-config --libs`
if you don't know the path for -L.
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.
I'm trying to combine object files created from C++ files into an executable using gcc. Unfortunately, gcc is giving me thousands of undefined reference errors to strings, arrays, etc.
I am doing this on a Windows machine, so no terminal commands; only cmd commands.
I'm simply doing:
gcc a.o b.o c.o -o prgm.exe
What am I missing/doing wrong?
EDIT:
I recreated the .o files with g++ doing:
g++ a.cpp -g -c -Wall -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -IC:\SDL-1.2.14\include -o a.o, where a.cpp and a.o are the directories where i keep the files, not the g++ directory
Then, I did g++ a.o b.o c.o -o prgm.exe. This gave dozens (I guess that's an improvement?) errors like
undefined reference to `_SDL_SetColorKey'
but I included SDL didnt I?
The final error from this is:
c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../li
bmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `_WinMain
#16'
collect2.exe: error: ld returned 1 exit status
int main(int argc, char * argv[]) is in the code
You are trying to link a C++ program with the C linker. You need to use g++ instead of gcc.
Generally speaking gcc is for compiling/linking C, while g++ is for C++. IIRC compiling C++-code with gcc works by virtue of dispatching according to the file extension. Linking C++ code with gcc however does not work, since it won't link the C++ standard libraries, resulting in your undefined reference errors.
If this does not solve your problem, you might want to give us a more concrete description of your errors and your system.
Based upon your updates then I think you'd need to do the following:
g++ a.cpp b.cpp c.cpp -g -Wall -IC:\SDL-1.2.14\include -LC:\SDL-1.2.14\lib -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -o prgm.exe
I'm guessing C:\SDL-1.2.14\lib exists based upon where the headers are located.
GCC is the C compiler. Your code is C++ so you need to use G++ to do the linking:
g++ a.o b.o c.o -o prgm.exe
This automatically adds the C++ libraries to the link line, resolving many if not all of your missing references.
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.
I was trying to do something like this in a makefile:
program.exe: ui.o main.o
gcc ......etc
ui.o: window1.o window2.o
gcc -c window1.o window2.o -o ui.o #this doesn't want to work
window1.o: window1.c window1.h window1_events.c window1_controls.c ...
gcc -c window1.c window1_events.c window1_controls.c... -o window1.o
window2.o: ...
gcc ...
main.o: ...
gcc ...
but when I compile like this, it gives the error "input file unused because linking not done," and then I get a bunch of unresolved externs, etc--problems which are resolved by changing
program.exe: ui.o main.o
gcc ...
to
program.exe: window1.o window2.o main.o
gcc ...
so is it possible to just link object files together, to avoid having mile-long lines in a makefile and break down the build process a little more?
Yes: to merge several object files into one, use ld -r or ld -Ur:
From "man ld" on Linux:
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can
in turn serve as input to ld. This is often called partial linking.
As a side effect, in environments that support standard Unix magic
numbers, this option also sets the output file’s magic number to
"OMAGIC".
If this option is not specified, an absolute file is produced.
When linking C++ programs, this option will not resolve references to
constructors; to do that, use -Ur.
You could also do this with gcc:
gcc -Wl,-r foo.o bar.o -o foobar.o -nostdlib
Merging object files like this has some advantages over using an archive library: if merged files change very infrequently (compared to say main.c), your final executable links will be faster.
OTOH, with archived library, the linker will only use what it needs, so your executable may end up being smaller if e.g. window2.c ends up not being necessary.
I bunch of object files is a library. You can create a library with the ar
utility. The following example creates a library called mylib.a containing the files foo.o and bar.o
ar rvs mylib.a foo.o bar.o
You can then link with it by using it on the compiler command line:
gcc -o myexe main.c mylib.a
To create a library:
ar rvs somelib.a file1.o file2.o file3.o
To link it:
gcc -o program.exe file4.o somelib.a