ubuntu 12.04 sdl makefile

Hi Guys

I seem to be having problems creating a working makefile for a simple sdl program. Ubuntu 12.04 lts is my operating system and no matter what I try to fix to makefile I haven't got a successful compile. I can manually compile it no probs tho. The files are as follows

skeletal.cpp

// skeletal sdl app

#include <SDL/SDL.h>
#include <iostream>

using namespace std;

int main(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_VIDEO)) {
cerr << "SDL failed to initialize" << endl;
} else { cerr << "SDL initialized sucessfully" << endl;
}

return -1;
}


and the makefile so far

# Set compiler to g++
CXX = g++

# Set comilation flags to include SDL
CPPFLAGS = -Wall $(shell sdl-config --cflags)

# Set Load flags to include SDL
LDFLAGS = $(shell sdl-config --libs)

# load all .cpp files in directory
SOURCES = $(wildcard *.cpp)

# create object files from source
OBJECTS = $(SOURCES:.cpp=.o)

# Set target
EXE = bin/skeletal

# g++ -Wall skeletal.cpp $(sdl-config --cflags --libs) -o skeletal
all: $(SOURCES) $(EXE)

$(EXE): $(OBJECTS)
$(CXX) $(CPPFLAGS) $(OBJECTS) -o $@

.cpp.o:
$(CXX) -c $(SOURCES) -o $@ $(LDFLAGS)

clean:
rm -f $(OBJECTS) $(EXE)

You'll see the line just above all which is a commented version of a working compile command. That's what I'm trying to emulate

I'm probably just missing something simple. Had no probs on ubuntu 10.04 but something's obviously changed along the way

thx in advance
You shouldn't define more than what is necessary in a makefile. For example, you shouldn't define CXX or .cpp.o

Target all should be $(EXE), it shouldn't specify $(SOURCES).

Can you please edit your post of the makefile and put it in code tags to be clear on what you have. Tabs are important.
Forgot to mention that the error I'm getting is undefined reference to 'SDL_Init'
That's because you are not linking

> I can manually compile it no probs tho
Compare your process with the one in the makefile
make --just-print
Have you got LDFLAGS and CPPFLAGS the right way round?

$(EXE): $(OBJECTS)
$(CXX) $(CPPFLAGS) $(OBJECTS) -o $@

.cpp.o:
$(CXX) -c $(SOURCES) -o $@ $(LDFLAGS)


And your inference rule doesn't look right. Why are you passing $(SOURCES) to the compiler here? (this rule is about converting one .cpp file to one .o file)

