Makefiles and such
<div class="IPBDescription">How I do Lunix?</div>So i'm not a big fan of Linux. Mostly because i've never really used it much, and also because i'm terminally lazy and Linux generally makes me work harder than Windows. So imagine my delight when I find that my 3rd year project has to be done under Linux rather than under windows as I had originally assumed. Thankfully I have a fairly Linux-savvy friend to help me out when things get too Linuxy, but i've stumbled across a problem that even he is unable to help me with.
Essentially what I need to do is take the output of an existing program (written by someone else from the interweb, but with full permission to do so) and send it to another program (written by someone from within the University). In this case this has meant modifying both programs to use sockets. I can do the actual programming required to make the program use sockets.... I just don't know what i'm supposed to do to the makefile to make it compile properly. There are actually two files in the directory, makefile and makefile.in, and i'm not sure what the difference is. The only difference I can see is the section towards the top, which is slightly different in makefile.in. I've posted first the whole of makefile, and then just the section of makefile.in which differs.
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->### RtMidi tests Makefile - for various flavors of unix
PROGRAMS = midiinfo midiout qmidiin cmidiin sysextest
RM = /bin/rm
SRC_PATH = ../
INCLUDE = ../
OBJECT_PATH = Release
vpath %.o $(OBJECT_PATH)
OBJECTS = RtMidi.o
CC = g++
DEFS =
DEFS += -D__LINUX_ALSASEQ__
CFLAGS = -O2
CFLAGS += -Wall -I$(INCLUDE)
LIBRARY = -lpthread -lasound
LIBRARY +=
%.o : $(SRC_PATH)/%.cpp
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
all : $(PROGRAMS)
midiinfo : midiinfo.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o midiinfo midiinfo.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
midiout : midiout.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o midiout midiout.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
qmidiin : qmidiin.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o qmidiin qmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
cmidiin : cmidiin.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o cmidiin cmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
sysextest : sysextest.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o sysextest sysextest.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
clean :
-rm $(OBJECT_PATH)/*.o
-rm $(PROGRAMS)
-rm -f *~
strip :
strip $(PROGRAMS)<!--QuoteEnd--></div><!--QuoteEEnd-->
And the "different" part in makefile.in:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->CC = @CXX@
DEFS = @debug@
DEFS += @midi_api@
CFLAGS = @cflags@
CFLAGS += @warn@ -I$(INCLUDE)
LIBRARY = @LIBS@
LIBRARY += @frameworks@<!--QuoteEnd--></div><!--QuoteEEnd-->
I'd hoped it would be as simple as adding the lines
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->Socket : Socket.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o Socket Socket.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
ClientSocket : ClientSocket.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o ClientSocket ClientSocket.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
<!--QuoteEnd--></div><!--QuoteEEnd-->
to the either or both of the makefiles, as Socket.cpp and ClientSocket.cpp are the only source files I want to add (there are some headers also, but I was under the impression that those handle themselves; I can't see any listed in the makefile for instance). Unfortunately, this is not the case. I have to do something probably far more complicated.
I've looked for a decent guide on makefileing, but most of them give me little clue what is going on here. If someone can explain just what these lines of near incomprehensible.... stuff.... mean, I would owe that someone many E-cookies. Those are still a valid form of currency here, right?
Essentially what I need to do is take the output of an existing program (written by someone else from the interweb, but with full permission to do so) and send it to another program (written by someone from within the University). In this case this has meant modifying both programs to use sockets. I can do the actual programming required to make the program use sockets.... I just don't know what i'm supposed to do to the makefile to make it compile properly. There are actually two files in the directory, makefile and makefile.in, and i'm not sure what the difference is. The only difference I can see is the section towards the top, which is slightly different in makefile.in. I've posted first the whole of makefile, and then just the section of makefile.in which differs.
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->### RtMidi tests Makefile - for various flavors of unix
PROGRAMS = midiinfo midiout qmidiin cmidiin sysextest
RM = /bin/rm
SRC_PATH = ../
INCLUDE = ../
OBJECT_PATH = Release
vpath %.o $(OBJECT_PATH)
OBJECTS = RtMidi.o
CC = g++
DEFS =
DEFS += -D__LINUX_ALSASEQ__
CFLAGS = -O2
CFLAGS += -Wall -I$(INCLUDE)
LIBRARY = -lpthread -lasound
LIBRARY +=
%.o : $(SRC_PATH)/%.cpp
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
all : $(PROGRAMS)
midiinfo : midiinfo.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o midiinfo midiinfo.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
midiout : midiout.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o midiout midiout.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
qmidiin : qmidiin.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o qmidiin qmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
cmidiin : cmidiin.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o cmidiin cmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
sysextest : sysextest.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o sysextest sysextest.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
clean :
-rm $(OBJECT_PATH)/*.o
-rm $(PROGRAMS)
-rm -f *~
strip :
strip $(PROGRAMS)<!--QuoteEnd--></div><!--QuoteEEnd-->
And the "different" part in makefile.in:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->CC = @CXX@
DEFS = @debug@
DEFS += @midi_api@
CFLAGS = @cflags@
CFLAGS += @warn@ -I$(INCLUDE)
LIBRARY = @LIBS@
LIBRARY += @frameworks@<!--QuoteEnd--></div><!--QuoteEEnd-->
I'd hoped it would be as simple as adding the lines
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->Socket : Socket.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o Socket Socket.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
ClientSocket : ClientSocket.cpp $(OBJECTS)
$(CC) $(CFLAGS) $(DEFS) -o ClientSocket ClientSocket.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
<!--QuoteEnd--></div><!--QuoteEEnd-->
to the either or both of the makefiles, as Socket.cpp and ClientSocket.cpp are the only source files I want to add (there are some headers also, but I was under the impression that those handle themselves; I can't see any listed in the makefile for instance). Unfortunately, this is not the case. I have to do something probably far more complicated.
I've looked for a decent guide on makefileing, but most of them give me little clue what is going on here. If someone can explain just what these lines of near incomprehensible.... stuff.... mean, I would owe that someone many E-cookies. Those are still a valid form of currency here, right?
Comments
If you have a working Makefile, then just ignore Makefile.in.
Assuming you have tab characters in front of the commands in your Socket and ClientSocket targets then they look okay. You will need to add the targets to the all: target or it won't get invoked unless you explicitly add it to the command line.
The all target is the key.
all : $(PROGRAMS)
When you invoke 'make' with no arguments it will try to satisfy the first target's dependencies in the filec ( in this case, all ). $PROGRAMS does not contain your new targets, so therefore they will not be looked at. You need to edit
PROGRAMS = midiinfo midiout qmidiin cmidiin sysextest
to
PROGRAMS = midiinfo midiout qmidiin cmidiin sysextest Socket ClientSocket
Alternatively, you can simply invoke those targets with make
bash-$ make Socket ClientSocket
80% of the features you should ever need to know about make are really straight forward. The file you have is very basic, but also very badly written. It is more confusing than it needs to be, and contains redundant targets and rules.
When I add Socket and ClientSocket to the list of programs in the makefile, it DOES try to compile them... and promptly fails. I've also noticed that regardless of the order I tell the makefile to compile in, it ALWAYS starts with either ClientSocket or Socket, whichever is first in the list, which seems strange. Or is it only showing output from the file which causes it to fail? It certainly doesn't like having qmidiin (the main program) compiled before Socket or ClientSocket because it complains about undefined references. If I compile in the order midiinfo midiout Socket ClientSocket qmidiin cmidiin sysextest I get this in response:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->rtmidi-1.0.6/tests> make
g++ -O2 -Wall -I../ -D__LINUX_ALSASEQ__ -o Socket Socket.cpp Release/RtMidi.o -lpthread -lasound
/usr/lib/gcc/i586-suse-linux/4.1.0/../../../crt1.o: In function `_start':
init.c:(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [Socket] Error 1
<!--QuoteEnd--></div><!--QuoteEEnd-->
If I do the same, but with ClientSocket first, I get many complaints about undefined references to functions in Socket, so that clearly won't work either. It seems to be looking for a main function in Socket, but Socket doesn't HAVE a main function. Is there a way to inform the makefile as such?
The original makefile for the socket program, if it helps, goes something like this:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->
simple_client_objects = ClientSocket.o Socket.o simple_client_main.o
all : simple_client
simple_client: $(simple_client_objects)
g++ -o simple_client $(simple_client_objects)
Socket: Socket.cpp
ClientSocket: ClientSocket.cpp
simple_client_main: simple_client_main.cpp
clean:
rm -f *.o simple_client<!--QuoteEnd--></div><!--QuoteEEnd-->
I can't help but notice that it compiles all three files to seperate object files, wheras RtMidi uses just one. Is that part of the problem?
*edit*
To clarify, simple_client consists of JUST the socket code. What i'm trying to do is put this code into RtMidi so that I can recieve MIDI data, then pass it to another program.
No offence, but you'll never learn anything useful that way. I really suggest you should RTFM on this one and learn the basics of how make works.
However, if you really just want a makefile that works, just send me your existing makefile and I'll fix it up for you.
Although it would be nice to just have the solution handed to me, I would like to know what the makefile is trying to do now, why it isn't working, and how I can fix it. Myself. I can't RTFM if I don't know where the M is. I've read tutorials on how to create a makefile, and none of them looked even nearly as complicated as this. I can see what the makefile is doing, I just don't understand why it isn't working, and having things in the wrong dependancy order (or having some missing dependencies) is the only reason I can see it would be complaining about not being able to find something.
I've already corrected my first mistake; Socket and ClientSocket don't need to be in the list of programs, because they don't actually produce an executable at the end. Now it just complains about qmidiin having undefined references. So I tried adding any files I can think of that qmidiin could possibly depend on to its dependancies.... nothing.
What I really need to know is; how do I tell the makefile that qmidiin depends on Socket.h, Socket.cpp, ClientSocket.h and ClientSocket.cpp? As far as I understand it, it <i>should</i> just be a line like:
qmidiin : qmidiin.cpp ClientSocket.cpp Socket.cpp ClientSocket.h Socket.h
But that doesn't work.
So if that's not how I tell the makefile that qmidiin depends on those files, how do I?