사용자 도구

사이트 도구


raylib:컴파일_및_makefile
컴파일 및 makefile

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
raylib:컴파일_및_makefile [2023/11/21 23:14] 이거니맨raylib:컴파일_및_makefile [2023/11/24 00:46] (현재) – 더 읽기 이거니맨
줄 122: 줄 122:
 ===== raylib 소스파일을 바꿔보기 ===== ===== raylib 소스파일을 바꿔보기 =====
  
-==== 다양한 비트맵 폰트를 써보기 ====+==== 1. 다양한 비트맵 폰트를 써보기 ====
  
 다음 파일을 다운 받자. 다음 파일을 다운 받자.
줄 143: 줄 143:
 그리고 폰트는 stb_image 등을 이용한다. 따라서 '/raylib/src/external' 등을 참조해 줘야 한다. 그리고 폰트는 stb_image 등을 이용한다. 따라서 '/raylib/src/external' 등을 참조해 줘야 한다.
  
-위와 같이 하여 컴파일 하면 한글이 다 안 보인다. +위와 같이 하여 컴파일 하면 컴파일은 잘 되는데 실행해보면 한글이 다 안 보인다. 
  
 raylib의 기본 비트맨 폰트 로더는 폰트 아틀라스를 하나만 로드하기 때문이다. 그렇다면 어떻게 해야 할까?  raylib의 기본 비트맨 폰트 로더는 폰트 아틀라스를 하나만 로드하기 때문이다. 그렇다면 어떻게 해야 할까? 
 +
 +==== 2. RAYLIB 소스파일 수정하기 ====
  
 'raylib/src'폴더에 가보면 rtext.c라는 파일이 있다.  'raylib/src'폴더에 가보면 rtext.c라는 파일이 있다. 
줄 151: 줄 153:
 가장 아래로 스크롤 하면 LoadBMFont라는 함수가 있다.  가장 아래로 스크롤 하면 LoadBMFont라는 함수가 있다. 
  
