Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

757
Views
C : Unix SDL2 library : undefined reference, issue in the Makefile?

I'm looking to make a Makefile that can compile a C program on Unix (Ubuntu). That Makefile should include the SDL library (2.0), as well as SDL_image.

So here's my current Makefile :

CC = gcc
OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c))
EXEC = main

LDFLAGS = `sdl2-config --libs` -L/usr/lib -lSDL2_image
CCFLAGS = `sdl2-config --cflags` -I/usr/include/SDL_image.h

$(EXEC): $(OBJECTS)
    $(CC) $(LDFLAGS) $< -o $@

%.o: %.c
    $(CC) -c $(CCFLAGS) $< -o $@

.PHONY: clean

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

And here's my current code (minimal code just to test the Makefile):

#include <stdio.h>
#include <SDL.h>
#include <SDL2/SDL_image.h>

int main(int argc, char **argv) {

    SDL_Window* window = NULL;
    SDL_Surface* screenSurface = NULL;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Initialization error: %s\n",SDL_GetError());
        return 1;
    }

    window = SDL_CreateWindow("Test",SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,640, 480,SDL_WINDOW_SHOWN);

    SDL_Quit();
    return 0;
}

So when I write the command : make

I get errors on all of the SDL functions. Here's an example : undefined reference to `SDL_Init'

I have tried many things (such as different paths for the Include and Link in the Makefile), but nothing seems to work.

So my question is : How can I solve theses undefined references to SDL2 functions ?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

You are specifying linker flags in the wrong order.

This is wrong:

LDFLAGS = `sdl2-config --libs` -L/usr/lib -lSDL2_image
$(EXEC): $(OBJECTS)
    $(CC) $(LDFLAGS) $< -o $@

This is correct:

LIBS = `sdl2-config --libs` -L/usr/lib -lSDL2_image
$(EXEC): $(OBJECTS)
    $(CC) $(LDFLAGS) $^ $(LIBS) -o $@

With GNU Binutils, the order of libraries is important. Libraries must come after the objects which have undefined references to symbols in those libraries. It sucks, it's stupid, but it's the way GNU Binutils works and you're stuck with it.

Other fixes

  • You want $^ instead of $<, because $< is only the first dependency.

  • Probably best to use pkg-config which can find SDL2_image for you:

    LIBS = `pkg-config --libs sdl2 SDL2_image`
    
  • You probably want := not = when you invoke shell programs, this will expand the variable once, instead of every time it is used:

    LIBS := $(shell pkg-config --libs sdl2 SDL2_image)
    CFLAGS := $(shell pkg-config --cflags sdl2 SDL2_image)
    

Full example

Here is a cleaned up example, close to how I would write it:

# use := not =
# convention: objects, exec are lower-case because they're private
objects := $(patsubst %.c,%.o,$(wildcard *.c))
CFLAGS := $(shell pkg-config --cflags sdl2 SDL2_image)
LIBS := $(shell pkg-config --libs sdl2 SDL2_image)

# Don't define CC, because the default (cc) is fine
# It's probably linked to gcc on your system anyway

# = or := doesn't matter here
exec = main

# must use = here
depflags = -MF $(patsubst %.o,%.d,$@) -MMD -MP
-include $(wildcard *.d)

$(exec): $(objects)
    $(CC) $(LDFLAGS) $^ $(LIBS) -o $@

%.o: %.c
    $(CC) $(depflags) -c $(CCFLAGS) $< -o $@

.PHONY: clean
clean:
    rm -f *.o *.d $(exec)
over 4 years ago · Santiago Trujillo Report

0

You inverted some compiler/linker options:

# linker options
LDFLAGS = `sdl2-config --libs` -I/usr/include/SDL_image.h
# compiler options
CCFLAGS = `sdl2-config --cflags` -L/usr/lib -lSDL2_image

It should be:

# linker options
LDFLAGS = `sdl2-config --libs` -L/usr/lib -lSDL2_image
# compiler options
CCFLAGS = `sdl2-config --cflags` -I/usr/include

Details:

-L Is to indicate to the linker where to find .so files
-l Is to link to a given library
-I Is to indicate to the compiler where to find .h files
over 4 years ago · Santiago Trujillo Report

0

As can be seen in the Catalogue of Built-In Rules:

Linking a single object file

n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is:

$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)

and Variables Used by Implicit Rules:

LDFLAGS

Extra flags to give to compilers when they are supposed to invoke the linker, ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.

So in this case -lSDL2_image should be set or added to LDLIBS, not LDFLAGS.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!