vimer linux kernel 爱好者

makefile 模板

2021-06-18

Refer to https://makefiletutorial.com/

易于理解

# Thanks to Job Vranish (https://spin.atomicobject.com/2016/08/26/makefile-c-projects/)
TARGET_EXEC := EswinE2r

BUILD_DIR := ./build
SRC_DIRS := ./src
INC_DIRS := ./include


CC	:= ../../../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
CXX := ../../../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
AR	:= ../../../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-ar
STRIP := ../../../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-strip


# Find all the C and C++ files we want to compile
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c)

# String substitution for every C/C++ file.
# As an example, hello.cpp turns into ./build/hello.cpp.o
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)

# String substitution (suffix version without %).
# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d
DEPS := $(OBJS:.o=.d)

# Every folder in ./src will need to be passed to GCC so that it can find header files
INC_DIRS := $(shell find $(INC_DIRS) -type d)
# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

# The -MMD and -MP flags together generate Makefiles for us!
# These files will have .d instead of .o as the output.
CPPFLAGS := $(INC_FLAGS) -MMD -MP

# The final build step.
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
	$(CC) $(OBJS) -o $@ $(LDFLAGS)

# Build step for C source
$(BUILD_DIR)/%.c.o: %.c
	mkdir -p $(dir $@)
	$(CC)  $(CFLAGS) $(INC_FLAGS) -c $< -o $@

# Build step for C++ source
#$(BUILD_DIR)/%.cpp.o: %.cpp
#	mkdir -p $(dir $@)
#	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

.PHONY: clean
clean:
	rm -r $(BUILD_DIR)

# Include the .d makefiles. The - at the front suppresses the errors of missing
# Makefiles. Initially, all the .d files will be missing, and we don't want those
# errors to show up.
-include $(DEPS)

复杂

还有一种模板,但是我不太清楚里面的用法,先看下代码:

#include ../../common.mk

EXECUTABLE = test
OBJ_BASE_DIR    := objs

HOST_ARCH       := $(shell uname -m)
TARGET_ARCH     := $(HOST_ARCH)
OBJDIR          := $(OBJ_BASE_DIR)/$(TARGET_ARCH)/release

SOURCEDIR  := src
SRCS       := $(wildcard $(SOURCEDIR)/*.c)
OBJS       := $(patsubst $(SOURCEDIR)/%c, $(OBJDIR)/%o, $(SRCS))

INCPATH         := -Iinclude

ifeq ($(HOST_ARCH), x86_64)
        ifeq ($(ARCH), )
        else ifneq ($(findstring $(ARCH), aarch64 arm64),)
                TARGET_ARCH := aarch64
                CROSS_CC    := 1
                CC          := ../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
                CXX         := ../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
                AR          := ../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-ar
                STRIP       := ../../../tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-strip
        else ifneq ($(ARCH), $(HOST_ARCH))
$(error $(ARCH) is not supported on $(HOST_ARCH) )
        endif
else
        ifeq ($(ARCH), )
        else ifneq ($(ARCH), $(HOST_ARCH))
                ifneq ($(ARCH)_$(HOST_ARCH), arm64_aarch64)
$(error $(ARCH) is not supported on $(HOST_ARCH) )
                endif
        endif
endif

.PHONY : all dir
all: dir $(EXECUTABLE)

dir:
        @mkdir -p $(OBJDIR)

$(EXECUTABLE): $(OBJS)
        $(CC) $^ -o $@
        @echo ++++++ $(EXECUTABLE) is generated successfully!!! ++++++

$(OBJS): $(OBJDIR)/%.o: $(SOURCEDIR)/%.c
        $(CC) $(CFLAGS) -o $@ -c $< $(INCPATH)

$(OBJDIR)/%.d : %.c
        @set -e; rm -rf $@; mkdir -p $(OBJDIR); \
        $(CC) -MM $(CFLAGS) $(INCPATH) $< > $@.$$$$; \
        sed 's,\($*\)\.o[ :]*,\$(OBJDIR)\/\1.o $@ : ,g' < $@.$$$$ > $@; \
        rm -f $@.$$$$

-include $(OBJS:.o=.d)

.PHONY : clean
clean:
        $(RM) $(OBJ_BASE_DIR)
        $(RM) $(EXECUTABLE)

其中,我不太明白的是 $(OBJDIR)/%.d: %.c这句话是什么意思。还有一点是,我们的连接的有文件 -Iinclude或者 -Llibxx,这个连接标志一般是放在定义的位置,我们不在规则里去显性的使用这个标志,,,一般情况下。

简单

CC       := gcc
RM       := rm -rf
OBJDIR   := objs

CFLAGS   := -Wall
EDKLIB   := xxsdk

TARGET_ARCH := $(shell uname -m)

EXECUTABLE = rtmp_push

SRCS     := rtmp_push.c
OBJS     := $(patsubst %c, $(OBJDIR)/%o, $(SRCS))
INCPATH  := -I/usr/include/eswin
LIBPATH  := /usr/lib/eswin/${TARGET_ARCH}
LIB      := -L$(LIBPATH) -Wl,-rpath=$(LIBPATH) -l$(EDKLIB)

.PHONY : all dir
all: dir $(EXECUTABLE)

dir:
        @mkdir -p $(OBJDIR)

$(EXECUTABLE): $(OBJS)
        $(CC) $^ -o $@ $(LIB)
        @echo ++++++ $(EXECUTABLE) is generated successfully!!! ++++++

$(OBJS): $(OBJDIR)/%.o: %.c
        $(CC) $(CFLAGS) -o $@ -c $< $(INCPATH)


.PHONY : clean
clean:
        $(RM) $(OBJDIR)
        $(RM) $(EXECUTABLE)


Comments

Content