Search code examples
makefilestatic-librariesld

ld: undefined reference, but it should leave them unresolved


I am unable to produce a library, which works with another library (SDL). I am using MinGW for make, and ld to link. I am confused because a) it shouldn't be trying to link in these libraries, but do this later when someone links my library in as well; and b) even if I do link in the SDL libraries, it still can't find the SDL functions (SDL_GetTicks, SDL_Delay) it's looking form -- the errors are the same. Also note that some of the missing items are from std.

Here are the errors. As you can see, I'm trying various flags on ld to make it not try to resolve references, but w/o success yet.

C:\Users\...\mcve>make
g++ -c -c -I../../../external/SDL2/include -I../include -o mcve.o mcve.cpp
ld -G --unresolved-symbols=ignore-all --warn-unresolved-symbols  -o libmcve.a mcve.o    
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x8): undefined reference to `SDL_GetTicks'
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x23): undefined reference to `SDL_GetTicks'
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x2f): undefined reference to `SDL_Delay'
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x46): undefined reference to `std::ios_base::Init::~Init()'
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x67): undefined reference to `std::ios_base::Init::Init()'
C:\MinGW\bin\ld.exe: mcve.o:mcve.cpp:(.text+0x73): undefined reference to `atexit'

Here's my source file:

#include <SDL.h>
#include <iostream>         //If I take this out, I no longer get the 
                            //unresolved references to std::ios_base::Init::Init,
                            // std::ios_base::Init::~Init, and atexit

Uint32 time;    

void doSomething () 
{
  if (time > SDL_GetTicks ()) 
    SDL_Delay (time - SDL_GetTicks());
}

This is the Makefile. If I uncomment the rest of the LDFLAGS and let the SDL libraries link in, it does not change the output.

CFLAGS  =-c -I../../../external/SDL2/include -I../include
LDFLAGS = --unresolved-symbols=ignore-all --warn-unresolved-symbols #-L. -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer 

# Files
SOURCE_FILES= mcve.cpp
OBJECT_FILES= mcve.o

libmcve.a: $(OBJECT_FILES)
    ld $(LDFLAGS) -o $@ $^ -G

$(OBJECT_FILES): %.o: $(SOURCE_FILES)
    g++ -c $(CFLAGS) -o $@ $<

Solution

  • You are attempting to create the static library libmcve.a from the object file mcve.o using the linker ld.

    The linker cannot produce a static library. A static library is merely an ar archive of object files that is produced by ar.

    The recipe to create or update the static library in your makefile would be:

    libmcve.a: $(OBJECT_FILES)
        rm -f $@    # Delete archive if already exists
        ar rcs $@ $^ # Recreate archive with contents $(OBJECT_FILES)
    

    BTW, note that you are passing the -c option in your compilation commands twice:

    g++ -c -c -I../../../external/SDL2/include -I../include -o mcve.o mcve.cpp
    

    That is because you have included it in your CFLAGS setting:

    CFLAGS  =-c -I../../../external/SDL2/include -I../include
    

    (where it should not be), and also in your compilation recipe:

    g++ -c $(CFLAGS) -o $@ $<
    

    (where it should be).