0
votes

I'm trying to use SDL and C++ for making a game.

So far, I haven't been able to do anything with that. I followed all the instructions for Mac (I have a Mac v. 10.12.2) and g++ on http://www.lazyfoo.net/tutorials/SDL/01_hello_SDL/index.php.

Right now, I'm having linker errors that say that they cannot find the library designated by the -l (lowercase L) option. Here is my Makefile:

CC = g++
CFLAGS = -g -Wall -std=c++11

SDL_PATH = /Users/myname/Documents/Code-Libraries/SDL2-2.0.5
SDL_INCLUDE = -I$(SDL_PATH)/include
SDL_LIB = -L$(SDL_PATH) -l/usr/local/lib/libSDL2.a

default: SDL01 

SDL01: 01_hello_SDL.cpp
    $(CC) $(CFLAGS) 01_hello_SDL.cpp $(SDL_LIB) $(SDL_INCLUDE) -o SDL01

clean:
    rm -f SDL01 *.o

I've tried -lSDL2. I've tried -lSDL. I've tried -l/usr/local/lib/libSDL2.a. I've tried just the -L option (no -l option) with various ways of writing /Users/myname/Documents/Code-Libraries/SDL2-2.0.5 and this one (/Users/myname/Documents/Code-Libraries/SDL2-2.0.5) gave me...

Undefined symbols for architecture x86_64:
  "_SDL_CreateWindow", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_Delay", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_DestroyWindow", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_FillRect", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_GetError", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_GetWindowSurface", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_Init", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_MapRGB", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_Quit", referenced from:
      _main in 01_hello_SDL-f65b5c.o
  "_SDL_UpdateWindowSurface", referenced from:
      _main in 01_hello_SDL-f65b5c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [SDL01] Error 1

...while the others told me they could not find the headers for the project. I'm really lost and would really love some help. Thank you.

EDIT1:

I did nm /usr/local/lib/libSDL2.a | grep _SDL_CreateWindow and got

0000000000001cb0 T _SDL_CreateWindow
0000000000000f80 T _SDL_CreateWindowAndRenderer
0000000000007620 t _SDL_CreateWindowAndRenderer_DEFAULT
                 U _SDL_CreateWindowAndRenderer_REAL
0000000000001cc0 T _SDL_CreateWindowFrom
0000000000009e80 t _SDL_CreateWindowFrom_DEFAULT
                 U _SDL_CreateWindowFrom_REAL
0000000000009e30 t _SDL_CreateWindow_DEFAULT
                 U _SDL_CreateWindow_REAL
0000000000000060 T _SDL_CreateWindowAndRenderer_REAL
                 U _SDL_CreateWindow_REAL
                 U _SDL_CreateWindow_REAL
00000000000030a0 T _SDL_CreateWindowFrom_REAL
0000000000000760 t _SDL_CreateWindowTexture
0000000000002010 T _SDL_CreateWindow_REAL
                 U _SDL_CreateWindow_REAL

EDIT2:

These are the files/directories in the ~/Documents/Code-Libraries/SDL2-2.0.5/ directory:

Android.mk                SDL2.spec.in              cmake_uninstall.cmake.in
BUGS.txt                  TODO.txt                  configure
CMakeLists.txt            VisualC/                  configure.in
COPYING.txt               VisualC-WinRT/            debian/
CREDITS.txt               VisualC.html              docs/
INSTALL.txt               WhatsNew.txt              include/
Makefile.in               Xcode/                    sdl2-config.cmake.in
Makefile.minimal          Xcode-iOS/                sdl2-config.in
Makefile.pandora          acinclude/                sdl2.m4
Makefile.psp              android-project/          sdl2.pc.in
Makefile.wiz              autogen.sh                src/
README-SDL.txt            build/                    test/
README.txt                build-scripts/            
SDL2.spec                 cmake/                    
1
The syntax here should be either -lSDL2 or /usr/local/lib/libSDL2.a , not -l/usr/local/lib/libSDL2.anos
@nos can you explain? I don't understand how g++ would understand /usr/local/lib/libSDL2.a to be the library I'm trying to link. Is it because it's *.a?astrocat1997
@nos also, it didn't work :-(. I got Undefined symbols for architecture x86_64: with a lot of junk.astrocat1997
Let's start with the basics. Does libSDL2.a exist on your computer? If so, in what directory? What does nm /your/path/to/libSDL2.a | grep _SDL_CreateWindow say?John Zwinck
We fixed it in chat. I'll leave it to you to post an answer summarizing what was wrong.John Zwinck

1 Answers

1
votes

Alright, so thanks to @JohnZwinck, I was able to figure out what I was doing wrong. When telling the compiler, g++, where the third-party library was, I was giving it the wrong place (-L/Users/myname/Documents/Code-Libraries/SDL2-2.0.5) and a name that means nothing to it (-lSDL2). So I did some further reading and here are some important quotes from https://linux.die.net/man/1/g++:

You can mix options and other arguments. For the most part, the order you use doesn't matter. Order does matter when you use several options of the same kind; for example, if you specify -L more than once, the directories are searched in the order specified. Also, the placement of the -l option is significant.

Linker Options

object-file-name -llibrary -nostartfiles -nodefaultlibs -nostdlib -pie -rdynamic -s -static -static-libgcc -shared -shared-libgcc -symbolic -T script -Wl,option -Xlinker option -u symbol

Directory Options

-Bprefix -Idir -iquotedir -Ldir -specs=file -I- --sysroot=dir

So basically, the -Ldirectory needs to come before the -llibrary because the -L option tells g++ where to look for the library, and then the -l option says what library it is. Without the -L before the -l, g++ doesn't know where to look for the library from -l.

Feel free to correct me if I'm wrong! But this solved my problem.