【问题标题】:Makefile for multiple executables with folders带有文件夹的多个可执行文件的 Makefile
【发布时间】:2014-05-25 11:29:20
【问题描述】:

如何在具有多个可执行文件的项目中创建简洁的 Makefile。 我尝试直接从 Makefile 文档中学习,但这对我来说太难了。 这是我的项目的一个例子。我发现了相关的问题,但它们只有一个可执行文件,我对编译所有不同的单元测试很感兴趣。我正在使用 gcc。

├── bin
├── include
│   ├── Action.h
│   ├── Consts.h
│   ├── Inventory.h
│   ├── Link.h
│   ├── Object.h
│   ├── Player.h
│   ├── Set.h
│   ├── Space.h
│   ├── World.h
│   └── WorldXMLReader.h
├── Mains
│   ├── Prototype.c
│   └── ... more source files with main()
├── obj
│   ├── Makefile
│   ├── Set.o
│   └── ... more object files
├── README.md
├── src
│   ├── Action.c
│   ├── Inventory.c
│   ├── Link.c
│   ├── Object.c
│   ├── Player.c
│   ├── Set.c
│   ├── Space.c
│   ├── World.c
│   └── WorldXMLReader.c
└── unitTests
    ├── UT_Inventory.c
    ├── UT_Link.c
    └── UT_Object.c

【问题讨论】:

    标签: gcc makefile


    【解决方案1】:

    大多数“制作”教程几乎没有涵盖您的情况:以通用方式处理不同的文件集。

    • 有些文件只是提供了一些实现(我们称这些“lib”文件,即使它们不会被编译成静态或动态库文件),
    • 其他文件包含main() 函数,每个文件都必须生成可执行二进制文件,并与前一个文件链接。

    我不会在这里给你一个完整的 makefile,但会尝试展示一个如何处理这种情况的全局方法。

    首先,定义不同的源文件夹和对象文件夹:

    SRC_DIR_LIB=src
    SRC_DIR_EXE=Mains    
    OBJ_DIR_LIB=obj/lib
    OBJ_DIR_EXE=obj/exe
    BIN_DIR=bin
    HEAD_DIR=include
    

    (这非常很有用,因为如果有一天树的组织发生变化,您只需在一个点上编辑更改。)

    而且,是的,您应该为目标文件设置单独的文件夹。

    然后,定义源文件集:

    SRC_FILES_LIB = $(wildcard $(SRC_DIR_LIB)/*.c)
    SRC_FILES_EXE = $(wildcard $(SRC_DIR_EXE)/*.c)
    HEAD_FILES    = $(wildcard $(HEAD_DIR)/*.h)
    

    让make生成一组目标文件:

    OBJ_FILES_LIB = $(patsubst $(SRC_DIR_LIB)/%.c,$(OBJ_DIR_LIB)/%.o,$(SRC_FILES_LIB))
    OBJ_FILES_EXE = $(patsubst $(SRC_DIR_EXE)/%.c,$(OBJ_DIR_EXE)/%.o,$(SRC_FILES_EXE))
    

    让make生成可执行文件集:

    EXEC_FILES  = $(patsubst $(SRC_DIR_EXE)/%.c,$(BIN_DIR)/%,$(SRC_FILES_EXE))
    

    这些将是你的最终目标,你告诉它:

    all: $(EXEC_FILES)
    

    为确保您拥有所有这些变量,您可以将show 目标添加到您的makefile:

    show:
        @echo "SRC_FILES_LIB=$(SRC_FILES_LIB)"
        @echo "SRC_FILES_EXE=$(SRC_FILES_EXE)"
         .. and so on for all the others
    

    尝试make show,并仔细检查。

    然后告诉make如何做真正的工作。您需要两个单独的编译目标:

    $(OBJ_DIR_EXE)/%.o: $(SRC_DIR_EXE)/%.c $(HEAD_FILES)
        $(CC) -o $@ -c $<  $(CFLAGS)
    $(OBJ_DIR_LIB)/%.o: $(SRC_DIR_LIB)/%.c $(HEAD_FILES)
        $(CC) -o $@ -c $<  $(CFLAGS)
    

    编辑:C程序使用$(CC),如果是C++,则使用$(CXX)

    以及使用subst()函数的程序链接步骤:

    $(BIN_DIR)/%: $(OBJ_DIR_EXE)/%.o
        $(CC) -o $@ -s $(subst $(BIN_DIR)/,$(OBJ_DIR_EXE)/,$@).o $(OBJ_FILES_LIB) $(LDFLAGS)
    

    决赛:

    • 在这里,只进行了基本的依赖关系检查:对 any 头文件的任何编辑都将导致 所有 文件的重建。这对于大型项目是不可接受的,但对于您描述的小型项目来说是可以的。
    • 我这里没有考虑需要在这里构建的“测试”程序,但是一旦你了解了这里的内容,处理这些应该不难。
    • 我没有对此进行测试(而是从我自己的 makefile 中复制粘贴过来的,那是一个 C++ 项目),因此可能还有一些小的改动。手动编写 makefile 是一门艺术...

    编辑:这是针对基于 Linux 的环境,其中程序名称通常没有扩展名。如果是 Windows,您可能需要在多个位置添加 .exe

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多