MinGW交叉编译SDL2程序时,-lSDL2与-lSDL2main顺序为何会影响编译结果?
问题原因
这个现象是GNU链接器(ld)的静态库依赖顺序规则导致的,具体逻辑如下:
- MinGW使用的GNU链接器在处理编译命令中
-l参数指定的库时,会严格按照命令行从左到右的顺序扫描库文件 - 扫描过程中,链接器只会保留当前已经记录的「未定义符号」需要用到的库代码,对于暂时没有被引用的符号,不会主动从后续库中提取预留
SDL2main库是SDL2针对Windows平台封装的入口适配层:它实现了Windows程序要求的WinMain入口函数,内部会调用SDL2核心库提供的SDL_Init等核心接口,也就是说**SDL2main依赖SDL2的符号实现**
当你把-lSDL2放在-lSDL2main前面时:
- 链接器先扫描
SDL2库,此时还没有记录任何来自SDL2main的未定义符号,所以只会提取极少部分必要的代码,甚至不会保留SDL2_Init等核心接口的实现 - 后续扫描
SDL2main库时,发现其中调用的SDL2相关接口都是未定义符号,但此时已经扫描完SDL2库,链接器不会回头重新查找,直接报未定义引用错误,编译失败
当你调换顺序,把-lSDL2main放在-lSDL2前面时:
- 链接器先扫描
SDL2main库,记录下所有需要的SDL2相关未定义符号 - 后续扫描
SDL2库时,会主动提取对应符号的实现,和SDL2main的代码完成链接,编译成功
补充说明:这个规则只针对静态库的链接,如果是动态库的话不会有这个问题。此外微软的MSVC链接器对库顺序不敏感,会先收集所有库的符号表再统一处理,所以不会出现类似问题。
内容的提问来源于stack exchange,提问作者Fariz Awi
相关产品推荐
相关产品推荐

