환경 변수에서 항목을 찾기 위해 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
에서와 같이내장 규칙 디렉터리:
단일 개체 파일 연결
n
n.o
링커(종종 호출됨)는 C 컴파일러를 실행하여 자동으로 생성됩니다.ld
사용된 정확한 레시피는 다음과 같습니다.$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
그리고암시적 규칙에 사용되는 변수:
LDFLAG
컴파일러가 링커를 호출 해야 할 때 컴파일러에 추가 플래그를 제공합니다
ld
. LDLIBS 변수에-L
라이브러리( )를 추가해야 합니다.-lfoo
따라서 이 경우에는 -lSDL2
LDFLAGS가 아닌 LDLIBS에 설정하거나 추가해야 합니다.