【问题标题】:Why am I still getting 'undefined reference' linker errors when using SDL2?为什么在使用 SDL2 时仍然出现“未定义的引用”链接器错误?
【发布时间】:2019-02-25 01:05:50
【问题描述】:

我已经查看了与此错误直接相关的堆栈溢出的所有其他页面。

我正在尽我所能,但我仍然收到此错误

对 `SDL_Init' 的未定义引用

这是构建日志:

C:\WINDOWS\system32\cmd.exe /C C:/TDM-GCC-64/bin/mingw32-make.exe -j4 SHELL=cmd.exe -e -f  Makefile
"----------Building project:[ testproject - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/Users/Andre/Documents/CodeLiteWorkspace/testproject'
C:/TDM-GCC-64/bin/g++.exe -o ./Debug/testproject @"testproject.txt" -L.
./Debug/main.cpp.o:main.cpp:(.text+0x43): undefined reference to `SDL_Init'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[1]: *** [Debug/testproject] Error 1
testproject.mk:82: recipe for target 'Debug/testproject' failed
mingw32-make.exe[1]: Leaving directory 'C:/Users/Andre/Documents/CodeLiteWorkspace/testproject'
mingw32-make.exe: *** [All] Error 2
Makefile:4: recipe for target 'All' failed
====2 errors, 0 warnings====

这些是我正在使用的构建选项

-std=c++11;-IC:\SDL2\include -LC:\SDL2\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2

而且我知道一切(编译器和库文件)都是 64 位二进制文​​件。我发现它给了我同样的错误,但不是SDL_Init,而是说WinMain,如果我要使用普通的int main()入口函数,所以现在我使用int WinMain(),它消除了那个错误。所以现在我的代码只包含

extern "C"{
    #include <SDL2/SDL.h>
}

int WinMain(){
    SDL_Init( SDL_INIT_EVERYTHING );
    return 0;
}

如果我注释掉 SDL_Init 函数,程序不会出现构建错误,但不会执行任何操作。

有人知道这是否与我使用的编译器略有不同有关吗?另外,我不确定,但从构建日志看来,它实际上并没有使用我提供的构建选项(我使用的是 IDE,因此程序可以管理它)。最后,如果有人知道它为什么要我使用 WinMain 而不是常规的 main 函数,并告诉我要改变什么来解决这个问题,那将不胜感激。

制作文件:

##
## Auto Generated makefile by CodeLite IDE
## any manual changes will be erased      
##
## Debug
ProjectName            :=testproject
ConfigurationName      :=Debug
WorkspacePath          :=C:/Users/Andre/Documents/CodeLiteWorkspace
ProjectPath            :=C:/Users/Andre/Documents/CodeLiteWorkspace/testproject
IntermediateDirectory  :=./Debug
OutDir                 := $(IntermediateDirectory)
CurrentFileName        :=
CurrentFilePath        :=
CurrentFileFullPath    :=
User                   :=Andrew900460
Date                   :=20/09/2018
CodeLitePath           :="C:/Program Files/CodeLite"
LinkerName             :=C:/TDM-GCC-64/bin/g++.exe
SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC
ObjectSuffix           :=.o
DependSuffix           :=.o.d
PreprocessSuffix       :=.i
DebugSwitch            :=-g 
IncludeSwitch          :=-I
LibrarySwitch          :=-l
OutputSwitch           :=-o 
LibraryPathSwitch      :=-L
PreprocessorSwitch     :=-D
SourceSwitch           :=-c 
OutputFile             :=$(IntermediateDirectory)/$(ProjectName)
Preprocessors          :=
ObjectSwitch           :=-o 
ArchiveOutputSwitch    := 
PreprocessOnlySwitch   :=-E
ObjectsFileList        :="testproject.txt"
PCHCompileFlags        :=
MakeDirCommand         :=makedir
RcCmpOptions           := 
RcCompilerName         :=C:/TDM-GCC-64/bin/windres.exe
LinkOptions            :=  
IncludePath            :=  $(IncludeSwitch). 
IncludePCH             := 
RcIncludePath          := 
Libs                   := 
ArLibs                 :=  
LibPath                := $(LibraryPathSwitch). 

