makefile에 추가한 실행라인 by 바죠

보다 전문적으로 프로그램을 개발하려고 하면 make 명령어와 makefile을 사용하는 것이 좋다. 이러한 것들은 프로그램들을 잘 분류해주고 보다 더 신속하게 프로그램들을 개발할 수 있도록 도와준다. 매우 간단한 프로그램 개발에서는 필요없는 것들이지만 일반적으로 매우 중요한 역할을 한다. 일반으로 매우 많은 프로그램들이 연결되어서 하나의 실행파일이 만들어지게 된다. 개발 중간에 테스트가 있을 수밖에 없다. 결국, 한 부분 한 부분 테스트 작업이 들어가게 된다. 이렇게 되면 계속해서 컴파일을 해야만 한다. 매우 번거로운 컴파일 작업을 도와줄 수 있는 기능이 필요하다. 이러한 것들을 위해서 make 명령어가 탄생하게 되었다.

cmpl= /usr/local/bin/mpif90
segl= /usr/local/bin/mpif90
INSTALL_DIR = /usr/local/mpich
OPT = -fast
FFLAGS = -c ${OPT} -I$(INSTALL_DIR)/include
#LIBS = -L$(INSTALL_DIR)/lib -lmpich -lpmpich
LIBS =
lib_tinker =  /home/ihlee/action_protein/tinker/source/libtinker.a

FILES= hfb_driver.o eql_alp.o hfb_set.o  \
       multi_andersen_md_hfb.o  multi_berendsen_md_hfb.o multi_elber_pln.o   \
       timestamp.o simpson.o rmarin.o lbfgs_for_action.o sint.o zeroin.o dqag.o

/home/ihlee/action_protein/hfb.x: $(FILES)
        $(segl) -o /home/ihlee/action_protein/hfb.x $(FILES) $(LIBS) $(lib_tinker)
hfb_driver.o:hfb_driver.f90 hfb_set.o eql_alp.o
        $(cmpl) $(FFLAGS) hfb_driver.f90
hfb_set.o:hfb_set.f90
        $(cmpl) $(FFLAGS) hfb_set.f90
eql_alp.o:eql_alp.f90 hfb_set.o
        $(cmpl) $(FFLAGS) eql_alp.f90
multi_andersen_md_hfb.o:multi_andersen_md_hfb.f90 hfb_set.o
        $(cmpl) $(FFLAGS) multi_andersen_md_hfb.f90
multi_berendsen_md_hfb.o:multi_berendsen_md_hfb.f90 hfb_set.o
        $(cmpl) $(FFLAGS) multi_berendsen_md_hfb.f90
multi_elber_pln.o:multi_elber_pln.f90 hfb_set.o
        $(cmpl) $(FFLAGS) multi_elber_pln.f90
timestamp.o:timestamp.f90
        $(cmpl) $(FFLAGS) timestamp.f90
rmarin.o:rmarin.f90
        $(cmpl) $(FFLAGS) rmarin.f90
simpson.o:simpson.f90
        $(cmpl) $(FFLAGS) simpson.f90
lbfgs_for_action.o:lbfgs_for_action.f
        $(cmpl) $(FFLAGS) lbfgs_for_action.f
sint.o:sint.f
        $(cmpl) $(FFLAGS) sint.f
zeroin.o:zeroin.f
        $(cmpl) $(FFLAGS) zeroin.f
dqag.o:dqag.f
        $(cmpl) $(FFLAGS) dqag.f

clean:
        rm -f *.x *.o *.mod *.M core* *.ps
touch:
        touch *.f90 *.i makefile ; chmod 600 *.f90 *.i makefile ; ls -l *.f90 *.i makefile
rmo:
        rm -f *.o *.mod *.M core*
lsl:
        ls -l *.f90 makefile *.i
a2ps:
        a2ps -o hfb_set.ps hfb_set.f90; a2ps -o hfb_driver.ps hfb_driver.f90; a2ps -o eql_alp.ps eql_alp.f90 ;  a2ps -o multi_andersen_md_hfb.ps multi_andersen_md_hfb.f90 ; a2ps -o multi_elber_pln.ps multi_elber_pln.f90

---------------

make a2ps

라고 실행하면, 아래와 같이 ps파일들이 만들어 진다.

