• Advertisement
Sign in to follow this  

problems to compile under linux..

This topic is 3966 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi people, I would want to try to make a very simple and short game on linux, for personal experience. coding the program is easy... the language is the same than windows OS... but I've some problems in compiling phase... I've caught from the net a makefile in order to have an idea... but there aren't comments and I don't understand some points. if is not too long, can you translate to me, step by step? My comments are written with capslock activated. (PS: I use knoppix and gcc)
GCCFLAGS= -Wall -pedantic -ggdb
LINKERFLAGS=-lpthread

all:  Apps MasterCow.exe

Apps:  Starter.exe Endless.exe 

Sender.exe: Starter.o Util.o
	gcc -o Starter.exe ${GCCFLAGS} ${LINKERFLAGS} Starter.o Util.o

Sender.o: Starter.c appdefs.h Util.h
	gcc -c ${GCCFLAGS} Starter.c

Receiver.exe: Endless.o Util.o
	gcc -o Endless.exe ${GCCFLAGS} ${LINKERFLAGS} Endless.o Util.o

Receiver.o: Endless.c appdefs.h Util.h
	gcc -c ${GCCFLAGS} Receiver.c

Ritardatore.o:	MasterCow.c appdefs.h Util.h
	gcc -c ${GCCFLAGS} MasterCow.c

Ritardatore.exe:	MasterCow.o Util.o
	gcc -o MasterCow.exe ${GCCFLAGS} ${LINKERFLAGS} Util.o MasterCow.o 

Util.o: Util.c 
	gcc -c ${GCCFLAGS}  Util.c

THIS IS EASY, IT REMOVES BOTTOM FILES, BUT WHY REMOVE .EXE FILE??
THESE ARE THAT I WANT, RIGHT???
clean:	
	rm -f core* 
	rm -f *.exe
	rm -f Starter.o Starter.exe
	rm -f Endless.o Endless.exe
	rm -f MasterCow.o MasterCow.exe
	rm -f Util.o 

thanks friends

Share this post


Link to post
Share on other sites
Advertisement
[google] - "makefile"

the meaning of "clean" is delete everything except the source code. hence it deletes the .exe files as well. i should note that linux doesn't require a .exe ending for executable files. that makefile is likely for a PC version of make.

-me

Share this post


Link to post
Share on other sites
oh yeah!! google is always a good choise!! :)

now I've understaood what .o is, and what mean this syntax:

Starter.o: Starter.c appdefs.h Util.h
gcc -c ${GCCFLAGS} Starter.c


but I still do not understand this code:

Starter.exe: Starter.o Util.o
gcc -o Starter.exe ${GCCFLAGS} ${LINKERFLAGS} Starter.o Util.o

Does starter.exe needs Util.o because in starter.c is included util.h?

And what is means?

all: Apps MasterCow.exe
Apps: Starter.exe Endless.exe

that MasterCow.exe is the most important .exe, with special skills?
and that Starter.exe Endless.exe are two .exe with less things?


PS: in this web site http://www.opussoftware.com/tutorial/TutMakefile.htm, on unix world, often the .exe files are use, but is not said the cause...
so, unix uses exe file, too??

Share this post


Link to post
Share on other sites
Ok, I'll run through this as best I can:

These two are variables that are used later. Sometimes you want to passed the same arguments for every file you compile, so it's easier to have one place to change it rather than having to change it for each file.
GCCFLAGS= -Wall -pedantic -ggdb
LINKERFLAGS=-lpthread

I would also like to note that these names are a little non-standard. Typically GCCFLAGS would be named CFLAGS and LINKERFLAGS would be called LDLIBS, I'll touch on why at the end.

Now the whole point of a makefile is that you don't want to have to compile every file every time. It wastes your time, especially on big projects. You could just set it up so that only updated files are recompiled, but what if one file depends on another? You have to remake that too, right? So you need some way to keep track of those dependencies and manage your build process. That's what a makefile does.

So the way we put that into the makefile is like this:
some_target: dependency1 dependency2 ...
<tab> commands that build some_target

Now "all" is a target you find in a lot of Makefiles. It means just that, build everything. It's also usually the very first target, because of the way you call make. You would type "make some_target", but if you just type "make" then it builds whatever target is first, so since most people want to "make all", "all" usually shows up first.
all:  Apps MasterCow.exe

Here we see that to satisfy "all" we need to make sure that both "Apps" and "MasterCow.exe" are up to date. If they are, then there's no follow-up commands. A file called "all" is never really built; in this way it's kind of a meta-target. In this case, it's like you called "make all" and now make is going to run "make Apps" and then "make MasterCow.exe" on its own.

Apps:  Starter.exe Endless.exe

Here it shows that "Apps" isn't satisfied unless "Starter.exe" and "Endless.exe" are up to date. So make is going to run "make Starter.exe" and "make Endless.exe".

Ah, here's some meat:
Sender.exe: Starter.o Util.o
gcc -o Starter.exe ${GCCFLAGS} ${LINKERFLAGS} Starter.o Util.o

In order to build "Sender.exe" we need to make sure that "Starter.o" and "Util.o" are up to date. If they are, then it's going to run the command "gcc -o Starter.exe ${GCCFLAGS} ${LINKERFLAGS} Starter.o Util.o". Remember defining GCCFLAGS before? Once you have a variable defined, ${var-name} is how you reference it. So the command run is actually "gcc -o Starter.exe -Wall -pedantic -ggdb -lpthread Starter.o Util.o".

