먼저 가장 큰 틀인 target, dependency, command, macro 이렇게 4가지에 대해 알아보겠습니다
target : dependency
command
# 여기서 target 다음줄은 반드시 tab으로 해야함
#tab으로 하지 않으면 인식을 하지 못함
gnu make의 큰 틀은 이런 모양을 갖춥니다
여기서 중요한 점은 command 줄들은 모두 앞이 tab이어야 합니다
어거지로 8칸 띄우면 되는거 아닌가? 하실 수도 있지만 스페이스바를 8번 누르게 되면
줄 자체가 틀렸다고 저렇게 다른 색으로 칠해지고
실행해봐도 아래와 같은 에러 메세지를 출력합니다
(base) lsh@DESKTOP-8N2HJ5V:~/rr$ make print
makefile:12: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
저 부분은 꼭 숙지하셔야합니다
target은 한 마디로 내가 사용할 명령어의 이름이며 자유롭게 정하셔도 됩니다
dependency는 영어 뜻과 마찬가지고 의존성을 뜻합니다
해당 target이 실행되기 전에 필수적으로 필요한 것들을 말합니다
B1 = 2
B ?= 10
B1 ?= 10
TARGETS = first print
.PHONY: $(TARGETS)
first:
@ echo "Makefile start"
print:
@ echo "Value of B = " $(B)
@ echo "Value of B1 = " $(B1)
예시 코드를 보면 first라는 단순히 메세지를 출력하는 타깃을 만들었습니다
두 타깃 모두 의존성이 설정되어 있지 않기 때문에 결과를 보면
(base) lsh@DESKTOP-8N2HJ5V:~/rr$ make print
Value of B = 10
Value of B1 = 2
이렇게 출력이 됩니다
하지만 print 타깃이 first에 의존하도록 코드를 수정하고 실행하면
B1 = 2
B ?= 10
B1 ?= 10
TARGETS = first print
.PHONY: $(TARGETS)
first:
@ echo "Makefile start"
print: first
@ echo "Value of B = " $(B)
@ echo "Value of B1 = " $(B1)
(base) lsh@DESKTOP-8N2HJ5V:~/rr$ make print
Makefile start
Value of B = 10
Value of B1 = 2
first에 출력 내용이 print에서 출력한 모습입니다
dependency는 반드시 있어야 하는 것은 아니기 때문에 사용법만 알아두시면 좋을 것 같습니다
보통 모델에서는 build와 install이 나누어져있기 때문에 build와 install을 따로 타깃을 만들고
install이 진행이 될 때 build를 dependency로 설정하여 한 번에 build와 install을 수행하게 만들 수 있습니다
command는 말 그대로 해당 타깃이 호출당하면 실행할 명령어들을 나타냅니다
위에 예시처럼 echo를 사용해서 메세지를 출력하거나 $(B)처럼 다른 변수들을 사용할 수도 있습니다
macro는 코드를 단순화 시키는 역할을 합니다
간단하게 말해서 환경 변수처럼 호출할 일이 많은 경우 미리 위에서 선언하여 언제든지 호출하여 사용할 수 있게
하는 역할을 합니다
쉬운 예로는 위에 선언되었던 B도 일종에 macro라고 할 수 있습니다
다음은 변수 선언으로 다른 코딩 언어들과 크게 다르지 않게 = 을 사용합니다
여기서 사용하는 =은 고정값이 아니기 때문에 변수가 사용될 때마다 값을 요구합니다
하지만 사용하려는 모든 변수가 이렇지는 않을 것입니다
예를 들어 원주율 π나 과학에서 사용하는 다양한 상수들은 한 번 선언하고 나서는 더 이상 수정이 필요없는 경우에는
:=나 ::=을 사용하면 됩니다
Fortran에서 parameter와 비슷한 역할을 합니다
추가적으로 할당 연산자는 3가지가 더 있어서 아래 표에 간단하게 정리하고
예시 코드고 작성해놓겠습니다
?= | 좌변의 변수가 정의되지 않은 경우에만 우변의 값을 변수에 할당한다 |
+= | 더하기 대입 연산자, 우변의 값이 이미 할당이 되어있다면 더하여서 새로 할당한다 |
!= | 새로 입력된 값을 바로 할당한다 |
B1 = 2
B ?= 10
B1 ?= 10
TARGETS = print
.PHONY: $(TARGETS)
print:
@ echo "Value of B = " $(B)
@ echo "Value of B1 = " $(B1)
위에서 봤던 예시로 만든 코드입니다
초기에 B에는 선언하지 않고 B1에는 2를 할당했습니다
그래서 그 다음에 쉬운 비교를 위해 ?=를 이용해서 10이라는 같은 숫자를 재할당했습니다
그리고 print 타깃을 만들고 서로 호출해보면 결과는 아래처럼 나옵니다
(base) lsh@DESKTOP-8N2HJ5V:~/rr$ make print
Value of B = 10
Value of B1 = 2
B는 아예 선언되지 않았던 변수이기 때문에 10이라는 변수가 할당이 되었지만
B1에는 기존에 2가 있었고 ?=은 변수가 선언되지 않았을 때만 할당하기 때문에 기존의 값인 2가 출력된 모습입니다
다음은 += 할당입니다
더하여서 할당하는게 파이썬과는 조금 의미가 다릅니다
a = 1
a += 2
a
파이썬에서 이런식으로 코드를 실행시키면 a는 3이라는 값이 할당이 되지만
A = 1
A += 2
TARGETS = print
.PHONY: $(TARGETS)
print:
@ echo $(A)
(base) lsh@DESKTOP-8N2HJ5V:~$ make print
1 2
makefile에서는 리스트처럼 그냥 뒤에 붙어버리기만 합니다
약간 파이썬에서 리스트에 +=를 할때와 비슷하게 작동을 합니다
이것들은 공백으로만 구분이 됩니다
어떻게 보면 파이썬에 리스트와 비슷하지만 또 다릅니다
먼저 array나 list처럼 하나로 묶여있는 애들이 아니라 그냥 2개가 띡 들어가있을 뿐이기 때문에
slicing은 못하지만 indexing은 가능합니다
idxing: print
@ echo $(word 1, $(A))
(base) lsh@DESKTOP-8N2HJ5V:~$ make idxing
1 2
1
파이썬처럼 작동하게는 제가 조금 더 공부하고 만들어서 포스팅 다시 해보겠습니다!
마지막으로 != 입니다
!=은 변수 뒤에 명령어를 작성하면 명령어의 실행 결과는 할당하는 일을 합니다
예시로 해보면 date는 쉘 명령어로 현재 날짜와 시간을 출력합니다
변수에 !=으로 date를 할당해서 출력해보면
dd != date
TARGETS = print
.PHONY: $(TARGETS)
print:
@ echo $(dd)
(base) lsh@DESKTOP-8N2HJ5V:~/lll$ make print
Fri Mar 1 18:03:16 KST 2024
이렇게 결과를 출력합니다
오늘은 기본 틀과 변수 할당에 대해서 공부해봤습니다
계속 더 공부해보고 기록해보겠습니다!
'개인 공부' 카테고리의 다른 글
GNU Make에 대해서 (4) | 2024.02.29 |
---|