【问题标题】:ld: undefined reference, but it should leave them unresolvedld:未定义的引用,但它应该让它们未解决
【发布时间】:2019-02-07 17:31:07
【问题描述】:

我无法生成与另一个库 (SDL) 一起使用的库。我正在使用 MinGW 进行制作,并使用 ld 进行链接。我很困惑,因为a)它不应该尝试链接这些库,但是稍后当有人也链接我的库时这样做; b) 即使我在 SDL 库中进行链接,它仍然找不到它正在查找的 SDL 函数(SDL_GetTicksSDL_Delay)——错误是相同的。另请注意,一些缺失的项目来自std

这里是错误。如您所见,我正在尝试 ld 上的各种标志,以使其不尝试解析引用,但尚未成功。

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'

这是我的源文件:

#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());
}

这是 Makefile。如果我取消注释 LDFLAGS 的其余部分并让 SDL 库链接,它不会更改输出。

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 $@ $<

【问题讨论】:

  • 我不知道 MinGW,但通常你不使用链接器来创建库 (*.a) 文件。您将使用归档程序,例如 ar.exe

标签: makefile static-libraries ld


【解决方案1】:

您正在尝试从目标文件创建静态库libmcve.a mcve.o 使用链接器ld

链接器无法生成静态库。 static library 只是 由ar 生成的目标文件的ar 存档。

在您的 makefile 中创建或更新静态库的方法是:

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

顺便说一句,请注意您在编译命令中传递了 -c 选项 两次:

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

那是因为您已将其包含在您的 CFLAGS 设置中:

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

(它不应该在的地方),也在你的编译配方中:

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

(它应该在哪里)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 2018-08-27
    • 2022-09-22
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    相关资源
    最近更新 更多