개발/개발 환경

[개발 환경] make, Makefile 기본 구조, 작성 방법

growing-dev 2023. 12. 1. 10:58
반응형

make와 Makefile은 개발할 때 많이 활용되는 빌드 도구 및 파일입니다. 기본적인 개념과 작성 방법에 대해서 알아보도록 하겠습니다.

 

 

make, Makefile 기본 구조, 작성 방법

 

 

 

 Make

 

make는 소프트웨어 개발에서 자동 빌드 및 빌드 관리 도구입니다. 주로 C, C++, Python 및 다른 프로그래밍 언어로 작성된 프로젝트에서 사용됩니다. make는 프로젝트의 소스 코드 파일을 컴파일하고 링크하는 작업을 자동화하며, 이를 통해 개발자는 코드 변경 사항을 효과적으로 관리하고 프로젝트를 더 효율적으로 관리할 수 있습니다.

make는 Makefile이라는 설정 파일을 사용하여 작동하며, 이 파일은 프로젝트의 구조와 의존성을 정의합니다. 각각의 작업 또는 "타깃"은 소스 파일, 명령어 및 의존성 목록을 기반으로 정의됩니다. make는 이러한 타깃을 실행하고 필요한 의존성을 자동으로 처리하여 정확한 빌드 프로세스를 생성합니다.

간단한 Makefile 예제를 통해 make의 작동 방식을 설명하겠습니다. 예제로 C++로 작성된 간단한 프로그램을 컴파일하는 Makefile을 만들어 보겠습니다.

 

 

 

 Makefile 예제

 

아래는 간단한 Makefile 예제이며 다음과 같은 구조로 작성되었습니다.

  • CC와 CFLAGS는 컴파일러와 컴파일러 플래그를 정의합니다.
  • my_program 타겟은 main.o와 utils.o 파일에 의존합니다. 이 두 파일을 컴파일하고 이를 이용하여 my_program을 링크합니다.
  • main.o와 utils.o 타깃은 각각 main.cpp와 utils.cpp 파일에 의존합니다. 이 파일들을 컴파일하여 각각의 오브젝트 파일을 생성합니다.
  • clean 타겟은 중간 파일인 오브젝트 파일들과 실행 파일을 정리합니다.
# Makefile 예제

# 컴파일러 설정
CC = g++
CFLAGS = -Wall

# 타겟과 의존성 정의
my_program: main.o utils.o
    $(CC) $(CFLAGS) -o my_program main.o utils.o

main.o: main.cpp
    $(CC) $(CFLAGS) -c main.cpp

utils.o: utils.cpp
    $(CC) $(CFLAGS) -c utils.cpp

# 정리 작업
clean:
    rm -f *.o my_program

 

 

 Makefile에 내장된 변수와 기호들

 

사실 위와 같은 예제는 간단한 예제이지만, 실제 여러 Makefile들을 보다 보면 이해하기 어려운 변수나 특수 기호들이 사용되기도 합니다. Makefile에는 내장된 변수와 특수 기호들이 있습니다. 이러한 변수와 기호들은 Makefile을 더 유연하게 만들고 빌드 프로세스를 효과적으로 제어하는 데 사용됩니다. 여기에 일반적으로 사용되는 몇 가지를 설명하겠습니다

변수는 앞서 설정했던 CC, CXX, CFLAGS, CXXFLAGS, LDFLAGS, LDLIBS와 같은 변수들이 내장되어 있습니다. 

일반적인 내용이고 꼭 사용하지 않아도 되긴합니다.

이것 말고 특수 기호들이 있는데 이것이 해석하기 조금 어려워서 이해가 좀 필요합니다. 

 

  • $@ (타깃 변수): 현재의 타깃(빌드하고자 하는 대상)을 나타냅니다. 주로 빌드 규칙에서 사용됩니다. 예제에서 $@는 my_program을 나타냅니다.
my_program: main.o utils.o
    $(CC) $(CFLAGS) -o $@ main.o utils.o

 

  • $< (첫 번째 의존성 변수): 현재 타깃의 첫 번째 의존성(타겟을 만들기 위해 필요한 파일)을 나타냅니다. 예제에서 $<는 main.cpp를 나타냅니다.
main.o: main.cpp
    $(CC) $(CFLAGS) -c $<

 

  • $^ (모든 의존성 변수): 현재 타겟의 모든 의존성을 나타냅니다. 예제에서 $^는 main.o utils.o를 나타냅니다
my_program: main.o utils.o
    $(CC) $(CFLAGS) -o $@ $^

 

  • $? (수정된 의존성 변수): 현재 타깃보다 최신인 의존성을 나타냅니다. 위 예제에서 $? 는 최신인 파일을 나타냅니다.
my_program: main.o utils.o
    $(CC) $(CFLAGS) -o $@ $?

 

  • $* (와일드카드로 일치한 부분): 규칙의 와일드카드와 일치하는 부분을 나타냅니다. 예제에서 $*는 룰이 적용된 파일명의 기본 부분을 나타냅니다.
%.o: %.cpp
    $(CC) $(CFLAGS) -c $<

 

이 외에도 다양한 기호가 있으며, Makefile을 작성할 때 특정한 상황에 맞게 활용할 수 있습니다. Makefile은 자유로운 표현력을 갖고 있어서 다양한 빌드 프로세스를 자동화하기에 유용합니다.

 

 

 

 결론

 

오늘은 Makefile에 대해서 알아보았습니다. 복잡한 빌드 시스템에서 기존 Makefile을 분석하는 것은 생각보다 쉽지 않은 것 같습니다. 그래서 CMake라는 유용한 도구가 점점 더 많이 사용되는 것 같습니다.

반응형