make --just-print (as ne555 mentioned), or equivalently make -n (if you're lazy) will help.

And make --print-data-base or make -p will print out all the predefined rules, including

CXX = g++

# Not a target:
.cpp.o:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# commands to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<

COMPILE.cpp = $(COMPILE.cc)

COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

Andy
Last edited on
I don't use Ubuntu, but I installed SDL2 on Mac OS using Fink.

I've tweaked your code, as x.cc:
1
2
3
4
5
6
7
8
9
#include <SDL2/SDL.h>
#include <iostream>

int main(int argc, char *argv[])
{
	std::cout << SDL_Init(SDL_INIT_VIDEO) << std::endl;

	return 0;
}


From the command line, it's built with this:
 
c++ -I/sw/include -L/sw/lib -lSDL2 x.cc -o x


On my system, Fink installs to /sw, and I'm using SDL2.

The makefile I created looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PROG = x

SDL_ROOT = /sw
SDL_INCPATH = $(SDL_ROOT)/include
SDL_LIBPATH = $(SDL_ROOT)/lib
SDL_LIBS = -lSDL2

CPPFLAGS = -I$(SDL_INCPATH)
LDFLAGS = -L$(SDL_LIBPATH) $(SDL_LIBS)

PROG_SRCS = x.cc
PROG_OBJS = $(PROG_SRCS:.cc=.o)

all: $(PROG)

$(PROG): $(PROG_OBJS)
	$(LINK.cc) $^ -o $@


When run, it does this:
c++  -I/sw/include  -c -o x.o x.cc
c++  -I/sw/include -L/sw/lib -lSDL2  x.o -o x


There's an introductory article on Make here:
http://www.cplusplus.com/articles/jTbCpfjN/

I hope this helps.
Last edited on
Hi ne555

I'm guessing the linking error may to to do with the addition of the -c? If I leave that out I get the following:

g++ skeletal.cpp -o skeletal.o -L/usr/lib/i386-linux-gnu -lSDL
g++ -Wall -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT skeletal.o -o bin/skeletal
skeletal.o:(.rodata+0x4): multiple definition of `_IO_stdin_used'
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 20 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 21 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 22 has invalid symbol index 21
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
skeletal.o:(.rodata+0x0): multiple definition of `_fp_hw'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:(.rodata+0x0): first defined here
skeletal.o: In function `__data_start':
(.data+0x4): multiple definition of `__dso_handle'
/usr/lib/gcc/i686-linux-gnu/4.6/crtbegin.o:(.data+0x0): first defined here
skeletal.o: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crti.o:(.fini+0x0): first defined here
skeletal.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:/build/buildd/eglibc-2.15/csu/../sysdeps/i386/elf/start.S:119: first defined here
skeletal.o: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crti.o:(.init+0x0): first defined here
skeletal.o: In function `__data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:(.data+0x0): first defined here
/usr/lib/gcc/i686-linux-gnu/4.6/crtend.o:(.dtors+0x0): multiple definition of `__DTOR_END__'
skeletal.o:(.dtors+0x4): first defined here
/usr/bin/ld: error in skeletal.o(.eh_frame); no .eh_frame_hdr table will be created.
collect2: ld returned 1 exit status
make: *** [bin/skeletal] Error 1

Basically a plethora of multiple definition errors. PS. did I mention I hadn't done this for nigh on 2 years so definitely rusty. When I added the -c the definition errors stopped and I didn't see any warnings re the object file creation. In fact the object file was created so I assumed that part worked and the error was with building the executable?
Hi andywestken

I do recall from my googling that the order of things is now important. and have tried various different ways around to no avail. I ether end up with SDL_Init undefined or multiple definitions of various functions which I gather is telling me make is trying to compile the same file twice?

Make -n gives me

g++ -Wall -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT skeletal.o -o bin/skeletal

Note I took the -c out of the equation. Mind you the working direct command is

g++ -Wall skeletal.cpp $(sdl-config --cflags --libs) -o skeletal

Ok. I think I see a discrepancy between the 2. The makefile generated version doesn't appear to have a .cpp file listed at all? That seems odd to me despite how rusty I am (2 - 3 years since I last tried on the pc). I've had no probs compiling on c4droid on my android devices apart from a chinese tablet. I've noticed the difference in trying to compile on the 2 platforms. I've ditched windows years ago so for now I don't have that option til maybe I replace my now defunct netbook. There's still a few replies to sort thru to give me ideas

Looking at your addition of CXXFLAGS has me thing possibly thing an implicit rule?. Either way a few things to think about til I get home to try again
Hi kbw

The thing that stands out most to me in your post is the

$(LINK.cc) $^ -o $@

line. I did have the impression that since my makefile actually generated and object file that that part was ok. I just added sdl2 to my system as well so I can try that later but 1st I'd rather get this right as it will likely impact my ability to compile that. I'm seeing my reply just above this as I type and am thinking the order in my makefile is wrong. The makefile generated command doesn't list a source file as I see it between the -Wall and the -I...... portions. Could that be the area giving me probs?. Also noticed the lack of a -c in the working command so guess that ain't need in the makefile. It doesn't help being over a family members place when every few secs I'm asked to fix this or that while i'm trying to work this out so I'll go thru everything tomorrow when I have no interruptions
The thing that stands out most to me in your post is the
 
$(LINK.cc) $^ -o $@


GNU Make has a number of standard rules. You can see them by running:
 
make -p


LINK.cc is the macro for running the C++ linker. By default GNU Make runs the C linker, that's why you have to specify the C++ linker.

The $^ and $@ macros are explained in the link I posted earlier.

I did have the impression that since my makefile actually generated and object file that that part was ok.
I considered your makefile problematic because it defined things that it should not define.

Why not define CXX in your makefile when the default will do? Let's say you installed Intels compiler. You use it without modifying your makefile by running:
 
make CXX=icc


Also, it's important not to mess around with the make rules unless you really need to, and in this case, you don't really need to.

I posted what I think is a better GNU Makefile for you to use as a reference.
hi kbw

re my make file I was actually going by tutorials I found online. I guess that's the minus side of googling, i.e. sometimes the info aint the best. I'd like to check out the makefile you posted but I don't see it or a link to it?
The makefile is listed above.

The link is posted above, it's a link to an article about make on this site.
Thx for the input guys. Got a working makefile by simplifying it somewhat. Now just one rule, aka all: with the recipe

$(CXX) -Wall $(SRC) $(LDFLAGS) -o $(EXE)

It compiles and executes so I guess this is solved
Topic archived. No new replies allowed.