VS Code下SDL2程序编译运行疑问:路径前缀与编译命令简化
我正在尝试让SDL2/SDL.h头文件在C语言中正常工作,使用的测试代码如下:
#include <stdio.h> #include <SDL2/SDL.h> #define WIDTH 800 #define HEIGHT 600 #define DELAY 1000 int main (int argc, char **argv) { SDL_Window *window = NULL; if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "SDL failed to initialise: %s\n", SDL_GetError()); return 1; } window = SDL_CreateWindow("SDL Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, 0); if (window == NULL) { fprintf(stderr, "SDL window failed to initialise: %s\n", SDL_GetError()); return 1; } SDL_Delay(DELAY); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
注:此代码并非我编写,我对其并未完全理解,仅用于演示问题。
在命令提示符中运行程序时,我输入的编译命令如下:
gcc -std=c11 main.c -I{Path to SDL2\include} -L{Path to SDL2\lib} -Wall -lmingw32 -lSDL2main -lSDL2 -o main
编译无错误,之后输入main.exe即可正常运行。但在Visual Studio Code的终端中操作时遇到两个问题:
- 运行程序时必须输入
./main.exe而非main.exe,请问原因是什么? - 每次编译都需要输入上述冗长的gcc命令,而我习惯仅输入
gcc main.c,之后运行./a,但这样会出现未定义引用等编译错误。请问如何避免输入冗长的编译命令,保留我熟悉的操作习惯?
我使用Windows系统,搭配32位MinGW编译器在Visual Studio Code中开发(处理器为64位)。
问题1解答:为什么VS Code终端需要输入./main.exe才能运行
VS Code默认使用的终端如果是Git Bash、WSL终端这类类Unix shell环境,它们的路径解析规则和Windows原生命令提示符(CMD)不同:
- 在CMD中,当前目录是默认的可执行文件搜索路径之一,直接输入
main.exe就能找到当前目录下的程序。 - 而在类Unix shell中,默认的
PATH环境变量不包含当前目录(.),所以必须明确指定./main.exe来告诉系统要在当前目录下查找这个可执行文件。
如果你的VS Code终端用的是CMD,那应该可以直接输入main.exe;如果是Git Bash或其他类Unix终端,就需要加./。
问题2解答:简化编译命令的方法
要实现输入gcc main.c就能完成SDL2的编译,有两种常用方法:
方法1:使用环境变量配置
添加SDL的头文件路径到
C_INCLUDE_PATH:
在系统环境变量中新增C_INCLUDE_PATH,值设为SDL2的include目录路径(比如D:\SDL2\include),这样gcc会自动搜索这个目录下的头文件,无需再加-I参数。添加SDL的库文件路径到
LIBRARY_PATH:
新增系统环境变量LIBRARY_PATH,值设为SDL2的lib目录路径(比如D:\SDL2\lib),gcc链接时会自动搜索这个目录下的库,无需加-L参数。添加SDL的库链接参数到
LDFLAGS:
新增环境变量LDFLAGS,值设为-lmingw32 -lSDL2main -lSDL2,这样gcc编译时会自动附加这些链接参数。
配置完环境变量后,重启VS Code终端,输入gcc main.c -std=c11 -Wall -o main就能完成编译;如果想进一步简化成gcc main.c,可以把-std=c11 -Wall -o main也加到环境变量CFLAGS里(CFLAGS用来存放编译参数),这样直接输入gcc main.c就会自动带上这些参数。
方法2:使用Makefile
在项目根目录创建一个名为Makefile的文件,内容如下:
CC = gcc CFLAGS = -std=c11 -Wall -I{Path to SDL2\include} LDFLAGS = -L{Path to SDL2\lib} -lmingw32 -lSDL2main -lSDL2 TARGET = main all: $(TARGET) $(TARGET): main.c $(CC) $(CFLAGS) main.c $(LDFLAGS) -o $(TARGET) clean: del $(TARGET).exe
把其中的{Path to SDL2\include}和{Path to SDL2\lib}替换成你实际的SDL路径。之后在VS Code终端中输入make就能自动完成编译,输入make clean可以清理生成的可执行文件。
如果想让输入gcc main.c也能触发编译,可以把Makefile的目标改成a.exe,这样编译后生成a.exe,就能用./a.exe运行:
CC = gcc CFLAGS = -std=c11 -Wall -I{Path to SDL2\include} LDFLAGS = -L{Path to SDL2\lib} -lmingw32 -lSDL2main -lSDL2 TARGET = a all: $(TARGET) $(TARGET): main.c $(CC) $(CFLAGS) main.c $(LDFLAGS) -o $(TARGET) clean: del $(TARGET).exe
内容的提问来源于stack exchange,提问作者Alexander Jonsson

