gcc无法编译SDL C程序(undefined reference to SDL functions)

4

我最近切换到了Linux系统,但在使用gcc编译SDL C程序时遇到了问题。

我使用的命令是:

gcc `sdl-config --cflags --libs` -o main main.c

即使分开使用sdl-config标志:
gcc `sdl-config --cflags` -c main.c
gcc `sdl-config --libs` -o main main.o

我遇到了同样的错误:

/tmp/ccHYyjKd.o: In function `main':
main.c:(.text+0xe): undefined reference to `SDL_SetMainReady'
main.c:(.text+0x18): undefined reference to `SDL_Init'
main.c:(.text+0x31): undefined reference to `SDL_SetVideoMode'
main.c:(.text+0x54): undefined reference to `SDL_MapRGB'
main.c:(.text+0x6b): undefined reference to `SDL_FillRect'
main.c:(.text+0x77): undefined reference to `SDL_Flip'
main.c:(.text+0x83): undefined reference to `SDL_WaitEvent'
main.c:(.text+0x90): undefined reference to `SDL_Quit'
collect2: error: ld returned 1 exit status

我非常简单的程序:

#include <stdio.h>
#include <stdlib.h>
#define SDL_MAIN_HANDLED
#include <SDL/SDL.h>

int main()
{   
    // SDL Initialize
    SDL_SetMainReady();
    SDL_Init(SDL_INIT_VIDEO);

    // Screen Initialize
    SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    Uint32 screenColor = SDL_MapRGB(screen->format, 255, 255, 255);
    SDL_FillRect(screen, NULL, screenColor);
    SDL_Flip(screen);

    // Main Program Loop
    SDL_Event event;
    do
    {
        SDL_WaitEvent(&event);
    } while (event.type != SDL_QUIT);

    // SDL Quit
    SDL_Quit();

    return 0;
}
5个回答

13

gcc的参数顺序非常重要。

请阅读调用GCC(以及gcc使用的binutils文档)。然后替换

 gcc `sdl-config --libs` -o main main.o

使用

 gcc main.o  `sdl-config --libs` -o main

更好的方法是学习如何使用 GNU make(通常使用GNU bash),并使用受此答案启发的 Makefile
此外,在程序没有错误之前,始终将-Wall -g传递给gcc(然后使用-Wall -O2)。
从在githubgitlab上使用SDL的开源程序中获得灵感。还可以考虑使用其他开源库和框架,例如QtSFMLGTKmm等,并研究它们的示例代码。

7
使用gcc编译命令时添加-lSDL,这将会添加sdl库。在编译之前安装sdl开发包。
gcc -o out main.c -lSDL

或者

gcc -I/usr/include/SDL/ main.c -o out -L/usr/lib -lSDL

你安装了sdl dev包吗?你使用的是哪个操作系统? - sujin
是的,我已经安装了。我该如何检查它是否成功安装? - rullof
搜索 libsdl-dev 包并安装,如果未安装的话。 - sujin
安装好了吗?我有这些软件包:libsdl1.2-devlibsdl1.2-debian - rullof
2
change lsdl to lSDL - sujin
显示剩余2条评论

2
非常感谢您的建议!这帮助我解决了一个有关SDL符号在Linux下从未被发现的旧谜团 :-) 正如评论中所写,gcc行的顺序至关重要。Makefile没有编写好,这导致了你提到的故障。

总之,请使用:gcc(标志)-o名称(包括和链接选项)

最后但并非最不重要的是,在x86_64下,请使用gdb64,而不是gdb(这是下一个头痛的问题;-)

例如,我自己编写的一个小Makefile(好吧,不是很好,但有效)

# Makefile pour le contrôle du robot Arduino 
# Controle Robot
# Sauf mention contraire, tout est place sous Licence GPL V2
# Historique : 
# Etienne HAMON / création du makefile initial (d'après cours IFT1), Novembre 2014
#
# Corrections du Makefile : Eric Bachard décembre 2014 

CC = gcc
C_STANDARD = -std=c99
INCLUDE_DIR = inc -I/usr/include/SDL
SOURCES_DIR = sources
BUILD_DIR = build
APPLICATION_NAME = Controle
FILENAME = ${BUILD_DIR}/${APPLICATION_NAME}
CFLAGS = -Wall -ansi ${C_STANDARD}
LDFLAGS = -lSDL $(sdl-config --static-libs) -lm
DEBUG_SUFFIX = _debug
CFLAGS_DEBUG = -v -gdwarf-2 -DDEBUG
OBJS = ${SOURCES_DIR}/*.c

all : ${FILENAME} ${FILENAME}${DEBUG_SUFFIX}

${FILENAME}: ${OBJS}
    ${CC} ${CFLAGS} -o $@  $^ -I${INCLUDE_DIR} ${LDFLAGS} 

${FILENAME}${DEBUG_SUFFIX}: ${OBJS}
    ${CC} ${CFLAGS} ${CFLAGS_DEBUG} -o $@ $^ -I${INCLUDE_DIR} ${LDFLAGS} 

clean:
    ${RM} *.o ${FILENAME} ${FILENAME}${DEBUG_SUFFIX}
    ${RM} -rf ${BUILD_DIR}/*.dSYM

1
我从 /usr/include/SDL2/SDL_main.h 看到了这个:
/* * 这是由真正的 SDL 主函数调用的,让库的其余部分知道初始化已经正确完成。 * * 如果你不知道自己在做什么就自己调用它,可能会导致应用程序崩溃和难以诊断的问题。 */ extern DECLSPEC void SDL_SetMainReady(void);
还要检查这个: nm /usr/lib/i386-linux-gnu/libSDL.a | grep SDL_SetMainReady
这不是解决方案,但可以让你专注于真正的问题,我认为这不是编译过程的问题。

0

这个问题的“流行”答案都是不正确或者无效的。其中一些答案甚至与问题本身毫不相关。我也遇到了同样的问题。

SDL文档提供了一个编译示例,类似于这样:gcc -o main main.c `sdl2-config --cflags --libs`

然而,有人建议说是参数的顺序导致了问题!事实上,他们建议的顺序是我从未见过的,肯定不是任何标准的。这个网站上关于SDL的回答质量非常低!

更新: 我找到了一种解决方法来处理一些缺失的函数。SDL2中不存在SDL_SetVideoMode函数,请使用SDL_CreateWindow。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接