개인 공부

GNU Make에 대해서

이석사 중 2024. 2. 29. 15:16
728x90

이 카테고리에 대해서는 제가 혼자 공부하고 남기는 기록 같은 곳이다보니

 

확실한 정보가 아닐 뿐더러 틀린 것도 많을 수도 있습니다

 

부담없이 틀린건 지적해주시고 알려주시면 감사하겠습니다!


당분간 gnu make에 대해서 공부해보려고 한다

 

공부 순서는 gnu make가 전체적으로 무슨 일을 하는지 알아보고 

 

그 이후에 상세하게 문법이나 다른 것들을 살펴보려고 한다

 

https://www.gnu.org/software/make/#download

 

Make - GNU Project - Free Software Foundation

GNU Make GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files. Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the

www.gnu.org

 

공식 홈페이지에 따르면

 

GNU Make는 소스 파일에서 프로그램의 실행 파일 및 기타 비소스 파일을 생성하는 도구라고 설명한다

 

소스 파일은 컴파일러나 어셈블러에 의해 기계어로 번역되기 전에 프로그램 형태를 말하며 

 

비소스 파일은 프로그램 실행에 필요한 정보들을ㅇ 제공하고 출력을 기록하는데 사용되는 파일을 말한다

 

즉, 프로그램을 실행하기 위한 파일들을 빌드하는 것이라고도 생각할 수 있다

 

make 명령어를 통해 빌드를 할 때 작업 순서와 방식을 알려주는 설명서와 같은 것이다

 

wrf를 예로 보면 이전에 설치했던 WRF에서 WRF/WRF-4.1.2 디렉토리에 Makefile이 존재한다 

 

(base) lsh@DESKTOP-8N2HJ5V:~/WRF/WRF-4.1.2/tools$ ls
CodeBase                     fortran_2008_gamma_test.F    gen_scalar_derefs.c          registry.o
DOMAIN_TIME_TEST             fortran_2008_gamma_test.exe  gen_scalar_derefs.o          regtest.csh
Makefile                     four2eight.c                 gen_scalar_indices.c         regtest_esmf.csh
all_reg.csh                  fseek_test.c                 gen_scalar_indices.o         regtest_hwrf.csh
any_updates_in_registry.csh  fseeko64_test                gen_streams.c                regtest_nmmne

 

3번째줄 첫 번째에 보면 Makefile이 존재하는 모습이다

 

#       Top level Makefile for wrf system

LN      =       ln -s
MAKE    =       make -i -r
MV      =       /bin/mv
RM      =       /bin/rm -f
CHEM_FILES =    ../chem/module_aerosols_sorgam.o \
                ../chem/module_gocart_aerosols.o \
                ../chem/module_mosaic_driver.o \
                ../chem/module_input_tracer.o \
                ../chem/module_aerosols_soa_vbs.o
CHEM_FILES2 =   ../chem/module_data_mosaic_asect.o

# these files are needed to compile 'phys' in wrfplus mode
MODS4 = ../wrftladj/module_mp_mkessler.o ../wrftladj/module_mp_nconvp.o \
        ../wrftladj/module_bl_surface_drag.o ../wrftladj/module_cu_du.o
MODMP = ../wrftladj/module_mp_mkessler.o ../wrftladj/module_mp_nconvp.o
MODBL = ../wrftladj/module_bl_surface_drag.o
MODCU = ../wrftladj/module_cu_du.o

# this file is needed to compile module_integrate.F and module_cpl.F under frame in wrfplus mode
MODLL = ../wrftladj/module_linked_list2.o ../share/module_model_constants.o

# these 2 file are needed to compile mediation_integrate.F under share in wrfplus mode
MODPT = ../dyn_em/module_bc_em.o ../wrftladj/mediation_pertmod_io.o

 

가장 맨 윗줄에 주석을 보면 wrf system을 위한 가장 높은 단계의 Makefile이라고 되어있다

 

WRF의 파일들이 들어있는 가장 상위 디렉토리인 만큼 Makefile 또한 가장 높은 단계인 것 같다

 

다음 줄들에는 변수들을 설정하는 부분인 것 같다

 

처음 4줄은 변수라기 보다는 간단한 기능들을 변수화시켜서 코드가 진행될 때 편하게 호출하기 위함으로 보인다

 

그 다음부턴 WRF가 빌드될 때 참고해야하는 파일들의 리스트 같아 보인다

 

단순히 변수에 할당한 것 뿐이기 때문에 저것 또한 코드 진행 시 호출하기 위함으로 보인다

 


include ./configure.wrf

EM_MODULE_DIR = -I../dyn_em
EM_MODULES =  $(EM_MODULE_DIR)

DA_WRFVAR_MODULES = $(INCLUDE_MODULES)
DA_WRFVAR_MODULES_2 = $(INC_MOD_WRFVAR)

DA_CONVERTOR_MOD_DIR = -I../var/convertor -p../var/convertor
DA_CONVERTOR_MODULES = $(DA_CONVERTOR_MOD_DIR) $(INCLUDE_MODULES)

 

include문이 쓰여진 것을 보면 현재 디렉토리에 있는 configure.wrf라는 파일에서 이후에 나올 변수들을 참조하는 것 같다

 

(base) lsh@DESKTOP-8N2HJ5V:~/WRF/WRF-4.1.2$ ls
LICENSE.txt  README.md  chem     configure      dyn_em    frame  main  share  var
Makefile     Registry   clean    configure.wrf  dyn_nmm   hydro  phys  test   wrftladj
README       arch       compile  doc            external  inc    run   tools

 