-이를 +이를 [[raylib:util:raylib_loadbmfont_extender|Load BitmapFont Extender]]에서 LoadBMFontEx() 내에 있는 코드로 바꾸어 주면 된다. 
 + 
 +잘 모르겠으면,  
 + 
 +[[https://github.com/DongkunLee/raylib/blob/master/src/rtext.c|rtext.c]]에 있는 LoadBMFont() 메서드 내의 코드로 바꾸어 주면 된다.  
 + 
 + 
 +==== 3. raylib 재컴파일 ==== 
 + 
 +이제 rtext.c를 고쳤으므로 libraylib.a라는 정적 라이브러리를 재컴파일 해줘야 한다. 
 + 
 +raylib/src 폴더에서 다시 한번 make 명령어를 넣자. 그러면 라이브러리가 재컴파일 된다.  
 + 
 + 
 +==== 4. 실행 파일 재컴파일 ====  
 + 
 +이제 다시 fontatlas폴더로 가서  
 + 
 +<code> 
 +gcc -o main  main.c  -Wall -std=c99 -Wno-missing-braces -Wunused-result    -L../raylib/src -lraylib -lgdi32 -lwinmm -lopengl32 -I../raylib/src -I../raylib/src/external -I'../raylib/utils' 
 +</code> 
 + 
 +명령어를 수행하자.  
 + 
 +그러면 [[raylib:util:raylib_loadbmfont_extender|Load BitmapFont Extender]] 에서 볼 수 있는 것과 같이. 다양한 한글이 제대로 나온다. 
 + 
 +이제 앞으로는 그냥 loadfont()함수만 쓰면 한글도 제대로 잘 나온다.  
 + 
 + 
 +===== Makefile 만들기 =====  
 + 
 +==== 1. 준비사항 ==== 
 + 
 +makefile은 탭을 인식한다. 따라서 탭이 에디터에서 제대로 입력되게 준비할 필요가 있다. 
 + 
 +만약 VS 코드라면 아래 하단 상태표시줄에서 'tab 크기'를 클릭한 후에 '탭을 사용한 들여쓰기(Indent using tab)'으로 설정을 바꾸어 줘야 한다. 
 + 
 +관련 [[https://www.youtube.com/watch?v=MOdWPA07bMU|동영상]]을 참조하자.  
 + 
 + 
 +==== 2. Makefile 만들기 ===== 
 + 
 +위의 멀티 아틀라스 소스에 대한 Makefile을 만든다고 해보자. 
 + 
 +하나의 소스만 컴파일 할 때에는 위와 같이 명령창에서 gcc 혹은 g++(c++로 만들 경우)로 명령어를 넣으면 되므로,  
 + 
 +여러가지 소스 파일이 있는 대상 프로젝트를 선택하자. [[raylib:flappybird:다국어_지원하기|플래피 버드]]다국어 지원하기 
 + 
 +위 소스의 폴더에 'Makefile'이란 파일을 만들자. 만약 VS Code로 한다고 하면, 위와 같이 탭을 사용한 들여쓰기 설정을 해놓자. 
 + 
 +Makefile이 이미 있다면 지우고 새로 만들자.  
 + 
 +=== 가. 최초 makefile === 
 + 
 +<file makefile Makefile> 
 +# Define required raylib variables 
 +RAYLIB_PATH        ?= C:/raylib5/raylib/src 
 +# Define compiler path on Windows 
 +COMPILER_PATH      ?= C:/raylib/w64devkit/bin 
 +# Build mode for project: DEBUG or RELEASE 
 +BUILD_MODE            ?= RELEASE 
 + 
 +# Define default C compiler: gcc 
 +# NOTE: define g++ compiler if using C++ 
 +CC = g++ 
 + 
 +# Define default make program: Mingw32-make 
 +MAKE = mingw32-make tetris 
 +# Compile option 
 +CFLAGS += -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces  
 + 
 +ifeq ($(BUILD_MODE),DEBUG) 
 +    CFLAGS += -g -O0 
 +else 
 +    CFLAGS += -s -O1 
 +endif 
 + 
 +# Define include paths for required headers 
 +# NOTE: Several external required libraries (stb and others) 
 +INCLUDE_PATHS = -I. -I$(RAYLIB_PATH) -I$(RAYLIB_PATH)/external -I'/utils' 
 + 
 +# Define library paths containing required libs. 
 +LDFLAGS = -L. -L$(RAYLIB_PATH) 
 + 
 +# Define any libraries required on linking 
 +# if you want to link libraries (libname.so or libname.a), use the -lname 
 +LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm 
 + 
 +# Define all source files required 
 +SRC_DIR = . 
 +OBJ_DIR = obj 
 + 
 +#목적 파일 만들기 
 +OBJS = $(OBJ_DIR)/buttonActionMap.o $(OBJ_DIR)/config.o $(OBJ_DIR)/gui.o $(OBJ_DIR)/logo.o $(OBJ_DIR)/game.o $(OBJ_DIR)/menu.o $(OBJ_DIR)/settingscreen.o $(OBJ_DIR)/main.o 
 + 
 +# Default target entry 
 +# NOTE: We call this Makefile target or Makefile.Android target 
 +all: 
 + $(MAKE) 
 + 
 +$(OBJ_DIR)/buttonActionMap.o : buttonActionMap.h buttonActionMap.cpp  
 + $(CC)  -c buttonActionMap.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/config.o : config.h config.cpp 
 + $(CC)  -c config.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/gui.o : gui.h gui.cpp 
 + $(CC)   -c gui.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/logo.o : logo.h logo.cpp 
 + $(CC)  -c logo.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/game.o : game.h game.cpp 
 + $(CC) -c game.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/menu.o : menu.h menu.cpp 
 + $(CC)  -c menu.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/settingscreen.o : settingscreen.h settingscreen.cpp 
 + $(CC)   -c settingscreen.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +$(OBJ_DIR)/main.o : main.cpp 
 + $(CC)  -c main.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 + 
 +#Icon file path 
 +ICON += $(RAYLIB_PATH)/raylib.rc.data 
 + 
 +#컴파일 
 +tetris : $(OBJS) 
 + $(CC) $(CFLAGS)  $(OBJS) -o tetris $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) $(ICON) 
 +</file> 
 + 
 +=== 나. 설명 === 
 + 
 +== (가) raylib 라이브러리 ==  
 + 
 +우리는 libraylib.a 라는 라이브러리를 이용할 것이다. 따라서 이에 대한 경로를 지정해 줘야 한다. 
 + 
 +  RAYLIB_PATH        ?= C:/raylib5/raylib/src 
 + 
 +로 하여 경로를 지정해 주었다. 
 + 
 +== (나) 컴파일러 ==  
 + 
 +c로 작성한 파일은 gcc로 컴파일 하고, c++로 작성한 파일은 g++로 컴파일 한다. 
 +따라서 컴파일러를 지정해 주어야 한다. 
 + 
 +  CC = g++ 
 +   
 +== (다) 디버그 모드/릴리스 모드 ==  
 + 
 +디버그 모드와 릴리스모드의 옵션을 설정해 준다. 다음과 같이 설정해주었다. 
 + 
 +<code> 
 +ifeq ($(BUILD_MODE),DEBUG) 
 +    CFLAGS += -g -O0 
 +else 
 +    CFLAGS += -s -O1 
 +endif 
 +</code>  
 + 
 +== (라) 헤더파일과 라이브러리 == 
 + 
 +헤어파일과 라이브러리를 각각 그 경로를 설정해주었다.  
 + 
 +== (마) 목적 파일 만들기 == 
 + 
 +각 소스파일들을 기계어로 만들어야 한다.  
 + 
 +그런데 우리가 배치파일(혹은 리눅스에서는 쉘 파일)을 만들지 않고 이렇게 Makefile을 만드는 이유는 뭘까? 
 + 
 +Makefile을 만들면 이미 만들어진 목적파일은 생략하고 변경된 소스만 다시 목적파일로 만들어 주기 때문이다. 만약 배치파일로 만든다면 목적파일의 변경여부와 상관없이 매번 목적파일을 새롭게 만들것이다.  
 + 
 +따라서 목적파일이 그대로 있어야만 한다. 그런데 목적파일이 내 소스파일과 섞이면 지저분하므로, 목적파일을 위한 디렉토리를 따로 만들어주자. 
 + 
 +파일탐색기로 'obj'란 디렉토리를 만들자. 
 + 
 +그리고 위의 소스에서 보는 바와 같이 각 목적파일은 'obj'라는 폴더 내부에서 목적 파일을 만드는 것이다. 하나만 따로 떼어서 살펴보자. 
 + 
 +<code> 
 +$(OBJ_DIR)/buttonActionMap.o : buttonActionMap.h buttonActionMap.cpp  
 + $(CC)  -c buttonActionMap.cpp $(CFLAGS) $(INCLUDE_PATHS) -o $@ 
 +</code> 
 + 
 +콜론(:)의 왼쪽, 즉 목적파일로 만들어지는 것을 타켓파일이라고 하고 오른쪽에 있는 것을 의존파일이라고 한다.  
 + 
 +의존파일을 이용하여 목적파일을 만드는 것이다. 
 + 
 +그런데 컴파일러(g++)에서 의존파일의 명칭을 바꾸려면 아웃풋을 뜻하는 -o 플래그 뒤에 그 의존파일의 전체 이름을 넣어야 한다.  
 + 
 +우리의 경우 'obj'라는 폴더 아래에 'buttonActionMap.o'라는 목적 파일을 만들 것이다. 이는 'obj/buttonActionMap.o'라고 적을 수 있다. 
 + 
 +이렇게 -o 플래그 뒤에 만들어질 목적 파일의 명칭을 적어야 한다.  
 + 
 +Makefile에서 타켓파일을 지정한느 매크로는 '$@'이다. 따라서 이를 이용하면 타켓파일을 두번 쓸 필요는 없다.  
 + 
 +== (바) 아이콘 ==  
 + 
 +윈도우 환경에서 파일의 아이콘을 설정해줄 수도 있다. 우리는 아이콘을 다음과 같이 링크해 줬다. 
 + 
 +  ICON += $(RAYLIB_PATH)/raylib.rc.data 
 +   
 +== (사) 컴파일 하기 ==  
 + 
 +이제 만들어진 목적파일들을 링크하여줘야 한다.  
 + 
 +<code> 
 +#컴파일 
 +tetris : $(OBJS) 
 + $(CC) $(CFLAGS)  $(OBJS) -o tetris $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) $(ICON) 
 +</code> 
 + 
 +tetris라는 이름으로 목적파일들을 컴파일 해준다. 그런데 라이브러리의 링크를 지시하는 플래그들은 맨 뒤에 와야 한다.  
 + 
 +따라서 '$(LDFLAGS) $(LDLIBS) $(ICON)'까지는 반드시 맨뒤에 와야 한다. 만약 그렇지 않으면 'undefined ...'하면서 컴파일러는 에러를 내뿜을 것이다.  
 + 
 + 
 +== (아) 메이크의 대상 지정하기 ==  
 + 
 +이렇게 Makefile을 만든 뒤에는 커맨드 창에서 'make' 명령어를 누르면 Makefile에 있는 매크로를 수행하면서 컴파일이 이루어진다. 
 + 
 +그런데 make는 지정된 타켓만 make를 한다. 우리는 최종적으로 tetris라는 실행파일을 만들 것인데,  
 + 
 +이러한 최종 실행파일은 tetris라는 이름으로 타켓이 지정되어 있다.  
 + 
 +따라서 'make tetris'를 해야만 최종 목표인 컴파일까지 한다.  
 + 
 +만약 아무런 지정도 안 해주고 단순히 'make'만 누르면 제일 처음에 설정한 타겟인 'buttonActionMap'만 목적파일로 만들어진다. 
 + 
 +그런데 이렇게 매번 'make tetris'를 누르는 것도 귀찮기 마련이다. 그냥 'make'만 했으면 좋을것다. 
 + 
 +따라서  
 + 
 +아예  
 + 
 +<code> 
 +# Define default make program: Mingw32-make 
 +MAKE = mingw32-make tetris 
 +</code> 
 + 
 +라고 하여 타겟 자체를 지정해 버리자.  
 + 
 +그리고는 이렇게 코드를 짜면 모든 목적파일을 검토 한 후에 tetris라는 최종 파일을 만든다. 
 + 
 +<code> 
 +all: 
 + $(MAKE) 
 +</code> 
 + 
 +이제 커맨드 창에서 단순하게 'make'만 누르면 프로젝트 전체의 컴파일이 된다.  
 + 
 + 
 +===== VS Code의 환경 설정하기 ===== 
 + 
 +==== 1. task.json 설정하기 ====  
 + 
 +우리는 위 Makefile에서 딱 한가지 분기만 만들었다. 디버그와 릴리스 모드 분기다.  
 + 
 +따라서 Makefile을 실행시키는 task.json에는 다른 인자들은 설정해 줄 필요 없고, 단지 하나, 디버그 모드에서는  
 + 
 +  BUILD_MODE=DEBUG 
 +   
 +를 넣어주면 된다. 굳이 이를 코드로 보여주면 다음과 같다. 
 + 
 +<file javascript task.json> 
 +
 +    "version": "2.0.0", 
 +    "tasks":
 +        { 
 +            "label": "build debug", 
 +            "type": "process", 
 +            "command": "make", 
 +            "args":
 +                "BUILD_MODE=DEBUG" 
 +            ], 
 +            "windows":
 +                "command": "C:/raylib/w64devkit/bin/mingw32-make.exe", 
 +                "args":
 +                    "BUILD_MODE=DEBUG" 
 +                ] 
 +            }, 
 +            "group": "build", 
 +            "problemMatcher":
 +                "$gcc" 
 +            ] 
 +        }, 
 +        { 
 +            "label": "build release", 
 +            "type": "process", 
 +            "command": "make", 
 +            "args": [    ], 
 +            "windows":
 +                "command": "C:/raylib/w64devkit/bin/mingw32-make.exe", 
 +                "args": [    ] 
 +            }, 
 +            "problemMatcher":
 +                "$gcc" 
 +            ], 
 +            "group":
 +                "kind": "build", 
 +                "isDefault": false 
 +            }, 
 +            "detail": "compiler: C:\\raylib\\w64devkit\\bin\\g++.exe" 
 +        } 
 +    ] 
 +
 +</file> 
 + 
 +==== 2. launch.json ====  
 + 
 +실행할 프로그램의 경로를 정확히 설정해 주면 된다.  
 + 
 +우리는 tetris.exe 하나로만 실행파일을 만들 것이므로,  
 + 
 +  "program": "${workspaceFolder}/tetris", 
 +   
 +이렇게만 바꾸어 주면 된다. 
 + 
 + 
 +==== 3. c_cpp_properties.json ====  
 + 
 +에디터가 인텔리센스를 보여줄 헤더의 위치를 설정해주는 것이다.  
 + 
 +다음과 같이 해당 경로를 설정해 주면 된다. 
 + 
 +<code> 
 +            "includePath":
 +                "C:/raylib5/raylib/src/**", 
 +                "${workspaceFolder}/**", 
 +                "${workspaceFolder}/utils/**" 
 +            ], 
 +</code> 
 + 
 +===== 더 읽어보기 =====  
 + 
 +[[raylib:정적_라이브러리_만들기|C / C++  에서 정적라이브러리 만들기]]도 읽어보자
raylib/컴파일_및_makefile.1700576054.txt.gz · 마지막으로 수정됨: 2023/11/21 23:14 저자 이거니맨