使用文件夹的多个可执行文件的Makefile [英] Makefile for multiple executables with folders

查看:235
本文介绍了使用文件夹的多个可执行文件的Makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建一个Makefile文件,该文件在具有多个可执行文件的项目中是简洁的。
我试着直接从Makefile文档中学习,但对我来说是压倒性的。
这是我的项目的一个例子。我发现了相关的问题,但他们只有一个可执行文件,我有兴趣编译所有不同的单元测试。

 ├──bin 
├──include
│├── Action.h
│├──Consts.h
│├──Inventory.h
│├──Link.h
│├──Object.h
│├──Player.h
│├──Set.h
│├──Space.h
│├──World.h
│└──WorldXMLReader .h
├──主电源
│├──Prototype.c
│└──...使用main()的更多源文件
├──obj
│├──Makefile
│├──Set.o
│└──...更多目标文件
├──README.md
├──src
│├──Action.c
│├──Inventory.c
│├──Link.c
│├──Object.c
│├─ ─Player.c
│├──Set.c
│├──Space.c
│├──World.c
│└──WorldXMLReader.c
└──unitTest s
├──UT_Inventory.c
├──UT_Link.c
└──UT_Object.c


解决方案

大多数make教程几乎没有涉及到这种情况:以通用的方式处理不同的文件集。




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



我不会在这里为您提供完整的makefile,但会尝试显示全局方法来处理这种情况。

首先,定义不同的源文件夹和目标文件夹:

  SRC_DIR_LIB = src 
SRC_DIR_EXE =主电源
OBJ_DIR_LIB = obj / lib
OBJ_DIR_EXE = obj / exe
BIN_DIR = bin
HEAD_DIR = i nclude

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



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



然后,定义源文件集:

  SRC_FILES_LIB = $(通配符$(SRC_DIR_LIB) /*.c)
SRC_FILES_EXE = $(通配符$(SRC_DIR_EXE)/ *。c)
HEAD_FILES = $(通配符$(HEAD_DIR)/ *。h)


 <$ c  

$ c> 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生成一组可执行文件:


$ b

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

这些是l是你的最终目标,你告诉你做:

 全部:$(EXEC_FILES)

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

  show:
@echoSRC_FILES_LIB = $(SRC_FILES_LIB)
@ echoSRC_FILES_EXE = $(SRC_FILES_EXE)
..等等所有其他

尝试 make show ,并仔细检查。

然后告诉如何做真正的工作。你需要两个单独的编译目标:
$ b $ $ $ $ $(OBJ_DIR_EXE)/%。$(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)/,$ @)。$(OBJ_FILES_LIB)$(LDFLAGS)

最终评论:


  • ,只进行基本的依赖性检查:任何任何头文件的编辑都会导致重建所有文件。这对于一个大型项目来说是不可接受的,但对于一个小型项目来说,就像你描述的那样。

  • 我没有在这里考虑需要在这里构建的测试程序,但是一旦你理解了这里的情况,处理这些应该不会很困难。我没有测试这个(相反,有点像从我自己的makefile中拷贝出来的那样,是一个C ++项目),所以可能还有一些小的变化。手动编写makefile是一门艺术......
  • b
    编辑: ,程序名称通常没有扩展名。如果是Windows,您可能需要在几处添加 .exe


    How do you create a Makefile that is concise in a project with multiple executables. I tried learning directly from the Makefile documentation but it's overwhelming for me. This is an example of my project. I found questions that are related but they only have one executable and I'm interested in compiling all the different Unit-tests. I'm using 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
    

    解决方案

    You have a situation that is barely covered by most of the "make" tutorials: handling different sets of files in a generic way.

    • Some files just provide some implementation (lets call these "lib" files, even if they are not going to be compiled into a static or dynamic library file),
    • other files hold a main() function and each of these must produce an executable binary, and links with the previous.

    I won't here give you an all-finished makefile, but will try to show a global method on how to handle this situation.

    So first, define the different source and object folders:

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

    (This is very useful because if one day the tree organisation changes, you will only have to edit the changes at a single point.)

    And, yes, you should have separate folders for object files.

    Then, define the sets of source files:

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

    Let make generate the set of object files:

    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))
    

    Let make generate the set of executable files:

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

    These will be your final target, you tell that to make with:

    all: $(EXEC_FILES)
    

    To make sure you have all these variables right, you can add a show target to your makefile:

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

    Try a make show, and carefully check.

    Then tell make how to do the real job. You need two separate compile targets:

    $(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)
    

    And the linking step for the programs, that makes use of the subst() function:

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

    Final comments:

    • here, only basic dependency checking is done: any editing of any header file will result in a rebuild of all the files. This is not acceptable for a large project, but is ok for a small project as the one you describe.
    • I did not here consider the "test" programs that need to be build here, but once you understand whats up here, it should not be difficult to handle these.
    • I did not test this (instead, kinda copy'n'pasted from a makefile of my own, that was a C++ project), so there might be some minor changes left. Manual writing of makefiles is an art...

    Edit: This is targeted for a Linux based environment, where program names usually have no extension. If Windows, you probably will need to add .exe at several places.

    这篇关于使用文件夹的多个可执行文件的Makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