a2ps -o hfb_set.ps hfb_set.f90; a2ps -o hfb_driver.ps hfb_driver.f90; a2ps -o eql_alp.ps eql_alp.f90 ;  a2ps -o multi_andersen_md_hfb.ps multi_andersen_md_hfb.f90 ; a2ps -o multi_elber_pln.ps multi_elber_pln.f90
[hfb_set.f90 (Fortran): 21 pages on 11 sheets]
[Total: 21 pages on 11 sheets] saved into the file `hfb_set.ps'
[82 lines wrapped]
[hfb_driver.f90 (Fortran): 5 pages on 3 sheets]
[Total: 5 pages on 3 sheets] saved into the file `hfb_driver.ps'
[21 lines wrapped]
[eql_alp.f90 (Fortran): 4 pages on 2 sheets]
[Total: 4 pages on 2 sheets] saved into the file `eql_alp.ps'
[4 lines wrapped]
[multi_andersen_md_hfb.f90 (Fortran): 5 pages on 3 sheets]
[Total: 5 pages on 3 sheets] saved into the file `multi_andersen_md_hfb.ps'
[39 lines wrapped]
[multi_elber_pln.f90 (Fortran): 4 pages on 2 sheets]
[Total: 4 pages on 2 sheets] saved into the file `multi_elber_pln.ps'
[25 lines wrapped]

a2ps -o get_seq_features.ps get_seq_features.f90 --prologue=color
처럼 하게 되면 컬러풀하게 프린트된다.
또는 아래와 같이 할 수도 있다.
a2ps --prologue=color -o hfb_set.ps hfb_set.f90

프로그램 언어에서 제공하는 키워드들은 볼드로 진하게 프린트됩니다. 위의 그림에서와 같이 많은 라인들이 한꺼번에 프린트되도록 도와줍니다.  물론, 글자는 작아져야 하겠습니다. 이렇게 여러 라인들을 한꺼번에 보는 것이 알고리듬 이해에 많은 도움이 됩니다.

실질적인 프로그램 개발 과정: 이론을 습득하고 있어야한다. 감각적으로 이론이 성립함을 알아야한다. a2ps로 프린트된, 종이에 프린트된 프로그램 자료을 준비한다. 이게 프로그램을 다차원적으로 볼 수 있게 해 준다. 물론, 많은 생각을 할 수 있게 도와 준다. 각종 파일들에 중간 단계의 테스트값들을 출력한다. 점진적으로 테스트를 해 나간다. 출력된 테스트 자료들을 잘 살펴본다. 그림들도 그려본다. 계산 중간 단계들에 대해서 그림들을 그려본다.


a2ps를 활용하여 프로그램을 ps파일 형식으로 출력하는것이다. 필요한 프로그램을 a2ps로 만들었다. 하지만, 이것을 makefile에 넣기로 했다.

make a2ps라고 실행하면, 여러개의 프로그램들이 ps 파일형식으로 만들어진다.

a2ps is an Any to PostScript filter. It started as a Text to PostScript converter, with pretty printing features and all the expected features from this kind of programs. But today, it is also able to deal with other file types (PostScript, Texinfo, compressed, whatever...) provided you have the necessary tools.

--------------------------------------------------------------------------------------------------------------------



처음 모듈과 관련된 것을 공부할 때, 어려운것 중 하나가 모듈들의 실질적인 배치였다. 즉, 모듈들을 파일 단위로 어떻게 배치해야 하는가?

사실, 모듈들을 한 파일에 배치하고, 관련된 모든 부프로그램들을 배치하고 마지막에 main program을 만들어서 컴파일해서 사용하면된다. 가장 원초적인 방법이다. 물론, 실전에서는 그렇지 않다. 통상적으로 모듈 하나 하나를 파일 하나에 담는것이 일반적이다. 간단한 모듈들의 경우, 한 파일에 담아 둘수도 있다.

한 모듈안에서 선언된 변수들은 모듈 속의 부 프로그램들에 의해서 변형되고 사용될 수 있다. 다른 모듈 속의 변수들, 부 프로그램들은 USE를 사용해서 사용될 수 있다. 따라서, 프로그램들을 컴파일할 때, USE를 통해서 사용되는 변수들, 함수들이 알려져 있어야 한다.  하나의 모듈을 컴파일하려고 할 때, implicit none보다 먼저 나와 있는 USE와 관련된 변수들을 알아야 한다. 즉, 이들이 있어야 현재의 모듈을 이해할 수 있다. 현재 모듈이 이것들을 사용하기 때문이다.  이러한 이유 때문에 컴파일에서, USE와 관련된 모듈이 먼저 컴파일이 되어 있어야한다. 논리적으로 그렇다. 그래서, implicit none 보다 먼저 나온다고 생각해도 무방하다. 하나의 모듈을 컴파일할 때, USE를 사용하지 않는다면, 바로 즉시, 현재의 모듈을 컴파일할 수 있다.   모듈이 아니라, 부함수의 경우도 마찬가지이다. 부함수를 컴파일하려고 하는데, USE가 있으면, 그 모듈이 먼저 컴파일되어 있어야한다.  이러한 프로그램들 사이의 관계를 dependence라고 한다. 하나의 프로그램이 다른 프로그램과 연관되어 있다는 말씀. makefile을 사용하면 이러한 의존성을 잘 표시할 수 있고, 잘 이용하여 컴파일을 할 수 있다. 위의 예제에서는 hfb_set.f90를 컴파일하여 생긴 hfb_set.o가 여러 프로그램들에서 사용됨을 확인할 수 있다. hfb_driver.o를 만들려고하면, 즉, hfb_driver.f90를 컴파일할려고 하면, hfb_set.o가 있어야한다는 뜻이다. 그렇게 될려면, hfb_set.f90가 컴파일이 되어야한다. 그런데, hfb_set.f90는 또 bennett_set.o에 의존한다. bennett_set.o를 만들려면 bennett_set.f90을 컴파일해야한다. 이와 같은 과정을 makefile이 수행할 수 있다. 의존성없는 프로그램이 나올때까지 추적한다. 그리고 그곳에서 부터 컴파일을 행한다. 나머지, 의존성이 없는 프로그램들은 그냥 순서대로 컴파일을 수행하여 목적파일(object file, *.o)를 만든다. 유닉스 명령어, make를 활용하면된다.

make

라고 명령어를 치면, 위의 과정을 실행한다. 결국, 프로그래머는 위에 나와 있는 makefile을 만들어야 한다는 뜻이다.

make clean

을 실행하면, 위의 makefile에 나와있는것처럼, 다음줄, 그리고 탭 뒤에 나와있는 실행문을 실행한다.

rm -f *.x *.o *.mod *.M core* *.ps

make a2ps

하면, 마찬가지로 a2ps프로그램을 이용하여 연속된 실행을 한다. 몇 가지 응용을 할 수 있겠다. 프로그램들 중에서  특정 부프로그램에서 아주 사소한 것을 하나 바꾸었다고 가정하자. 이렇게 하고 make를 실행하면 그 파일의 변화를 make프로그램이 감지해서 필요한 부분에 대해서 재 컴파일을 수행한다.  make라는 명령어는 Makefile이라는 것을 찾아서 명령들을 수행한다. Makefile이 없으면 makefile을 찾아서 일을 한다. makefile속에서는 pound (#) 로 코멘트를 작성한다. 시작하는 곳은 첫번째 칼럼일 필요없다.
다음줄에 연이어서 사용할 때는 back slash (\)를 적고 다음줄로 넘어간다.

makefile 튜토리얼:

http://www.opussoftware.com/tutorial/TutMakefile.htm

http://www.eng.hawaii.edu/Tutor/Make/2-3.html

아래 그림들의 출처: http://www.eng.hawaii.edu/Tutor/Make/2-3.html






 

프로그램 파일들 mainy.f90 bb.f90 cc.f90 zlib.f들이 있다고 하자.

pgf90 mainy.f90 bb.f90 cc.f90 zlib.f

처럼 하면 실행파일 a.out가 만들어 진다.

이것이 가장 기본이 되는 컴파일이다.

pgf90  -c bb.f90

pgf90 -c cc.f90

pgf90 -c zlib.f

pgf90 mainy.f90 bb.o cc.o zlib.o

처럼 일들을 처리해도 된다.


제법 큰 프로그램을 개발하기 위해서는 상당히 많은 단계로 나누어서 일을 해야만 한다. 계속해서 프로그램을 순차적으로 바꾸어 가면서 테스트를 병행해야만 한다. 이러한 절차들을 위해서 makefile, make명령어가 상당한 도움을 준다.

b0012811_gnu-make-manual.pdf



--------------------------------------------------------------------------------------------------------------------
clean:
        rm -f *.x *.o *.mod *.M core* *~   *.ps~  *__genmod.f90
touch:
        touch *.f90  makefile ; chmod 600 *.f90  makefile ; ls -l *.f90  makefile
rmo:
        rm -f *.o *.mod *.M core*  *.ps~ *~  __genmod.f90
lsl:
        ls -l *.f90 makefile
wc:
        wc *.f90 *.f
a2ps:
        a2ps --prologue=color -o action_multi.ps action_multi.f90 ; a2ps --prologue=color -o action_lbfgs.ps action_lbfgs.f90 ; a2ps --prologue=color -o multivasp.ps multivasp.f90 ; a2ps --prologue=color -o multi_arc_length.ps multi_arc_length.f90 ; a2ps --prologue=color -o multi_eql_arc.ps multi_eql_arc.f90 ; a2ps --prologue=color -o multi_app_eql_arc.ps multi_app_eql_arc.f90 ; a2ps --prologue=color -o app_real_equal.ps app_real_equal.f90 ; a2ps --prologue=color -o opt_equal_dist.ps opt_equal_dist.f90 ; a2ps --prologue=color -o rand_path.ps rand_path.f90 ; a2ps --prologue=color -o qst_lst_path.ps qst_lst_path.f90 ; a2ps --prologue=color -o xyz2ak0.ps xyz2ak0.f90

--------------------------------------------------------------------------------------------------------------------
a2ps:
        a2ps --prologue=color -o action_multi.ps action_multi.f90 ; a2ps --prologue=color -o action_lbfgs.ps action_lbfgs.f90 ; a2ps --prologue=color -o multivasp.ps multivasp.f90 ; a2ps --prologue=color -o multi_arc_length.ps multi_arc_length.f90 ; a2ps --prologue=color -o multi_eql_arc.ps multi_eql_arc.f90 ; a2ps --prologue=color -o multi_app_eql_arc.ps multi_app_eql_arc.f90 ; a2ps --prologue=color -o app_real_equal.ps app_real_equal.f90 ; a2ps --prologue=color -o opt_equal_dist.ps opt_equal_dist.f90 ; a2ps --prologue=color -o rand_path.ps rand_path.f90 ; a2ps --prologue=color -o qst_lst_path.ps qst_lst_path.f90 ; a2ps --prologue=color -o xyz2ak0.ps xyz2ak0.f90
a2psblack:
        a2ps --medium=A4 --line-numbers=1 -o action_multi.ps action_multi.f90 ; a2ps --medium=A4 --line-numbers=1 -o action_lbfgs.ps action_lbfgs.f90 ; a2ps --medium=A4 --line-numbers=1 -o multivasp.ps multivasp.f90 ; a2ps --medium=A4 --line-numbers=1 -o multi_arc_length.ps multi_arc_length.f90 ; a2ps --medium=A4 --line-numbers=1 -o multi_eql_arc.ps multi_eql_arc.f90 ; a2ps --medium=A4 --line-numbers=1 -o multi_app_eql_arc.ps multi_app_eql_arc.f90 ; a2ps --medium=A4 --line-numbers=1 -o app_real_equal.ps app_real_equal.f90 ; a2ps --medium=A4 --line-numbers=1 -o opt_equal_dist.ps opt_equal_dist.f90 ; a2ps --medium=A4 --line-numbers=1 -o rand_path.ps rand_path.f90 ; a2ps --medium=A4 --line-numbers=1 -o qst_lst_path.ps qst_lst_path.f90 ; a2ps --medium=A4 --line-numbers=1 -o xyz2ak0.ps xyz2ak0.f90
ps2pdf:
        ps2pdf -sPAPERSIZE=a4 action_multi.ps ; ps2pdf -sPAPERSIZE=a4 action_lbfgs.ps  ; ps2pdf -sPAPERSIZE=a4 multivasp.ps ; ps2pdf -sPAPERSIZE=a4 multi_arc_length.ps ; ps2pdf -sPAPERSIZE=a4 multi_eql_arc.ps ; ps2pdf -sPAPERSIZE=a4 multi_app_eql_arc.ps ; ps2pdf -sPAPERSIZE=a4 app_real_equal.ps ; ps2pdf -sPAPERSIZE=a4 opt_equal_dist.ps ; ps2pdf -sPAPERSIZE=a4 rand_path.ps ; ps2pdf -sPAPERSIZE=a4 qst_lst_path.ps ; ps2pdf -sPAPERSIZE=a4 xyz2ak0.ps


--------------------------------------------------------------------------------------------------------------------
두 개의 실행 파일들을 순서대로 만드는 makefile

 cat makefile
cmpl=mpif90
segl=mpif90
#OPT = -fast
#OPT = -check all
OPT = -CB -check all -warn interface -assume realloc_lhs
OPT = -fast
OPT =
OPT =  -O2
FFLAGS = -c ${OPT}
FFLAGSc = -c

FILES= trainingpot.o grbfnn.o t3p.o crystal_set.o onedprint10.o init_seed.o strings.o timestamp.o sortnr.o numeral.o lbfgs_for_action.o
FILES1= predictionpot.o t3p.o strings.o timestamp.o lbfgs_for_action.o

all: /home/ihlee/gaussi/trainingpot.x  /home/ihlee/gaussi/predictionpot.x


/home/ihlee/gaussi/predictionpot.x: $(FILES1)
        $(segl) -o /home/ihlee/gaussi/predictionpot.x  $(FILES1)
/home/ihlee/gaussi/trainingpot.x:  $(FILES)
        $(segl) -o /home/ihlee/gaussi/trainingpot.x $(FILES)

predictionpot.o:predictionpot.f90 strings.o t3p.o
        $(cmpl) $(FFLAGS) predictionpot.f90
trainingpot.o:trainingpot.f90 crystal_set.o grbfnn.o
        $(cmpl) $(FFLAGS) trainingpot.f90
crystal_set.o:crystal_set.f90 strings.o
        $(cmpl) $(FFLAGS) crystal_set.f90
grbfnn.o:grbfnn.f90  crystal_set.o t3p.o
        $(cmpl) $(FFLAGS) grbfnn.f90
t3p.o:t3p.f90
        $(cmpl) $(FFLAGS) t3p.f90
onedprint10.o:onedprint10.f90
        $(cmpl) $(FFLAGS) onedprint10.f90
init_seed.o:init_seed.f90
        $(cmpl) $(FFLAGS) init_seed.f90
sortnr.o:sortnr.f90
        $(cmpl) $(FFLAGS) sortnr.f90
strings.o:strings.f90
        $(cmpl) $(FFLAGS) strings.f90
timestamp.o:timestamp.f90
        $(cmpl) $(FFLAGS) timestamp.f90
numeral.o:numeral.f
        $(cmpl) $(FFLAGS) numeral.f
lbfgs_for_action.o:lbfgs_for_action.f
        $(cmpl) $(FFLAGS) lbfgs_for_action.f


clean:
        rm -f *.x *.o *.mod *.M core*  *.ps  *.ps~  *__genmod.f90  *~  *.pdf *.pdf~
touch:
        touch *.f90 *.f  *.i makefile ; chmod 600 *.f90 *.i makefile ; ls -l *.f90 *.i makefile
rmo:
        rm -f *.o *.mod *.M core*  *.ps~  *__genmod.f90  *~
lsl:
        ls -l *.f90 *.f makefile *.i
wc:
        wc trainingpot.f90 predictionpot.f90 crystal_set.f90 grbfnn.f90 t3p.f90 onedprint10.f90 init_seed.f90 strings.f90 timestamp.f90 sortnr.f90 numeral.f lbfgs_for_action.f
a2ps:
        a2ps -o trainingpot.ps trainingpot.f90 --prologue=color ; a2ps -o crystal_set.ps crystal_set.f90 --prologue=color ; a2ps -o grbfnn.ps grbfnn.f90 --prologue=color ; a2ps -o t3p.ps t3p.f90 --prologue=color  ; a2ps -o predictionpot.ps predictionpot.f90 --prologue=color
a2psblack:
         a2ps -o trainingpot.ps trainingpot.f90 --medium=A4 --line-numbers=1 ; a2ps -o crystal_set.ps crystal_set.f90 --medium=A4 --line-numbers=1 ; a2ps -o grbfnn.ps  grbfnn.f90 --medium=A4 --line-numbers=1 ; a2ps -o predictionpot.ps  predictionpot.f90 --medium=A4 --line-numbers=1
ps2pdf:
         ps2pdf -sPAPERSIZE=a4 trainingpot.ps ; ps2pdf -sPAPERSIZE=a4 grbfnn.ps  ; ps2pdf -sPAPERSIZE=a4 crystal_set.ps ; ps2pdf -sPAPERSIZE=a4 t3p.ps ; ps2pdf -sPAPERSIZE=a4 predictionpot.ps


http://web.mit.edu/gnu/doc/html/make_4.html

--------------------------------------------------------------------------------------------------------------------


핑백

덧글

댓글 입력 영역

최근 포토로그



MathJax