使用 gcc 编译标志

使用 gcc 编译标志

我试图了解如何正确设置 gcc 以在环境变量中查找内容。

目前,我编译了一些代码,SDL,并将其添加到我的 .bashrc 中,并获取了该 .bashrc 。

这是一个简单的 hello 程序。

#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include <stdlib.h>
#include <stdio.h>

SDL_Window* window;
SDL_GLContext* main_context;

int main(int argc, char** argv) {
    printf("hello world %d  %c \n", argc, argv[0][argc]);


    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        SDL_Log("sdl failed to core_engine_init, %s", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
                        SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    window = SDL_CreateWindow(
        "title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 300, 300,
        SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);


    if (NULL == window) {
        SDL_Log("SDL Failed to create window, %s", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    main_context = SDL_GL_CreateContext(window);
    if (NULL == main_context) {
        SDL_Log("SDL failed to create main context, %s", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    return 0;
}

尝试编译它,gcc -o main main.c我收到以下错误:

blubee$ gcc -o main main.c
/tmp/cc5hRcaO.o: In function `main':
main.c:(.text+0x3e): undefined reference to `SDL_Init'
main.c:(.text+0x47): undefined reference to `SDL_GetError'
main.c:(.text+0x59): undefined reference to `SDL_Log'
main.c:(.text+0x5e): undefined reference to `SDL_Quit'
main.c:(.text+0x77): undefined reference to `SDL_GL_SetAttribute'
main.c:(.text+0x86): undefined reference to `SDL_GL_SetAttribute'
main.c:(.text+0x95): undefined reference to `SDL_GL_SetAttribute'
main.c:(.text+0xa4): undefined reference to `SDL_GL_SetAttribute'
main.c:(.text+0xb3): undefined reference to `SDL_GL_SetAttribute'
main.c:(.text+0xd8): undefined reference to `SDL_CreateWindow'
main.c:(.text+0xf0): undefined reference to `SDL_GetError'
main.c:(.text+0x102): undefined reference to `SDL_Log'
main.c:(.text+0x107): undefined reference to `SDL_Quit'
main.c:(.text+0x11d): undefined reference to `SDL_GL_CreateContext'
main.c:(.text+0x135): undefined reference to `SDL_GetError'
main.c:(.text+0x147): undefined reference to `SDL_Log'
main.c:(.text+0x14c): undefined reference to `SDL_Quit'
collect2: error: ld returned 1 exit status

添加 SDL2 链接器标志仍然会返回错误:

blubee$ gcc -lSDL2 -o main main.c
/usr/bin/ld: cannot find -lSDL2
collect2: error: ld returned 1 exit status

这个命令编译一切都很好

blubee$ gcc -I/opt/SDL2/include/SDL2 main.c -o main -L/opt/SDL2/lib -l
SDL2

问题是我已将这些路径添加到我的 .bashrc 中,尽管我可能做得不正确。这是我的 bashrc

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SDL2/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SDL_IMAGE/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SDL_TTF/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SDL_MIXER/lib

export LD_RUN_PATH=$LD_RUN_PATH:/opt/SDL2/lib
export LD_RUN_PATH=$LD_RUN_PATH:/opt/SDL_IMAGE/lib
export LD_RUN_PATH=$LD_RUN_PATH:/opt/SDL_TTF/lib
export LD_RUN_PATH=$LD_RUN_PATH:/opt/SDL_MIXER/lib

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/SDL2/include/SDL2
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/SDL_IMAGE/include/SDL2
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/SDL_TTF/include/SDL2
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/SDL_MIXER/include/SDL2

呼应这些环境变量表明它们在那里并且应该起作用,但事实并非如此。

我这个设置做错了什么?

答案1

您不需要任何环境变量,只需传入 SDL2 希望您使用的正确 cflags 和 ldflags 即可:

gcc main.c `pkg-config --cflags sdl2` -o main `pkg-config --libs sdl2`

或任一

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

请记住:CFLAGS 位于 LDFLAGS 之前,LDFLAGS(以及带 -l 的库规范)位于最后。

SDL2 预装了 sdl2-config 脚本。您需要将 PATH 设置为它所在的目录才能成功调用它:

export PATH=/opt/SDL2/bin:$PATH

如果您直接运行每个 *-config 命令,您将看到它们只是为您输出正确的 cflags 和 ldflags。这是因为使用这些脚本的库通常比指定单个 -I/-L 参数更大,并且为它们指定单个 -I/-L 参数是不可移植的,因为将来可能会增加此类参数的数量。

并且您不应将每个包安装在其自己的目录中。例如,将所有内容安装到/usr/local例如中,那么您甚至不需要指定任何内容(大多数发行版都会/usr/local自动指向您)。

答案2

正如在内置规则目录:

链接单个目标文件

n通过 C 编译器n.o运行链接器(通常称为 )自动生成。ld使用的精确配方是:

$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)

隐式规则使用的变量:

LDFLAG

当编译器应该调用链接器时,为编译器提供额外的标志, ld例如-L。应将库 ( -lfoo) 添加到 LDLIBS 变量中。

所以在这种情况下-lSDL2应该设置或添加到LDLIBS,而不是LDFLAGS。

相关内容