包含文件夹的多个可执行文件的Makefile

时间:2014-05-25 11:29:21

标签: gcc makefile

如何在具有多个可执行文件的项目中创建简洁的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

1 个答案:

答案 0 :(得分:1)

大多数" make"你的情况几乎无法覆盖。教程:以通用方式处理不同的文件集。

  • 有些文件只是提供了一些实现(让我们调用这些" 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)

为了确保所有这些变量都正确,您可以在makefile中添加show目标:

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)

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

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

最终评论:

  • 此处仅进行基本相关性检查:对任何头文件进行任何编辑都将导致重建所有文件。这对于大型项目来说是不可接受的,但对于您描述的小项目来说是可以接受的。
  • 我这里没有考虑&#34;测试&#34;需要在这里构建的程序,但是一旦你理解了这里的内容,处理它们应该不难。
  • 我没有对此进行测试(相反,有点复制&#39; n从我自己的makefile中粘贴,这是一个C ++项目),所以可能会有一些小的改动。手工编写makefile是一门艺术......

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