수색…


다른 원본 폴더에서 다른 대상 폴더로 작성

이 Makefile의 주요 기능 :

  • 지정된 폴더에서 C 소스 자동 감지
  • 여러 원본 폴더
  • 객체 및 종속 파일에 대한 여러 해당 대상 폴더
  • 각 대상 폴더에 대한 자동 규칙 생성
  • 존재하지 않는 대상 폴더 만들기
  • gcc 사용한 종속성 관리 : 필요한 것만 빌드하기
  • Unix 및 DOS 시스템에서 작동합니다.
  • GNU Make 글

이 Makefile은 다음과 같은 구조의 프로젝트를 빌드하는 데 사용할 수 있습니다.

\---Project
    +---Sources
    |   +---Folder0
    |   |       main.c
    |   |       
    |   +---Folder1
    |   |       file1_1.c
    |   |       file1_1.h
    |   |       
    |   \---Folder2
    |           file2_1.c
    |           file2_1.h
    |           file2_2.c
    |           file2_2.h
    \---Build
        |   Makefile
        |   myApp.exe
        |   
        +---Folder0
        |       main.d
        |       main.o
        |       
        +---Folder1
        |       file1_1.d
        |       file1_1.o
        |       
        \---Folder2
                file2_1.d
                file2_1.o
                file2_2.d
                file2_2.o

Makefile

# Set project directory one level above of Makefile directory. $(CURDIR) is a GNU make variable containing the path to the current working directory
PROJDIR := $(realpath $(CURDIR)/..)
SOURCEDIR := $(PROJDIR)/Sources
BUILDDIR := $(PROJDIR)/Build

# Name of the final executable
TARGET = myApp.exe

# Decide whether the commands will be shwon or not
VERBOSE = TRUE

# Create the list of directories
DIRS = Folder0 Folder1 Folder2
SOURCEDIRS = $(foreach dir, $(DIRS), $(addprefix $(SOURCEDIR)/, $(dir)))
TARGETDIRS = $(foreach dir, $(DIRS), $(addprefix $(BUILDDIR)/, $(dir)))

# Generate the GCC includes parameters by adding -I before each source folder
INCLUDES = $(foreach dir, $(SOURCEDIRS), $(addprefix -I, $(dir)))

# Add this list to VPATH, the place make will look for the source files
VPATH = $(SOURCEDIRS)

# Create a list of *.c sources in DIRS
SOURCES = $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.c))

# Define objects for all sources
OBJS := $(subst $(SOURCEDIR),$(BUILDDIR),$(SOURCES:.c=.o))

# Define dependencies files for all objects
DEPS = $(OBJS:.o=.d)

# Name the compiler
CC = gcc

# OS specific part
ifeq ($(OS),Windows_NT)
    RM = del /F /Q 
    RMDIR = -RMDIR /S /Q
    MKDIR = -mkdir
    ERRIGNORE = 2>NUL || true
    SEP=\\
else
    RM = rm -rf 
    RMDIR = rm -rf 
    MKDIR = mkdir -p
    ERRIGNORE = 2>/dev/null
    SEP=/
endif

# Remove space after separator
PSEP = $(strip $(SEP))

# Hide or not the calls depending of VERBOSE
ifeq ($(VERBOSE),TRUE)
    HIDE =  
else
    HIDE = @
endif

# Define the function that will generate each rule
define generateRules
$(1)/%.o: %.c
    @echo Building $$@
    $(HIDE)$(CC) -c $$(INCLUDES) -o $$(subst /,$$(PSEP),$$@) $$(subst /,$$(PSEP),$$<) -MMD
endef

.PHONY: all clean directories 

all: directories $(TARGET)

$(TARGET): $(OBJS)
    $(HIDE)echo Linking $@
    $(HIDE)$(CC) $(OBJS) -o $(TARGET)

# Include dependencies
-include $(DEPS)

# Generate rules
$(foreach targetdir, $(TARGETDIRS), $(eval $(call generateRules, $(targetdir))))

directories: 
    $(HIDE)$(MKDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE)

# Remove all objects, dependencies and executable files generated during the build
clean:
    $(HIDE)$(RMDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE)
    $(HIDE)$(RM) $(TARGET) $(ERRIGNORE)
    @echo Cleaning done ! 

이 Makefile을 사용하는 방법 이 Makefile을 프로젝트에 적용하려면 다음을 수행해야합니다.

  1. 타겟 이름과 일치하도록 TARGET 변수를 변경하십시오
  2. SOURCEDIR 및 BUILDDIR 에서 Sources 및 Build 폴더의 이름 변경
  3. Makefile 자체 또는 make 호출에서 Makefile의 자세한 정보 수준 변경
  4. DIRS 에있는 폴더 이름을 소스 및 빌드 폴더와 일치하도록 변경하십시오
  5. 필요한 경우 컴파일러와 플래그를 변경하십시오.

지핑 목록

GNU make

이 pairmap 함수는 세 개의 인수를 취합니다.

  1. 함수 이름
  2. 첫 번째 공백으로 구분 된 목록
  3. 두 번째 공백으로 구분 된 목록

목록의 각 압축 된 튜플에 대해 다음 인수를 사용하여 함수를 호출합니다.

  1. 첫 번째 목록의 튜플 요소
  2. 두 번째 목록의 튜플 요소

공백으로 구분 된 함수 확장 목록으로 확장됩니다.

list-rem = $(wordlist 2,$(words $1),$1)
pairmap = $(and $(strip $2),$(strip $3),$(call \
    $1,$(firstword $2),$(firstword $3)) $(call \
    pairmap,$1,$(call list-rem,$2),$(call list-rem,$3)))

예를 들면 다음과 같습니다.

LIST1 := foo bar baz
LIST2 := 1 2 3

func = $1-$2

all:
    @echo $(call pairmap,func,$(LIST1),$(LIST2))

.PHONY: all

foo-1 bar-2 baz-3 인쇄합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow