【问题标题】:Makefile based on sub-directories基于子目录的 Makefile
【发布时间】:2018-03-13 22:13:31
【问题描述】:

我有一个 C 项目程序,我想用 makefile 编译和管理:

./include:标头所在的位置

a.h , b.h , c.h

./obj:对象的存放位置

-

./src:源文件所在的位置

main.c、a.c、b.c、c.c

如何创建 makefile 来创建 executable test ,并将目标文件放入 obj 文件夹?

【问题讨论】:

标签: c makefile


【解决方案1】:

您可以使用我为简单项目制作的这个模板。我不知道您使用的是哪个编译器,但您可以使用第一部分中的变量以及其他有用的配置对其进行配置:

#=============================================================================
# Project related variables
EXENAME           = test
FILEIDENTIFIER    = .c
COMPFLAGS         = -pedantic -Wall
COMPSTANDARD      = -std=c11
EXELINKS          = -lm
DBARGS            = -g

BUILDDIR          = build/
BINARY_OUTPUT_DIR = $(BUILDDIR)bin/
OBJDIR            = obj/
SOURCEDIRS        = src/
INCLUDEDIRS       = include/
LIBSDIRS          = /usr/lib/


#=============================================================================
# Commands variables
COMPILER          = gcc
LINKER            = ld -r

DISPLAY           = printf
MKDIR             = mkdir -p
RMDIR             = rmdir
RM                = rm -f


#=============================================================================
# Other
VOIDECHO          = > /dev/null 2>&1


#=============================================================================
# Semi-automatic variables
EXEFINALOBJ       = $(OBJDIR)$(EXENAME).o
EXEFINAL          = $(BINARY_OUTPUT_DIR)$(EXENAME)
INCLUDEARGS       = $(addprefix -I,$(INCLUDEDIRS))


#=============================================================================
# Automatic variables
SOURCES           = $(foreach sourcedir,$(SOURCEDIRS),$(wildcard $(sourcedir)**/*$(FILEIDENTIFIER)) $(wildcard $(sourcedir)*$(FILEIDENTIFIER)))
OBJECTS           = $(patsubst %$(FILEIDENTIFIER),%.o,$(foreach sourcedir,$(SOURCEDIRS),$(subst $(sourcedir),$(OBJDIR),$(wildcard $(sourcedir)**/*$(    FILEIDENTIFIER)) $(wildcard $(sourcedir)*$(FILEIDENTIFIER)))))
GENERATED_FILES   = $(OBJECTS) $(EXEFINALOBJ) $(EXEFINAL)
GENERATED_FOLDERS = $(OBJDIR) $(BINARY_OUTPUT_DIR) $(BUILDDIR)


#=============================================================================
# Special GNU make variables
VPATH             = $(SOURCEDIRS)


#=============================================================================
# Rules: Phony Targets
.PHONY: silent
silent:
    @make --silent $(EXEFINAL)

.PHONY: all
all: $(EXEFINAL)

.PHONY: debug
debug: COMPFLAGS += $(DBARGS)
debug: all

.PHONY: clean
clean:
    @$(DISPLAY) "\n-> Cleaning files...\n"
    @$(DISPLAY) " $(foreach file,$(GENERATED_FILES),$(if $(wildcard $(file)),- Removing file $(file)\n,\b))"
    @$(RM) $(GENERATED_FILES)
    @$(DISPLAY) "\n-> Cleaning folders...\n"
    @$(DISPLAY) " $(foreach folder,$(GENERATED_FOLDERS),$(if $(wildcard $(folder)),- Removing folder $(folder)\n,\b))"
    @$(RMDIR) $(GENERATED_FOLDERS) $(VOIDECHO) || true
    @$(DISPLAY) "\n"


#=============================================================================
# Rules: File Targets
$(EXEFINAL): $(EXEFINALOBJ)
    @$(DISPLAY) "\n - Building $@ from $^...   "
    @$(MKDIR) $(BINARY_OUTPUT_DIR)
    $(COMPILER) $(EXEFINALOBJ) -o $@ $(LIBARGS) $(EXELINKS)
    @$(DISPLAY) "Done"
    @$(DISPLAY) "\n\n"

$(EXEFINALOBJ): $(OBJECTS)
    @$(DISPLAY) "\n - Merging objects files into $@...   "
    $(LINKER) $(OBJECTS) -o $@
    @$(DISPLAY) "Done"

$(OBJDIR)%.o: %$(FILEIDENTIFIER)
    @$(DISPLAY) "\n - Building $@ from $^...   "
    @$(MKDIR) $(OBJDIR)
    $(COMPILER) $(COMPFLAGS) $(COMPSTANDARD) $(INCLUDEARGS) -c $^ -o $@
    @$(DISPLAY) "Done"

实际配置是针对 Linux 的,使用 gcc 和 ld。它支持源的子文件夹,并定义了 4 个目标:

  • 静默(默认):静默构建
  • 全部:详细构建
  • 调试:调试构建
  • clean:删除 makefile 生成的文件和文件夹

如果您想确切了解 Makefile 的工作原理,正如 MadScientist 所写,请查看位于 https://www.gnu.org/software/make/manual/html_node/Introduction.html 的 GNU make 手册

【讨论】:

    猜你喜欢
    • 2011-12-23
    • 1970-01-01
    • 2011-03-30
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    相关资源
    最近更新 更多