디렉토리를 보면 예상대로 configure.wrf라는 파일이 존재한다

 

아까 코드에서 보면 EM_MODULE_DIR과 EM_MODULES는 파일 내에서 선언이 되어있지만

 

 

INCLUDE_MODULES라는 변수는 파일 내에 사진에서 처럼 3개 밖에 없지만 / 로 INCLUDE_MODULES를 더 찾아봐도

 

선언된 것은 없었다

 

그래서 아까 include한 configure.wrf를 살펴보면

 

INCLUDE_MODULES =    $(MODULE_SRCH_FLAG) \
                     $(ESMF_MOD_INC) $(ESMF_LIB_FLAGS) \
                      -I$(WRF_SRC_ROOT_DIR)/main \
                      -I$(WRF_SRC_ROOT_DIR)/external/io_netcdf \
                      -I$(WRF_SRC_ROOT_DIR)/external/io_int \
                      -I$(WRF_SRC_ROOT_DIR)/frame \
                      -I$(WRF_SRC_ROOT_DIR)/share \
                      -I$(WRF_SRC_ROOT_DIR)/phys \
                      -I$(WRF_SRC_ROOT_DIR)/wrftladj \
                      -I$(WRF_SRC_ROOT_DIR)/chem -I$(WRF_SRC_ROOT_DIR)/inc \
                      -I$(NETCDFPATH)/include \

 

이렇게 INCLUDE_MODULES라는 변수가 선언이 되어있다

 

하지만 이 변수도 더 많은 변수들을 호출하여 하나의 변수를 구성하고 있다

 

다른 변수들도 다 찾아보면

 

MODULE_SRCH_FLAG =

ESMF_MOD_INC        =  $(ESMF_IO_INC)
ESMF_IO_INC         = -I$(WRF_SRC_ROOT_DIR)/external/esmf_time_f90

여기서  WRF_SRC_ROOT_DIR이라는 변수가 정확히 선언이 안 되어있지만
다른 디렉토리들과 SRC_ROOT_DIR이라는 것들을 가지고 추측해보면
환경 변수로 선언이 되어있는 WRF_DIR이라는 변수를 자동으로 가져오는게 아닐까 생각해본다

WRF_DIR = "/home/lsh/WRF/WRF-4.1.2"

ESMF_LIB_FLAGS  =

ESMF_IO_INC         = -I$(WRF_SRC_ROOT_DIR)/external/esmf_time_f90

NETCDFPATH      =    /home/lsh/WRF/Library

 

 이렇게 나와있다

 

파이썬 같은 다른 언어들에서는 변수에 빈 값을 할당할 수 없지만 Makefile에서는 가능한 것 같다

 

저 변수의 값들이 자리에 맞게 대체되면서

INCLUDE_MODULES = -I/home/lsh/WRF/WRF-4.1.2/external/esmf_time_f90 \
                      -I/home/lsh/WRF/WRF-4.1.2/main \
                      -I/home/lsh/WRF/WRF-4.1.2/external/io_netcdf \
                      -I/home/lsh/WRF/WRF-4.1.2/external/io_int \
                      -I/home/lsh/WRF/WRF-4.1.2/frame \
                      -I/home/lsh/WRF/WRF-4.1.2/share \
                      -I/home/lsh/WRF/WRF-4.1.2/phys \
                      -I/home/lsh/WRF/WRF-4.1.2/wrftladj \
                      -I/home/lsh/WRF/WRF-4.1.2/chem -I/home/lsh/WRF/WRF-4.1.2/inc \
                      -I/home/lsh/WRF/Library/include \

 

이러한 형태의 변수가 되는것 같다

 

여기서 옵션 -I는 헤더파일의 디렉토리를 지정하는 것이다

 

포트란의 헤더파일은 .mod, C언어의 헤더파일은 .h라는 확장자를 사용한다

 

저렇게 디렉토리를 지정해줌으로써 저 디렉토리에 있는 .mod와 .h라는 확장자를 가진 파일들에 접근할 수 있는것 같다


deflt :
                @ echo Please compile the code using ./compile

 

이 부분은 @echo 가 있는 것을 보면 특정 기능을 수행하는 부분으로 보인다

 

사용자가 deflt라는 것을 어떤 방식으로 호출하면 Please compile the code using ./compile 을 출력하는 부분인 것 같다

 

delft는 타깃이라는 속성을 가지고 있다

 

make 뒤에 타깃을 붙여서 명령어를 실행하면 Makefile내에 해당 타깃이 액션을 취한다

 

wrf를 빌드할 때 make install, make clean을 사용했던 것 처럼 install, clean, deflt 모두 Makefile에 타깃 중에 하나이다

 

명령어를 실행해보면

(base) lsh@DESKTOP-8N2HJ5V:~/WRF/WRF-4.1.2$ make deflt
Please compile the code using ./compile

 

추측한 것처럼 출력이 되는 모습이다


총 정리해보면 Makefile에서는 다른 디렉토리의 헤더파일을 찾거나 

 

타깃에 액션을 주어 자동으로 커맨드를 실행하고 

 

include를 통해 파일을 연결하여 변수를 불러와 사용할 수 있는 유용한 파일인 것을 알 수 있다

 

다음부턴 문법에 대해서 조금 더 자세하게 알아보겠다

728x90

'개인 공부' 카테고리의 다른 글

GNU Make 문법 공부1  (0) 2024.03.01