gcc 컴파일 플래그 사용

gcc 컴파일 플래그 사용

환경 변수에서 항목을 찾기 위해 gcc를 올바르게 설정하는 방법을 이해하려고 노력 중입니다.

현재 저는 SDL이라는 코드를 컴파일하여 .bashrc에 추가하고 해당 .bashrc를 가져왔습니다.

이것은 간단한 안녕하세요 프로그램입니다.

#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

에서와 같이내장 규칙 디렉터리:

단일 개체 파일 연결

nn.o링커(종종 호출됨)는 C 컴파일러를 실행하여 자동으로 생성됩니다. ld사용된 정확한 레시피는 다음과 같습니다.

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

그리고암시적 규칙에 사용되는 변수:

LDFLAG

컴파일러가 링커를 호출 해야 할 때 컴파일러에 추가 플래그를 제공합니다 ld. LDLIBS 변수에 -L라이브러리( )를 추가해야 합니다.-lfoo

따라서 이 경우에는 -lSDL2LDFLAGS가 아닌 LDLIBS에 설정하거나 추가해야 합니다.

관련 정보