Usando sinalizadores de compilação do gcc

2

Estou tentando entender como configurar corretamente o gcc para encontrar coisas em minhas variáveis ambientais.

Atualmente eu compilei alguns códigos, o SDL e o adicionei ao meu .bashrc e também criaram o .bashrc.

Aqui está um programa simples de Olá.

#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;
}

Tentando compilar isso com gcc -o main main.c , recebo estes erros:

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

adicionando o sinalizador de vinculador SDL2, isso retorna um erro ainda:

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

este comando compila tudo muito bem embora

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

A única coisa é que eu adicionei esses caminhos ao meu .bashrc embora eu possa ter feito isso incorretamente. Aqui está o meu 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

ecoar essas variáveis ambientais mostra que elas estão lá e deveriam estar funcionando, mas não está.

O que estou fazendo de errado com essa configuração?

    
por user1610950 10.11.2015 / 08:17

2 respostas

1

Você não precisa de nenhuma variável de ambiente, basta passar os cflags e os ldflags que o SDL2 quer que você use:

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

ou

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

Lembre-se: CFLAGS vem antes de LDFLAGS, e LDFLAGS (e especificação de biblioteca com -l) vem por último.

O SDL2 vem com o script sdl2-config pré-instalado. Você precisará definir seu PATH para o diretório onde ele reside para chamá-lo com êxito:

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

Se você executar todos os comandos * -config diretamente, verá que eles apenas exibem cflags e ldflags corretos para você. Isso ocorre porque as bibliotecas que empregam esses scripts geralmente são maiores do que para especificar um argumento -I / -L único, e não é portável especificar argumentos únicos -I / -L para eles, porque o número desses argumentos pode ser aumentado no futuro. / p>

E você não deve instalar todos os pacotes em seu próprio diretório. Instale tudo em /usr/local , por exemplo, então você não precisará especificar nada (a maioria das distros aponta para /usr/local automaticamente).

    
por 10.11.2015 / 08:38
1

Como pode ser visto no Catálogo de regras incorporadas :

Linking a single object file

n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is:

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

e Variáveis usadas por regras implícitas :

LDFLAGS

Extra flags to give to compilers when they are supposed to invoke the linker, ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.

Portanto, neste caso, -lSDL2 deve ser definido ou adicionado ao LDLIBS, não ao LDFLAGS.

    
por 05.06.2016 / 17:43