##
## Common variables
## AR, CXX, CC, AS, CXXFLAGS and CFLAGS can be overriden using an environment variables
##
AR       := C:/TDM-GCC-64/bin/ar.exe rcu
CXX      := C:/TDM-GCC-64/bin/g++.exe
CC       := C:/TDM-GCC-64/bin/gcc.exe
CXXFLAGS := -std=c++11 -IC:\SDL2\include -Dmain=SDL_main -LC:\SDL2\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -mwindows  $(Preprocessors)
CFLAGS   := -g -O0 -Wall  $(Preprocessors)
ASFLAGS  := 
AS       := C:/TDM-GCC-64/bin/as.exe


##
## User defined environment variables
##
CodeLiteDir:=C:\Program Files\CodeLite
Objects0=$(IntermediateDirectory)/main.cpp$(ObjectSuffix) 



Objects=$(Objects0) 

##
## Main Build Targets 
##
.PHONY: all clean PreBuild PrePreBuild PostBuild MakeIntermediateDirs
all: $(OutputFile)

$(OutputFile): $(IntermediateDirectory)/.d $(Objects) 
    @$(MakeDirCommand) $(@D)
    @echo "" > $(IntermediateDirectory)/.d
    @echo $(Objects0)  > $(ObjectsFileList)
    $(LinkerName) $(OutputSwitch)$(OutputFile) @$(ObjectsFileList) $(LibPath) $(Libs) $(LinkOptions)

MakeIntermediateDirs:
    @$(MakeDirCommand) "./Debug"


$(IntermediateDirectory)/.d:
    @$(MakeDirCommand) "./Debug"

PreBuild:


##
## Objects
##
$(IntermediateDirectory)/main.cpp$(ObjectSuffix): main.cpp $(IntermediateDirectory)/main.cpp$(DependSuffix)
    $(CXX) $(IncludePCH) $(SourceSwitch) "C:/Users/Andre/Documents/CodeLiteWorkspace/testproject/main.cpp" $(CXXFLAGS) $(ObjectSwitch)$(IntermediateDirectory)/main.cpp$(ObjectSuffix) $(IncludePath)
$(IntermediateDirectory)/main.cpp$(DependSuffix): main.cpp
    @$(CXX) $(CXXFLAGS) $(IncludePCH) $(IncludePath) -MG -MP -MT$(IntermediateDirectory)/main.cpp$(ObjectSuffix) -MF$(IntermediateDirectory)/main.cpp$(DependSuffix) -MM main.cpp

$(IntermediateDirectory)/main.cpp$(PreprocessSuffix): main.cpp
    $(CXX) $(CXXFLAGS) $(IncludePCH) $(IncludePath) $(PreprocessOnlySwitch) $(OutputSwitch) $(IntermediateDirectory)/main.cpp$(PreprocessSuffix) main.cpp


-include $(IntermediateDirectory)/*$(DependSuffix)
##
## Clean
##
clean:
    $(RM) -r ./Debug/

【问题讨论】:

  • 为什么你的构建选项中有;
  • 哦,那是因为我正在使用的 ide。它有一个用于不同构建选项的复选框列表,然后是一个您可以输入自己的选项的位置。当您使用复选框时,它会在您选中的每个框后放置分号
  • 另外,有时当我构建时,它会在日志中列出错误之前的所有构建选项,而大多数其他时候它不会,就像我在这里粘贴的那样
  • 请同时发布您的makefile。
  • 有点长但还可以。我会把它放在帖子的底部

标签: c++ sdl sdl-2


【解决方案1】:

您已将链接选项添加到 CXXFLAGS - 它们不属于它们 - 但未添加到 LibPathLibsLinkOptions。因此,您在编译阶段指定了链接器选项(它什么都不做,因为没有执行链接),但在链接阶段没有它们。

“逻辑上”正确的设置是

Libs:=-lmingw32 -lSDL2main -lSDL2
LibPath:=-LC:\SDL2\lib -L.
LinkOptions:=-Wl,-subsystem,windows -mwindows

(不确定 SDL2main 是否应该存在,因为不清楚您是否使用它,因为您有 WinMain 而不是 main/SDL_main

此外,您确实询问了-w 选项的问题,所以您不应该感到惊讶。如果您不想要额外的问题,请不要阻止编译器为您提供帮助,甚至更好 - 至少通过 -Wall 寻求更多帮助。

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 2019-11-25
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多