This one is a little simpler; "Sender.o" depends on "Starter.c" "appsdef.h" and "Util.h" so if you changed any of those files, "Sender.o" get rebuilt.
Sender.o: Starter.c appdefs.h Util.h
gcc -c ${GCCFLAGS} Starter.c


This is probably not the best makefile to use for a subject of study; why does the target "Receiver.exe" create the file "Endless.exe"?
Receiver.exe: Endless.o Util.o
gcc -o Endless.exe ${GCCFLAGS} ${LINKERFLAGS} Endless.o Util.o


This is something that could be handled automatically, but I'll get to that at the end.
Receiver.o: Endless.c appdefs.h Util.h
gcc -c ${GCCFLAGS} Receiver.c


Hopefully the next chunk should be easy to understand by now:

Ritardatore.o: MasterCow.c appdefs.h Util.h
gcc -c ${GCCFLAGS} MasterCow.c

Ritardatore.exe: MasterCow.o Util.o
gcc -o MasterCow.exe ${GCCFLAGS} ${LINKERFLAGS} Util.o MasterCow.o

Util.o: Util.c
gcc -c ${GCCFLAGS} Util.c


So here's "clean". It's a meta-target in a way. If you wanted to get rid of all your binary files that you've made, perhaps because you're building an archive, or didn't set up dependencies right and you need a fresh start. It doesn't depend on anything, so calling "make clean" should always work (depending on your particular implementation of make). When we call "make clean" it runs through all those commands, cleaning out the object files, the executables, and apparently any core dumps.

clean:
rm -f core*
rm -f *.exe
rm -f Starter.o Starter.exe
rm -f Endless.o Endless.exe
rm -f MasterCow.o MasterCow.exe
rm -f Util.o


So what's the right way to do it? Not really this. I'll post that in a minute.

Share this post


Link to post
Share on other sites
Ok, proper Makefiles, and project management in general.

Rule number one: a source file's name should reflect the binary it creates.

For instance, what source file do you use to make "Sender.o"? It should be "Sender.c" but instead it's "Starter.c". That's confusing and can lead to headaches later. "foo.c" should make "foo.o" and "bar.o" should come from "bar.c".

Rule number two: Don't depend on something there's no rule to build. "Apps" depends on "Starter.exe" but where does it say how to build that executable? There's "Sender.exe" "Receiver.exe" and "Ritadatore.exe" but no "Starter.exe" anywhere!

Rule number three: Don't build object files that get make into executables.

If you have some "foo.c" that makes "foo.exe", don't do something like this:
foo.exe: foo.o
gcc -o foo.exe foo.o
foo.o: foo.c
gcc -c foo.c

When you could just do:
foo.exe: foo.c
gcc -o foo.exe foo.c

It's redundant and unmanageable. It creates extra files, and it's hard to understand what you goal is when reading the makefile.

Rule number four: Make use of default rules.

Make is pretty smart. It knows that .c files make .o files. It knows what an executable is. It even knows how to compile them. It knows the difference between C and C++ and a few other languages.

If you look at the example in rule 3, both of those targets are completely unnecessary. You can call "make foo.o" and if there's a foo.c or foo.cpp then make figures it out. If there's no appropriate named source file, it complains and quits.

It also knows that anything that isn't an object file, but depends on .c and .o files is probably an executable, so even the foo.exe is unnecessary.

So excluding these doesn't violate rule two, because the targets are implicitly already there.

Ah, but what about GCCFLAGS and LINKERFLAGS? Well, like I said, these should be named CFLAGS and LDLIBS. That way, make knows what they are and where to include them. When we type "make foo.exe" and there's an appropriate "foo.c" then make will run
gcc ${CFLAGS} -o foo.exe foo.c ${LDLIBS}

all on its own.

But what if it needs more than foo.c? What if it needs bar.o? All you need is a single entry:
foo.exe: foo.c bar.o

No commands necessary. When you run "make foo.exe" it checks to see if foo.c exists, and then it sees if bar.o is up to date. If not then it runs:
gcc ${CFLAGS} -c bar.o

(no linking is done for object files)
After bar.o is all set to go, it works out the command to make foo.exe:
gcc ${CFLAGS} -o foo.exe foo.c bar.o ${LDLIBS}

and voila!

Share this post


Link to post
Share on other sites
Now the makefile you provided is a little confusing, but I took a stab at what you probably want. Feel free to ask questions.


CFLAGS= -Wall -pedantic -ggdb
LLDLIBS=-lpthread

all: Apps MasterCow.exe

MasterCow.exe: MasterCow.c Util.o appsdef.h

Apps: Starter.exe Endless.exe

Starter.exe: Starter.c Util.o appdefs.h

Endless.exe: Endless.c Util.o

Receiver.o: Receiver.c appdefs.h Util.h

Util.o: Util.c Util.h

clean:
rm -f *.exe *.o core*

Share this post


Link to post
Share on other sites
I'm without words...
thank you erissian!!!

excellent lesson... now is all clear!!

I thought that 'all' or 'app' were a commands... and not labels :)
because I found them in more makefile on the net...

thanks again!
now I go to test my new knowledge!!

goodbye

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement