이 카테고리에 대해서는 제가 혼자 공부하고 남기는 기록 같은 곳이다보니
확실한 정보가 아닐 뿐더러 틀린 것도 많을 수도 있습니다
부담없이 틀린건 지적해주시고 알려주시면 감사하겠습니다!
당분간 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를 통해 파일을 연결하여 변수를 불러와 사용할 수 있는 유용한 파일인 것을 알 수 있다
다음부턴 문법에 대해서 조금 더 자세하게 알아보겠다
'개인 공부' 카테고리의 다른 글
GNU Make 문법 공부1 (0) | 2024.03.01 |
---|