티스토리 뷰

42/others

Makefile - relink, dependency

stdbc 2020. 10. 29. 17:58

리링크

 

코드를 바꾸지 않은 상태에서 다시 make 했을 때, 변경사항이 없어서 타겟을 다시 만들지 않으면 리링크되지 않은 것.

보통 의존성이 있는 경우 리링크가 많이 발생함.

 

 

A primary feature of make is that dependencies are specified in a makefile (often named makefile but may have other names such as MyRules.mk) in a form like:

FileX: FileA FileB FileC
    Command to make FileX from FileA FileB FileC

Given this dependency, if any of FileA, FileB, or FileC has a modification time later than the modification time of FileX, then make will execute the command to make a new version of FileX.

 

stackoverflow.com/questions/52502399/what-does-it-mean-for-a-makefile-to-relink

 


<기본 개념>

LIBFT = ./libft/libft.a ... 정의(타겟)

$(NAME) : $(LIBFT)  ... 의존성
	cp $(LIBFT) ./$(NAME)

$(LIBFT) :
	$(MAKE) -C ./libft
    
    
<룰>
타겟 : 의존성
	명령
	명령

1. $(LIBFT)에 의존할 때, LIBFT가 정의하는 타겟이 있다면

2. $(LIBFT) 룰을 실행한다

 

 

<매크로 없는 버전>

$(NAME) : ./libft/libft.a
	cp ./libft/libft.a ./$(NAME)

./libft/libft.a :
	$(MAKE) -C ./libft

1. ./libft/libft.a에 의존할 때,

2. ./libft/libft.a 룰을 실행한다


에러1. No rule to make target 'test'

test = libft/libft.a

all : $(NAME)
$(NAME) : test
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

libft :
	$(MAKE) -C ./libft

$()가 없는 test는 매크로가 아니라 얘 자체가 'test'라는 이름의 타겟(파일 혹은 폴더). 

따라서 위에서 test의 정의를 찾는 것이 아니라 항상 룰을 찾으러 내려감.

하지만 아래에 'test'라는 룰이 없기 때문에 No rule to make target 'test' 에러

 

 

test = libft/libft.a

all : $(NAME)
$(NAME) : test
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

$(test) :
	$(MAKE) -C ./libft

'test' 이름의 타겟을 만나서 명령하러 내려갔지만 test 룰이 없기 때문에 No rule to make target 'test'

 


에러 1-1. No rule to make target 'libft/libft.a'

test = libft/libft.a

all : $(NAME)
$(NAME) : $(test)
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

test :
	$(MAKE) -C ./libft

$(test)를 만났을 때 정의하는 타겟은 있지만, $(test) 룰이 없기 때문에 No rule to make target 'libft/libft.a'에러

 


에러2. 리링크

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : test
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

test :
	$(MAKE) -C ./libft

<make all>

1) make all : 'test' 타겟 만나서 test 룰(./libft/libfta.a 생성) cp, ar rcs 다 실행

2) 또 make all : 첫 명령 후에도 현재 루트에 'test'라는 타겟(파일, 폴더)이 없기 때문에 같은 과정 계속 반복 = 리링크

 

<make test>

1) make test : 처음 명령 실행, ./libft/libft.a 생성

2) 또 make test : 첫 명령 후에도 현재 루트에 'test'라는 타겟(파일, 폴더)이 없기 때문에 같은 과정 계속 반복 = 리링크

 

 

test = libft/libft.a

all : $(NAME)
$(NAME) : test
	cp ./libft/libft.a ./$(NAME)
	ar -rcs $(NAME) $(OBJS)

test :
	$(MAKE) -C ./libft

이렇게 위에 test가 정의하는 타겟을 만들어줘도 과정은 똑같음.

의존하는 test자체가 'test'라는 이름의 타겟이고 $(test) 매크로가 아니기 때문에, test가 어떻게 정의되어 있는지와는 상관없는 과정이기 때문.

 

<make all>

1. test는 매크로가 아님. 'test' 이름의 타겟을 만들러 그냥 밑으로 내려가서 명령 실행,

2. 실행 후에도 현재 루트에 'test' 이름의 타겟이 만들어지지 않기 때문에 과정 반복, 계속 리링크 발생

 

<make test>

1. 현재 루트에 'test' 타겟이 존재하지 않기 때문에 명령 실행,

2. 실행 후에도 현재 루트에 'test'이름의 파일이 만들어지지 않기 때문에 과정 반복, 계속 리링크 발생


에러3. 아무일도 일어나지 않음

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : $(test)
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

GGGG :
	$(MAKE) -C ./libft

<make all>

1. $(test)를 만났지만 위에 정의된 test 타겟이 없기 때문에 아무 일 없이 그냥 다음으로 넘어감

2. cp에서 해당 파일이 없어 실패

cp libft/libft.a ./libftprintf.a

cp libft/libft.a : No such file or directory

 

 

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : $(test)
	cp ./libft/libft.a ./$(NAME)
	ar -rcs $(NAME) ...

$(test) :
	$(MAKE) -C ./libft

$(test) 룰을 만들어줘도 동일함.

$(test)에 해당하는 타겟이 없기 때문에 아무 일 없이 넘어감, cp 에러

 

 

* make 매크로들은 대소문자 구분함.

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : $(libft)
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

$(libft) :
	$(MAKE) -C ./libft

$(libft)에 해당하는 타겟이 없어서 동일한 cp에러 발생.

libft와 LIBFT가 다르다는 것을 알 수 있음.


에러3-1. 아무일도 일어나지 않음 (타겟이 파일, 폴더명과 동일할 때 : up to date)

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : libft
	cp ./libft/libft.a ./$(NAME)
	ar -rcs $(NAME) ...

libft :
	$(MAKE) -C ./libft

<make all>

1. 'libft'라는 이름의 타겟을 의존하는데, 이미 현재 루트에 'libft'라는 폴더가 있기 때문에 명령어로 안내려감.

2. ./libft/libfta.a 파일이 없어서 cp 에러

 

<make libft>

1. make libft: 이미 libft폴더가 존재하기 때문에 결과: 'libft' is up to date

 

 

*이때 폴더명은 대소문자 동일하게 판단됨.

Makefile에서 LIBFT 타겟을 의존하더라도 libft일 때와 같음, 동일한 에러.

 


정상성공

 

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : $(LIBFT)
	cp ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

$(LIBFT) :
	$(MAKE) -C ./libft

<make all>

1. make all : $(LIBFT)를 만났을 때 LIBFT가 정의하는 타겟이 있기 떄문에 $(LIBFT) 룰이 실행됨

2. 또 make all : $(LIBFT)를 만났을 때 해당 타겟(./libft/libft.a)가 이미 존재하기 때문에 더이상 진행 X, 리링크 없음

 

 

LIBFT = libft/libft.a

all : $(NAME)
$(NAME) : $(LIBFT)
	mv ./libft/libft.a ./$(NAME)
	ar rcs $(NAME) ...

$(LIBFT) :
	$(MAKE) -C ./libft

만약 cp대신 mv를 쓰면 리링크 생김

또 make할 때엔, (mv로 옮겨버려서) LIBFT 타겟이 존재하지 않기 때문에 $(LIBFT) 룰이 다시 실행됨 = 리링크.

 

 


GNU make 버전 3.77. 1998/05 

'42 > others' 카테고리의 다른 글

libasm  (1) 2020.11.19
ft_server 수정중  (0) 2020.09.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함