【问题标题】:Linking an SDL/openGL application manually using ld使用 ld 手动链接 SDL/openGL 应用程序
【发布时间】:2015-05-17 18:00:36
【问题描述】:

我正在尝试为演示场景比赛创建一个最小尺寸的可执行文件。我正在尝试通过自己链接来最小化可执行文件的大小。

这是我最小的 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 检查可执行文件时,此工作版本和自链接损坏版本具有完全相同的链接库列表。

【问题讨论】:

    标签: c linux opengl linker demoscene


    【解决方案1】:

    TL;DR:患者:“医生,我做 ${THAT} 会很痛” – 医生:“那就不要做 ${THAT}”。

    如果您不想在其中使用 C 运行时,则必须确保不使用任何依赖于 C 运行时可用且更重要的是已初始化的代码。 SDL 强烈依赖于 libc 的功能(这就是为什么您可能添加了 -lc 以便可以正确链接 SDL),因此当您链接它时,您需要所有 libc 的东西。然而,为了使 libc 正常工作,它必须被初始化,这就是 _start() 所做的。

    如果您想减小可执行文件的大小,当然,这还涉及摆脱(臃肿的 GNU)libc,您必须自己做很多事情和/或修补您使用的库而不依赖于你想删除的东西。

    【讨论】:

    • 谢谢。我只是想知道为什么本教程看起来如此简单:int21.de/linux4k
    • @jnalanko:一个可能的原因是,使用了共享对象版本的 libSDL;并且根据其构建的配置方式,它可能会在其构造函数段中进行所有 libc 初始化。请注意,在使用 SDL 的 4k 介绍的情况下,您可能会失去资格,因为 SDL 不是在原始系统上找到的标准库(4k 介绍的要求通常是它们必须在仅安装了必需品和驱动程序且什么都没有的系统上工作更多的)。然而,只用 Xlib 创建一个 X11 窗口并不是那么难。
    猜你喜欢
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多