개인 공부

GNU Make 문법 공부1

이석사 중 2024. 3. 1. 18:06
728x90

먼저 가장 큰 틀인 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

 

이렇게 결과를 출력합니다


오늘은 기본 틀과 변수 할당에 대해서 공부해봤습니다

 

계속 더 공부해보고 기록해보겠습니다!

 

728x90

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

GNU Make에 대해서  (4) 2024.02.29