โน๏ธ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.3 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://modoocode.com/311 |
| Last Crawled | 2026-03-30 07:37:32 (8 days ago) |
| First Indexed | 2020-06-10 13:51:41 (5 years ago) |
| HTTP Status Code | 200 |
| Meta Title | ์น์ด๋จน๋ C++ - <19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)> |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | ์์ฑ์ผ : 2020-06-10
์ด ๊ธ์ 105837 ๋ฒ ์ฝํ์ต๋๋ค.
์ด๋ฒ ๊ฐ์ข์์๋
make
์ ์๋ ์ดํด
Makefile
๋ฌธ๋ฒ ์ดํด
๋ง๋ฅ
Makefile
๋ง๋ค๊ธฐ
์ ๋ํด์ ๋ค๋ฃจ์ด ๋ณด๊ฒ ์ต๋๋ค.
์๋
ํ์ธ์. ์ด๋ฒ ๊ฐ์ข ๋ถํฐ๋ ์น์ด๋จน๋ C++ ์๋ฆฌ์ฆ์
๋ถ๋ก
๊ณผ ๊ฐ์ ๊ฐ๋
์ผ๋ก C++ ์ธ์ด ์์ฒด์๋ ์ง์ ๊ด๋ จ์ ์์ง๋ง ์ค์ ๋ก C++ ์ ํ๋ก๊ทธ๋๋ฐ ํ๊ธฐ ์ํด์ ํ์ํ ์ง์๋ค๊ณผ ํด๋ค์ ๋ํด์ ์ด์ผ๊ธฐ ํ๊ณ ์ ํฉ๋๋ค. ๊ทธ ์ฒซ ๋ฒ์งธ ํ์๋ก
Makefile
๋ง๋ค๊ธฐ๊ฐ ๋๊ฒ ์ต๋๋ค.
์๋ฌด๋๋ ๋ฆฌ๋
์ค ํ๊ฒฝ์์ ํ๋ก๊ทธ๋๋ฐ์ ํ์ ๋ถ๋ค์ ์์๊ฒ ์ง๋ง, ๋ณดํต ํ๋ก๊ทธ๋จ์ ์ปดํ์ผ ํ ๋
make
๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํฉ๋๋ค. ์๋์ฐ์์ ๋น์ฃผ์ผ ์คํ๋์ค๋ฅผ ์ฌ์ฉํ์ ๋ค๋ฉด ์ปดํ์ผ ๋ฒํผ์ ๋๋ฅด๋ฉด ์์์ ์ปดํ์ผ ๋๋ ๊ฒ๊ณผ๋ ๋ฌ๋ฆฌ, ์ ์์์ ์ปดํ์ผ์ ํ๋ ค๋ฉด
์ด๋ค ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ณ , ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ ์ง ์ง์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ค์ผ ํฉ๋๋ค
.
๋ฌผ๋ก ๋งค๋ฒ ๋ช
๋ น์ด๋ฅผ ์น๋ฉด ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง ํ๋ก์ ํธ์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ํ์ผ๋ค์ด ๋ง์์ง๋ค๋ฉด ๋งค๋ฒ ๊ทธ๋ ๊ฒ ์น๋ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น์์ง๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๋ฆฌ๋
์ค์์๋
make
๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋๋ฐ, ์ด ํ๋ก๊ทธ๋จ์
Makefile
๋ผ๋ ํ์ผ์ ์ฝ์ด์ ์ฃผ์ด์ง ๋ฐฉ์๋๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํ๊ฒ ํฉ๋๋ค. ๋๋ถ์ ๋ง์ ์์ ํ์ผ๋ค์ ๋ช
๋ น์ด ํ ๋ฒ์ผ๋ก ์ปดํ์ผ ํ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋
make
ํ๋ก๊ทธ๋จ์ด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋๋๊ณ , ํ๋ก๊ทธ๋จ๋ค์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก
Makefile
์ ์์ฑํด์ผ ํ๋์ง ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋จผ์
make
๊ฐ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋ํ๋์ง ์๊ธฐ ์ ์ ์ปดํ์ผ๋ฌ๋ฅผ ํตํด ํ๋ก๊ทธ๋จ์ ๋น๋ํ๊ฒ ๋๋ฉด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์์ค ์ฝ๋์์ ํ๋์ ํ๋ก๊ทธ๋จ์ด ์์ฑ๋๋์ง ์ดํด๋ณด๋๋ก ํฉ์๋ค.
๊ฐ์ฅ ๋จผ์ ์ฌ๋ฌ๋ถ์ ๋จธ๋ฆฌ ์์ผ๋ก ๋ ์ค๋ฅด๋ ๊ณผ์ ์ ๋ฐ๋ก
์ปดํ์ผ(Compile)
์ผ ๊ฒ์
๋๋ค. ์ด ์ปดํ์ผ์ด๋ผ๋ ๊ณผ์ ์ ์ฌ๋ฌ๋ถ์ ์์ค ์ฝ๋๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ์ด์
๋ธ๋ฆฌ์ด๋ก ๋ณํํ๋ ๊ณผ์ ์
๋๋ค.
์๋ฅผ ๋ค์ด์ ์๋์ ๊ฐ์ด
foo.h
์ ์ ์๋
foo
ํจ์์
bar.h
์ ์ ์๋
bar
ํจ์๋ฅผ
main
ํจ์์์ ํธ์ถํ๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ์ดํด๋ด
์๋ค.
foo.h
int
foo
();
foo.cc
#include
<iostream>
#include
"foo.h"
int
foo
() {
std
::
cout
<<
"Foo!"
<<
std
::
endl;
return
0
;
}
bar.h
int
bar
();
bar.cc
#include
<iostream>
#include
"bar.h"
int
bar
() {
std
::
cout
<<
"Bar!"
<<
std
::
endl;
return
0
;
}
main.cc
#include
"bar.h"
#include
"foo.h"
int
main
() {
foo
();
bar
();
}
์๋ฅผ ๋ค์ด์
main.cc
๋ฅผ ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์๋์ ๊ฐ์ด ํ๋ฉด ๋ฉ๋๋ค.
$ g++ -c main.cc
g++
์ ์ ๋ฌํ๋
-c
๋ช
๋ น์ด๋ ์ธ์ ๋ค์์ ์ฃผ์ด์ง๋ ํ์ผ์ ์ปดํ์ผ ํด์
๋ชฉ์ ํ์ผ(object file)
์ ์์ฑํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
์ค์ ๋ก, ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผ ํ์๋ค๋ฉด ์๋์ ๊ฐ์ด
main.o
๋ผ๋ ํ์ผ์ด ์์ฑ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
$ ls main.o
main.o
์ด
main.o
๋
main.cc
๋ฅผ ์ปดํ์ผ ํ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ๋ด๊ฒจ์๋ ํ์ผ ์
๋๋ค. ์ค์ ๋ก
main.o
๋ฅผ ๋ฏ์ด๋ณด๋ฉด
$ objdump -S main.o
main.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: e8 00 00 00 00 callq d <main+0xd>
d: e8 00 00 00 00 callq 12 <main+0x12>
12: b8 00 00 00 00 mov $0x0,%eax
17: 5d pop %rbp
18: c3 retq
์ ๊ฐ์ด
main.cc
์ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ์ ๋ค์ด์์์ ์ ์ ์์ต๋๋ค.
ํ ๊ฐ์ง ์ฌ๋ฏธ์๋ ์ ์ ์ปดํ์ผ๋ฌ๊ฐ
main.cc
๋ฅผ ์ปดํ์ผ ํ ๋ ๋ค๋ฅธ ํ์ผ๋ค์ ์ฐธ์กฐํ์ง ์์๋ค๋ ์ ์
๋๋ค. ์ค์ ๋ก
main.o
์ ์ด์
๋ธ๋ฆฌ๋ฅผ ์ฌ์ฉ ๋ณด๋ฉด
foo
๋
bar
์ ๊ดํ ๋ด์ฉ์ด ํ๋๋ ์์์ ์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์
main.o
์์ฒด๋ก๋ ์ฐ๋ฆฌ์ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ํ๋ฉด
main.o
์๋
foo
๋ผ๋ ํจ์๋ฅผ ํธ์ถํด๋ผ!
๋ผ๋ ๋ด์ฉ๋ง ์์ง,
foo
๋ ์ด๋์ ์๊ณ ์ด๋ฌ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค
์ ๊ดํ ์ด์ผ๊ธฐ๋ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
์ค์ ๋ก ์๋ํ๋
foo
์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋
foo.cc
๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋ค์ด์ง
foo.o
๊ฐ ํ์ํ๊ณ , ๋ง์ฐฌ๊ฐ์ง๋ก
bar
์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋
bar.cc
๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋
bar.o
๊ฐ ํ์ํฉ๋๋ค.
๋ฐ๋ผ์ ์ค์ ํ๋ก๊ทธ๋จ์ ์ ์ํ๊ธฐ ์ํด์๋ ์ด ๊ฐ๊ฐ์
main.o, foo.o, bar.o
๋ฅผ ํ๋๋ก ํฉ์น๋ ๊ณผ์ ์ด ํ์ํ๊ฒ ์ฃ . ์ด์ ๊ฐ์ ๊ณผ์ ์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด
๋งํน(Linking)
์ด๋ผ๊ณ ํฉ๋๋ค.
๋งํน์ด ์ด๋ฆ ๊ทธ๋๋ก
๋งํฌ ํ๋ ์์
์ธ ์ด์ ๋ ์ค์ ๋ก ์๋ก ๋ค๋ฅธ ํ์ผ์ ํฉ์ด์ ธ ์๋ ํจ์๋ ํด๋์ค๋ค์ ํ ๋ฐ ๋ฌถ์ด์ ๋งํฌํด์ฃผ๋ ์์
์ด๊ธฐ ๋๋ฌธ์ด์ฃ . ์ด ๊ณผ์ ์์
main
ํจ์ ์์
foo
ํจ์๊ฐ ์ด๋์ ์ ์๋์ด ์๋์ง ์์น๋ฅผ ์ฐพ๊ณ ์ ๋๋ก ๋ ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ฌ์ค ์ด ๋งํน์ ๊ดํด์ ์ด์ผ๊ธฐ๋ง ํด๋ ํ์ฐธ ํ ์ ์๋๋ฐ, ์ผ๋จ ์ด ๊ธ์ ๋ชฉํ๋ ๋น๋ ํ์ผ ๋ง๋ค๊ธฐ ์ด๋ฏ๋ก ์ฌ๊ธฐ์ ์ค์ด๊ฒ ์ต๋๋ค.
์๋ฌดํผ ์ด ๋งํน ๊ณผ์ ์ ์๋์ ๊ฐ์ด ์ปดํ์ผ๋ฌ์ ๋ชฉ์ ํ์ผ์ ์ ๋ฌํจ์ผ๋ก์จ ์ํ๋ฉ๋๋ค.
$ g++ main.o foo.o bar.o -o main
์ฌ๊ธฐ์
-o
์ต์
์ ๊ทธ ๋ค์ ๋งํน ํ์ ์์ฑํ ์คํ ํ์ผ ์ด๋ฆ์ ์ด์ผ๊ธฐ ํฉ๋๋ค. ์ ๊ฒฝ์ฐ
main
์ด๋ผ๋ ์คํ ํ์ผ์ ๋ง๋ค์๊ณ ๋ง์ฝ์ ์ด๋ฅผ ๋ฐ๋ก ์ง์ ํ์ง ์๋๋ค๋ฉด ๊ทธ๋ฅ
./a.out
์ด๋ผ๋ ํ์ผ์ ๋ํดํธ๋ก ์์ฑํ๊ฒ ๋ฉ๋๋ค.
์ค์ ๋ก
main
ํ์ผ์ ์คํํ๊ฒ ๋๋ค๋ฉด
์คํ ๊ฒฐ๊ณผ
Foo!
Bar!
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
์ผ๋จ ์์ ๊ฐ์ด
main
์คํ ํ์ผ์ ์์ฑํ๊ธฐ ์ํด์ ์
๋ ฅํ ์ ๋ช
๋ น์ด๋ฅผ ์ญ ๋์ดํด๋ณด์๋ฉด;
$ g++ -c main.cc
$ g++ -c foo.cc
$ g++ -c bar.cc
$ g++ main.o foo.o bar.o -o main
์ ๊ฐ์ต๋๋ค. ๋ฌผ๋ก ํ์ผ ๊ฐ์๊ฐ ์๋ค๋ฉด ๋งค ๋ฒ ์
๋ ฅํ๋ ๊ฒ์ด ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋์ง๋ ์์ต๋๋ค๋ง, ํ๋ก์ ํธ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ์ณ์ผํ ๋ช
๋ น์ด๊ฐ ๋ ๋ง์์ง๊ฒ ๋์ ๋ณต์กํ๊ฒ ์ง์ (ํนํ ํ์ผ๋ค์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ์๋๋ค๋ฉด ๋ง์ด์ฃ .)
๋ฌผ๋ก ์ ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ๊ธ ์์๋ ๋ถ์ด๋ผ๋ฉด
๊ทธ๋ฅ ์ ๋ช
๋ น์ด๋ค์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?
๋ผ๊ณ ๋ฌผ์ผ์ค ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋ฐฉ์์ผ๋ก ํ๋ค๋ฉด ํ ๊ฐ์ง ๋ฌธ์ ์ ์ด ์๋๋ฐ, ์๋ฅผ ๋ค์ด์ ์ฌ๋ฌ๋ถ์ด
main.cc
๋ฅผ ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ค์ ๋ก๋
$ g++ -c main.cc
$ g++ main.o foo.o bar.o -o main
๋ฑ ์ด ๋ ๋ช
๋ น์ด๋ง ์คํํ๋ฉด ๋ฉ๋๋ค. ์๋ํ๋ฉด
main
ํ์ผ์ ๋ฐ๊พผ๋ค๊ณ ํด์
foo
๋
bar
์ ์ปดํ์ผ ๋ ๋ด์ฉ์ด ๋ฐ๋์ง ์๊ธฐ ๋๋ฌธ์ด์ฃ . ํ์ง๋ง ์ ์ฒ๋ผ ๋จ์ํ๊ฒ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๊ฒ ๋๋ค๋ฉด ํ์ผ ํ๋๋ง ๋ฐ๊ฟ๋ ์ ์ฒด ๋ชจ๋ ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ฒ ๋๋ฏ๋ก ์ปดํ์ผ ์๊ฐ์ด
๋งค์ฐ
๊ธธ์ด์ง๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง
make
๋ฅผ ์ฌ์ฉํ๋ฉด ์ผ๋ถ ํ์ผ์ ์์ ํ ๊ฒฝ์ฐ ํ์ํ ๋ช
๋ น๋ง ๋น ๋ฅด๊ฒ ์ปดํ์ผ์ ํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ ๊ทธ๋ ๋ค๋ฉด ๊ฑฐ๋์ ๋ฏธํ๊ณ
make
์ ์ฌ์ฉ๋ฒ๊ณผ
make
๋ฅผ ์ํ
Makefile
์ ์ด๋ป๊ฒ ์์ฑํ๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
make
๋ ๊ฐ๋จํ ๋งํ์๋ฉด
์ฃผ์ด์ง ์ ๋ช
๋ น์ด๋ค์ ์กฐ๊ฑด์ ๋ง๊ฒ ์คํํ๋ ํ๋ก๊ทธ๋จ
์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ด ๋ ์ด๋ ํ ์กฐ๊ฑด์ผ๋ก ๋ช
๋ น์ด๋ฅผ ์คํํ ์ง ๋ด์ ํ์ผ์
Makefile
์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ,
make
๋ฅผ ํฐ๋ฏธ๋ ์์์ ์คํํ๊ฒ ๋๋ค๋ฉด ํด๋น ์์น์ ์๋
Makefile
์ ์ฐพ์์ ์ฝ์ด๋ค์ด๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด
Makefile
์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์กฐ๊ฑด์ ๊ธฐ์ ํ ๊น์?
target โฆ : prerequisites โฆ
(ํญ)recipe
โฆ
โฆ
Makefile
์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๊ฐ์ด 3 ๊ฐ์ง ์์๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
make
๋ฅผ ์คํํ ๋
make abc
๊ณผ ๊ฐ์ด ์ด๋ ํ ๊ฒ์
make
ํ ์ง ์ ๋ฌํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ ํ๊ฒ(target) ์ด๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ๋ง์ผ
make abc
๋ฅผ ํ์์ ๊ฒฝ์ฐ ํ๊ฒ ์ค์
abc
๋ฅผ ์ฐพ์์ ์ด์ ๋์๋๋ ๋ช
๋ น์ ์คํํด์ค๋๋ค.
์ฃผ์ด์ง ํ๊ฒ์
make
ํ ๋ ์คํํ ๋ช
๋ น์ด๋ค์ ๋์ด์
๋๋ค. ํ ๊ฐ์ง ์ค์ํ ์ ์ recipe ์๋ฆฌ์ ๋ช
๋ น์ด๋ฅผ ์ธ ๋
๋ฐ๋์ ํญ ํ ๋ฒ์ผ๋ก ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํด์ค์ผ๋ง ํฉ๋๋ค
. ๋ณดํต ์์ฆ์ ํธ์ง๊ธฐ์ ๊ฒฝ์ฐ (์๋ฅผ ๋ค์ด VSCode), ์๋์ผ๋ก ํญ์ ์คํ์ด์ค๋ก ๋ฐ๊ฟ์ฃผ๋ ์ต์
์ด ํ์ฑํ ๋์ด ์์ ํ
๋ฐ
make
๊ฐ
Makefile
์ ์ ๋๋ก ์ฝ์ด๋ค์ด๊ธฐ ์ํด์๋ ๋ฐ๋์ ํญ์ ์ฌ์ฉํด์ผ๋ง ํฉ๋๋ค!
์ฃผ์ด์ง ํ๊ฒ์
make
ํ ๋ ์ฌ์ฉ๋ ํ์ผ๋ค์ ๋ชฉ๋ก ์
๋๋ค. ๋ค๋ฅธ ๋ง๋ก ์์กด ํ์ผ(dependency) ์ด๋ผ๊ณ ๋ ํฉ๋๋ค. ์๋ํ๋ฉด ํด๋น ํ๊ฒ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฑด๋๋ ค์ผ ํ ํ์ผ๋ค์ ์จ๋์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ง์ผ ์ฃผ์ด์ง ํ์ผ๋ค์ ์์ ์๊ฐ ๋ณด๋ค ํ๊ฒ์ด ๋ ๋์ค์ ์์ ๋์๋ค๋ฉด ํด๋น ํ๊ฒ์ ๋ช
๋ น์ด๋ฅผ ์คํํ์ง ์์ต๋๋ค.
์๋ํ๋ฉด ์ด๋ฏธ ์ด์ ์ ํ๊ฒ์ด ๋ง๋ค์ด์ ธ์๋ค๊ณ ๊ฐ์ฃผํ๊ธฐ ๋๋ฌธ์ด์ฃ .
์๋ฅผ ๋ค์ด์ ํ๊ฒ์ด
main.o
์ด๊ณ , ๋ช
๋ น์ด๊ฐ
g++ -c main.cc
๋ผ๋ฉด, ํ์ ์กฐ๊ฑด๋ค์
main.cc
,
foo.h
,
bar.h
๊ฐ ๋๊ฒ ์ฃ . ์๋ํ๋ฉด ์ด๋ค ํ์ผ๋ค ์ค ํ๋๋ผ๋ ๋ฐ๋๋ค๋ฉด
main
์ ์๋ก ์ปดํ์ผ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ฐ๋ฉด์
main.o
์ ์์ฑ ์๊ฐ์ด
main.cc
,
foo.h
,
bar.h
๋ค์ ๋ง์ง๋ง ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ผ๋ฉด, ๊ตณ์ด
main.o
๋ฅผ ๋ค์ ์ปดํ์ผ ํ ํ์๊ฐ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก
Makefile
์ ๊ฐ๋จํ๊ฒ ๊ตฌ์ฑํด๋ณด๊ฒ ์ต๋๋ค.
foo.o : foo.h foo.cc
g++ -c foo.cc
bar.o : bar.h bar.cc
g++ -c bar.cc
main.o : main.cc foo.h bar.h
g++ -c main.cc
main : foo.o bar.o main.o
g++ foo.o bar.o main.o -o main
์ฃผ์ ์ฌํญ
์ Makefile ์ ๊ทธ๋๋ก ๋ณต์ฌํด์ ์คํํ๋ค๋ฉด ์๋ง ์คํ์ด ์๋ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด ํญ์ด ์คํ์ด์ค๋ก ๋ฐ๋์ด์ ๊ทธ๋ฐ๋ฐ์, ์ ๋๋ก Makefile ์ ๋ง๋์๊ธฐ ์ํด์๋ g++ ์์ ์ค๋ ์คํ์ด์ค ๋ ๋ฒ์ ํญ์ผ๋ก ๋ฐ๊พธ์ด์ ์ ์ฅํด๋ณด์ธ์.
์ฐ๋ฆฌ์ ๋ชฉํ๋ ์คํ ํ์ผ์ธ
main
์ ๋ง๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
make main
์ ์คํํด๋ณด๋ฉด
$ make main
g++ -c foo.cc
g++ -c bar.cc
g++ -c main.cc
g++ foo.o bar.o main.o -o main
๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก
main
์ด ์ ๋ง๋ค์ด์ง์ ์ ์ ์์ต๋๋ค.
์ฌ๋ฌ๋ถ์ด ํ ๋ฒ๋ ์ปดํ์ผ ํ์ง ์์ ์ํ์์
make main
์ ์คํํ๋ฉด
make
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
make main
์ด๋๊น
Makefile
์์ ํ๊ฒ์ด
main
์ธ ๋
์์ ์ฐพ์๋ณด์.
์ค.
main
์ ํ์ํ ํ์ผ๋ค์ด
foo.o bar.o main.o
์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
foo.o
์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด
foo.cc
๋ค? ์์ง
foo.o
๊ฐ ์์ผ๋๊น ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ์คํํด์ผ ํ๊ฒ ๊ตฐ!
๋ง์ฐฌ๊ฐ์ง๋ก
bar.o, main.o
๋ ์ปดํ์ผ
์ ์ด์ ๋ง์ง๋ง์ผ๋ก
g++ foo.o bar.o main.o -o main
๋ฅผ ์คํํด์ผ์ง
๋ง์ฝ์ ์ฌ๋ฌ๋ถ์ด
make main
์ ํ ๋ฒ ์คํํ ์ํ์์
foo.cc
๋ง ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค. ๊ทธ๋ ๋ค๋ฉด ์๋์ ๊ฐ์ด ํ์ํ ๋ถ๋ถ๋ง ์ฌ์ปดํ์ผ ๋ฉ๋๋ค.
make main
์ด๋๊น
Makefile
์์ ํ๊ฒ์ด
main
์ธ ๋
์์ ์ฐพ์๋ณด์.
์ค.
main
์ ํ์ํ ํ์ผ๋ค์ด
foo.o bar.o main.o
์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
foo.o
์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด
foo.cc
๋ค? ๊ทธ๋ฐ๋ฐ
foo.o
์ ์์ฑ ์๊ฐ ๋ณด๋ค
foo.cc
์ ์์ ์๊ฐ์ด ๋ ๋์ค์ด๊ตฐ! ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ๋ค์ ์คํํด์ผ๊ฒ ์ด
bar.o
์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด
bar.cc
์ธ๋ฐ,
bar.o
์ ์์ฑ ์๊ฐ์ด
bar.cc
์ ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ค. ๊ตณ์ด ๋ช
๋ น์ด๋ค์ ์คํํ์ง ์์๋ ๋๊ฒ ์ด
main.o
๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ค์ ์๋ฐ๊ฟ๋ ๋๊ฒ ๊ตฐ!
main
์ ํ์ํ ํ์ผ๋ค ์ค
foo.o
๊ฐ ๋ฐ๋์์ผ๋ ๋ด ๋ช
๋ น์ด๋ค๋ ๋ค์ ์คํํด์ผ๊ฒ ์ด.
๋ฐ๋ผ์ ๋ฑ ํ์ํ
g++ -c foo.cc
์
g++ foo.o bar.o main.o -o main
๋ง์ด ์คํ๋ฉ๋๋ค.
์ฌ๋ฏธ์๊ฒ๋
Makefile
๋ด์์ ๋ณ์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
CC = g++
์ ๊ฒฝ์ฐ
CC
๋ผ๋ ๋ณ์๋ฅผ ์ ์ํ์๋๋ฐ, ์ด์
Makefile
๋ด์์
CC
๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด ํด๋น ๋ณ์์ ๋ฌธ์์ด์ธ
g++
๋ก ์นํ๋ฉ๋๋ค. ์ด ๋ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋
$(CC)
์ ๊ฐ์ด
$()
์์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ณ์์ ์ด๋ฆ์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด์
CC = g++
foo.o : foo.h foo.cc
$(CC) -c foo.cc
๋ ์ฌ์ค
CC = g++
foo.o : foo.h foo.cc
g++ -c foo.cc
๊ณผ ์ ํํ ๊ฐ์ ๋ช
๋ น์ด ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก ์ ์ํ์ง ์๋ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ฒ ๋๋ค๋ฉด ๊ทธ๋ฅ ๋น ๋ฌธ์์ด๋ก ์นํ๋ฉ๋๋ค.
์ฃผ์ ์ฌํญ
์ด ๋ถ๋ถ์ TMI ์ด๋ฏ๋ก ๋ฐ์์ ๋ถ๋ค์ ๊ทธ๋ฅ ๋์ด๊ฐ์
๋ ๋ฉ๋๋ค.
Makefile
์์์ ๋ณ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก = ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ๊ณผ
:=
๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด ๋์ ์ด์ง ๋ค๋ฆ
๋๋ค.
= ๋ฅผ ์ฌ์ฉํด์ ๋ณ์๋ฅผ ์ ์ํ์์ ๋, ์ ์์ ๋ค๋ฅธ ๋ณ์๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ํด๋น ๋ณ์๊ฐ ์ ์๋๊ธฐ ๋ ๋ ๊น์ง ๋ณ์์ ๊ฐ์ด ์ ํด์ง์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด์
B = $(A)
C = $(B)
A = a
C
์ ๊ฒฝ์ฐ
B
์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์๊ณ ,
B
์ ๊ฒฝ์ฐ
A
์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์์ต๋๋ค. ํ์ง๋ง
B =
๋ฅผ ์คํํ ์์ ์์
A
๊ฐ ์ ์๋์ง ์์์ผ๋ฏ๋ก
B
๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋์ด์ผ ํ์ง๋ง
=
๋ก ์ ์ํ์๊ธฐ ๋๋ฌธ์
A
๊ฐ ์ค์ ๋ก ์ ์๋ ๋ ๊น์ง
B
์
C
๊ฐ ๊ฒฐ์ ๋์ง ์์ต๋๋ค. ๊ฒฐ๊ตญ ๋ง์ง๋ง์
A = a
๋ฅผ ํตํด
A
๊ฐ
a
๋ก ๋์๋์ด์ผ,
C
๊ฐ
a
๋ก ๊ฒฐ์ ๋ฉ๋๋ค.
B := $(A)
A = a
๋ฐ๋ฉด์
:=
๋ก ๋ณ์๋ฅผ ์ ์ํ ๊ฒฝ์ฐ,
ํด๋น ์์ ์์ ๋ณ์์ ๊ฐ๋ง ํ์ธ
ํฉ๋๋ค. ๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ
B
๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋๊ฒ ์ง์.
๋๋ถ๋ถ์ ์ํฉ์์๋
=
๋
:=
์ค ์๋ฌด๊ฑฐ๋ ์ฌ์ฉํด๋ ์๊ด ์์ต๋๋ค. ํ์ง๋ง
๋ง์ผ ๋ณ์๋ค์ ์ ์ ์์์ ํฌ๊ฒ ๊ตฌ์ ๋ฐ๊ณ ์ถ์ง ์๋ค๋ฉด
=
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํธํฉ๋๋ค.
A =
์ ๊ฐ์ด ์๊ธฐ ์์ ์ ์์ ํ๊ณ ์ถ๋ค๋ฉด
:=
๋ฅผ ์ฌ์ฉํด์ผ์ง ๋ฌดํ ๋ฃจํ๋ฅผ ํผํ ์ ์์ต๋๋ค.
๋ง ๋ช
์ฌํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ค ๋ณ์๋ฅผ ์ฌ์ฉํด์
Makefile
์ ์กฐ๊ธ ๋ ๊น๋ํ๊ฒ ๋ฐ๊พธ์ด๋ณด๊ฒ ์ต๋๋ค.
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
make
๋ฅผ ์คํํด๋ณด๋ฉด
$ make main
g++ -Wall -O2 -c foo.cc
g++ -Wall -O2 -c bar.cc
g++ -Wall -O2 -c main.cc
g++ -Wall -O2 foo.o bar.o main.o -o main
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
CC
์
CXXFLAGS
๋
Makefile
์์ ์์ฃผ ์ฌ์ฉ๋๋ ๋ณ์๋ก ๋ณดํต
CC
์๋ ์ฌ์ฉํ๋ ์ปดํ์ผ๋ฌ ์ด๋ฆ์,
CXXFLAGS
์๋ ์ปดํ์ผ๋ฌ ์ต์
์ ์ฃผ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ์ฐธ๊ณ ๋ก ์ด๋ C++ ์ ๊ฒฝ์ฐ ์ด๊ณ , C ์ ๊ฒฝ์ฐ CFLAGS ์ ์ต์
์ ์ค๋๋ค.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ
g++
์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์ต์
์ผ๋ก๋
Wall
(๋ชจ๋ ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฅผ ํ์) ๊ณผ
O2
(์ต์ ํ ๋ ๋ฒจ 2) ๋ฅผ ์ฃผ์์ต๋๋ค.
Makefile
์ ํํ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ์ผ๋ก ๋น๋ ๊ด๋ จ๋ ํ์ผ๋ค (.o ํ์ผ๋ค)์ ๋ชจ๋ ์ ๊ฑฐํ๋ ๋ช
๋ น์ ๋ฃ์ต๋๋ค.
clean:
rm -f $(OBJS) main
์ค์ ๋ก
make clean
์ ์คํํด๋ณด๋ฉด ์์ฑ๋ ๋ชจ๋ ๋ชฉ์ ํ์ผ๊ณผ
main
์ ์ง์๋ฒ๋ฆผ์ ์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ, ๋ง์ฝ์ ์ค์ ๋ก
clean
์ด๋ผ๋ ํ์ผ์ด ๋๋ ํ ๋ฆฌ์ ์์ฑ๋๋ค๋ฉด ์ด๋จ๊น์? ์ฐ๋ฆฌ๊ฐ
make clean
์ ํ๊ฒ ๋๋ฉด,
make
๋
clean ์ ํ์ ํ์ผ๋ค์ด ์๋๋ฐ, clean ํ์ผ์ด ์์ผ๋๊น clean ํ์ผ์ ํญ์ ์ต์ ์ด๋ค? recipe ๋ฅผ ์คํ ์ํด๋ ๋๊ฒ ๋ค!
ํ๋ฉด์ ๊ทธ๋ฅ
make clean
๋ช
๋ น์ ๋ฌด์ํด๋ฒ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
$ ls clean
clean
$ make clean
make: 'clean' is up to date.
์ค์ ๋ก ๋๋ ํ ๋ฆฌ์
clean
์ด๋ผ๋ ํ์ผ์ ๋ง๋ค์ด๋๊ณ ์คํํด๋ณด๋ฉด ์์ ๊ฐ์ด ์ด๋ฏธ
clean
์ ์ต์ ์ด๋ผ๋ฉฐ
recipe
์คํ์ ๊ฑฐ๋ถํฉ๋๋ค.
์ด์ ๊ฐ์ ์ํฉ์ ๋ง๊ธฐ ์ํด์๋
clean
์
PHONY
๋ผ๊ณ ๋ฑ๋กํ๋ฉด ๋ฉ๋๋ค.
์๋์ ๊ฐ์ด ๋ง์ด์ง์.
.PHONY: clean
clean:
rm -f $(OBJS) main
์ด์
make clean
์ ํ๊ฒ ๋๋ฉด
clean
ํ์ผ์ ์ ๋ฌด์ ์๊ด ์์ด ์ธ์ ๋ ํด๋น ํ๊ฒ์ ๋ช
๋ น์ ์คํํ๊ฒ ๋ฉ๋๋ค.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ํ์ผ์ด 3 ๊ฐ ๋ฐ์ ์์ด์ ๋คํ์ด์์ง๋ง ์ค์ ํ๋ก์ ํธ์๋ ์์ญ~ ์๋ฐฑ ๊ฐ์ ํ์ผ๋ค์ ๋ค๋ฃจ๊ฒ ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฐ๋ฐ, ๊ฐ๊ฐ์ ํ์ผ๋ค์ ๋ํด์ ๋ชจ๋ ๋น๋ ๋ฐฉ์์ ๋ช
์ํด์ค๋ค๋ฉด
Makefile
์ ํฌ๊ธฐ๊ฐ ์์ฒญ ์ปค์ง๊ฒ ์ง์.
๋คํ์ด๋
Makefile
์์๋ ํจํด ๋งค์นญ์ ํตํด์ ํน์ ์กฐ๊ฑด์ ๋ถํฉํ๋ ํ์ผ๋ค์ ๋ํด์ ๊ฐ๋จํ๊ฒ
recipe
๋ฅผ ์์ฑํ ์ ์๊ฒ ํด์ค๋๋ค.
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
์ผ๋จ ๋จผ์ ๋น์ทํ๊ฒ ์๊ธด ์ ๋ ๋ช
๋ น๋ค์ ์ด๋ป๊ฒ ํ๋ฉด ํ๋๋ก ๊ฐ๋จํ๊ฒ ๋ํ๋ผ ์ ์๋์ง ๋ณด๊ฒ ์ต๋๋ค.
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
๋จผ์
%.o
๋ ์์ผ๋์นด๋๋ก ๋ฐ์ง๋ฉด ๋ง์น
*.o
์ ๊ฐ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ฆ,
.o
๋ก ๋๋๋ ํ์ผ ์ด๋ฆ๋ค์ด ํ๊ฒ์ด ๋ ์ ์๊ฒ ์ง์. ์๋ฅผ ๋ค์ด์
foo.o
๊ฐ ํ๊ฒ์ด๋ผ๋ฉด % ์๋
foo
๊ฐ ๋ค์ด๊ฐ ๊ฒ์ด๊ณ
bar.o
์ ๊ฒฝ์ฐ % ์๋
bar
๊ฐ ๋ค์ด๊ฐ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ ์๋ฅผ ๋ค์ด
foo.o
๊ฐ ํ๊ฒ์ผ ๊ฒฝ์ฐ
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c $<
๊ฐ ๋ฉ๋๋ค. ์ฐธ๊ณ ๋ก ํจํด์ ํ๊ฒ๊ณผ
prerequisite
๋ถ๋ถ์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
recipe
๋ถ๋ถ์์๋ ํจํด์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ปดํ์ผ๋ฌ์
foo.cc
๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด์๋
Makefile
์ ์๋ ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
$<
์ ๊ฒฝ์ฐ
prerequisite
์์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ์ด๋ฆ์ ๋์๋์ด ์๋ ๋ณ์ ์
๋๋ค. ์ ๊ฒฝ์ฐ
foo.cc
๊ฐ ๋๊ฒ ์ง์. ๋ฐ๋ผ์ ์ ๋ช
๋ น์ด๋ ๊ฒฐ๊ณผ์ ์ผ๋ก
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c foo.cc
๊ฐ ๋์ด์ ์ด์ ์ ๋ช
๋ น์ด์ ๋์ผํ๊ฒ ๋ง๋ค์ด๋
๋๋ค.
Makefile
์์ ์ ๊ณตํ๋ ์๋ ๋ณ์๋ก๋ ๊ทธ ์ธ์๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด
$@
,
$<
,
$^
๋ฑ๋ฑ์ด ์์ต๋๋ค.
$@
: ํ๊ฒ ์ด๋ฆ์ ๋์๋ฉ๋๋ค.
$<
: ์์กด ํ์ผ ๋ชฉ๋ก์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ๋์๋ฉ๋๋ค.
$^
: ์์กด ํ์ผ ๋ชฉ๋ก ์ ์ฒด์ ๋์๋ฉ๋๋ค.
$?
: ํ๊ฒ ๋ณด๋ค ์ต์ ์ธ ์์กด ํ์ผ๋ค์ ๋์๋ฉ๋๋ค.
$+
:
$^
์ ๋น์ทํ์ง๋ง, ์ค๋ณต๋ ํ์ผ ์ด๋ฆ๋ค ๊น์ง ๋ชจ๋ ํฌํจํฉ๋๋ค.
ํ์ง๋ง ์ ์ํ๊ฒ๋ ์ ํจํด์ผ๋ก๋
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
๋ฅผ ํํํ๊ธฐ์๋ ๋ถ์กฑํฉ๋๋ค. ์๋ํ๋ฉด ์์กด ํ์ผ ๋ชฉ๋ก์
main.h
๊ฐ ์๊ณ
foo.h
์
bar.h
๊ฐ ์๊ธฐ ๋๋ฌธ์ด์ฃ . ์ฌ์ค ๊ณฐ๊ณฐํ ์๊ฐํด๋ณด๋ฉด ์ด ์์กดํ์ผ ๋ชฉ๋ก์๋ ๋ ํด๋น ์์ค ํ์ผ์ด ์ด๋ ํ ํค๋ํ์ผ์ ํฌํจํ๋์ ๊ฒฐ์ ๋์ด ์์ต๋๋ค.
main.cc
๊ฐ
foo.h
์
bar.h
๋ฅผ
include
ํ๊ณ ์๊ธฐ ๋๋ฌธ์
main.o
์
prerequisite
๋ก
main.cc
์ธ์๋
foo.h
์
bar.h
๊ฐ ๋ค์ด๊ฐ ์๋ ๊ฒ์
๋๋ค.
๋ฌผ๋ก ๋งค๋ฒ ์ด๋ ๊ฒ ์ผ์ผํ ์ถ๊ฐํ ์ ์๊ฒ ์ง๋ง, ์์ค ํ์ผ์ ํค๋ ํ์ผ์ ์ถ๊ฐํ ๋ ๋ง๋ค
Makefile
์ ๋ฐ๊ฟ ์๋ ์๋ ๋
ธ๋ฆ์ด๋๊น์. ํ์ง๋ง ๋คํ์ด๋ ์ปดํ์ผ๋ฌ์ ๋์์ ๋ฐ์์ ์์กดํ์ผ ๋ชฉ๋ก ๋ถ๋ถ์ ์์ฑํ ์ ์์ต๋๋ค.
์ปดํ์ผ ์์
-MD
์ต์
์ ์ถ๊ฐํด์ ์ปดํ์ผ ํด๋ด
์๋ค.
$ g++ -c -MD main.cc
๊ทธ๋ ๋ค๋ฉด
main.d
๋ผ๋ ํ์ผ์ ์์ฑํฉ๋๋ค. ํ์ผ ๋ด์ฉ์ ์ดํด๋ณด๋ฉด;
$ cat main.d
main.o: main.cc /usr/include/stdc-predef.h foo.h bar.h
๋๋๊ฒ๋ ๋ง์น
Makefile
์
target: prerequisite
์ธ๊ฒ ๊ฐ์ ๋ถ๋ถ์ ์์ฑํ์์ต๋๋ค. ๊ทธ๋ ์ต๋๋ค. ์ปดํ์ผ ์์
-MD
์ต์
์ ์ถ๊ฐํด์ฃผ๋ฉด, ๋ชฉ์ ํ์ผ ๋ง๊ณ ๋ ์ปดํ์ผ ํ ์์คํ์ผ์ ํ๊ฒ์ผ๋ก ํ๋ ์์กดํ์ผ ๋ชฉ๋ก์ ๋ด์ ํ์ผ์ ์์ฑํด์ค๋๋ค.
์ฐธ๊ณ ๋ก
main.cc, foo.h, bar.h
๊น์ง๋ ์ดํด๊ฐ ๊ฐ๋๋ฐ ์ ์๋ฑ๋ง์
/usr/include/stdc-predef.h
์ด ๋ค์ด๊ฐ ์๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ, ์ด ํ์ผ์ ์ปดํ์ผ๋ฌ๊ฐ ์ปดํ์ผ ํ ๋ ์๋ฌต์ ์ผ๋ก ์ฐธ์กฐํ๋ ํค๋ ํ์ผ์ด๋ผ๊ณ ๋ณด์๋ฉด ๋ฉ๋๋ค. ์๋ฌดํผ ์ด ๋๋ฌธ์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ์์กด ํ์ผ ๋ชฉ๋ก์๋ ํฌํจ๋์์ต๋๋ค.
๋ฌธ์ ๋ ์ด๋ ๊ฒ ์์ฑ๋
main.d
๋ฅผ ์ด๋ป๊ฒ ์ฐ๋ฆฌ์
Makefile
์ ํฌํจํ ์ ์๋ ์
๋๋ค. ์ด๋ ์๊ฐ๋ณด๋ค ๊ฐ๋จํฉ๋๋ค.
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
include main.d
์
include main.d
๋
main.d
๋ผ๋ ํ์ผ์ ๋ด์ฉ์
Makefile
์ ํฌํจํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์ธ๋ฆฌ
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
๋ถ๋ถ์ ์์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ
.d
ํ์ผ๋ก ๋์ฒดํ ์๋ ์์๊น์? ๋ฌผ๋ก ์์ต๋๋ค!
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
-include $(OBJS:.o=.d)
$(OBJS:.o=.d)
๋ถ๋ถ์
OBJS
์์
.o
๋ก ๋๋๋ ๋ถ๋ถ์
.d
๋ก ๋ชจ๋ ๋์ฒดํ๋ผ๋ ์๋ฏธ ์
๋๋ค. ์ฆ, ํด๋น ๋ถ๋ถ์
-include foo.d bar.d main.d
๊ฐ ๋๊ฒ ์ฃ . ์ฐธ๊ณ ๋ก
foo.d
๋
bar.d
๊ฐ
include
๋ ๋ ์ด๋ฏธ ์๋
%.o: %.cc
๋ ์ด๋ป๊ฒ ๋๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ
๊ฐ์ ํ๊ฒ์ ๋ํด์ ์ฌ๋ฌ ์์กด ํ์ผ ๋ชฉ๋ก๋ค์ด ์ ํด์ ธ ์๋ค๋ฉด ์ด๋ make ์ ์ํด ๋ชจ๋ ํ๋๋ก ํฉ์ณ์ง๋๋ค.
๋ฐ๋ผ์ ํฌ๊ฒ ๊ฑฑ์ ํ์ค ํ์๋ ์์ต๋๋ค.
๋ง๋ถ์ฌ
include
์์
-include
๋ก ๋ฐ๊พธ์๋๋ฐ,
-include
์ ๊ฒฝ์ฐ ํฌํจํ๊ณ ์ ํ๋ ํ์ผ์ด ์กด์ฌํ์ง ์์๋
make
๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ์ง ์์ต๋๋ค.
๋งจ ์ฒ์์
make
๋ฅผ ํ ๋์๋
.d
ํ์ผ๋ค์ด ์ ๋๋ก ์์ฑ๋์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์
include
๊ฐ ์๋ฌด๋ฐ
.d
ํ์ผ๋ค์ ํฌํจํ์ง ์์ต๋๋ค. ๋ฌผ๋ก ํฌ๊ฒ ๋ฌธ์ ์๋ ๊ฒ์ด ์ด์ฐจํผ
.o
ํ์ผ๋ค๋
make
๊ฐ
%.o: %.cc
๋ถ๋ถ์ ๋ช
๋ น์ด๋ค์ ์คํํ๋ฉด์ ์ปดํ์ผ์ ํ๊ธฐ ๋๋ฌธ์ ๋ค์์
make
๋ฅผ ํ๊ฒ ๋ ๋์๋ ์ ๋๋ก
.d
ํ์ผ๋ค์ ๋ก๋ํ ์ ์๊ฒ ์ฃ .
์๋์ ๊ฐ์ด ๊ฐ๋จํ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์๊ฐํด๋ด
์๋ค.
$ tree
.
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ bar.h
โโโ foo.cc
โโโ foo.h
โโโ main.cc
๋ชจ๋ ์์ค ํ์ผ์
src
์ ๋ค์ด๊ฐ๊ณ ๋น๋ ํ์ผ๋ค์
obj
์ ๋ค์ด๊ฐ๋๋ค. ์ข
์ข
ํค๋ ํ์ผ๋ค์ ๋ฐ๋ก
include
์ ๋นผ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ์ ๋ ๊ตณ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ๋ณ๋ก ์ ํธํ์ง ์์ต๋๋ค. (๊ตณ์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ๋ฃ์ ์ด์ ๊ฐ ๋ญ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.)
์๋ฌดํผ ์ด์ ๊ฐ์ ๊ตฌ์กฐ์์ ํญ์ ์ฌ์ฉํ ์ ์๋
๋ง๋ฅ
Makefile
์ ์๋์ ๊ฐ์ต๋๋ค.
์ฃผ์ ์ฌํญ
๋ณต์ฌํ ํ์
$(CC)
์
rm
์์ ์คํ์ด์ค ๋ ๊ฐ๋ฅผ ๊ผญ TAB ์ผ๋ก ์นํํด์ฃผ์ธ์! ์ ๊ทธ๋ฌ๋ฉด
make
๊ฐ ์ฝ์ง ๋ชปํฉ๋๋ค.
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
์ถ๊ฐ๋ ๋ถ๋ถ๋ง ๊ฐ๋จํ ๋ถ์ฐ ์ค๋ช
์ ํ์๋ฉด
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
๋จผ์
SRC_DIR
์์ ์๋ ๋ชจ๋ ํ์ผ๋ค์
SRCS
๋ก ์ฝ์ด๋ค์ด๋ ค ํ๊ณ ์์ต๋๋ค.
wildcard
๋ ํจ์๋ก ํด๋น ์กฐ๊ฑด์ ๋ง๋ ํ์ผ๋ค์ ๋ฝ์๋ด๊ฒ ๋๋๋ฐ, ์๋ฅผ ๋ค์ด์
foo.cc, bar.cc, main.cc
๊ฐ ์์ ๊ฒฝ์ฐ
$(wildcard $(SRC_DIR)/*.cc)
์ ์คํ ๊ฒฐ๊ณผ๋
./src/foo.cc ./src/bar.cc ./src/main.cc
๊ฐ ๋ ๊ฒ์
๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋
foo.cc bar.cc main.cc
๋ก ๊น๋ํ๊ฒ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ด๊ธฐ ์ํด
notdir
ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
notdir
์ ์์ ์ค๋ ๊ฒฝ๋ก๋ฅผ ๋ ๋ ค๋ฒ๋ฆฌ๊ณ ํ์ผ ์ด๋ฆ๋ง ๊น๋ํ๊ฒ ์ถ์ถํด์ค๋๋ค.
OBJS = $(SRCS:.cc=.o)
๋ฐ๋ผ์ ์ด ๋ถ๋ถ์์
OBJS
๋
foo.o bar.o main.o
๊ฐ ๋ ๊ฒ์
๋๋ค.
์ด์ ์ด
OBJS
๋ฅผ ๋ฐํ์ผ๋ก ์ค์
.o
ํ์ผ๋ค์ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ด๋ด๊ณ ์ถ์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ด๋ค ํ์ผ ์ด๋ฆ ์์
$(OBJ_DIR)/
์ ๋ถ์ฌ์ค์ผ ๊ฒ ์ง์. ์ด๋ฅผ ์ํด์
patsubst
ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
patsubst
ํจ์๋
$(patsubst ํจํด,์นํ ํ ํํ,๋ณ์)
์ ๊ฐ์ ๊ผด๋ก ์ฌ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ
$(OBJS)
์์ ์๋ ๋ชจ๋
%.o
ํจํด์
$(OBJ_DIR)/%.o
๋ก ์นํํด๋ผ
๋ผ๋ ์๋ฏธ๊ฐ ๋ ๊ฒ์
๋๋ค. ์๋ฌดํผ ๋๋ถ์
OBJECTS
์๋ ์ด์ .
/obj/foo.o ./obj/bar.o ./obj/main.o
๊ฐ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ ๋ค์ ๋ด์ฉ์ ์์ ๊ธ์ ์ ๋ฐ๋ผ ์ค์ ๋ถ๋ค์ด๋ผ๋ฉด ์ ์ดํด ํ์ค ์ ์์ผ๋ฆฌ๋ผ ๋ฏฟ์ต๋๋ค.
๋ง์ฝ์ ํค๋ ํ์ผ๋ค๋ง ๋ฐ๋ก ๋ฝ๋๋ค๋ฉด ์๋์ ๊ฐ์ ํ์ผ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ์ฃ .
$ tree
.
โโโ include
โย ย โโโ bar.h
โย ย โโโ foo.h
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ foo.cc
โโโ main.cc
์ด ๊ฒฝ์ฐ
Makefile
์ ์๋์ ๊ฐ์ด ๊ฐ๋จํ ์์ ํ๋ฉด ๋ฉ๋๋ค.
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ํค๋ํ์ผ ๊ฒฝ๋ก
INCLUDE = -Iinclude/
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
DEPS = $(SRCS:.cc=.d)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) $(INCLUDE) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
์ฌ์ค ๊ธฐ์กด๊ณผ ๋ณ ์ฐจ์ด ์๊ณ ๊ทธ๋ฅ ์ปดํ์ผ๋ฌ ์ต์
์
-Iinclude/
๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋ฉ๋๋ค. ์ฌ๊ธฐ์
include
๋ ํค๋ํ์ผ ๊ฒฝ๋ก ์
๋๋ค.
ํ ๊ฐ์ง ํ์ผ๋ก ๊ทธ๋ฅ
make
๋ฅผ ์คํํ๊ฒ ๋๋ฉด 1 ๊ฐ์ ์ฐ๋ ๋๋ง ์คํ๋์ด์ ์๋๊ฐ ๊ฝค๋ ๋๋ฆฝ๋๋ค. ํนํ GCC ๋ ์ปค๋์ ์ปดํ์ผ ํ ๊ฒฝ์ฐ ํ ๋ ์๊ฐ์ ๊ทธ๋ฅ ๊ฑธ๋ฆฌ์ง์. ๋ง์ผ ์ฌ๋ฌ๋ถ์ ์ปดํจํฐ๊ฐ ๋ฉํฐ ์ฝ์ด CPU ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด (
์๋ง ๋๋ถ๋ถ ๊ทธ๋ด ๊ฒ์ด๋ผ ์๊ฐํฉ๋๋ค
)
make
๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์ฐ๋ ๋์์ ๋๋ฆด ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ธ์๋ก
-j
๋ค์ ๋ช ๊ฐ์ ์ฐ๋ ๋๋ฅผ ์ฌ์ฉํ ์ง ์ซ์๋ฅผ ์ ์ด์ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด์
$ make -j8
์ ํ๋ฉด
make
๊ฐ 8 ๊ฐ์ ์ฐ๋ ๋์ ๋๋์ด์ ์คํ๋ฉ๋๋ค. ์๋ง
make
์๋๊ฐ ์๋ฑํ๊ฒ ํฅ์๋๋ ๊ฒ์ ๋ณด์ค ์ ์์ ๊ฒ์
๋๋ค. ํต์์ ์ผ๋ก
์ฝ์ด ๊ฐ์ + 1
๋งํผ์ ์ฐ๋ ๋๋ฅผ ์์ฑํด์ ๋๋ฆฌ๋ ๊ฒ์ด ๊ฐ์ฅ ์๋๊ฐ ๋น ๋ฆ
๋๋ค.
๋ง์ฝ์ ๋ด ์ปดํจํฐ์ ์ฝ์ด ๊ฐ์๋ฅผ ๋ชจ๋ฅธ๋ค๋ฉด ๋ฆฌ๋
์ค ํฐ๋ฏธ๋์ ๊ฒฝ์ฐ
$ make -j$(nproc)
์ผ๋ก ํ๋ฉด
$(nproc)
์ด ์์์ ๋ด ์ปดํจํฐ์ ํ์ฌ ์ฝ์ด ๊ฐ์๋ก ์นํ๋ฉ๋๋ค.
๊ฐ์ข๋ฅผ ๋ณด๋ค๊ฐ ์กฐ๊ธ์ด๋ผ๋
๊ถ๊ธํ ๊ฒ์ด๋ ์ด์ํ ์ ์ด ์๋ค๋ฉด ๊ผญ ๋๊ธ
์ ๋จ๊ฒจ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค. ๊ทธ ์ธ์๋ ๊ฐ์ข์ ๊ด๋ จ๋ ๊ฒ์ด๋ผ๋ฉด ์ด๋ ํ ๊ฒ๋ ์ง๋ฌธํด ์ฃผ์
๋ ์๊ด ์์ต๋๋ค. ์๊ฐํด ๋ณผ ๋ฌธ์ ๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ๋๊ธ์ ๋ฌ์์ฃผ์ธ์.
ํ์ฌ ์ฌ๋ฌ๋ถ์ด ๋ณด์ ๊ฐ์ข๋
<์น์ด๋จน๋ C++ - <19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)>>
์
๋๋ค. ์ด๋ฒ ๊ฐ์ข์ ๋ชจ๋ ์์ ๋ค์ ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ ์งค ์์ค๊น์ง ๊ฐ์ข๋ฅผ ์ฝ์ด ๋ณด์๊ธฐ ์ ๊น์ง ๋ค์ ๊ฐ์ข๋ก ๋์ด๊ฐ์ง ๋ง์์ฃผ์ธ์ |
| Markdown | [๋ชจ๋์ ์ฝ๋](https://modoocode.com/)
๋ก๊ทธ์ธ
- [๋ชจ๋ ๊ธ](https://modoocode.com/category)
- [C ์ธ์ด](https://modoocode.com/category/C)
- [C ๋ ํผ๋ฐ์ค](https://modoocode.com/category/C%20Reference)
- [stdio.h](https://modoocode.com/category/C%20Reference/stdio.h)
- [stdlib.h](https://modoocode.com/category/C%20Reference/stdlib.h)
- [string.h](https://modoocode.com/category/C%20Reference/string.h)
- [time.h](https://modoocode.com/category/C%20Reference/time.h)
- [C++](https://modoocode.com/category/C++)
- [C++ ๋ ํผ๋ฐ์ค](https://modoocode.com/category/C++%20Reference)
- [Containers](https://modoocode.com/category/C++%20Reference/Containers)
- [algorithm](https://modoocode.com/category/C++%20Reference/algorithm)
- [array](https://modoocode.com/category/C++%20Reference/array)
- [iostream](https://modoocode.com/category/C++%20Reference/iostream)
- [string](https://modoocode.com/category/C++%20Reference/string)
- [string\_view](https://modoocode.com/category/C++%20Reference/string_view)
- [utility](https://modoocode.com/category/C++%20Reference/utility)
- [Rust](https://modoocode.com/category/Rust)
- [X86-64 ๋ช
๋ น์ด ๋ ํผ๋ฐ์ค](https://modoocode.com/category/X86-64%20%EB%AA%85%EB%A0%B9%EC%96%B4%20%EB%A0%88%ED%8D%BC%EB%9F%B0%EC%8A%A4)
- [์๊ณ ๋ฆฌ์ฆ](https://modoocode.com/category/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98)
- [์๋ฃ ๊ตฌ์กฐ](https://modoocode.com/category/%EC%9E%90%EB%A3%8C%20%EA%B5%AC%EC%A1%B0)
- [์ก๋ด](https://modoocode.com/category/%EC%9E%A1%EB%8B%B4)
- [ํ๋ก๊ทธ๋๋ฐ](https://modoocode.com/category/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)
ยง ์นดํ
๊ณ ๋ฆฌ - [C++](https://modoocode.com/category/C++)
[โฎ(๋๋ณด๊ธฐ)](https://modoocode.com/category/C++)
- [17 - 4. C++ ํ์ผ ์์คํ
() ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๊ฐ](https://modoocode.com/306)
- [17 - 5. C++ 17 ์ std::optional, variant, tuple ์ดํด๋ณด๊ธฐ](https://modoocode.com/309)
- [์ด๋ณด์๋ฅผ ์ํ C++ ๊ฐ์ข - ์น์ด๋จน๋ C++ (์๊ฒฐ)](https://modoocode.com/310)
- [19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)](https://modoocode.com/311)
- [19 - 2. C++ ํ๋ก์ ํธ๋ฅผ ์ํ CMake ์ฌ์ฉ๋ฒ](https://modoocode.com/332)
- [20 - 1. ์ฝ๋ ๋ถํฐ ์คํ ํ์ผ ๊น์ง](https://modoocode.com/319)
- [20 - 2.์ฝ๋ ๋ถํฐ ์คํ ํ์ผ ๊น์ง - ์ปดํ์ผ (Compile)](https://modoocode.com/320)
[(๋๋ณด๊ธฐ)โฎ](https://modoocode.com/category/C++)
๋ชฉ์ฐจ
1. ์์ค ์ฝ๋์์ ์์ฑ๋ ํ๋ก๊ทธ๋จ๊น์ง
1. ์ปดํ์ผ (Compile)
2. ๋งํน (Linking)
2. ๊ทธ๋ ๋ค๋ฉด ์ make ๋ฅผ ์ฐ๋์ง?
3. make
1. target
2. ์คํํ ๋ช
๋ น์ด(recipes)
3. ํ์ ์กฐ๊ฑด๋ค(prerequisites)
4. ๋ณ์
1. ๋ณ์๋ฅผ ์ ์ํ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ
5. PHONY
6. ํจํด ์ฌ์ฉํ๊ธฐ
7. ์๋์ผ๋ก prerequisite ๋ง๋ค๊ธฐ
8. ์ต์ข
์ ๋ฆฌ
1. ํค๋ ํ์ผ๋ค์ ๋ฐ๋ก ๋ฝ๋ ๊ฒฝ์ฐ
9. ๋ฉํฐ ์ฝ์ด๋ฅผ ํ์ฉํด์ Make ์๋๋ฅผ ์ฌ๋ฆฌ์
ํ์ ๊ด๊ณ
## [๋ชจ๋์ ์ฝ๋](https://modoocode.com/ "Home") ์น์ด๋จน๋ C++ - \<19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)\>
์์ฑ์ผ : 2020-06-10
์ด ๊ธ์ 105837 ๋ฒ ์ฝํ์ต๋๋ค.
์ด๋ฒ ๊ฐ์ข์์๋
- make ์ ์๋ ์ดํด
- Makefile ๋ฌธ๋ฒ ์ดํด
- ๋ง๋ฅ Makefile ๋ง๋ค๊ธฐ
์ ๋ํด์ ๋ค๋ฃจ์ด ๋ณด๊ฒ ์ต๋๋ค.

์๋
ํ์ธ์. ์ด๋ฒ ๊ฐ์ข ๋ถํฐ๋ ์น์ด๋จน๋ C++ ์๋ฆฌ์ฆ์ ๋ถ๋ก ๊ณผ ๊ฐ์ ๊ฐ๋
์ผ๋ก C++ ์ธ์ด ์์ฒด์๋ ์ง์ ๊ด๋ จ์ ์์ง๋ง ์ค์ ๋ก C++ ์ ํ๋ก๊ทธ๋๋ฐ ํ๊ธฐ ์ํด์ ํ์ํ ์ง์๋ค๊ณผ ํด๋ค์ ๋ํด์ ์ด์ผ๊ธฐ ํ๊ณ ์ ํฉ๋๋ค. ๊ทธ ์ฒซ ๋ฒ์งธ ํ์๋ก Makefile ๋ง๋ค๊ธฐ๊ฐ ๋๊ฒ ์ต๋๋ค.
์๋ฌด๋๋ ๋ฆฌ๋
์ค ํ๊ฒฝ์์ ํ๋ก๊ทธ๋๋ฐ์ ํ์ ๋ถ๋ค์ ์์๊ฒ ์ง๋ง, ๋ณดํต ํ๋ก๊ทธ๋จ์ ์ปดํ์ผ ํ ๋ make ๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํฉ๋๋ค. ์๋์ฐ์์ ๋น์ฃผ์ผ ์คํ๋์ค๋ฅผ ์ฌ์ฉํ์ ๋ค๋ฉด ์ปดํ์ผ ๋ฒํผ์ ๋๋ฅด๋ฉด ์์์ ์ปดํ์ผ ๋๋ ๊ฒ๊ณผ๋ ๋ฌ๋ฆฌ, ์ ์์์ ์ปดํ์ผ์ ํ๋ ค๋ฉด ์ด๋ค ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ณ , ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ ์ง ์ง์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ค์ผ ํฉ๋๋ค.
๋ฌผ๋ก ๋งค๋ฒ ๋ช
๋ น์ด๋ฅผ ์น๋ฉด ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง ํ๋ก์ ํธ์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ํ์ผ๋ค์ด ๋ง์์ง๋ค๋ฉด ๋งค๋ฒ ๊ทธ๋ ๊ฒ ์น๋ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น์์ง๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๋ฆฌ๋
์ค์์๋ make ๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋๋ฐ, ์ด ํ๋ก๊ทธ๋จ์ Makefile ๋ผ๋ ํ์ผ์ ์ฝ์ด์ ์ฃผ์ด์ง ๋ฐฉ์๋๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํ๊ฒ ํฉ๋๋ค. ๋๋ถ์ ๋ง์ ์์ ํ์ผ๋ค์ ๋ช
๋ น์ด ํ ๋ฒ์ผ๋ก ์ปดํ์ผ ํ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ make ํ๋ก๊ทธ๋จ์ด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋๋๊ณ , ํ๋ก๊ทธ๋จ๋ค์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก Makefile ์ ์์ฑํด์ผ ํ๋์ง ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
### ์์ค ์ฝ๋์์ ์์ฑ๋ ํ๋ก๊ทธ๋จ๊น์ง
๋จผ์ make ๊ฐ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋ํ๋์ง ์๊ธฐ ์ ์ ์ปดํ์ผ๋ฌ๋ฅผ ํตํด ํ๋ก๊ทธ๋จ์ ๋น๋ํ๊ฒ ๋๋ฉด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์์ค ์ฝ๋์์ ํ๋์ ํ๋ก๊ทธ๋จ์ด ์์ฑ๋๋์ง ์ดํด๋ณด๋๋ก ํฉ์๋ค.
#### ์ปดํ์ผ (Compile)
๊ฐ์ฅ ๋จผ์ ์ฌ๋ฌ๋ถ์ ๋จธ๋ฆฌ ์์ผ๋ก ๋ ์ค๋ฅด๋ ๊ณผ์ ์ ๋ฐ๋ก ์ปดํ์ผ(Compile) ์ผ ๊ฒ์
๋๋ค. ์ด ์ปดํ์ผ์ด๋ผ๋ ๊ณผ์ ์ ์ฌ๋ฌ๋ถ์ ์์ค ์ฝ๋๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ์ด์
๋ธ๋ฆฌ์ด๋ก ๋ณํํ๋ ๊ณผ์ ์
๋๋ค.
์๋ฅผ ๋ค์ด์ ์๋์ ๊ฐ์ด `foo.h` ์ ์ ์๋ `foo` ํจ์์ `bar.h` ์ ์ ์๋ `bar` ํจ์๋ฅผ `main` ํจ์์์ ํธ์ถํ๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ์ดํด๋ด
์๋ค.
- foo.h
```
int foo();
```
- foo.cc
```
#include <iostream>
#include "foo.h"
int foo() {
std::cout << "Foo!" << std::endl;
return 0;
}
```
- bar.h
```
int bar();
```
- bar.cc
```
#include <iostream>
#include "bar.h"
int bar() {
std::cout << "Bar!" << std::endl;
return 0;
}
```
- main.cc
```
#include "bar.h"
#include "foo.h"
int main() {
foo();
bar();
}
```
์๋ฅผ ๋ค์ด์ `main.cc` ๋ฅผ ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์๋์ ๊ฐ์ด ํ๋ฉด ๋ฉ๋๋ค.
๋ง์ผ clang ์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด g++ ์๋ฆฌ์ clang ์ ๋ฃ์ผ์๋ฉด ๋ฉ๋๋ค. clang ๊ณผ g++ ์ ์ฌ์ฉ ๋ช
๋ น์ด๊ฐ ๊ฑฐ์ ๋๊ฐ์ต๋๋ค.
```
$ g++ -c main.cc
```
`g++` ์ ์ ๋ฌํ๋ `-c` ๋ช
๋ น์ด๋ ์ธ์ ๋ค์์ ์ฃผ์ด์ง๋ ํ์ผ์ ์ปดํ์ผ ํด์ ๋ชฉ์ ํ์ผ(object file) ์ ์์ฑํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
์ค์ ๋ก, ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผ ํ์๋ค๋ฉด ์๋์ ๊ฐ์ด `main.o` ๋ผ๋ ํ์ผ์ด ์์ฑ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
```
$ ls main.o
main.o
```
์ด `main.o` ๋ `main.cc` ๋ฅผ ์ปดํ์ผ ํ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ๋ด๊ฒจ์๋ ํ์ผ ์
๋๋ค. ์ค์ ๋ก `main.o` ๋ฅผ ๋ฏ์ด๋ณด๋ฉด
```
$ objdump -S main.o
main.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: e8 00 00 00 00 callq d <main+0xd>
d: e8 00 00 00 00 callq 12 <main+0x12>
12: b8 00 00 00 00 mov $0x0,%eax
17: 5d pop %rbp
18: c3 retq
```
์ ๊ฐ์ด `main.cc` ์ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ์ ๋ค์ด์์์ ์ ์ ์์ต๋๋ค.
์ ์ด์
๋ธ๋ฆฌ๊ฐ ๋ญ์ง ์ดํด๊ฐ ์ ํ ์๊ฐ๋ Make ๊ฐ ๋ญ์ง ์ดํดํ๋๋ฐ ์ ํ ์๊ด ์์ต๋๋ค. ๊ทธ๋ฅ '๋ชฉ์ ํ์ผ์๋ ์์ค ์ฝ๋๋ฅผ ์ปดํ์ผ ํ ์ด์
๋ธ๋ฆฌ๊ฐ ๋ค์ด ์๊ตฌ๋' ์ ๋๋ก ์ดํดํ์๋ฉด ๋ฉ๋๋ค.
ํ ๊ฐ์ง ์ฌ๋ฏธ์๋ ์ ์ ์ปดํ์ผ๋ฌ๊ฐ `main.cc` ๋ฅผ ์ปดํ์ผ ํ ๋ ๋ค๋ฅธ ํ์ผ๋ค์ ์ฐธ์กฐํ์ง ์์๋ค๋ ์ ์
๋๋ค. ์ค์ ๋ก `main.o` ์ ์ด์
๋ธ๋ฆฌ๋ฅผ ์ฌ์ฉ ๋ณด๋ฉด `foo` ๋ `bar` ์ ๊ดํ ๋ด์ฉ์ด ํ๋๋ ์์์ ์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ `main.o` ์์ฒด๋ก๋ ์ฐ๋ฆฌ์ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ํ๋ฉด `main.o` ์๋ `foo` ๋ผ๋ ํจ์๋ฅผ ํธ์ถํด๋ผ\! ๋ผ๋ ๋ด์ฉ๋ง ์์ง, `foo` ๋ ์ด๋์ ์๊ณ ์ด๋ฌ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค ์ ๊ดํ ์ด์ผ๊ธฐ๋ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
๋์ฐ๋ฏธ๊ฐ ์ข์ผ์ ๋ถ๋ค์ ์ ์ด์
๋ธ๋ฆฌ์ callq ์๋ฆฌ์ ํจ์ ์ด๋ฆ ๋์ ์ ์ด์ํ ๊ฐ์ด ๋ค์ด์์์ ์ ์ ์์ต๋๋ค.
์ค์ ๋ก ์๋ํ๋ `foo` ์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋ `foo.cc` ๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋ค์ด์ง `foo.o` ๊ฐ ํ์ํ๊ณ , ๋ง์ฐฌ๊ฐ์ง๋ก `bar` ์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋ `bar.cc` ๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋ `bar.o` ๊ฐ ํ์ํฉ๋๋ค.
๋ฐ๋ผ์ ์ค์ ํ๋ก๊ทธ๋จ์ ์ ์ํ๊ธฐ ์ํด์๋ ์ด ๊ฐ๊ฐ์ `main.o, foo.o, bar.o` ๋ฅผ ํ๋๋ก ํฉ์น๋ ๊ณผ์ ์ด ํ์ํ๊ฒ ์ฃ . ์ด์ ๊ฐ์ ๊ณผ์ ์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋งํน(Linking) ์ด๋ผ๊ณ ํฉ๋๋ค.

#### ๋งํน (Linking)
๋งํน์ด ์ด๋ฆ ๊ทธ๋๋ก ๋งํฌ ํ๋ ์์
์ธ ์ด์ ๋ ์ค์ ๋ก ์๋ก ๋ค๋ฅธ ํ์ผ์ ํฉ์ด์ ธ ์๋ ํจ์๋ ํด๋์ค๋ค์ ํ ๋ฐ ๋ฌถ์ด์ ๋งํฌํด์ฃผ๋ ์์
์ด๊ธฐ ๋๋ฌธ์ด์ฃ . ์ด ๊ณผ์ ์์ `main` ํจ์ ์์ `foo` ํจ์๊ฐ ์ด๋์ ์ ์๋์ด ์๋์ง ์์น๋ฅผ ์ฐพ๊ณ ์ ๋๋ก ๋ ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ฌ์ค ์ด ๋งํน์ ๊ดํด์ ์ด์ผ๊ธฐ๋ง ํด๋ ํ์ฐธ ํ ์ ์๋๋ฐ, ์ผ๋จ ์ด ๊ธ์ ๋ชฉํ๋ ๋น๋ ํ์ผ ๋ง๋ค๊ธฐ ์ด๋ฏ๋ก ์ฌ๊ธฐ์ ์ค์ด๊ฒ ์ต๋๋ค.
์๋ฌดํผ ์ด ๋งํน ๊ณผ์ ์ ์๋์ ๊ฐ์ด ์ปดํ์ผ๋ฌ์ ๋ชฉ์ ํ์ผ์ ์ ๋ฌํจ์ผ๋ก์จ ์ํ๋ฉ๋๋ค.
```
$ g++ main.o foo.o bar.o -o main
```
์ฌ๊ธฐ์ `-o` ์ต์
์ ๊ทธ ๋ค์ ๋งํน ํ์ ์์ฑํ ์คํ ํ์ผ ์ด๋ฆ์ ์ด์ผ๊ธฐ ํฉ๋๋ค. ์ ๊ฒฝ์ฐ `main` ์ด๋ผ๋ ์คํ ํ์ผ์ ๋ง๋ค์๊ณ ๋ง์ฝ์ ์ด๋ฅผ ๋ฐ๋ก ์ง์ ํ์ง ์๋๋ค๋ฉด ๊ทธ๋ฅ `./a.out` ์ด๋ผ๋ ํ์ผ์ ๋ํดํธ๋ก ์์ฑํ๊ฒ ๋ฉ๋๋ค.
์ค์ ๋ก `main` ํ์ผ์ ์คํํ๊ฒ ๋๋ค๋ฉด
์คํ ๊ฒฐ๊ณผ
```
Foo!
Bar!
```
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
### ๊ทธ๋ ๋ค๋ฉด ์ make ๋ฅผ ์ฐ๋์ง?
์ผ๋จ ์์ ๊ฐ์ด `main` ์คํ ํ์ผ์ ์์ฑํ๊ธฐ ์ํด์ ์
๋ ฅํ ์ ๋ช
๋ น์ด๋ฅผ ์ญ ๋์ดํด๋ณด์๋ฉด;
```
$ g++ -c main.cc
$ g++ -c foo.cc
$ g++ -c bar.cc
$ g++ main.o foo.o bar.o -o main
```
์ ๊ฐ์ต๋๋ค. ๋ฌผ๋ก ํ์ผ ๊ฐ์๊ฐ ์๋ค๋ฉด ๋งค ๋ฒ ์
๋ ฅํ๋ ๊ฒ์ด ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋์ง๋ ์์ต๋๋ค๋ง, ํ๋ก์ ํธ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ์ณ์ผํ ๋ช
๋ น์ด๊ฐ ๋ ๋ง์์ง๊ฒ ๋์ ๋ณต์กํ๊ฒ ์ง์ (ํนํ ํ์ผ๋ค์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ์๋๋ค๋ฉด ๋ง์ด์ฃ .)
๋ฌผ๋ก ์ ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ๊ธ ์์๋ ๋ถ์ด๋ผ๋ฉด
> ๊ทธ๋ฅ ์ ๋ช
๋ น์ด๋ค์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?
๋ผ๊ณ ๋ฌผ์ผ์ค ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋ฐฉ์์ผ๋ก ํ๋ค๋ฉด ํ ๊ฐ์ง ๋ฌธ์ ์ ์ด ์๋๋ฐ, ์๋ฅผ ๋ค์ด์ ์ฌ๋ฌ๋ถ์ด `main.cc` ๋ฅผ ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ค์ ๋ก๋
```
$ g++ -c main.cc
$ g++ main.o foo.o bar.o -o main
```
๋ฑ ์ด ๋ ๋ช
๋ น์ด๋ง ์คํํ๋ฉด ๋ฉ๋๋ค. ์๋ํ๋ฉด `main` ํ์ผ์ ๋ฐ๊พผ๋ค๊ณ ํด์ `foo` ๋ `bar` ์ ์ปดํ์ผ ๋ ๋ด์ฉ์ด ๋ฐ๋์ง ์๊ธฐ ๋๋ฌธ์ด์ฃ . ํ์ง๋ง ์ ์ฒ๋ผ ๋จ์ํ๊ฒ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๊ฒ ๋๋ค๋ฉด ํ์ผ ํ๋๋ง ๋ฐ๊ฟ๋ ์ ์ฒด ๋ชจ๋ ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ฒ ๋๋ฏ๋ก ์ปดํ์ผ ์๊ฐ์ด ๋งค์ฐ ๊ธธ์ด์ง๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง make ๋ฅผ ์ฌ์ฉํ๋ฉด ์ผ๋ถ ํ์ผ์ ์์ ํ ๊ฒฝ์ฐ ํ์ํ ๋ช
๋ น๋ง ๋น ๋ฅด๊ฒ ์ปดํ์ผ์ ํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ ๊ทธ๋ ๋ค๋ฉด ๊ฑฐ๋์ ๋ฏธํ๊ณ make ์ ์ฌ์ฉ๋ฒ๊ณผ make ๋ฅผ ์ํ Makefile ์ ์ด๋ป๊ฒ ์์ฑํ๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
### make
make ๋ ๊ฐ๋จํ ๋งํ์๋ฉด ์ฃผ์ด์ง ์ ๋ช
๋ น์ด๋ค์ ์กฐ๊ฑด์ ๋ง๊ฒ ์คํํ๋ ํ๋ก๊ทธ๋จ ์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ด ๋ ์ด๋ ํ ์กฐ๊ฑด์ผ๋ก ๋ช
๋ น์ด๋ฅผ ์คํํ ์ง ๋ด์ ํ์ผ์ Makefile ์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, make ๋ฅผ ํฐ๋ฏธ๋ ์์์ ์คํํ๊ฒ ๋๋ค๋ฉด ํด๋น ์์น์ ์๋ Makefile ์ ์ฐพ์์ ์ฝ์ด๋ค์ด๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด Makefile ์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์กฐ๊ฑด์ ๊ธฐ์ ํ ๊น์?
```
target โฆ : prerequisites โฆ
(ํญ)recipe
โฆ
โฆ
```
Makefile ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๊ฐ์ด 3 ๊ฐ์ง ์์๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
#### target
make ๋ฅผ ์คํํ ๋ `make abc` ๊ณผ ๊ฐ์ด ์ด๋ ํ ๊ฒ์ make ํ ์ง ์ ๋ฌํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ ํ๊ฒ(target) ์ด๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ๋ง์ผ `make abc` ๋ฅผ ํ์์ ๊ฒฝ์ฐ ํ๊ฒ ์ค์ `abc` ๋ฅผ ์ฐพ์์ ์ด์ ๋์๋๋ ๋ช
๋ น์ ์คํํด์ค๋๋ค.
#### ์คํํ ๋ช
๋ น์ด(recipes)
์ฃผ์ด์ง ํ๊ฒ์ make ํ ๋ ์คํํ ๋ช
๋ น์ด๋ค์ ๋์ด์
๋๋ค. ํ ๊ฐ์ง ์ค์ํ ์ ์ recipe ์๋ฆฌ์ ๋ช
๋ น์ด๋ฅผ ์ธ ๋ ๋ฐ๋์ ํญ ํ ๋ฒ์ผ๋ก ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํด์ค์ผ๋ง ํฉ๋๋ค. ๋ณดํต ์์ฆ์ ํธ์ง๊ธฐ์ ๊ฒฝ์ฐ (์๋ฅผ ๋ค์ด VSCode), ์๋์ผ๋ก ํญ์ ์คํ์ด์ค๋ก ๋ฐ๊ฟ์ฃผ๋ ์ต์
์ด ํ์ฑํ ๋์ด ์์ ํ
๋ฐ make ๊ฐ Makefile ์ ์ ๋๋ก ์ฝ์ด๋ค์ด๊ธฐ ์ํด์๋ ๋ฐ๋์ ํญ์ ์ฌ์ฉํด์ผ๋ง ํฉ๋๋ค\!
#### ํ์ ์กฐ๊ฑด๋ค(prerequisites)
์ฃผ์ด์ง ํ๊ฒ์ make ํ ๋ ์ฌ์ฉ๋ ํ์ผ๋ค์ ๋ชฉ๋ก ์
๋๋ค. ๋ค๋ฅธ ๋ง๋ก ์์กด ํ์ผ(dependency) ์ด๋ผ๊ณ ๋ ํฉ๋๋ค. ์๋ํ๋ฉด ํด๋น ํ๊ฒ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฑด๋๋ ค์ผ ํ ํ์ผ๋ค์ ์จ๋์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ง์ผ ์ฃผ์ด์ง ํ์ผ๋ค์ ์์ ์๊ฐ ๋ณด๋ค ํ๊ฒ์ด ๋ ๋์ค์ ์์ ๋์๋ค๋ฉด ํด๋น ํ๊ฒ์ ๋ช
๋ น์ด๋ฅผ ์คํํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด ์ด๋ฏธ ์ด์ ์ ํ๊ฒ์ด ๋ง๋ค์ด์ ธ์๋ค๊ณ ๊ฐ์ฃผํ๊ธฐ ๋๋ฌธ์ด์ฃ .
์๋ฅผ ๋ค์ด์ ํ๊ฒ์ด `main.o` ์ด๊ณ , ๋ช
๋ น์ด๊ฐ `g++ -c main.cc` ๋ผ๋ฉด, ํ์ ์กฐ๊ฑด๋ค์ `main.cc`, `foo.h`, `bar.h` ๊ฐ ๋๊ฒ ์ฃ . ์๋ํ๋ฉด ์ด๋ค ํ์ผ๋ค ์ค ํ๋๋ผ๋ ๋ฐ๋๋ค๋ฉด `main` ์ ์๋ก ์ปดํ์ผ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ฐ๋ฉด์ `main.o` ์ ์์ฑ ์๊ฐ์ด `main.cc`, `foo.h`, `bar.h` ๋ค์ ๋ง์ง๋ง ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ผ๋ฉด, ๊ตณ์ด `main.o` ๋ฅผ ๋ค์ ์ปดํ์ผ ํ ํ์๊ฐ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก Makefile ์ ๊ฐ๋จํ๊ฒ ๊ตฌ์ฑํด๋ณด๊ฒ ์ต๋๋ค.
```
foo.o : foo.h foo.cc
g++ -c foo.cc
bar.o : bar.h bar.cc
g++ -c bar.cc
main.o : main.cc foo.h bar.h
g++ -c main.cc
main : foo.o bar.o main.o
g++ foo.o bar.o main.o -o main
```
์ฃผ์ ์ฌํญ
์ Makefile ์ ๊ทธ๋๋ก ๋ณต์ฌํด์ ์คํํ๋ค๋ฉด ์๋ง ์คํ์ด ์๋ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด ํญ์ด ์คํ์ด์ค๋ก ๋ฐ๋์ด์ ๊ทธ๋ฐ๋ฐ์, ์ ๋๋ก Makefile ์ ๋ง๋์๊ธฐ ์ํด์๋ g++ ์์ ์ค๋ ์คํ์ด์ค ๋ ๋ฒ์ ํญ์ผ๋ก ๋ฐ๊พธ์ด์ ์ ์ฅํด๋ณด์ธ์.
์ฐ๋ฆฌ์ ๋ชฉํ๋ ์คํ ํ์ผ์ธ `main` ์ ๋ง๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ `make main` ์ ์คํํด๋ณด๋ฉด
```
$ make main
g++ -c foo.cc
g++ -c bar.cc
g++ -c main.cc
g++ foo.o bar.o main.o -o main
```
๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก `main` ์ด ์ ๋ง๋ค์ด์ง์ ์ ์ ์์ต๋๋ค.
์ฌ๋ฌ๋ถ์ด ํ ๋ฒ๋ ์ปดํ์ผ ํ์ง ์์ ์ํ์์ `make main` ์ ์คํํ๋ฉด make ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
1. `make main` ์ด๋๊น Makefile ์์ ํ๊ฒ์ด `main` ์ธ ๋
์์ ์ฐพ์๋ณด์.
2. ์ค. `main` ์ ํ์ํ ํ์ผ๋ค์ด `foo.o bar.o main.o` ์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
3. `foo.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `foo.cc` ๋ค? ์์ง `foo.o` ๊ฐ ์์ผ๋๊น ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ์คํํด์ผ ํ๊ฒ ๊ตฐ\!
4. ๋ง์ฐฌ๊ฐ์ง๋ก `bar.o, main.o` ๋ ์ปดํ์ผ
5. ์ ์ด์ ๋ง์ง๋ง์ผ๋ก `g++ foo.o bar.o main.o -o main` ๋ฅผ ์คํํด์ผ์ง
๋ง์ฝ์ ์ฌ๋ฌ๋ถ์ด `make main` ์ ํ ๋ฒ ์คํํ ์ํ์์ `foo.cc` ๋ง ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค. ๊ทธ๋ ๋ค๋ฉด ์๋์ ๊ฐ์ด ํ์ํ ๋ถ๋ถ๋ง ์ฌ์ปดํ์ผ ๋ฉ๋๋ค.
1. `make main` ์ด๋๊น Makefile ์์ ํ๊ฒ์ด `main` ์ธ ๋
์์ ์ฐพ์๋ณด์.
2. ์ค. `main` ์ ํ์ํ ํ์ผ๋ค์ด `foo.o bar.o main.o` ์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
3. `foo.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `foo.cc` ๋ค? ๊ทธ๋ฐ๋ฐ `foo.o` ์ ์์ฑ ์๊ฐ ๋ณด๋ค `foo.cc` ์ ์์ ์๊ฐ์ด ๋ ๋์ค์ด๊ตฐ! ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ๋ค์ ์คํํด์ผ๊ฒ ์ด
4. `bar.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `bar.cc` ์ธ๋ฐ, `bar.o` ์ ์์ฑ ์๊ฐ์ด `bar.cc` ์ ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ค. ๊ตณ์ด ๋ช
๋ น์ด๋ค์ ์คํํ์ง ์์๋ ๋๊ฒ ์ด
5. `main.o` ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ค์ ์๋ฐ๊ฟ๋ ๋๊ฒ ๊ตฐ\!
6. `main` ์ ํ์ํ ํ์ผ๋ค ์ค `foo.o` ๊ฐ ๋ฐ๋์์ผ๋ ๋ด ๋ช
๋ น์ด๋ค๋ ๋ค์ ์คํํด์ผ๊ฒ ์ด.
๋ฐ๋ผ์ ๋ฑ ํ์ํ `g++ -c foo.cc` ์ `g++ foo.o bar.o main.o -o main` ๋ง์ด ์คํ๋ฉ๋๋ค.
### ๋ณ์
์ฌ๋ฏธ์๊ฒ๋ Makefile ๋ด์์ ๋ณ์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
```
CC = g++
```
์ ๊ฒฝ์ฐ `CC` ๋ผ๋ ๋ณ์๋ฅผ ์ ์ํ์๋๋ฐ, ์ด์ Makefile ๋ด์์ `CC` ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด ํด๋น ๋ณ์์ ๋ฌธ์์ด์ธ `g++` ๋ก ์นํ๋ฉ๋๋ค. ์ด ๋ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ `$(CC)` ์ ๊ฐ์ด `$()` ์์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ณ์์ ์ด๋ฆ์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด์
```
CC = g++
foo.o : foo.h foo.cc
$(CC) -c foo.cc
```
๋ ์ฌ์ค
```
CC = g++
foo.o : foo.h foo.cc
g++ -c foo.cc
```
๊ณผ ์ ํํ ๊ฐ์ ๋ช
๋ น์ด ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก ์ ์ํ์ง ์๋ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ฒ ๋๋ค๋ฉด ๊ทธ๋ฅ ๋น ๋ฌธ์์ด๋ก ์นํ๋ฉ๋๋ค.
#### ๋ณ์๋ฅผ ์ ์ํ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ
์ฃผ์ ์ฌํญ
์ด ๋ถ๋ถ์ TMI ์ด๋ฏ๋ก ๋ฐ์์ ๋ถ๋ค์ ๊ทธ๋ฅ ๋์ด๊ฐ์
๋ ๋ฉ๋๋ค.
Makefile ์์์ ๋ณ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก = ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ๊ณผ `:=` ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด ๋์ ์ด์ง ๋ค๋ฆ
๋๋ค.
\= ๋ฅผ ์ฌ์ฉํด์ ๋ณ์๋ฅผ ์ ์ํ์์ ๋, ์ ์์ ๋ค๋ฅธ ๋ณ์๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ํด๋น ๋ณ์๊ฐ ์ ์๋๊ธฐ ๋ ๋ ๊น์ง ๋ณ์์ ๊ฐ์ด ์ ํด์ง์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด์
```
B = $(A)
C = $(B)
A = a
```
`C` ์ ๊ฒฝ์ฐ `B` ์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์๊ณ , `B` ์ ๊ฒฝ์ฐ `A` ์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์์ต๋๋ค. ํ์ง๋ง `B =` ๋ฅผ ์คํํ ์์ ์์ `A` ๊ฐ ์ ์๋์ง ์์์ผ๋ฏ๋ก `B` ๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋์ด์ผ ํ์ง๋ง `=`๋ก ์ ์ํ์๊ธฐ ๋๋ฌธ์ `A` ๊ฐ ์ค์ ๋ก ์ ์๋ ๋ ๊น์ง `B` ์ `C` ๊ฐ ๊ฒฐ์ ๋์ง ์์ต๋๋ค. ๊ฒฐ๊ตญ ๋ง์ง๋ง์ `A = a` ๋ฅผ ํตํด `A` ๊ฐ `a` ๋ก ๋์๋์ด์ผ, `C` ๊ฐ `a` ๋ก ๊ฒฐ์ ๋ฉ๋๋ค.
```
B := $(A)
A = a
```
๋ฐ๋ฉด์ `:=` ๋ก ๋ณ์๋ฅผ ์ ์ํ ๊ฒฝ์ฐ, ํด๋น ์์ ์์ ๋ณ์์ ๊ฐ๋ง ํ์ธ ํฉ๋๋ค. ๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ `B` ๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋๊ฒ ์ง์.
๋๋ถ๋ถ์ ์ํฉ์์๋ `=` ๋ `:=` ์ค ์๋ฌด๊ฑฐ๋ ์ฌ์ฉํด๋ ์๊ด ์์ต๋๋ค. ํ์ง๋ง
- ๋ง์ผ ๋ณ์๋ค์ ์ ์ ์์์ ํฌ๊ฒ ๊ตฌ์ ๋ฐ๊ณ ์ถ์ง ์๋ค๋ฉด `=` ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํธํฉ๋๋ค.
- `A =` ์ ๊ฐ์ด ์๊ธฐ ์์ ์ ์์ ํ๊ณ ์ถ๋ค๋ฉด `:=` ๋ฅผ ์ฌ์ฉํด์ผ์ง ๋ฌดํ ๋ฃจํ๋ฅผ ํผํ ์ ์์ต๋๋ค.
๋ง ๋ช
์ฌํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ค ๋ณ์๋ฅผ ์ฌ์ฉํด์ Makefile ์ ์กฐ๊ธ ๋ ๊น๋ํ๊ฒ ๋ฐ๊พธ์ด๋ณด๊ฒ ์ต๋๋ค.
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
```
make ๋ฅผ ์คํํด๋ณด๋ฉด
```
$ make main
g++ -Wall -O2 -c foo.cc
g++ -Wall -O2 -c bar.cc
g++ -Wall -O2 -c main.cc
g++ -Wall -O2 foo.o bar.o main.o -o main
```
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
`CC` ์ `CXXFLAGS` ๋ Makefile ์์ ์์ฃผ ์ฌ์ฉ๋๋ ๋ณ์๋ก ๋ณดํต `CC` ์๋ ์ฌ์ฉํ๋ ์ปดํ์ผ๋ฌ ์ด๋ฆ์, `CXXFLAGS` ์๋ ์ปดํ์ผ๋ฌ ์ต์
์ ์ฃผ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ์ฐธ๊ณ ๋ก ์ด๋ C++ ์ ๊ฒฝ์ฐ ์ด๊ณ , C ์ ๊ฒฝ์ฐ CFLAGS ์ ์ต์
์ ์ค๋๋ค.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ `g++` ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์ต์
์ผ๋ก๋ `Wall` (๋ชจ๋ ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฅผ ํ์) ๊ณผ `O2` (์ต์ ํ ๋ ๋ฒจ 2) ๋ฅผ ์ฃผ์์ต๋๋ค.
์ฌ์ค -Wall ์ ์ด๋ฆ๊ณผ๋ ๋ค๋ฅด๊ฒ ๋ชจ๋ ๊ฒฝ๊ณ ๋ฅผ ํ์ํ์ง ์์ต๋๋ค.
### PHONY
Makefile ์ ํํ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ์ผ๋ก ๋น๋ ๊ด๋ จ๋ ํ์ผ๋ค (.o ํ์ผ๋ค)์ ๋ชจ๋ ์ ๊ฑฐํ๋ ๋ช
๋ น์ ๋ฃ์ต๋๋ค.
```
clean:
rm -f $(OBJS) main
```
์ค์ ๋ก `make clean` ์ ์คํํด๋ณด๋ฉด ์์ฑ๋ ๋ชจ๋ ๋ชฉ์ ํ์ผ๊ณผ `main` ์ ์ง์๋ฒ๋ฆผ์ ์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ, ๋ง์ฝ์ ์ค์ ๋ก `clean` ์ด๋ผ๋ ํ์ผ์ด ๋๋ ํ ๋ฆฌ์ ์์ฑ๋๋ค๋ฉด ์ด๋จ๊น์? ์ฐ๋ฆฌ๊ฐ `make clean` ์ ํ๊ฒ ๋๋ฉด, make ๋ clean ์ ํ์ ํ์ผ๋ค์ด ์๋๋ฐ, clean ํ์ผ์ด ์์ผ๋๊น clean ํ์ผ์ ํญ์ ์ต์ ์ด๋ค? recipe ๋ฅผ ์คํ ์ํด๋ ๋๊ฒ ๋ค\! ํ๋ฉด์ ๊ทธ๋ฅ `make clean` ๋ช
๋ น์ ๋ฌด์ํด๋ฒ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
```
$ ls clean
clean
$ make clean
make: 'clean' is up to date.
```
์ค์ ๋ก ๋๋ ํ ๋ฆฌ์ `clean` ์ด๋ผ๋ ํ์ผ์ ๋ง๋ค์ด๋๊ณ ์คํํด๋ณด๋ฉด ์์ ๊ฐ์ด ์ด๋ฏธ `clean` ์ ์ต์ ์ด๋ผ๋ฉฐ `recipe` ์คํ์ ๊ฑฐ๋ถํฉ๋๋ค.
์ด์ ๊ฐ์ ์ํฉ์ ๋ง๊ธฐ ์ํด์๋ `clean` ์ `PHONY` ๋ผ๊ณ ๋ฑ๋กํ๋ฉด ๋ฉ๋๋ค.
Phony ๋ '๊ฐ์ง์, ํ์์' ์ด๋ผ๋ ๋ป์
๋๋ค.
์๋์ ๊ฐ์ด ๋ง์ด์ง์.
```
.PHONY: clean
clean:
rm -f $(OBJS) main
```
์ด์ `make clean` ์ ํ๊ฒ ๋๋ฉด `clean` ํ์ผ์ ์ ๋ฌด์ ์๊ด ์์ด ์ธ์ ๋ ํด๋น ํ๊ฒ์ ๋ช
๋ น์ ์คํํ๊ฒ ๋ฉ๋๋ค.
### ํจํด ์ฌ์ฉํ๊ธฐ
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ํ์ผ์ด 3 ๊ฐ ๋ฐ์ ์์ด์ ๋คํ์ด์์ง๋ง ์ค์ ํ๋ก์ ํธ์๋ ์์ญ~ ์๋ฐฑ ๊ฐ์ ํ์ผ๋ค์ ๋ค๋ฃจ๊ฒ ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฐ๋ฐ, ๊ฐ๊ฐ์ ํ์ผ๋ค์ ๋ํด์ ๋ชจ๋ ๋น๋ ๋ฐฉ์์ ๋ช
์ํด์ค๋ค๋ฉด Makefile ์ ํฌ๊ธฐ๊ฐ ์์ฒญ ์ปค์ง๊ฒ ์ง์.
๋คํ์ด๋ Makefile ์์๋ ํจํด ๋งค์นญ์ ํตํด์ ํน์ ์กฐ๊ฑด์ ๋ถํฉํ๋ ํ์ผ๋ค์ ๋ํด์ ๊ฐ๋จํ๊ฒ `recipe` ๋ฅผ ์์ฑํ ์ ์๊ฒ ํด์ค๋๋ค.
```
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
```
์ผ๋จ ๋จผ์ ๋น์ทํ๊ฒ ์๊ธด ์ ๋ ๋ช
๋ น๋ค์ ์ด๋ป๊ฒ ํ๋ฉด ํ๋๋ก ๊ฐ๋จํ๊ฒ ๋ํ๋ผ ์ ์๋์ง ๋ณด๊ฒ ์ต๋๋ค.
```
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
```
๋จผ์ `%.o` ๋ ์์ผ๋์นด๋๋ก ๋ฐ์ง๋ฉด ๋ง์น `*.o` ์ ๊ฐ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ฆ, `.o` ๋ก ๋๋๋ ํ์ผ ์ด๋ฆ๋ค์ด ํ๊ฒ์ด ๋ ์ ์๊ฒ ์ง์. ์๋ฅผ ๋ค์ด์ `foo.o` ๊ฐ ํ๊ฒ์ด๋ผ๋ฉด % ์๋ `foo` ๊ฐ ๋ค์ด๊ฐ ๊ฒ์ด๊ณ `bar.o` ์ ๊ฒฝ์ฐ % ์๋ `bar` ๊ฐ ๋ค์ด๊ฐ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ ์๋ฅผ ๋ค์ด `foo.o` ๊ฐ ํ๊ฒ์ผ ๊ฒฝ์ฐ
```
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c $<
```
๊ฐ ๋ฉ๋๋ค. ์ฐธ๊ณ ๋ก ํจํด์ ํ๊ฒ๊ณผ `prerequisite` ๋ถ๋ถ์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค. `recipe` ๋ถ๋ถ์์๋ ํจํด์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ปดํ์ผ๋ฌ์ `foo.cc` ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด์๋ Makefile ์ ์๋ ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
`$<` ์ ๊ฒฝ์ฐ `prerequisite` ์์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ์ด๋ฆ์ ๋์๋์ด ์๋ ๋ณ์ ์
๋๋ค. ์ ๊ฒฝ์ฐ `foo.cc` ๊ฐ ๋๊ฒ ์ง์. ๋ฐ๋ผ์ ์ ๋ช
๋ น์ด๋ ๊ฒฐ๊ณผ์ ์ผ๋ก
```
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c foo.cc
```
๊ฐ ๋์ด์ ์ด์ ์ ๋ช
๋ น์ด์ ๋์ผํ๊ฒ ๋ง๋ค์ด๋
๋๋ค.
Makefile ์์ ์ ๊ณตํ๋ ์๋ ๋ณ์๋ก๋ ๊ทธ ์ธ์๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด `$@`, `$<`, `$^` ๋ฑ๋ฑ์ด ์์ต๋๋ค.

- `$@` : ํ๊ฒ ์ด๋ฆ์ ๋์๋ฉ๋๋ค.
- `$<` : ์์กด ํ์ผ ๋ชฉ๋ก์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ๋์๋ฉ๋๋ค.
- `$^` : ์์กด ํ์ผ ๋ชฉ๋ก ์ ์ฒด์ ๋์๋ฉ๋๋ค.
- `$?` : ํ๊ฒ ๋ณด๋ค ์ต์ ์ธ ์์กด ํ์ผ๋ค์ ๋์๋ฉ๋๋ค.
- `$+` : `$^` ์ ๋น์ทํ์ง๋ง, ์ค๋ณต๋ ํ์ผ ์ด๋ฆ๋ค ๊น์ง ๋ชจ๋ ํฌํจํฉ๋๋ค.
ํ์ง๋ง ์ ์ํ๊ฒ๋ ์ ํจํด์ผ๋ก๋
```
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
```
๋ฅผ ํํํ๊ธฐ์๋ ๋ถ์กฑํฉ๋๋ค. ์๋ํ๋ฉด ์์กด ํ์ผ ๋ชฉ๋ก์ `main.h` ๊ฐ ์๊ณ `foo.h` ์ `bar.h` ๊ฐ ์๊ธฐ ๋๋ฌธ์ด์ฃ . ์ฌ์ค ๊ณฐ๊ณฐํ ์๊ฐํด๋ณด๋ฉด ์ด ์์กดํ์ผ ๋ชฉ๋ก์๋ ๋ ํด๋น ์์ค ํ์ผ์ด ์ด๋ ํ ํค๋ํ์ผ์ ํฌํจํ๋์ ๊ฒฐ์ ๋์ด ์์ต๋๋ค. `main.cc` ๊ฐ `foo.h` ์ `bar.h` ๋ฅผ `include` ํ๊ณ ์๊ธฐ ๋๋ฌธ์ `main.o` ์ `prerequisite` ๋ก `main.cc` ์ธ์๋ `foo.h` ์ `bar.h` ๊ฐ ๋ค์ด๊ฐ ์๋ ๊ฒ์
๋๋ค.
๋ฌผ๋ก ๋งค๋ฒ ์ด๋ ๊ฒ ์ผ์ผํ ์ถ๊ฐํ ์ ์๊ฒ ์ง๋ง, ์์ค ํ์ผ์ ํค๋ ํ์ผ์ ์ถ๊ฐํ ๋ ๋ง๋ค Makefile ์ ๋ฐ๊ฟ ์๋ ์๋ ๋
ธ๋ฆ์ด๋๊น์. ํ์ง๋ง ๋คํ์ด๋ ์ปดํ์ผ๋ฌ์ ๋์์ ๋ฐ์์ ์์กดํ์ผ ๋ชฉ๋ก ๋ถ๋ถ์ ์์ฑํ ์ ์์ต๋๋ค.
### ์๋์ผ๋ก prerequisite ๋ง๋ค๊ธฐ
์ปดํ์ผ ์์ `-MD` ์ต์
์ ์ถ๊ฐํด์ ์ปดํ์ผ ํด๋ด
์๋ค.
```
$ g++ -c -MD main.cc
```
๊ทธ๋ ๋ค๋ฉด `main.d` ๋ผ๋ ํ์ผ์ ์์ฑํฉ๋๋ค. ํ์ผ ๋ด์ฉ์ ์ดํด๋ณด๋ฉด;
```
$ cat main.d
main.o: main.cc /usr/include/stdc-predef.h foo.h bar.h
```
๋๋๊ฒ๋ ๋ง์น Makefile ์ `target: prerequisite` ์ธ๊ฒ ๊ฐ์ ๋ถ๋ถ์ ์์ฑํ์์ต๋๋ค. ๊ทธ๋ ์ต๋๋ค. ์ปดํ์ผ ์์ `-MD` ์ต์
์ ์ถ๊ฐํด์ฃผ๋ฉด, ๋ชฉ์ ํ์ผ ๋ง๊ณ ๋ ์ปดํ์ผ ํ ์์คํ์ผ์ ํ๊ฒ์ผ๋ก ํ๋ ์์กดํ์ผ ๋ชฉ๋ก์ ๋ด์ ํ์ผ์ ์์ฑํด์ค๋๋ค.
์ฐธ๊ณ ๋ก `main.cc, foo.h, bar.h` ๊น์ง๋ ์ดํด๊ฐ ๊ฐ๋๋ฐ ์ ์๋ฑ๋ง์ `/usr/include/stdc-predef.h` ์ด ๋ค์ด๊ฐ ์๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ, ์ด ํ์ผ์ ์ปดํ์ผ๋ฌ๊ฐ ์ปดํ์ผ ํ ๋ ์๋ฌต์ ์ผ๋ก ์ฐธ์กฐํ๋ ํค๋ ํ์ผ์ด๋ผ๊ณ ๋ณด์๋ฉด ๋ฉ๋๋ค. ์๋ฌดํผ ์ด ๋๋ฌธ์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ์์กด ํ์ผ ๋ชฉ๋ก์๋ ํฌํจ๋์์ต๋๋ค.
๋ฌธ์ ๋ ์ด๋ ๊ฒ ์์ฑ๋ `main.d` ๋ฅผ ์ด๋ป๊ฒ ์ฐ๋ฆฌ์ Makefile ์ ํฌํจํ ์ ์๋ ์
๋๋ค. ์ด๋ ์๊ฐ๋ณด๋ค ๊ฐ๋จํฉ๋๋ค.
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
include main.d
```
์ `include main.d` ๋ `main.d` ๋ผ๋ ํ์ผ์ ๋ด์ฉ์ Makefile ์ ํฌํจํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์ธ๋ฆฌ
```
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
```
๋ถ๋ถ์ ์์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ `.d` ํ์ผ๋ก ๋์ฒดํ ์๋ ์์๊น์? ๋ฌผ๋ก ์์ต๋๋ค\!
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
-include $(OBJS:.o=.d)
```
`$(OBJS:.o=.d)` ๋ถ๋ถ์ `OBJS` ์์ `.o` ๋ก ๋๋๋ ๋ถ๋ถ์ `.d` ๋ก ๋ชจ๋ ๋์ฒดํ๋ผ๋ ์๋ฏธ ์
๋๋ค. ์ฆ, ํด๋น ๋ถ๋ถ์ `-include foo.d bar.d main.d` ๊ฐ ๋๊ฒ ์ฃ . ์ฐธ๊ณ ๋ก `foo.d` ๋ `bar.d` ๊ฐ `include` ๋ ๋ ์ด๋ฏธ ์๋ `%.o: %.cc` ๋ ์ด๋ป๊ฒ ๋๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ ๊ฐ์ ํ๊ฒ์ ๋ํด์ ์ฌ๋ฌ ์์กด ํ์ผ ๋ชฉ๋ก๋ค์ด ์ ํด์ ธ ์๋ค๋ฉด ์ด๋ make ์ ์ํด ๋ชจ๋ ํ๋๋ก ํฉ์ณ์ง๋๋ค. ๋ฐ๋ผ์ ํฌ๊ฒ ๊ฑฑ์ ํ์ค ํ์๋ ์์ต๋๋ค.
๋ง๋ถ์ฌ `include` ์์ `-include` ๋ก ๋ฐ๊พธ์๋๋ฐ, `-include` ์ ๊ฒฝ์ฐ ํฌํจํ๊ณ ์ ํ๋ ํ์ผ์ด ์กด์ฌํ์ง ์์๋ make ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ์ง ์์ต๋๋ค.
๋งจ ์ฒ์์ make ๋ฅผ ํ ๋์๋ `.d` ํ์ผ๋ค์ด ์ ๋๋ก ์์ฑ๋์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ `include` ๊ฐ ์๋ฌด๋ฐ `.d` ํ์ผ๋ค์ ํฌํจํ์ง ์์ต๋๋ค. ๋ฌผ๋ก ํฌ๊ฒ ๋ฌธ์ ์๋ ๊ฒ์ด ์ด์ฐจํผ `.o` ํ์ผ๋ค๋ make ๊ฐ `%.o: %.cc` ๋ถ๋ถ์ ๋ช
๋ น์ด๋ค์ ์คํํ๋ฉด์ ์ปดํ์ผ์ ํ๊ธฐ ๋๋ฌธ์ ๋ค์์ make ๋ฅผ ํ๊ฒ ๋ ๋์๋ ์ ๋๋ก `.d` ํ์ผ๋ค์ ๋ก๋ํ ์ ์๊ฒ ์ฃ .
### ์ต์ข
์ ๋ฆฌ
์๋์ ๊ฐ์ด ๊ฐ๋จํ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์๊ฐํด๋ด
์๋ค.
```
$ tree
.
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ bar.h
โโโ foo.cc
โโโ foo.h
โโโ main.cc
```
๋ชจ๋ ์์ค ํ์ผ์ `src` ์ ๋ค์ด๊ฐ๊ณ ๋น๋ ํ์ผ๋ค์ `obj` ์ ๋ค์ด๊ฐ๋๋ค. ์ข
์ข
ํค๋ ํ์ผ๋ค์ ๋ฐ๋ก `include` ์ ๋นผ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ์ ๋ ๊ตณ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ๋ณ๋ก ์ ํธํ์ง ์์ต๋๋ค. (๊ตณ์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ๋ฃ์ ์ด์ ๊ฐ ๋ญ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.)
์๋ฌดํผ ์ด์ ๊ฐ์ ๊ตฌ์กฐ์์ ํญ์ ์ฌ์ฉํ ์ ์๋ ๋ง๋ฅ Makefile ์ ์๋์ ๊ฐ์ต๋๋ค.
์ฃผ์ ์ฌํญ
๋ณต์ฌํ ํ์ `$(CC)` ์ `rm` ์์ ์คํ์ด์ค ๋ ๊ฐ๋ฅผ ๊ผญ TAB ์ผ๋ก ์นํํด์ฃผ์ธ์! ์ ๊ทธ๋ฌ๋ฉด make ๊ฐ ์ฝ์ง ๋ชปํฉ๋๋ค.
```
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
```
์ถ๊ฐ๋ ๋ถ๋ถ๋ง ๊ฐ๋จํ ๋ถ์ฐ ์ค๋ช
์ ํ์๋ฉด
```
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
```
๋จผ์ `SRC_DIR` ์์ ์๋ ๋ชจ๋ ํ์ผ๋ค์ `SRCS` ๋ก ์ฝ์ด๋ค์ด๋ ค ํ๊ณ ์์ต๋๋ค. `wildcard` ๋ ํจ์๋ก ํด๋น ์กฐ๊ฑด์ ๋ง๋ ํ์ผ๋ค์ ๋ฝ์๋ด๊ฒ ๋๋๋ฐ, ์๋ฅผ ๋ค์ด์ `foo.cc, bar.cc, main.cc` ๊ฐ ์์ ๊ฒฝ์ฐ `$(wildcard $(SRC_DIR)/*.cc)` ์ ์คํ ๊ฒฐ๊ณผ๋ `./src/foo.cc ./src/bar.cc ./src/main.cc` ๊ฐ ๋ ๊ฒ์
๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ `foo.cc bar.cc main.cc` ๋ก ๊น๋ํ๊ฒ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ด๊ธฐ ์ํด `notdir` ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. `notdir` ์ ์์ ์ค๋ ๊ฒฝ๋ก๋ฅผ ๋ ๋ ค๋ฒ๋ฆฌ๊ณ ํ์ผ ์ด๋ฆ๋ง ๊น๋ํ๊ฒ ์ถ์ถํด์ค๋๋ค.
```
OBJS = $(SRCS:.cc=.o)
```
๋ฐ๋ผ์ ์ด ๋ถ๋ถ์์ `OBJS` ๋ `foo.o bar.o main.o` ๊ฐ ๋ ๊ฒ์
๋๋ค.
์ด์ ์ด `OBJS` ๋ฅผ ๋ฐํ์ผ๋ก ์ค์ `.o` ํ์ผ๋ค์ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ด๋ด๊ณ ์ถ์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ด๋ค ํ์ผ ์ด๋ฆ ์์ `$(OBJ_DIR)/` ์ ๋ถ์ฌ์ค์ผ ๊ฒ ์ง์. ์ด๋ฅผ ์ํด์ `patsubst` ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
```
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
```
`patsubst` ํจ์๋ `$(patsubst ํจํด,์นํ ํ ํํ,๋ณ์)` ์ ๊ฐ์ ๊ผด๋ก ์ฌ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ `$(OBJS)` ์์ ์๋ ๋ชจ๋ `%.o` ํจํด์ `$(OBJ_DIR)/%.o` ๋ก ์นํํด๋ผ ๋ผ๋ ์๋ฏธ๊ฐ ๋ ๊ฒ์
๋๋ค. ์๋ฌดํผ ๋๋ถ์ `OBJECTS` ์๋ ์ด์ .`/obj/foo.o ./obj/bar.o ./obj/main.o` ๊ฐ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ ๋ค์ ๋ด์ฉ์ ์์ ๊ธ์ ์ ๋ฐ๋ผ ์ค์ ๋ถ๋ค์ด๋ผ๋ฉด ์ ์ดํด ํ์ค ์ ์์ผ๋ฆฌ๋ผ ๋ฏฟ์ต๋๋ค.
#### ํค๋ ํ์ผ๋ค์ ๋ฐ๋ก ๋ฝ๋ ๊ฒฝ์ฐ
๋ง์ฝ์ ํค๋ ํ์ผ๋ค๋ง ๋ฐ๋ก ๋ฝ๋๋ค๋ฉด ์๋์ ๊ฐ์ ํ์ผ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ์ฃ .
```
$ tree
.
โโโ include
โย ย โโโ bar.h
โย ย โโโ foo.h
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ foo.cc
โโโ main.cc
```
์ด ๊ฒฝ์ฐ Makefile ์ ์๋์ ๊ฐ์ด ๊ฐ๋จํ ์์ ํ๋ฉด ๋ฉ๋๋ค.
```
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ํค๋ํ์ผ ๊ฒฝ๋ก
INCLUDE = -Iinclude/
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
DEPS = $(SRCS:.cc=.d)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) $(INCLUDE) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
```
์ฌ์ค ๊ธฐ์กด๊ณผ ๋ณ ์ฐจ์ด ์๊ณ ๊ทธ๋ฅ ์ปดํ์ผ๋ฌ ์ต์
์ `-Iinclude/` ๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋ฉ๋๋ค. ์ฌ๊ธฐ์ `include` ๋ ํค๋ํ์ผ ๊ฒฝ๋ก ์
๋๋ค.
### ๋ฉํฐ ์ฝ์ด๋ฅผ ํ์ฉํด์ Make ์๋๋ฅผ ์ฌ๋ฆฌ์
ํ ๊ฐ์ง ํ์ผ๋ก ๊ทธ๋ฅ make ๋ฅผ ์คํํ๊ฒ ๋๋ฉด 1 ๊ฐ์ ์ฐ๋ ๋๋ง ์คํ๋์ด์ ์๋๊ฐ ๊ฝค๋ ๋๋ฆฝ๋๋ค. ํนํ GCC ๋ ์ปค๋์ ์ปดํ์ผ ํ ๊ฒฝ์ฐ ํ ๋ ์๊ฐ์ ๊ทธ๋ฅ ๊ฑธ๋ฆฌ์ง์. ๋ง์ผ ์ฌ๋ฌ๋ถ์ ์ปดํจํฐ๊ฐ ๋ฉํฐ ์ฝ์ด CPU ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด (์๋ง ๋๋ถ๋ถ ๊ทธ๋ด ๊ฒ์ด๋ผ ์๊ฐํฉ๋๋ค) make ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์ฐ๋ ๋์์ ๋๋ฆด ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ธ์๋ก `-j` ๋ค์ ๋ช ๊ฐ์ ์ฐ๋ ๋๋ฅผ ์ฌ์ฉํ ์ง ์ซ์๋ฅผ ์ ์ด์ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด์
```
$ make -j8
```
์ ํ๋ฉด make ๊ฐ 8 ๊ฐ์ ์ฐ๋ ๋์ ๋๋์ด์ ์คํ๋ฉ๋๋ค. ์๋ง make ์๋๊ฐ ์๋ฑํ๊ฒ ํฅ์๋๋ ๊ฒ์ ๋ณด์ค ์ ์์ ๊ฒ์
๋๋ค. ํต์์ ์ผ๋ก ์ฝ์ด ๊ฐ์ + 1 ๋งํผ์ ์ฐ๋ ๋๋ฅผ ์์ฑํด์ ๋๋ฆฌ๋ ๊ฒ์ด ๊ฐ์ฅ ์๋๊ฐ ๋น ๋ฆ
๋๋ค.
๋ง์ฝ์ ๋ด ์ปดํจํฐ์ ์ฝ์ด ๊ฐ์๋ฅผ ๋ชจ๋ฅธ๋ค๋ฉด ๋ฆฌ๋
์ค ํฐ๋ฏธ๋์ ๊ฒฝ์ฐ
```
$ make -j$(nproc)
```
์ผ๋ก ํ๋ฉด `$(nproc)` ์ด ์์์ ๋ด ์ปดํจํฐ์ ํ์ฌ ์ฝ์ด ๊ฐ์๋ก ์นํ๋ฉ๋๋ค.
๊ฐ์ข๋ฅผ ๋ณด๋ค๊ฐ ์กฐ๊ธ์ด๋ผ๋ ๊ถ๊ธํ ๊ฒ์ด๋ ์ด์ํ ์ ์ด ์๋ค๋ฉด ๊ผญ ๋๊ธ์ ๋จ๊ฒจ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค. ๊ทธ ์ธ์๋ ๊ฐ์ข์ ๊ด๋ จ๋ ๊ฒ์ด๋ผ๋ฉด ์ด๋ ํ ๊ฒ๋ ์ง๋ฌธํด ์ฃผ์
๋ ์๊ด ์์ต๋๋ค. ์๊ฐํด ๋ณผ ๋ฌธ์ ๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ๋๊ธ์ ๋ฌ์์ฃผ์ธ์.
ํ์ฌ ์ฌ๋ฌ๋ถ์ด ๋ณด์ ๊ฐ์ข๋ \<์น์ด๋จน๋ C++ - \<19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)\>\> ์
๋๋ค. ์ด๋ฒ ๊ฐ์ข์ ๋ชจ๋ ์์ ๋ค์ ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ ์งค ์์ค๊น์ง ๊ฐ์ข๋ฅผ ์ฝ์ด ๋ณด์๊ธฐ ์ ๊น์ง ๋ค์ ๊ฐ์ข๋ก ๋์ด๊ฐ์ง ๋ง์์ฃผ์ธ์
[๋ค์ ๊ฐ์ข ๋ณด๋ฌ๊ฐ๊ธฐ](https://modoocode.com/135)
๋๊ธ์ด 37 ๊ฐ ์์ต๋๋ค\!

๊ฐ์ข์ ๊ด๋ จ ์์ด ๊ถ๊ธํ ๋ด์ฉ์ [์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํด์ฃผ์ธ์](https://forum.modoocode.com/)
๋ค์์ผ๋ก ๋ก๊ทธ์ธ
๋๋ ์ง์ ์
๋ ฅํ์ธ์ (๋๊ธ ์์ ์ ๋น๋ฐ๋ฒํธ๊ฐ ํ์ํฉ๋๋ค)
๋๊ธ ๋ฌ๊ธฐ
- 
ํ์ฐ์ง2025-08-07 16:08:30.495617
์ต์ข
์ ๋ฆฌ ๋ถ๋ถ์ Makefile ์ฝ๋๋ฅผ C ๋ฒ์ ์ผ๋ก ์์ฑํด๋ณด์์ต๋๋ค. ๊ฑฐ์ ๋๊ฐ์๋ฐ ๋ค์์ ๋ถ๋ถ์์ ์ฝ๊ฐ์ ๋ณ๊ฒฝ์ฌํญ์ด ์์ต๋๋ค. 1. make DEBUG=1 ์ด๋ ๊ฒ ์คํํ๋ฉด ์ปดํ์ผํ ๋ -g ํ๋๊ทธ๊ฐ ํฌํจ๋ผ์ gdb๋ก ๋๋ฒ๊น
ํ ์ ์๊ฒ ๋ง๋ค์์ต๋๋ค. 2. BIN\_DIR = ./bin ์ผ๋ก ์ค์ ํ์ฌ /bin ํด๋ ์์ main ์คํํ์ผ์ด ๋ง๋ค์ด์ง๊ฒ ํ์์ต๋๋ค. 3. notdir ํจ์๋ฅผ ๋นผ๊ณ ๋์ ์ patsubst ๋ถ๋ถ์ ์ด๋ ๊ฒ ๋ฐ๊ฟจ์ต๋๋ค. OBJS = \$(patsubst \$(SRC\_DIR)/%.c,\$(OBJ\_DIR)/%.o,\$(SRCS)) \# Makefile CC = gcc ifeq (\$(DEBUG), 1) CFLAGS = -Wall -Wextra -g -O0 else CFLAGS = -Wall -Wextra -O2 endif SRC\_DIR = ./src OBJ\_DIR = ./obj BIN\_DIR = ./bin TARGET = \$(BIN\_DIR)/main all: \$(TARGET) SRCS = \$(wildcard \$(SRC\_DIR)/\*.c) OBJS = \$(patsubst \$(SRC\_DIR)/%.c,\$(OBJ\_DIR)/%.o,\$(SRCS)) DEPS = \$(OBJS:.o=.d) \$(OBJ\_DIR): mkdir -p \$(OBJ\_DIR) \$(BIN\_DIR): mkdir -p \$(BIN\_DIR) \$(OBJ\_DIR)/%.o : \$(SRC\_DIR)/%.c \| \$(OBJ\_DIR) \$(CC) \$(CFLAGS) -c \$\< -o \$@ -MD \$(TARGET) : \$(OBJS) \| \$(BIN\_DIR) \$(CC) \$(CFLAGS) \$(OBJS) -o \$@ .PHONY: clean clean: rm -rf \$(OBJ\_DIR) \$(BIN\_DIR) -include \$(DEPS)
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
^^2024-07-26 02:55:07.617106
^^
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
์ดํ์ฌ2024-04-07 01:37:44.467766
์ข์ ์๋ฃ ๊ฐ์ฌํฉ๋๋ค! ์ด๋ ๊ฒ ์ดํด๊ฐ ์๋๊ณ ์ ๋ฌ๋ ฅ์ด ์ข์ ๋ธ๋ก๊ทธ ๊ธ์ ์ค๋๋ง์ ๋ณด๋ค์.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊น๋ฏผ๊ฒธ2024-01-24 15:03:09.492404
์ดํด ์์ ์๋๋ค์ ๊ฐ์ฌํฉ๋๋ค
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
ํ๋ง๋ง2023-10-19 11:27:45.472561
์ ์ ๋ง ์ต๊ณ ๋ค์!!!!! ๊ฐ์ฌํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
GroundP2023-05-10 02:11:01.781
์ข์ ๊ฐ์ ๊ฐ์ฌํฉ๋๋ค^^ ์ด๋ฏธ ๋น๋ํ ํ์ผ๋ค ์ ์ธํ๊ณ ๋ณ๊ฒฝ๋ ์ฌํญ์ ๋ํด์๋ง ๋น๋ํ๊ณ ์ถ์ผ๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๋ฐ๋ธํน2022-09-30 04:13:06.194
\-I ๋ฅผ ํตํด ํค๋ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ์ธํด๋ฃจ๋ ํ์๋ -include \*.d ๊ณผ์ (.d ์์ฑ -M \> .d)ํฌํจ ์๋ต ํ ์ ์์ด ๋ณด์ด๋๋ฐ ์ ๋๋ก ์ดํดํ๊ฒ ๋ง์๊น์? ๊ทธ๋ ๋ค๋ฉด .d ๋ฅผ ์์ฑํ๊ณ includeํ๋ ๊ณผ์ ์ ์ด๋จ๋ ํ์์ ์ผ๋ก ์ ์ฉํ ๊น์? ์๋ก์ด ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๊ณ -I์ ๋ณ๋๋ก ๊ฒฝ๋ก์ถ๊ฐ ์์ด ์ ์ฐํ๊ฒ ์ธ ์ ์๋ ์ฅ์ ์ธ๊ฒ์ผ๊น์?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Lee Kanghee2022-03-29 15:48:49.631
obj ํ์ผ์ ๋ง๋คํ์์์ด prerequisite์ .o ํ์ผ์ ๋ช
์ํด์ฃผ์ด๋ implicit rule์ ์ํด์ ์๋์ .cpp๋ก๋ถํฐ .o๋ก ์ปดํ์ผํด์ฃผ๊ณ ๊ทธ๊ฑธ prerequisite์ผ๋ก ์ฌ์ฉํ๋๊ฑฐ๋ก ์๋๋ฐ ํน์ ์์ฒ๋ผ ๋ค ์ ๋ ๊ฒ์ด ์ ํธ๋๋๊ฑด๊ฐ์??
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Gilbert Kim2022-02-14 00:57:48.097
์ข์ ๊ฐ์ ๊ฐ์ฌํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2022-02-16 04:44:19.917
๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
ad2022-01-19 12:47:53.072
So helpful\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊ฐ์๋ฏผ2021-11-22 08:08:59.891
์ ๋ง ์ ๋ฐฐ์ฐ๊ณ ๊ฐ๋๋ค! ๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Chris Moon2021-09-28 06:46:48.145
์ ๋ฐฐ์ฐ๊ณ ๊ฐ๋๋ค. ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๋ณ์ฑ์ด2021-08-15 07:24:23.791
์ญ์ ์ต๊ณ ์
๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊น์ ๋ฏผ2021-08-12 09:59:45.205
์ ๋ธ๋ก๊ทธ์ ๊ฐ์ ์ค๊ฐ์ค๊ฐ ์ฐ์ธ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํด๋ ๋ ๊น์?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
์ ์งํ2021-07-25 13:00:52.878
all : main ์ด๊ฒ์ ์ ์๋ ๊ฑด๊ฐ์?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2022-02-16 04:44:47.605
๋ณดํต make ํ ๋ ์ ์ฒด๋ฅผ ๋น๋ํ๋ผ๋ ์๋ฏธ๋ก make all ์ด๋ผ๊ณ ๋ง์ด ์๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
ty2021-05-06 04:53:22.369
์ข์ ๊ฐ์ ๋๋ฌด ๊ฐ์ฌํฉ๋๋ค. ์คํ ๋ฆฌํฌํธ ํฉ๋๋ค. ์ต์ข
์ ๋ฆฌ ์ค๊ฐ๋ถ๋ถ์์ \>\> ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ foo.cc bar.cc main.cc ๋ก ๊น๋ํ๊ฒ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ด๊ธฐ ์ํด nodir ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. nodir ์ ์์ ์ค๋ ๊ฒฝ๋ก๋ฅผ ๋ ๋ ค๋ฒ๋ฆฌ๊ณ ํ์ผ ์ด๋ฆ๋ง ๊น๋ํ๊ฒ ์ถ์ถํด์ค๋๋ค. nodir -\> notdir์ด์ฃ ?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
ty2021-05-06 05:06:48.265
์ ์ผ ๋ง์ง๋ง ์ค์์ \>\> ์ผ๋ก ํ๋ฉด \$(proc) ์ด ์์์ ๋ด ์ปดํจํฐ์ ํ์ฌ ์ฝ์ด ๊ฐ์๋ก ์นํ๋ฉ๋๋ค. \$(proc) -\> \$(nproc) ์ธ๋ฏํฉ๋๋ค
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2021-06-25 05:36:01.573
๊ฐ์ฌํฉ๋๋ค. ์์ ํ์์ต๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Harry2020-12-08 13:56:43.121
๊ถ๊ธํ์ ์ด ์์ต๋๋ค. target์์ด make๋ช
๋ น์ด๋ง ์
๋ ฅํ๋ฉด ์ฒ์์ผ๋ก ๋ง๋๋ target์ ์คํํ๋ ๊ฒ์ผ๋ก ์๊ณ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ %.o:์ ๊ฐ์ target์ ๋ฌด์ํ๋๊ฑฐ ๊ฐ๋๋ผ๊ตฌ์. ๋ถ๋ช
all์ด %.o๋ณด๋ค ์๋์ ์์นํด ์๋๋ก Makefile์ ๋ง๋ค์๋๋ฐ make๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด make all์ ํ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง์ ๊ฒฐ๊ณผ๊ฐ ๋์ ์ ๊ทธ๋ฐ์ง ๊ถ๊ธํฉ๋๋ค. %.o: %.c \${CC} \${CFALGS} -c \$\< all: \${NAME} ์์ ๊ฐ์ ์ฝ๋์
๋๋ค. ์ด ๋ %.o ํ์ผ์์ clean ํ๊ฒ์ ์จ์ฃผ๋ฉด make ์คํ์ make clean์ด ์คํ๋ฉ๋๋ค. ๊ฒฐ๋ก ์ ์ผ๋ก ์ %.o๋ ๋ฌด์ํ๋์ง ๊ถ๊ธํฉ๋๋ค. ๋ .c.o์ ํ๊ฒ์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฌด์ํ๋๋ฐ ๊ฐ์ ์ด์ ์ธ์ง ๊ถ๊ธํฉ๋๋ค. ๋๋ฒ ์งธ ์ง๋ฌธ์
๋๋ค. ๋ค๋ฅธ ์ฌ์ดํธ์์ \$\< ์
๋ ฅ ํ์ผ์ ์๋ฏธํฉ๋๋ค. ์ฝ๋ก ์ ์ค๋ฅธ์ชฝ์ ์ค๋ ํจํด์ ์นํํฉ๋๋ค. \$@ ์ถ๋ ฅ ํ์ผ์ ์๋ฏธํฉ๋๋ค. ์ฝ๋ก ์ ์ผ์ชฝ์ ์ค๋ ํจํด์ ์นํํฉ๋๋ค. \$\* ์
๋ ฅ ํ์ผ์์ ๊ผฌ๋ฆฌ๋ง(.c, .s ๋ฑ)์ ๋ผ๋จ ํ์ผ๋ช
์ ๋ํ๋
๋๋ค. ์ด๋ฐ์์ผ๋ก ์ ์๋ฅผ ์จ๋จ์ต๋๋ค. http://doc.kldp.org/KoreanDoc/html/gcc\_and\_make/gcc\_and\_make-3.html ํด๋น ์ฌ์ดํธ์
๋๋ค. ์ ์๋๊ป์ ์จ๋์ ์ ์์ ๋ค๋ฅธ๊ฑฐ ๊ฐ์์ ๋ฌธ์๋๋ฆฝ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ๋ฆฌํด๋์ผ์ ์๋ฃ๋ค์ด ๋๋ฌด ์ข์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค. ๋ง์ ๋์์ด ๋์์ต๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-12-08 22:53:26.178
make ์ค๋ช
์ ๋ณด๋ฉด "By default, make starts with the first target (not targets whose names start with โ.โ)." ์ด๋ผ๊ณ ์ฐ์ฌ์ ธ ์๋๋ฐ, %.o ์ญ์ . ์ผ๋ก ์์ํ๋ ํ๊ฒ ์ด๋ฆ์ผ๋ก ๊ฐ์ฃผ๋๋๊ฒ ๊ฐ๋ค์. ๊ทธ๋์ ๋ฌด์๋๋ ๊ฒ ๊ฐ์ต๋๋ค. \$\< ์ค๋ช
์ ๊ฒฝ์ฐ ์ ์ค๋ช
์ด ๋ง์ต๋๋ค. (https://www.gnu.org/software/make/manual/html\_node/Automatic-Variables.html) \$\< ๋ ์ค๋ฅธ์ชฝ ์ ์ฒด๊ฐ ์๋๋ผ ์ค๋ฅธ์ชฝ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ํ์ผ๋ง์ ์๋ฏธํฉ๋๋ค. ์ค๋ฅธ์ชฝ ์ ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ์ถ๋ค๋ฉด \$^ ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Harry2020-12-22 06:59:46.108
๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค ํฐ ๋์์ด ๋๊ณ ์์ต๋๋ค! ์ข์ ํ๋ฃจ๋์ธ์\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
ํ์ฐ์ญ2020-09-21 06:53:31.842
์๋
ํ์ธ์. ์ด๋ ๊ฒ ๊ท์คํ ๊ฐ์๋ฅผ ๊ณต๊ฐํ์ฌ ์ฃผ์
์ ์ ๋ง ๊ฐ์ฌํฉ๋๋ค. ํฌ์คํ
์ ๊ณต๋ถํ๋ค๊ฐ ํ ๊ฐ์ง ์ง๋ฌธ์ด ๋ ์ฌ๋์ต๋๋ค. ๋ณ๋์ ํด๋(์:bin)๋ฅผ ๋ง๋ค๊ณ ์ต์ข
์ ์ผ๋ก ๋ง๋ค์ด์ง๋ ์คํํ์ผ์ ๊ทธ ํด๋์ ์์น์ํค๋ ค๋ฉด Makefile์ ์ด๋ป๊ฒ ๊ตฌ์ฑํด์ผ ํ ์ง ์ด๋ ค์์ ์ฌ์ญ๋๋ค^^; ์๊ณ ํ์ธ์^^
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-10-16 05:25:07.105
\$(CC) \$(CXXFLAGS) \$(OBJECTS) -o \$(TARGET) \$(LDFLAGS) ์ด ๋ถ๋ถ์ \$(CC) \$(CXXFLAGS) \$(OBJECTS) -o bin/\$(TARGET) \$(LDFLAGS) ๊ณผ ๊ฐ์ด ์ถ๋ ฅํ๊ณ ์ ํ๋ ํ์ผ์ ๊ฒฝ๋ก๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋์ง ์์๊น์?
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
kaze2020-09-20 01:01:14.372
gcc ์ปดํ์ผ ํ๊ฒฝ์ ๋น์ฅฌ์ผ ์คํ๋์ค์ฒ๋ผ ๋ธ๋ ์ดํฌ๋ฅผ ์ก๊ณ ๋๋ฒ๊น
ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์๋๊ฒ์ธ๊ฐ์? ๋งค๋ฒ ๊ณ ์น๊ณ ์ปดํ์ผํ๊ณ txt๋ก ๋ก๊ทธํ์ผ ๋ง๋ค๊ณ ๋ณด๊ณ ๋ค์ ๊ณ ์น๊ณ ์ปดํ์ผํ๊ณ txt๋ก ๋ก๊ทธํ์ผ ๋ง๋ค๊ณ ๋ฅผ ๋ฐ๋ณตํ๋๋ฐ ๊ถ๊ธํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-09-21 05:05:13.256
๋ฆฌ๋
์ค ํ๊ฒฝ์ ๊ฒฝ์ฐ gdb ๋ lldb ๋ผ๋ ํ๋ฅญํ ๋๋ฒ๊ฑฐ๋ค์ด ์์ต๋๋ค. ๋ฌผ๋ก ๋ธ๋ ์ดํฌ ํฌ์ธํธ ์ญ์ ์ถ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊นํ์2020-09-04 08:38:46.289
make -j ์ต์
์ฌ์ฉ์ \$(nproc)๋ฅผ ์ถ๊ฐํด์ฃผ์๋ฉด ์ข์๊ฑฐ ๊ฐ๋ค์. \$(cmd)ํํ๋ก ๋ช
๋ น์ด cmd๋ฅผ ์ฌ์ฉํ๋ฉด cmd๋ช
๋ น์ ๊ฒฐ๊ณผ๊ฐ ์นํ๋ฉ๋๋ค. nproc๋ ๋ฆฌ๋
์ค ๊ณ์ด์์ ์์คํ
CPU์ ์ฝ์ด์๋ฅผ ํ์ธํ๋ ๋ช
๋ น์ด๊ตฌ์. ์ข์ ๊ฐ์ข ์ ๋ณด๊ณ ์์ต๋๋ค. Make๋ ์ ๋งคํ๊ฒ ์๊ณ ์๋ ๋ด์ฉ ๊น๋ํ๊ฒ ์ ๋ฆฌ๋์ด์ ์ข์ต๋๋ค. CMake ๋ถ๋ก๋ ์์ผ๋ฉด ์ด๋จ๊นํ๋ ๋ฌด๋ฆฌํ (?) ์ ์์ ํด๋ด
๋๋ค. ์ฝ๋ก๋ ์กฐ์ฌํ์๊ณ ๊ฑด๊ฐํ์๊ธฐ๋ฅผ ๋น๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-09-06 22:55:24.492
๊ฐ์ฌํฉ๋๋ค. ์ถํ์ ์ถ๊ฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
dd2020-08-03 16:11:08.570
๋๋์ฒด ๋ญํ์๋ ๋ถ์ด๊ธธ๋.. ์ด๋ฐ ๊ทํ ๊ฐ์๋ฅผ ๋ฌด๋ฃ๋ก ํด์ฃผ์๋์ง ใ
ใ
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-08-03 22:34:44.604
๊ฐ์ฌํฉ๋๋ค. ์ฌ๋ฏธ๋ก ํ๊ณ ์์ต๋๋ค ใ
ใ
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊น์ค์2020-07-08 03:05:03.475
์๋
ํ์ธ์! ๊ถ๊ธํ ๋ถ๋ถ์ด ์์ด์ ์ฌ์ญค๋ด
๋๋ค! ์๋์ผ๋ก prerequisite ๋ง๋ค๊ธฐ ๋ถ๋ถ์์ main.d๋ฅผ includeํ๋ฉด %.o: %.cc %.h \$(CC) \$(CXXFLAGS) -c \$\< ์์ main.d๊ฐ ํจํด๋งค์นญ๋์ \$(CC) \$(CXXFLAGS) -c \$\<๊ฐ ์คํ๋๋ ๊ฑด๊ฐ์? ์ด๋ ๋ค๋ฉด ํจํด์ด ๋ง์ง ์๋๋ฐ ์คํ๋๋ ๊ฒ ๊ฐ์์์. ์๋๋ฉด main.d๋ง includeํ๋ฉด ๋งค์นญ๋๋ ๊ฒ ์์ด ์๋์ผ๋ก main.o๊ฐ ๋ง๋ค์ด์ง๋ ๊ฑด๊ฐ์? ์ ์ดํด๊ฐ ๋์ง ์์์ ์ง๋ฌธ๋๋ฆฝ๋๋ค. ๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-07-08 09:22:15.557
main.d ๋ฅผ include ํ๊ฒ ๋๋ฉด main.d ์ ๋ด์ฉ์ด Makefile ์ ๋ชจ๋ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค. (๋ง์น \#include ๋ฅผ ํ๋ ๊ฒ ์ฒ๋ผ์) ์๋ฅผ ๋ค์ด์ main.d ์ ์๋ ์ฒ๋ผ ์จ์๋ค๊ณ ํด๋ด
์๋ค. main.o: a.h b.h main.cc ๊ทธ๋ ๋ค๋ฉด make ๋ ๊ฐ์ target ์ ๋ํ prerequisite ๋ฅผ ๋ชจ๋ ํ๋๋ก ํฉ์น๋ฏ๋ก main.o: main.cc main.h ์ main.o: a.h b.h main.cc ๊ฐ ํ๋๋ก ํฉ์ณ์ ธ์ ๋ง์น main.o: a.h b.h main.cc main.h \$(CC) \$(CXXFLAGS) -c \$\< ๋ฅผ ์ฌ์ฉํ ๋ฏํ ํจ๊ณผ๋ฅผ ๋ด๊ฒ ๋ฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
asdf2020-07-02 06:56:51.939
์ ๋ง ๋์์ด ๋ง์ด ๋ฉ๋๋ค ๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-07-02 22:14:33.788
๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
๊ณ ์์ฐ2020-06-30 23:53:39.358
๊ฐ์ฌํฉ๋๋ค.
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
- 
Jaebum Lee2020-07-01 06:45:56.145
๊ฐ์ฌํฉ๋๋ค\!
๋ต๊ธ ๋ฌ๊ธฐ๋ต๊ธ ์ญ์
๋๊ธ ๋ ๋ณด๊ธฐ |
| Readable Markdown | ์์ฑ์ผ : 2020-06-10 ์ด ๊ธ์ 105837 ๋ฒ ์ฝํ์ต๋๋ค.
์ด๋ฒ ๊ฐ์ข์์๋
- make ์ ์๋ ์ดํด
- Makefile ๋ฌธ๋ฒ ์ดํด
- ๋ง๋ฅ Makefile ๋ง๋ค๊ธฐ
์ ๋ํด์ ๋ค๋ฃจ์ด ๋ณด๊ฒ ์ต๋๋ค.

์๋
ํ์ธ์. ์ด๋ฒ ๊ฐ์ข ๋ถํฐ๋ ์น์ด๋จน๋ C++ ์๋ฆฌ์ฆ์ ๋ถ๋ก ๊ณผ ๊ฐ์ ๊ฐ๋
์ผ๋ก C++ ์ธ์ด ์์ฒด์๋ ์ง์ ๊ด๋ จ์ ์์ง๋ง ์ค์ ๋ก C++ ์ ํ๋ก๊ทธ๋๋ฐ ํ๊ธฐ ์ํด์ ํ์ํ ์ง์๋ค๊ณผ ํด๋ค์ ๋ํด์ ์ด์ผ๊ธฐ ํ๊ณ ์ ํฉ๋๋ค. ๊ทธ ์ฒซ ๋ฒ์งธ ํ์๋ก Makefile ๋ง๋ค๊ธฐ๊ฐ ๋๊ฒ ์ต๋๋ค.
์๋ฌด๋๋ ๋ฆฌ๋
์ค ํ๊ฒฝ์์ ํ๋ก๊ทธ๋๋ฐ์ ํ์ ๋ถ๋ค์ ์์๊ฒ ์ง๋ง, ๋ณดํต ํ๋ก๊ทธ๋จ์ ์ปดํ์ผ ํ ๋ make ๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํฉ๋๋ค. ์๋์ฐ์์ ๋น์ฃผ์ผ ์คํ๋์ค๋ฅผ ์ฌ์ฉํ์ ๋ค๋ฉด ์ปดํ์ผ ๋ฒํผ์ ๋๋ฅด๋ฉด ์์์ ์ปดํ์ผ ๋๋ ๊ฒ๊ณผ๋ ๋ฌ๋ฆฌ, ์ ์์์ ์ปดํ์ผ์ ํ๋ ค๋ฉด ์ด๋ค ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ณ , ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ ์ง ์ง์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ค์ผ ํฉ๋๋ค.
๋ฌผ๋ก ๋งค๋ฒ ๋ช
๋ น์ด๋ฅผ ์น๋ฉด ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง ํ๋ก์ ํธ์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ํ์ผ๋ค์ด ๋ง์์ง๋ค๋ฉด ๋งค๋ฒ ๊ทธ๋ ๊ฒ ์น๋ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น์์ง๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๋ฆฌ๋
์ค์์๋ make ๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋๋ฐ, ์ด ํ๋ก๊ทธ๋จ์ Makefile ๋ผ๋ ํ์ผ์ ์ฝ์ด์ ์ฃผ์ด์ง ๋ฐฉ์๋๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํ๊ฒ ํฉ๋๋ค. ๋๋ถ์ ๋ง์ ์์ ํ์ผ๋ค์ ๋ช
๋ น์ด ํ ๋ฒ์ผ๋ก ์ปดํ์ผ ํ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ make ํ๋ก๊ทธ๋จ์ด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋๋๊ณ , ํ๋ก๊ทธ๋จ๋ค์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก Makefile ์ ์์ฑํด์ผ ํ๋์ง ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋จผ์ make ๊ฐ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์๋ํ๋์ง ์๊ธฐ ์ ์ ์ปดํ์ผ๋ฌ๋ฅผ ํตํด ํ๋ก๊ทธ๋จ์ ๋น๋ํ๊ฒ ๋๋ฉด ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์์ค ์ฝ๋์์ ํ๋์ ํ๋ก๊ทธ๋จ์ด ์์ฑ๋๋์ง ์ดํด๋ณด๋๋ก ํฉ์๋ค.
๊ฐ์ฅ ๋จผ์ ์ฌ๋ฌ๋ถ์ ๋จธ๋ฆฌ ์์ผ๋ก ๋ ์ค๋ฅด๋ ๊ณผ์ ์ ๋ฐ๋ก ์ปดํ์ผ(Compile) ์ผ ๊ฒ์
๋๋ค. ์ด ์ปดํ์ผ์ด๋ผ๋ ๊ณผ์ ์ ์ฌ๋ฌ๋ถ์ ์์ค ์ฝ๋๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ์ด์
๋ธ๋ฆฌ์ด๋ก ๋ณํํ๋ ๊ณผ์ ์
๋๋ค.
์๋ฅผ ๋ค์ด์ ์๋์ ๊ฐ์ด `foo.h` ์ ์ ์๋ `foo` ํจ์์ `bar.h` ์ ์ ์๋ `bar` ํจ์๋ฅผ `main` ํจ์์์ ํธ์ถํ๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ์ดํด๋ด
์๋ค.
- foo.h
```
int foo();
```
- foo.cc
```
#include <iostream>
#include "foo.h"
int foo() {
std::cout << "Foo!" << std::endl;
return 0;
}
```
- bar.h
```
int bar();
```
- bar.cc
```
#include <iostream>
#include "bar.h"
int bar() {
std::cout << "Bar!" << std::endl;
return 0;
}
```
- main.cc
```
#include "bar.h"
#include "foo.h"
int main() {
foo();
bar();
}
```
์๋ฅผ ๋ค์ด์ `main.cc` ๋ฅผ ์ปดํ์ผ ํ๊ธฐ ์ํด์๋ ์๋์ ๊ฐ์ด ํ๋ฉด ๋ฉ๋๋ค.
```
$ g++ -c main.cc
```
`g++` ์ ์ ๋ฌํ๋ `-c` ๋ช
๋ น์ด๋ ์ธ์ ๋ค์์ ์ฃผ์ด์ง๋ ํ์ผ์ ์ปดํ์ผ ํด์ ๋ชฉ์ ํ์ผ(object file) ์ ์์ฑํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
์ค์ ๋ก, ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผ ํ์๋ค๋ฉด ์๋์ ๊ฐ์ด `main.o` ๋ผ๋ ํ์ผ์ด ์์ฑ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
```
$ ls main.o
main.o
```
์ด `main.o` ๋ `main.cc` ๋ฅผ ์ปดํ์ผ ํ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ๋ด๊ฒจ์๋ ํ์ผ ์
๋๋ค. ์ค์ ๋ก `main.o` ๋ฅผ ๋ฏ์ด๋ณด๋ฉด
```
$ objdump -S main.o
main.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: e8 00 00 00 00 callq d <main+0xd>
d: e8 00 00 00 00 callq 12 <main+0x12>
12: b8 00 00 00 00 mov $0x0,%eax
17: 5d pop %rbp
18: c3 retq
```
์ ๊ฐ์ด `main.cc` ์ ์ด์
๋ธ๋ฆฌ ์ฝ๋๊ฐ ์ ๋ค์ด์์์ ์ ์ ์์ต๋๋ค.
ํ ๊ฐ์ง ์ฌ๋ฏธ์๋ ์ ์ ์ปดํ์ผ๋ฌ๊ฐ `main.cc` ๋ฅผ ์ปดํ์ผ ํ ๋ ๋ค๋ฅธ ํ์ผ๋ค์ ์ฐธ์กฐํ์ง ์์๋ค๋ ์ ์
๋๋ค. ์ค์ ๋ก `main.o` ์ ์ด์
๋ธ๋ฆฌ๋ฅผ ์ฌ์ฉ ๋ณด๋ฉด `foo` ๋ `bar` ์ ๊ดํ ๋ด์ฉ์ด ํ๋๋ ์์์ ์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ `main.o` ์์ฒด๋ก๋ ์ฐ๋ฆฌ์ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ํ๋ฉด `main.o` ์๋ `foo` ๋ผ๋ ํจ์๋ฅผ ํธ์ถํด๋ผ\! ๋ผ๋ ๋ด์ฉ๋ง ์์ง, `foo` ๋ ์ด๋์ ์๊ณ ์ด๋ฌ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค ์ ๊ดํ ์ด์ผ๊ธฐ๋ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
์ค์ ๋ก ์๋ํ๋ `foo` ์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋ `foo.cc` ๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋ค์ด์ง `foo.o` ๊ฐ ํ์ํ๊ณ , ๋ง์ฐฌ๊ฐ์ง๋ก `bar` ์ ๊ดํ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด์๋ `bar.cc` ๋ฅผ ์ปดํ์ผ ํด์ ๋ง๋ `bar.o` ๊ฐ ํ์ํฉ๋๋ค.
๋ฐ๋ผ์ ์ค์ ํ๋ก๊ทธ๋จ์ ์ ์ํ๊ธฐ ์ํด์๋ ์ด ๊ฐ๊ฐ์ `main.o, foo.o, bar.o` ๋ฅผ ํ๋๋ก ํฉ์น๋ ๊ณผ์ ์ด ํ์ํ๊ฒ ์ฃ . ์ด์ ๊ฐ์ ๊ณผ์ ์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋งํน(Linking) ์ด๋ผ๊ณ ํฉ๋๋ค.

๋งํน์ด ์ด๋ฆ ๊ทธ๋๋ก ๋งํฌ ํ๋ ์์
์ธ ์ด์ ๋ ์ค์ ๋ก ์๋ก ๋ค๋ฅธ ํ์ผ์ ํฉ์ด์ ธ ์๋ ํจ์๋ ํด๋์ค๋ค์ ํ ๋ฐ ๋ฌถ์ด์ ๋งํฌํด์ฃผ๋ ์์
์ด๊ธฐ ๋๋ฌธ์ด์ฃ . ์ด ๊ณผ์ ์์ `main` ํจ์ ์์ `foo` ํจ์๊ฐ ์ด๋์ ์ ์๋์ด ์๋์ง ์์น๋ฅผ ์ฐพ๊ณ ์ ๋๋ก ๋ ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ฌ์ค ์ด ๋งํน์ ๊ดํด์ ์ด์ผ๊ธฐ๋ง ํด๋ ํ์ฐธ ํ ์ ์๋๋ฐ, ์ผ๋จ ์ด ๊ธ์ ๋ชฉํ๋ ๋น๋ ํ์ผ ๋ง๋ค๊ธฐ ์ด๋ฏ๋ก ์ฌ๊ธฐ์ ์ค์ด๊ฒ ์ต๋๋ค.
์๋ฌดํผ ์ด ๋งํน ๊ณผ์ ์ ์๋์ ๊ฐ์ด ์ปดํ์ผ๋ฌ์ ๋ชฉ์ ํ์ผ์ ์ ๋ฌํจ์ผ๋ก์จ ์ํ๋ฉ๋๋ค.
```
$ g++ main.o foo.o bar.o -o main
```
์ฌ๊ธฐ์ `-o` ์ต์
์ ๊ทธ ๋ค์ ๋งํน ํ์ ์์ฑํ ์คํ ํ์ผ ์ด๋ฆ์ ์ด์ผ๊ธฐ ํฉ๋๋ค. ์ ๊ฒฝ์ฐ `main` ์ด๋ผ๋ ์คํ ํ์ผ์ ๋ง๋ค์๊ณ ๋ง์ฝ์ ์ด๋ฅผ ๋ฐ๋ก ์ง์ ํ์ง ์๋๋ค๋ฉด ๊ทธ๋ฅ `./a.out` ์ด๋ผ๋ ํ์ผ์ ๋ํดํธ๋ก ์์ฑํ๊ฒ ๋ฉ๋๋ค.
์ค์ ๋ก `main` ํ์ผ์ ์คํํ๊ฒ ๋๋ค๋ฉด
์คํ ๊ฒฐ๊ณผ
```
Foo!
Bar!
```
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
์ผ๋จ ์์ ๊ฐ์ด `main` ์คํ ํ์ผ์ ์์ฑํ๊ธฐ ์ํด์ ์
๋ ฅํ ์ ๋ช
๋ น์ด๋ฅผ ์ญ ๋์ดํด๋ณด์๋ฉด;
```
$ g++ -c main.cc
$ g++ -c foo.cc
$ g++ -c bar.cc
$ g++ main.o foo.o bar.o -o main
```
์ ๊ฐ์ต๋๋ค. ๋ฌผ๋ก ํ์ผ ๊ฐ์๊ฐ ์๋ค๋ฉด ๋งค ๋ฒ ์
๋ ฅํ๋ ๊ฒ์ด ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋์ง๋ ์์ต๋๋ค๋ง, ํ๋ก์ ํธ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ์ณ์ผํ ๋ช
๋ น์ด๊ฐ ๋ ๋ง์์ง๊ฒ ๋์ ๋ณต์กํ๊ฒ ์ง์ (ํนํ ํ์ผ๋ค์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ์๋๋ค๋ฉด ๋ง์ด์ฃ .)
๋ฌผ๋ก ์ ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ๊ธ ์์๋ ๋ถ์ด๋ผ๋ฉด
> ๊ทธ๋ฅ ์ ๋ช
๋ น์ด๋ค์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?
๋ผ๊ณ ๋ฌผ์ผ์ค ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋ฐฉ์์ผ๋ก ํ๋ค๋ฉด ํ ๊ฐ์ง ๋ฌธ์ ์ ์ด ์๋๋ฐ, ์๋ฅผ ๋ค์ด์ ์ฌ๋ฌ๋ถ์ด `main.cc` ๋ฅผ ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ค์ ๋ก๋
```
$ g++ -c main.cc
$ g++ main.o foo.o bar.o -o main
```
๋ฑ ์ด ๋ ๋ช
๋ น์ด๋ง ์คํํ๋ฉด ๋ฉ๋๋ค. ์๋ํ๋ฉด `main` ํ์ผ์ ๋ฐ๊พผ๋ค๊ณ ํด์ `foo` ๋ `bar` ์ ์ปดํ์ผ ๋ ๋ด์ฉ์ด ๋ฐ๋์ง ์๊ธฐ ๋๋ฌธ์ด์ฃ . ํ์ง๋ง ์ ์ฒ๋ผ ๋จ์ํ๊ฒ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๊ฒ ๋๋ค๋ฉด ํ์ผ ํ๋๋ง ๋ฐ๊ฟ๋ ์ ์ฒด ๋ชจ๋ ํ์ผ๋ค์ ์ปดํ์ผ ํ๊ฒ ๋๋ฏ๋ก ์ปดํ์ผ ์๊ฐ์ด ๋งค์ฐ ๊ธธ์ด์ง๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง make ๋ฅผ ์ฌ์ฉํ๋ฉด ์ผ๋ถ ํ์ผ์ ์์ ํ ๊ฒฝ์ฐ ํ์ํ ๋ช
๋ น๋ง ๋น ๋ฅด๊ฒ ์ปดํ์ผ์ ํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ ๊ทธ๋ ๋ค๋ฉด ๊ฑฐ๋์ ๋ฏธํ๊ณ make ์ ์ฌ์ฉ๋ฒ๊ณผ make ๋ฅผ ์ํ Makefile ์ ์ด๋ป๊ฒ ์์ฑํ๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
make ๋ ๊ฐ๋จํ ๋งํ์๋ฉด ์ฃผ์ด์ง ์ ๋ช
๋ น์ด๋ค์ ์กฐ๊ฑด์ ๋ง๊ฒ ์คํํ๋ ํ๋ก๊ทธ๋จ ์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ด ๋ ์ด๋ ํ ์กฐ๊ฑด์ผ๋ก ๋ช
๋ น์ด๋ฅผ ์คํํ ์ง ๋ด์ ํ์ผ์ Makefile ์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, make ๋ฅผ ํฐ๋ฏธ๋ ์์์ ์คํํ๊ฒ ๋๋ค๋ฉด ํด๋น ์์น์ ์๋ Makefile ์ ์ฐพ์์ ์ฝ์ด๋ค์ด๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด Makefile ์๋ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ์กฐ๊ฑด์ ๊ธฐ์ ํ ๊น์?
```
target โฆ : prerequisites โฆ
(ํญ)recipe
โฆ
โฆ
```
Makefile ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๊ฐ์ด 3 ๊ฐ์ง ์์๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
make ๋ฅผ ์คํํ ๋ `make abc` ๊ณผ ๊ฐ์ด ์ด๋ ํ ๊ฒ์ make ํ ์ง ์ ๋ฌํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ ํ๊ฒ(target) ์ด๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ๋ง์ผ `make abc` ๋ฅผ ํ์์ ๊ฒฝ์ฐ ํ๊ฒ ์ค์ `abc` ๋ฅผ ์ฐพ์์ ์ด์ ๋์๋๋ ๋ช
๋ น์ ์คํํด์ค๋๋ค.
์ฃผ์ด์ง ํ๊ฒ์ make ํ ๋ ์คํํ ๋ช
๋ น์ด๋ค์ ๋์ด์
๋๋ค. ํ ๊ฐ์ง ์ค์ํ ์ ์ recipe ์๋ฆฌ์ ๋ช
๋ น์ด๋ฅผ ์ธ ๋ ๋ฐ๋์ ํญ ํ ๋ฒ์ผ๋ก ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํด์ค์ผ๋ง ํฉ๋๋ค. ๋ณดํต ์์ฆ์ ํธ์ง๊ธฐ์ ๊ฒฝ์ฐ (์๋ฅผ ๋ค์ด VSCode), ์๋์ผ๋ก ํญ์ ์คํ์ด์ค๋ก ๋ฐ๊ฟ์ฃผ๋ ์ต์
์ด ํ์ฑํ ๋์ด ์์ ํ
๋ฐ make ๊ฐ Makefile ์ ์ ๋๋ก ์ฝ์ด๋ค์ด๊ธฐ ์ํด์๋ ๋ฐ๋์ ํญ์ ์ฌ์ฉํด์ผ๋ง ํฉ๋๋ค\!
์ฃผ์ด์ง ํ๊ฒ์ make ํ ๋ ์ฌ์ฉ๋ ํ์ผ๋ค์ ๋ชฉ๋ก ์
๋๋ค. ๋ค๋ฅธ ๋ง๋ก ์์กด ํ์ผ(dependency) ์ด๋ผ๊ณ ๋ ํฉ๋๋ค. ์๋ํ๋ฉด ํด๋น ํ๊ฒ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฑด๋๋ ค์ผ ํ ํ์ผ๋ค์ ์จ๋์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ง์ผ ์ฃผ์ด์ง ํ์ผ๋ค์ ์์ ์๊ฐ ๋ณด๋ค ํ๊ฒ์ด ๋ ๋์ค์ ์์ ๋์๋ค๋ฉด ํด๋น ํ๊ฒ์ ๋ช
๋ น์ด๋ฅผ ์คํํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด ์ด๋ฏธ ์ด์ ์ ํ๊ฒ์ด ๋ง๋ค์ด์ ธ์๋ค๊ณ ๊ฐ์ฃผํ๊ธฐ ๋๋ฌธ์ด์ฃ .
์๋ฅผ ๋ค์ด์ ํ๊ฒ์ด `main.o` ์ด๊ณ , ๋ช
๋ น์ด๊ฐ `g++ -c main.cc` ๋ผ๋ฉด, ํ์ ์กฐ๊ฑด๋ค์ `main.cc`, `foo.h`, `bar.h` ๊ฐ ๋๊ฒ ์ฃ . ์๋ํ๋ฉด ์ด๋ค ํ์ผ๋ค ์ค ํ๋๋ผ๋ ๋ฐ๋๋ค๋ฉด `main` ์ ์๋ก ์ปดํ์ผ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ฐ๋ฉด์ `main.o` ์ ์์ฑ ์๊ฐ์ด `main.cc`, `foo.h`, `bar.h` ๋ค์ ๋ง์ง๋ง ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ผ๋ฉด, ๊ตณ์ด `main.o` ๋ฅผ ๋ค์ ์ปดํ์ผ ํ ํ์๊ฐ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก Makefile ์ ๊ฐ๋จํ๊ฒ ๊ตฌ์ฑํด๋ณด๊ฒ ์ต๋๋ค.
```
foo.o : foo.h foo.cc
g++ -c foo.cc
bar.o : bar.h bar.cc
g++ -c bar.cc
main.o : main.cc foo.h bar.h
g++ -c main.cc
main : foo.o bar.o main.o
g++ foo.o bar.o main.o -o main
```
์ฃผ์ ์ฌํญ
์ Makefile ์ ๊ทธ๋๋ก ๋ณต์ฌํด์ ์คํํ๋ค๋ฉด ์๋ง ์คํ์ด ์๋ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด ํญ์ด ์คํ์ด์ค๋ก ๋ฐ๋์ด์ ๊ทธ๋ฐ๋ฐ์, ์ ๋๋ก Makefile ์ ๋ง๋์๊ธฐ ์ํด์๋ g++ ์์ ์ค๋ ์คํ์ด์ค ๋ ๋ฒ์ ํญ์ผ๋ก ๋ฐ๊พธ์ด์ ์ ์ฅํด๋ณด์ธ์.
์ฐ๋ฆฌ์ ๋ชฉํ๋ ์คํ ํ์ผ์ธ `main` ์ ๋ง๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ `make main` ์ ์คํํด๋ณด๋ฉด
```
$ make main
g++ -c foo.cc
g++ -c bar.cc
g++ -c main.cc
g++ foo.o bar.o main.o -o main
```
๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก `main` ์ด ์ ๋ง๋ค์ด์ง์ ์ ์ ์์ต๋๋ค.
์ฌ๋ฌ๋ถ์ด ํ ๋ฒ๋ ์ปดํ์ผ ํ์ง ์์ ์ํ์์ `make main` ์ ์คํํ๋ฉด make ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
1. `make main` ์ด๋๊น Makefile ์์ ํ๊ฒ์ด `main` ์ธ ๋
์์ ์ฐพ์๋ณด์.
2. ์ค. `main` ์ ํ์ํ ํ์ผ๋ค์ด `foo.o bar.o main.o` ์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
3. `foo.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `foo.cc` ๋ค? ์์ง `foo.o` ๊ฐ ์์ผ๋๊น ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ์คํํด์ผ ํ๊ฒ ๊ตฐ\!
4. ๋ง์ฐฌ๊ฐ์ง๋ก `bar.o, main.o` ๋ ์ปดํ์ผ
5. ์ ์ด์ ๋ง์ง๋ง์ผ๋ก `g++ foo.o bar.o main.o -o main` ๋ฅผ ์คํํด์ผ์ง
๋ง์ฝ์ ์ฌ๋ฌ๋ถ์ด `make main` ์ ํ ๋ฒ ์คํํ ์ํ์์ `foo.cc` ๋ง ์์ ํ์๋ค๊ณ ํด๋ด
์๋ค. ๊ทธ๋ ๋ค๋ฉด ์๋์ ๊ฐ์ด ํ์ํ ๋ถ๋ถ๋ง ์ฌ์ปดํ์ผ ๋ฉ๋๋ค.
1. `make main` ์ด๋๊น Makefile ์์ ํ๊ฒ์ด `main` ์ธ ๋
์์ ์ฐพ์๋ณด์.
2. ์ค. `main` ์ ํ์ํ ํ์ผ๋ค์ด `foo.o bar.o main.o` ์ด๋ค? ์ด๋ค ํ์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๊ฐ๊ฐ์ ํ์ผ ์ด๋ฆ์ผ๋ก๋ ํ๊ฒ๋ค์ ์ฐพ์๋ณด์.
3. `foo.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `foo.cc` ๋ค? ๊ทธ๋ฐ๋ฐ `foo.o` ์ ์์ฑ ์๊ฐ ๋ณด๋ค `foo.cc` ์ ์์ ์๊ฐ์ด ๋ ๋์ค์ด๊ตฐ! ์ฃผ์ด์ง ๋ช
๋ น์ด๋ฅผ ๋ค์ ์คํํด์ผ๊ฒ ์ด
4. `bar.o` ์ ๊ฒฝ์ฐ ํ์ํ ํ์ผ์ด `bar.cc` ์ธ๋ฐ, `bar.o` ์ ์์ฑ ์๊ฐ์ด `bar.cc` ์ ์์ ์๊ฐ ๋ณด๋ค ๋์ค์ด๋ค. ๊ตณ์ด ๋ช
๋ น์ด๋ค์ ์คํํ์ง ์์๋ ๋๊ฒ ์ด
5. `main.o` ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ค์ ์๋ฐ๊ฟ๋ ๋๊ฒ ๊ตฐ\!
6. `main` ์ ํ์ํ ํ์ผ๋ค ์ค `foo.o` ๊ฐ ๋ฐ๋์์ผ๋ ๋ด ๋ช
๋ น์ด๋ค๋ ๋ค์ ์คํํด์ผ๊ฒ ์ด.
๋ฐ๋ผ์ ๋ฑ ํ์ํ `g++ -c foo.cc` ์ `g++ foo.o bar.o main.o -o main` ๋ง์ด ์คํ๋ฉ๋๋ค.
์ฌ๋ฏธ์๊ฒ๋ Makefile ๋ด์์ ๋ณ์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
```
CC = g++
```
์ ๊ฒฝ์ฐ `CC` ๋ผ๋ ๋ณ์๋ฅผ ์ ์ํ์๋๋ฐ, ์ด์ Makefile ๋ด์์ `CC` ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด ํด๋น ๋ณ์์ ๋ฌธ์์ด์ธ `g++` ๋ก ์นํ๋ฉ๋๋ค. ์ด ๋ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ `$(CC)` ์ ๊ฐ์ด `$()` ์์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ณ์์ ์ด๋ฆ์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด์
```
CC = g++
foo.o : foo.h foo.cc
$(CC) -c foo.cc
```
๋ ์ฌ์ค
```
CC = g++
foo.o : foo.h foo.cc
g++ -c foo.cc
```
๊ณผ ์ ํํ ๊ฐ์ ๋ช
๋ น์ด ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก ์ ์ํ์ง ์๋ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ฒ ๋๋ค๋ฉด ๊ทธ๋ฅ ๋น ๋ฌธ์์ด๋ก ์นํ๋ฉ๋๋ค.
์ฃผ์ ์ฌํญ
์ด ๋ถ๋ถ์ TMI ์ด๋ฏ๋ก ๋ฐ์์ ๋ถ๋ค์ ๊ทธ๋ฅ ๋์ด๊ฐ์
๋ ๋ฉ๋๋ค.
Makefile ์์์ ๋ณ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก = ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ๊ณผ `:=` ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด ๋์ ์ด์ง ๋ค๋ฆ
๋๋ค.
\= ๋ฅผ ์ฌ์ฉํด์ ๋ณ์๋ฅผ ์ ์ํ์์ ๋, ์ ์์ ๋ค๋ฅธ ๋ณ์๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ํด๋น ๋ณ์๊ฐ ์ ์๋๊ธฐ ๋ ๋ ๊น์ง ๋ณ์์ ๊ฐ์ด ์ ํด์ง์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด์
```
B = $(A)
C = $(B)
A = a
```
`C` ์ ๊ฒฝ์ฐ `B` ์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์๊ณ , `B` ์ ๊ฒฝ์ฐ `A` ์ ๊ฐ์ ์ฐธ์กฐํ๊ณ ์์ต๋๋ค. ํ์ง๋ง `B =` ๋ฅผ ์คํํ ์์ ์์ `A` ๊ฐ ์ ์๋์ง ์์์ผ๋ฏ๋ก `B` ๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋์ด์ผ ํ์ง๋ง `=`๋ก ์ ์ํ์๊ธฐ ๋๋ฌธ์ `A` ๊ฐ ์ค์ ๋ก ์ ์๋ ๋ ๊น์ง `B` ์ `C` ๊ฐ ๊ฒฐ์ ๋์ง ์์ต๋๋ค. ๊ฒฐ๊ตญ ๋ง์ง๋ง์ `A = a` ๋ฅผ ํตํด `A` ๊ฐ `a` ๋ก ๋์๋์ด์ผ, `C` ๊ฐ `a` ๋ก ๊ฒฐ์ ๋ฉ๋๋ค.
```
B := $(A)
A = a
```
๋ฐ๋ฉด์ `:=` ๋ก ๋ณ์๋ฅผ ์ ์ํ ๊ฒฝ์ฐ, ํด๋น ์์ ์์ ๋ณ์์ ๊ฐ๋ง ํ์ธ ํฉ๋๋ค. ๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ `B` ๋ ๊ทธ๋ฅ ๋น ๋ฌธ์์ด์ด ๋๊ฒ ์ง์.
๋๋ถ๋ถ์ ์ํฉ์์๋ `=` ๋ `:=` ์ค ์๋ฌด๊ฑฐ๋ ์ฌ์ฉํด๋ ์๊ด ์์ต๋๋ค. ํ์ง๋ง
- ๋ง์ผ ๋ณ์๋ค์ ์ ์ ์์์ ํฌ๊ฒ ๊ตฌ์ ๋ฐ๊ณ ์ถ์ง ์๋ค๋ฉด `=` ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํธํฉ๋๋ค.
- `A =` ์ ๊ฐ์ด ์๊ธฐ ์์ ์ ์์ ํ๊ณ ์ถ๋ค๋ฉด `:=` ๋ฅผ ์ฌ์ฉํด์ผ์ง ๋ฌดํ ๋ฃจํ๋ฅผ ํผํ ์ ์์ต๋๋ค.
๋ง ๋ช
์ฌํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ค ๋ณ์๋ฅผ ์ฌ์ฉํด์ Makefile ์ ์กฐ๊ธ ๋ ๊น๋ํ๊ฒ ๋ฐ๊พธ์ด๋ณด๊ฒ ์ต๋๋ค.
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
```
make ๋ฅผ ์คํํด๋ณด๋ฉด
```
$ make main
g++ -Wall -O2 -c foo.cc
g++ -Wall -O2 -c bar.cc
g++ -Wall -O2 -c main.cc
g++ -Wall -O2 foo.o bar.o main.o -o main
```
์ ๊ฐ์ด ์ ๋์ต๋๋ค.
`CC` ์ `CXXFLAGS` ๋ Makefile ์์ ์์ฃผ ์ฌ์ฉ๋๋ ๋ณ์๋ก ๋ณดํต `CC` ์๋ ์ฌ์ฉํ๋ ์ปดํ์ผ๋ฌ ์ด๋ฆ์, `CXXFLAGS` ์๋ ์ปดํ์ผ๋ฌ ์ต์
์ ์ฃผ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ์ฐธ๊ณ ๋ก ์ด๋ C++ ์ ๊ฒฝ์ฐ ์ด๊ณ , C ์ ๊ฒฝ์ฐ CFLAGS ์ ์ต์
์ ์ค๋๋ค.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ `g++` ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์ต์
์ผ๋ก๋ `Wall` (๋ชจ๋ ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฅผ ํ์) ๊ณผ `O2` (์ต์ ํ ๋ ๋ฒจ 2) ๋ฅผ ์ฃผ์์ต๋๋ค.
Makefile ์ ํํ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ์ผ๋ก ๋น๋ ๊ด๋ จ๋ ํ์ผ๋ค (.o ํ์ผ๋ค)์ ๋ชจ๋ ์ ๊ฑฐํ๋ ๋ช
๋ น์ ๋ฃ์ต๋๋ค.
```
clean:
rm -f $(OBJS) main
```
์ค์ ๋ก `make clean` ์ ์คํํด๋ณด๋ฉด ์์ฑ๋ ๋ชจ๋ ๋ชฉ์ ํ์ผ๊ณผ `main` ์ ์ง์๋ฒ๋ฆผ์ ์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ, ๋ง์ฝ์ ์ค์ ๋ก `clean` ์ด๋ผ๋ ํ์ผ์ด ๋๋ ํ ๋ฆฌ์ ์์ฑ๋๋ค๋ฉด ์ด๋จ๊น์? ์ฐ๋ฆฌ๊ฐ `make clean` ์ ํ๊ฒ ๋๋ฉด, make ๋ clean ์ ํ์ ํ์ผ๋ค์ด ์๋๋ฐ, clean ํ์ผ์ด ์์ผ๋๊น clean ํ์ผ์ ํญ์ ์ต์ ์ด๋ค? recipe ๋ฅผ ์คํ ์ํด๋ ๋๊ฒ ๋ค\! ํ๋ฉด์ ๊ทธ๋ฅ `make clean` ๋ช
๋ น์ ๋ฌด์ํด๋ฒ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
```
$ ls clean
clean
$ make clean
make: 'clean' is up to date.
```
์ค์ ๋ก ๋๋ ํ ๋ฆฌ์ `clean` ์ด๋ผ๋ ํ์ผ์ ๋ง๋ค์ด๋๊ณ ์คํํด๋ณด๋ฉด ์์ ๊ฐ์ด ์ด๋ฏธ `clean` ์ ์ต์ ์ด๋ผ๋ฉฐ `recipe` ์คํ์ ๊ฑฐ๋ถํฉ๋๋ค.
์ด์ ๊ฐ์ ์ํฉ์ ๋ง๊ธฐ ์ํด์๋ `clean` ์ `PHONY` ๋ผ๊ณ ๋ฑ๋กํ๋ฉด ๋ฉ๋๋ค.
์๋์ ๊ฐ์ด ๋ง์ด์ง์.
```
.PHONY: clean
clean:
rm -f $(OBJS) main
```
์ด์ `make clean` ์ ํ๊ฒ ๋๋ฉด `clean` ํ์ผ์ ์ ๋ฌด์ ์๊ด ์์ด ์ธ์ ๋ ํด๋น ํ๊ฒ์ ๋ช
๋ น์ ์คํํ๊ฒ ๋ฉ๋๋ค.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ํ์ผ์ด 3 ๊ฐ ๋ฐ์ ์์ด์ ๋คํ์ด์์ง๋ง ์ค์ ํ๋ก์ ํธ์๋ ์์ญ~ ์๋ฐฑ ๊ฐ์ ํ์ผ๋ค์ ๋ค๋ฃจ๊ฒ ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฐ๋ฐ, ๊ฐ๊ฐ์ ํ์ผ๋ค์ ๋ํด์ ๋ชจ๋ ๋น๋ ๋ฐฉ์์ ๋ช
์ํด์ค๋ค๋ฉด Makefile ์ ํฌ๊ธฐ๊ฐ ์์ฒญ ์ปค์ง๊ฒ ์ง์.
๋คํ์ด๋ Makefile ์์๋ ํจํด ๋งค์นญ์ ํตํด์ ํน์ ์กฐ๊ฑด์ ๋ถํฉํ๋ ํ์ผ๋ค์ ๋ํด์ ๊ฐ๋จํ๊ฒ `recipe` ๋ฅผ ์์ฑํ ์ ์๊ฒ ํด์ค๋๋ค.
```
foo.o : foo.h foo.cc
$(CC) $(CXXFLAGS) -c foo.cc
bar.o : bar.h bar.cc
$(CC) $(CXXFLAGS) -c bar.cc
```
์ผ๋จ ๋จผ์ ๋น์ทํ๊ฒ ์๊ธด ์ ๋ ๋ช
๋ น๋ค์ ์ด๋ป๊ฒ ํ๋ฉด ํ๋๋ก ๊ฐ๋จํ๊ฒ ๋ํ๋ผ ์ ์๋์ง ๋ณด๊ฒ ์ต๋๋ค.
```
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
```
๋จผ์ `%.o` ๋ ์์ผ๋์นด๋๋ก ๋ฐ์ง๋ฉด ๋ง์น `*.o` ์ ๊ฐ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ฆ, `.o` ๋ก ๋๋๋ ํ์ผ ์ด๋ฆ๋ค์ด ํ๊ฒ์ด ๋ ์ ์๊ฒ ์ง์. ์๋ฅผ ๋ค์ด์ `foo.o` ๊ฐ ํ๊ฒ์ด๋ผ๋ฉด % ์๋ `foo` ๊ฐ ๋ค์ด๊ฐ ๊ฒ์ด๊ณ `bar.o` ์ ๊ฒฝ์ฐ % ์๋ `bar` ๊ฐ ๋ค์ด๊ฐ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ ์๋ฅผ ๋ค์ด `foo.o` ๊ฐ ํ๊ฒ์ผ ๊ฒฝ์ฐ
```
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c $<
```
๊ฐ ๋ฉ๋๋ค. ์ฐธ๊ณ ๋ก ํจํด์ ํ๊ฒ๊ณผ `prerequisite` ๋ถ๋ถ์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค. `recipe` ๋ถ๋ถ์์๋ ํจํด์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ปดํ์ผ๋ฌ์ `foo.cc` ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด์๋ Makefile ์ ์๋ ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
`$<` ์ ๊ฒฝ์ฐ `prerequisite` ์์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ์ด๋ฆ์ ๋์๋์ด ์๋ ๋ณ์ ์
๋๋ค. ์ ๊ฒฝ์ฐ `foo.cc` ๊ฐ ๋๊ฒ ์ง์. ๋ฐ๋ผ์ ์ ๋ช
๋ น์ด๋ ๊ฒฐ๊ณผ์ ์ผ๋ก
```
foo.o: foo.cc foo.h
$(CC) $(CXXFLAGS) -c foo.cc
```
๊ฐ ๋์ด์ ์ด์ ์ ๋ช
๋ น์ด์ ๋์ผํ๊ฒ ๋ง๋ค์ด๋
๋๋ค.
Makefile ์์ ์ ๊ณตํ๋ ์๋ ๋ณ์๋ก๋ ๊ทธ ์ธ์๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด `$@`, `$<`, `$^` ๋ฑ๋ฑ์ด ์์ต๋๋ค.

- `$@` : ํ๊ฒ ์ด๋ฆ์ ๋์๋ฉ๋๋ค.
- `$<` : ์์กด ํ์ผ ๋ชฉ๋ก์ ์ฒซ ๋ฒ์งธ ํ์ผ์ ๋์๋ฉ๋๋ค.
- `$^` : ์์กด ํ์ผ ๋ชฉ๋ก ์ ์ฒด์ ๋์๋ฉ๋๋ค.
- `$?` : ํ๊ฒ ๋ณด๋ค ์ต์ ์ธ ์์กด ํ์ผ๋ค์ ๋์๋ฉ๋๋ค.
- `$+` : `$^` ์ ๋น์ทํ์ง๋ง, ์ค๋ณต๋ ํ์ผ ์ด๋ฆ๋ค ๊น์ง ๋ชจ๋ ํฌํจํฉ๋๋ค.
ํ์ง๋ง ์ ์ํ๊ฒ๋ ์ ํจํด์ผ๋ก๋
```
main.o : main.cc foo.h bar.h
$(CC) $(CXXFLAGS) -c main.cc
```
๋ฅผ ํํํ๊ธฐ์๋ ๋ถ์กฑํฉ๋๋ค. ์๋ํ๋ฉด ์์กด ํ์ผ ๋ชฉ๋ก์ `main.h` ๊ฐ ์๊ณ `foo.h` ์ `bar.h` ๊ฐ ์๊ธฐ ๋๋ฌธ์ด์ฃ . ์ฌ์ค ๊ณฐ๊ณฐํ ์๊ฐํด๋ณด๋ฉด ์ด ์์กดํ์ผ ๋ชฉ๋ก์๋ ๋ ํด๋น ์์ค ํ์ผ์ด ์ด๋ ํ ํค๋ํ์ผ์ ํฌํจํ๋์ ๊ฒฐ์ ๋์ด ์์ต๋๋ค. `main.cc` ๊ฐ `foo.h` ์ `bar.h` ๋ฅผ `include` ํ๊ณ ์๊ธฐ ๋๋ฌธ์ `main.o` ์ `prerequisite` ๋ก `main.cc` ์ธ์๋ `foo.h` ์ `bar.h` ๊ฐ ๋ค์ด๊ฐ ์๋ ๊ฒ์
๋๋ค.
๋ฌผ๋ก ๋งค๋ฒ ์ด๋ ๊ฒ ์ผ์ผํ ์ถ๊ฐํ ์ ์๊ฒ ์ง๋ง, ์์ค ํ์ผ์ ํค๋ ํ์ผ์ ์ถ๊ฐํ ๋ ๋ง๋ค Makefile ์ ๋ฐ๊ฟ ์๋ ์๋ ๋
ธ๋ฆ์ด๋๊น์. ํ์ง๋ง ๋คํ์ด๋ ์ปดํ์ผ๋ฌ์ ๋์์ ๋ฐ์์ ์์กดํ์ผ ๋ชฉ๋ก ๋ถ๋ถ์ ์์ฑํ ์ ์์ต๋๋ค.
์ปดํ์ผ ์์ `-MD` ์ต์
์ ์ถ๊ฐํด์ ์ปดํ์ผ ํด๋ด
์๋ค.
```
$ g++ -c -MD main.cc
```
๊ทธ๋ ๋ค๋ฉด `main.d` ๋ผ๋ ํ์ผ์ ์์ฑํฉ๋๋ค. ํ์ผ ๋ด์ฉ์ ์ดํด๋ณด๋ฉด;
```
$ cat main.d
main.o: main.cc /usr/include/stdc-predef.h foo.h bar.h
```
๋๋๊ฒ๋ ๋ง์น Makefile ์ `target: prerequisite` ์ธ๊ฒ ๊ฐ์ ๋ถ๋ถ์ ์์ฑํ์์ต๋๋ค. ๊ทธ๋ ์ต๋๋ค. ์ปดํ์ผ ์์ `-MD` ์ต์
์ ์ถ๊ฐํด์ฃผ๋ฉด, ๋ชฉ์ ํ์ผ ๋ง๊ณ ๋ ์ปดํ์ผ ํ ์์คํ์ผ์ ํ๊ฒ์ผ๋ก ํ๋ ์์กดํ์ผ ๋ชฉ๋ก์ ๋ด์ ํ์ผ์ ์์ฑํด์ค๋๋ค.
์ฐธ๊ณ ๋ก `main.cc, foo.h, bar.h` ๊น์ง๋ ์ดํด๊ฐ ๊ฐ๋๋ฐ ์ ์๋ฑ๋ง์ `/usr/include/stdc-predef.h` ์ด ๋ค์ด๊ฐ ์๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ, ์ด ํ์ผ์ ์ปดํ์ผ๋ฌ๊ฐ ์ปดํ์ผ ํ ๋ ์๋ฌต์ ์ผ๋ก ์ฐธ์กฐํ๋ ํค๋ ํ์ผ์ด๋ผ๊ณ ๋ณด์๋ฉด ๋ฉ๋๋ค. ์๋ฌดํผ ์ด ๋๋ฌธ์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ์์กด ํ์ผ ๋ชฉ๋ก์๋ ํฌํจ๋์์ต๋๋ค.
๋ฌธ์ ๋ ์ด๋ ๊ฒ ์์ฑ๋ `main.d` ๋ฅผ ์ด๋ป๊ฒ ์ฐ๋ฆฌ์ Makefile ์ ํฌํจํ ์ ์๋ ์
๋๋ค. ์ด๋ ์๊ฐ๋ณด๋ค ๊ฐ๋จํฉ๋๋ค.
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
include main.d
```
์ `include main.d` ๋ `main.d` ๋ผ๋ ํ์ผ์ ๋ด์ฉ์ Makefile ์ ํฌํจํ๋ผ๋ ์๋ฏธ ์
๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์ธ๋ฆฌ
```
%.o: %.cc %.h
$(CC) $(CXXFLAGS) -c $<
```
๋ถ๋ถ์ ์์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ `.d` ํ์ผ๋ก ๋์ฒดํ ์๋ ์์๊น์? ๋ฌผ๋ก ์์ต๋๋ค\!
```
CC = g++
CXXFLAGS = -Wall -O2
OBJS = foo.o bar.o main.o
%.o: %.cc
$(CC) $(CXXFLAGS) -c $<
main : $(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o main
.PHONY: clean
clean:
rm -f $(OBJS) main
-include $(OBJS:.o=.d)
```
`$(OBJS:.o=.d)` ๋ถ๋ถ์ `OBJS` ์์ `.o` ๋ก ๋๋๋ ๋ถ๋ถ์ `.d` ๋ก ๋ชจ๋ ๋์ฒดํ๋ผ๋ ์๋ฏธ ์
๋๋ค. ์ฆ, ํด๋น ๋ถ๋ถ์ `-include foo.d bar.d main.d` ๊ฐ ๋๊ฒ ์ฃ . ์ฐธ๊ณ ๋ก `foo.d` ๋ `bar.d` ๊ฐ `include` ๋ ๋ ์ด๋ฏธ ์๋ `%.o: %.cc` ๋ ์ด๋ป๊ฒ ๋๋๊ณ ๋ฌผ์ ์ ์๋๋ฐ ๊ฐ์ ํ๊ฒ์ ๋ํด์ ์ฌ๋ฌ ์์กด ํ์ผ ๋ชฉ๋ก๋ค์ด ์ ํด์ ธ ์๋ค๋ฉด ์ด๋ make ์ ์ํด ๋ชจ๋ ํ๋๋ก ํฉ์ณ์ง๋๋ค. ๋ฐ๋ผ์ ํฌ๊ฒ ๊ฑฑ์ ํ์ค ํ์๋ ์์ต๋๋ค.
๋ง๋ถ์ฌ `include` ์์ `-include` ๋ก ๋ฐ๊พธ์๋๋ฐ, `-include` ์ ๊ฒฝ์ฐ ํฌํจํ๊ณ ์ ํ๋ ํ์ผ์ด ์กด์ฌํ์ง ์์๋ make ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ์ง ์์ต๋๋ค.
๋งจ ์ฒ์์ make ๋ฅผ ํ ๋์๋ `.d` ํ์ผ๋ค์ด ์ ๋๋ก ์์ฑ๋์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ `include` ๊ฐ ์๋ฌด๋ฐ `.d` ํ์ผ๋ค์ ํฌํจํ์ง ์์ต๋๋ค. ๋ฌผ๋ก ํฌ๊ฒ ๋ฌธ์ ์๋ ๊ฒ์ด ์ด์ฐจํผ `.o` ํ์ผ๋ค๋ make ๊ฐ `%.o: %.cc` ๋ถ๋ถ์ ๋ช
๋ น์ด๋ค์ ์คํํ๋ฉด์ ์ปดํ์ผ์ ํ๊ธฐ ๋๋ฌธ์ ๋ค์์ make ๋ฅผ ํ๊ฒ ๋ ๋์๋ ์ ๋๋ก `.d` ํ์ผ๋ค์ ๋ก๋ํ ์ ์๊ฒ ์ฃ .
์๋์ ๊ฐ์ด ๊ฐ๋จํ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์๊ฐํด๋ด
์๋ค.
```
$ tree
.
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ bar.h
โโโ foo.cc
โโโ foo.h
โโโ main.cc
```
๋ชจ๋ ์์ค ํ์ผ์ `src` ์ ๋ค์ด๊ฐ๊ณ ๋น๋ ํ์ผ๋ค์ `obj` ์ ๋ค์ด๊ฐ๋๋ค. ์ข
์ข
ํค๋ ํ์ผ๋ค์ ๋ฐ๋ก `include` ์ ๋นผ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ์ ๋ ๊ตณ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ๋ณ๋ก ์ ํธํ์ง ์์ต๋๋ค. (๊ตณ์ด ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ๋ฃ์ ์ด์ ๊ฐ ๋ญ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.)
์๋ฌดํผ ์ด์ ๊ฐ์ ๊ตฌ์กฐ์์ ํญ์ ์ฌ์ฉํ ์ ์๋ ๋ง๋ฅ Makefile ์ ์๋์ ๊ฐ์ต๋๋ค.
์ฃผ์ ์ฌํญ
๋ณต์ฌํ ํ์ `$(CC)` ์ `rm` ์์ ์คํ์ด์ค ๋ ๊ฐ๋ฅผ ๊ผญ TAB ์ผ๋ก ์นํํด์ฃผ์ธ์! ์ ๊ทธ๋ฌ๋ฉด make ๊ฐ ์ฝ์ง ๋ชปํฉ๋๋ค.
```
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
```
์ถ๊ฐ๋ ๋ถ๋ถ๋ง ๊ฐ๋จํ ๋ถ์ฐ ์ค๋ช
์ ํ์๋ฉด
```
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
```
๋จผ์ `SRC_DIR` ์์ ์๋ ๋ชจ๋ ํ์ผ๋ค์ `SRCS` ๋ก ์ฝ์ด๋ค์ด๋ ค ํ๊ณ ์์ต๋๋ค. `wildcard` ๋ ํจ์๋ก ํด๋น ์กฐ๊ฑด์ ๋ง๋ ํ์ผ๋ค์ ๋ฝ์๋ด๊ฒ ๋๋๋ฐ, ์๋ฅผ ๋ค์ด์ `foo.cc, bar.cc, main.cc` ๊ฐ ์์ ๊ฒฝ์ฐ `$(wildcard $(SRC_DIR)/*.cc)` ์ ์คํ ๊ฒฐ๊ณผ๋ `./src/foo.cc ./src/bar.cc ./src/main.cc` ๊ฐ ๋ ๊ฒ์
๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ `foo.cc bar.cc main.cc` ๋ก ๊น๋ํ๊ฒ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ด๊ธฐ ์ํด `notdir` ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. `notdir` ์ ์์ ์ค๋ ๊ฒฝ๋ก๋ฅผ ๋ ๋ ค๋ฒ๋ฆฌ๊ณ ํ์ผ ์ด๋ฆ๋ง ๊น๋ํ๊ฒ ์ถ์ถํด์ค๋๋ค.
```
OBJS = $(SRCS:.cc=.o)
```
๋ฐ๋ผ์ ์ด ๋ถ๋ถ์์ `OBJS` ๋ `foo.o bar.o main.o` ๊ฐ ๋ ๊ฒ์
๋๋ค.
์ด์ ์ด `OBJS` ๋ฅผ ๋ฐํ์ผ๋ก ์ค์ `.o` ํ์ผ๋ค์ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ด๋ด๊ณ ์ถ์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ด๋ค ํ์ผ ์ด๋ฆ ์์ `$(OBJ_DIR)/` ์ ๋ถ์ฌ์ค์ผ ๊ฒ ์ง์. ์ด๋ฅผ ์ํด์ `patsubst` ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
```
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
```
`patsubst` ํจ์๋ `$(patsubst ํจํด,์นํ ํ ํํ,๋ณ์)` ์ ๊ฐ์ ๊ผด๋ก ์ฌ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๊ฒฝ์ฐ `$(OBJS)` ์์ ์๋ ๋ชจ๋ `%.o` ํจํด์ `$(OBJ_DIR)/%.o` ๋ก ์นํํด๋ผ ๋ผ๋ ์๋ฏธ๊ฐ ๋ ๊ฒ์
๋๋ค. ์๋ฌดํผ ๋๋ถ์ `OBJECTS` ์๋ ์ด์ .`/obj/foo.o ./obj/bar.o ./obj/main.o` ๊ฐ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ ๋ค์ ๋ด์ฉ์ ์์ ๊ธ์ ์ ๋ฐ๋ผ ์ค์ ๋ถ๋ค์ด๋ผ๋ฉด ์ ์ดํด ํ์ค ์ ์์ผ๋ฆฌ๋ผ ๋ฏฟ์ต๋๋ค.
๋ง์ฝ์ ํค๋ ํ์ผ๋ค๋ง ๋ฐ๋ก ๋ฝ๋๋ค๋ฉด ์๋์ ๊ฐ์ ํ์ผ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ์ฃ .
```
$ tree
.
โโโ include
โย ย โโโ bar.h
โย ย โโโ foo.h
โโโ Makefile
โโโ obj
โโโ src
โโโ bar.cc
โโโ foo.cc
โโโ main.cc
```
์ด ๊ฒฝ์ฐ Makefile ์ ์๋์ ๊ฐ์ด ๊ฐ๋จํ ์์ ํ๋ฉด ๋ฉ๋๋ค.
```
CC = g++
# C++ ์ปดํ์ผ๋ฌ ์ต์
CXXFLAGS = -Wall -O2
# ๋ง์ปค ์ต์
LDFLAGS =
# ํค๋ํ์ผ ๊ฒฝ๋ก
INCLUDE = -Iinclude/
# ์์ค ํ์ผ ๋๋ ํ ๋ฆฌ
SRC_DIR = ./src
# ์ค๋ธ์ ํธ ํ์ผ ๋๋ ํ ๋ฆฌ
OBJ_DIR = ./obj
# ์์ฑํ๊ณ ์ ํ๋ ์คํ ํ์ผ ์ด๋ฆ
TARGET = main
# Make ํ ์์ค ํ์ผ๋ค
# wildcard ๋ก SRC_DIR ์์ *.cc ๋ก ๋ ํ์ผ๋ค ๋ชฉ๋ก์ ๋ฝ์๋ธ ๋ค์
# notdir ๋ก ํ์ผ ์ด๋ฆ๋ง ๋ฝ์๋ธ๋ค.
# (e.g SRCS ๋ foo.cc bar.cc main.cc ๊ฐ ๋๋ค.)
SRCS = $(notdir $(wildcard $(SRC_DIR)/*.cc))
OBJS = $(SRCS:.cc=.o)
DEPS = $(SRCS:.cc=.d)
# OBJS ์์ object ํ์ผ๋ค ์ด๋ฆ ์์ $(OBJ_DIR)/ ์ ๋ถ์ธ๋ค.
OBJECTS = $(patsubst %.o,$(OBJ_DIR)/%.o,$(OBJS))
DEPS = $(OBJECTS:.o=.d)
all: main
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
$(CC) $(CXXFLAGS) $(INCLUDE) -c $< -o $@ -MD $(LDFLAGS)
$(TARGET) : $(OBJECTS)
$(CC) $(CXXFLAGS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
.PHONY: clean all
clean:
rm -f $(OBJECTS) $(DEPS) $(TARGET)
-include $(DEPS)
```
์ฌ์ค ๊ธฐ์กด๊ณผ ๋ณ ์ฐจ์ด ์๊ณ ๊ทธ๋ฅ ์ปดํ์ผ๋ฌ ์ต์
์ `-Iinclude/` ๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋ฉ๋๋ค. ์ฌ๊ธฐ์ `include` ๋ ํค๋ํ์ผ ๊ฒฝ๋ก ์
๋๋ค.
ํ ๊ฐ์ง ํ์ผ๋ก ๊ทธ๋ฅ make ๋ฅผ ์คํํ๊ฒ ๋๋ฉด 1 ๊ฐ์ ์ฐ๋ ๋๋ง ์คํ๋์ด์ ์๋๊ฐ ๊ฝค๋ ๋๋ฆฝ๋๋ค. ํนํ GCC ๋ ์ปค๋์ ์ปดํ์ผ ํ ๊ฒฝ์ฐ ํ ๋ ์๊ฐ์ ๊ทธ๋ฅ ๊ฑธ๋ฆฌ์ง์. ๋ง์ผ ์ฌ๋ฌ๋ถ์ ์ปดํจํฐ๊ฐ ๋ฉํฐ ์ฝ์ด CPU ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด (์๋ง ๋๋ถ๋ถ ๊ทธ๋ด ๊ฒ์ด๋ผ ์๊ฐํฉ๋๋ค) make ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์ฐ๋ ๋์์ ๋๋ฆด ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ธ์๋ก `-j` ๋ค์ ๋ช ๊ฐ์ ์ฐ๋ ๋๋ฅผ ์ฌ์ฉํ ์ง ์ซ์๋ฅผ ์ ์ด์ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด์
```
$ make -j8
```
์ ํ๋ฉด make ๊ฐ 8 ๊ฐ์ ์ฐ๋ ๋์ ๋๋์ด์ ์คํ๋ฉ๋๋ค. ์๋ง make ์๋๊ฐ ์๋ฑํ๊ฒ ํฅ์๋๋ ๊ฒ์ ๋ณด์ค ์ ์์ ๊ฒ์
๋๋ค. ํต์์ ์ผ๋ก ์ฝ์ด ๊ฐ์ + 1 ๋งํผ์ ์ฐ๋ ๋๋ฅผ ์์ฑํด์ ๋๋ฆฌ๋ ๊ฒ์ด ๊ฐ์ฅ ์๋๊ฐ ๋น ๋ฆ
๋๋ค.
๋ง์ฝ์ ๋ด ์ปดํจํฐ์ ์ฝ์ด ๊ฐ์๋ฅผ ๋ชจ๋ฅธ๋ค๋ฉด ๋ฆฌ๋
์ค ํฐ๋ฏธ๋์ ๊ฒฝ์ฐ
```
$ make -j$(nproc)
```
์ผ๋ก ํ๋ฉด `$(nproc)` ์ด ์์์ ๋ด ์ปดํจํฐ์ ํ์ฌ ์ฝ์ด ๊ฐ์๋ก ์นํ๋ฉ๋๋ค.
๊ฐ์ข๋ฅผ ๋ณด๋ค๊ฐ ์กฐ๊ธ์ด๋ผ๋ ๊ถ๊ธํ ๊ฒ์ด๋ ์ด์ํ ์ ์ด ์๋ค๋ฉด ๊ผญ ๋๊ธ์ ๋จ๊ฒจ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค. ๊ทธ ์ธ์๋ ๊ฐ์ข์ ๊ด๋ จ๋ ๊ฒ์ด๋ผ๋ฉด ์ด๋ ํ ๊ฒ๋ ์ง๋ฌธํด ์ฃผ์
๋ ์๊ด ์์ต๋๋ค. ์๊ฐํด ๋ณผ ๋ฌธ์ ๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ๋๊ธ์ ๋ฌ์์ฃผ์ธ์.
ํ์ฌ ์ฌ๋ฌ๋ถ์ด ๋ณด์ ๊ฐ์ข๋ \<์น์ด๋จน๋ C++ - \<19 - 1. Make ์ฌ์ฉ ๊ฐ์ด๋ (Makefile ๋ง๋ค๊ธฐ)\>\> ์
๋๋ค. ์ด๋ฒ ๊ฐ์ข์ ๋ชจ๋ ์์ ๋ค์ ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ ์งค ์์ค๊น์ง ๊ฐ์ข๋ฅผ ์ฝ์ด ๋ณด์๊ธฐ ์ ๊น์ง ๋ค์ ๊ฐ์ข๋ก ๋์ด๊ฐ์ง ๋ง์์ฃผ์ธ์ |
| Shard | 138 (laksa) |
| Root Hash | 9372826391188590538 |
| Unparsed URL | com,modoocode!/311 s443 |