使用 ld 手动链接 SDL/openGL 应用程序
Linking an SDL/openGL application manually using ld
我正在尝试为演示场景创建一个最小尺寸的可执行文件。我试图通过自己链接来最小化可执行文件的大小。
这是我的最小值 main.c,取自 http://www.int21.de/linux4k/ 它在屏幕上绘制了一个白色三角形:
#include "SDL/SDL.h"
#include "GL/gl.h"
void _start(){
SDL_Event event;
SDL_SetVideoMode(640,480,0,SDL_OPENGL|SDL_FULLSCREEN);
SDL_ShowCursor(SDL_DISABLE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.33,1.33,-1,1,1.5,100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glVertex3i(1,1,-10);
glVertex3i(1,-1,-10);
glVertex3i(-1,1,-10);
glEnd();
SDL_GL_SwapBuffers();
do{
SDL_PollEvent(&event);
} while (event.type!=SDL_KEYDOWN);
SDL_Quit();
}
我正在使用 void _start()
而不是 int main()
,因为我不想使用 C 运行时。这是我的构建命令(我的机器是 运行 Ubuntu Linux):
gcc -c main.c
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -lSDL -lGL main.o -o main
程序在 SDL_SetVideoMode 崩溃。 gdb 报告:
Program received signal SIGSEGV, Segmentation fault.
_dl_map_object_from_fd (name=0x7ffff77dfcec "libXrender.so.1", fd=-1, fbp=0x7fffffffd908,
realname=0x601de0 "/usr/lib/x86_64-linux-gnu/libXrender.so.1", loader=<optimized out>, l_type=<optimized out>,
mode=-1879048190, stack_endp=0x7fffffffdc68, nsid=0) at dl-load.c:1574
怎么了?如果我将 void _start()
更改为 int main()
,并使用 gcc main.c -o main -lSDL -lGL
编译整个内容,它就可以正常工作。当我用 ldd
.
检查可执行文件时,这个工作版本和自链接损坏版本具有完全相同的链接库列表
TL;DR:患者:"Doctor, it hurts when I do ${THAT}" – 医生:"Then don't do ${THAT}".
如果您不想在其中安装 C 运行时,则必须确保您不使用任何依赖于 C 运行时可用的代码,更重要的是 已初始化。 SDL 强烈依赖于 libc 的设施(这就是为什么你可能添加了 -lc
以便 SDL 可以正确 linked),所以当你 link 它时,你需要所有的 libc东西。然而,为了使 libc 正常工作,它必须被初始化,这就是 _start()
所做的。
如果你想减小可执行文件的大小,这也涉及摆脱(臃肿的 GNU)libc,你将不得不自己做很多事情 and/or 你不使用的补丁库依靠你想删除的东西。
我正在尝试为演示场景创建一个最小尺寸的可执行文件。我试图通过自己链接来最小化可执行文件的大小。
这是我的最小值 main.c,取自 http://www.int21.de/linux4k/ 它在屏幕上绘制了一个白色三角形:
#include "SDL/SDL.h"
#include "GL/gl.h"
void _start(){
SDL_Event event;
SDL_SetVideoMode(640,480,0,SDL_OPENGL|SDL_FULLSCREEN);
SDL_ShowCursor(SDL_DISABLE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.33,1.33,-1,1,1.5,100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glVertex3i(1,1,-10);
glVertex3i(1,-1,-10);
glVertex3i(-1,1,-10);
glEnd();
SDL_GL_SwapBuffers();
do{
SDL_PollEvent(&event);
} while (event.type!=SDL_KEYDOWN);
SDL_Quit();
}
我正在使用 void _start()
而不是 int main()
,因为我不想使用 C 运行时。这是我的构建命令(我的机器是 运行 Ubuntu Linux):
gcc -c main.c
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -lSDL -lGL main.o -o main
程序在 SDL_SetVideoMode 崩溃。 gdb 报告:
Program received signal SIGSEGV, Segmentation fault.
_dl_map_object_from_fd (name=0x7ffff77dfcec "libXrender.so.1", fd=-1, fbp=0x7fffffffd908,
realname=0x601de0 "/usr/lib/x86_64-linux-gnu/libXrender.so.1", loader=<optimized out>, l_type=<optimized out>,
mode=-1879048190, stack_endp=0x7fffffffdc68, nsid=0) at dl-load.c:1574
怎么了?如果我将 void _start()
更改为 int main()
,并使用 gcc main.c -o main -lSDL -lGL
编译整个内容,它就可以正常工作。当我用 ldd
.
TL;DR:患者:"Doctor, it hurts when I do ${THAT}" – 医生:"Then don't do ${THAT}".
如果您不想在其中安装 C 运行时,则必须确保您不使用任何依赖于 C 运行时可用的代码,更重要的是 已初始化。 SDL 强烈依赖于 libc 的设施(这就是为什么你可能添加了 -lc
以便 SDL 可以正确 linked),所以当你 link 它时,你需要所有的 libc东西。然而,为了使 libc 正常工作,它必须被初始化,这就是 _start()
所做的。
如果你想减小可执行文件的大小,这也涉及摆脱(臃肿的 GNU)libc,你将不得不自己做很多事情 and/or 你不使用的补丁库依靠你想删除的东西。