【问题标题】:How can I write Makefile (with sub Makfile ) more concise如何更简洁地编写 Makefile(带有子 Makfile )
【发布时间】:2013-08-08 16:17:11
【问题描述】:

当我练习时,我有一个练习路径。

在这个路径下,我有一个名为myInclude 的包含路径(这个文件夹我有一些有用的功能,我总是使用它。)

还有一个名为symbol_try的代码路径。我总是在symbol_try中添加新文件夹(里面有一个c文件和main函数)并编译它。

每次我都要在终端通过gcc编译。这是一个无聊的工作,所以我写了一个Makefile。

这是一个例子:

练习路径中的主Makefile:

FOBJS=
include myInclude/Rule.mk
include symbol_try/codeList_13.1/Rule.mk
symbol:$(FOBJS)                   <==What exactly I what . A executable file.
    gcc -o symbol $(FOBJS) -pthread -lpthread

subsystem:
    cd myInclude/ && $(MAKE)
    cd symbol_try/codeList_13.1/ &&$(MAKE)
clean:
    rm -rf symbol   

在 myInclude/Rule.mk 中

FOBJS+=myInclude/otherFunction.o myInclude/error.o \
       myInclude/unit.o myInclude/unitTest.o\

在 symbol_try/codeList_13.1/Rule.mk 中

FOBJS+=symbol_try/codeList_13.1/codeList_13.1.o

在 myInclude/Makefile 中:

    OBJS=otherFunction.o error.o unit.o unitTest.o
    ALL:$(OBJS)
    .PHONY:ALL
    $(OBJS):%.o:%.c
        gcc -c $< -o $@

    clean :
        otherFunction.o error.o unit.o

在 symbol_try/codeList_13.1/Makefile:

codeList_13.1.o:codeList_13.1.c
    gcc -c codeList_13.1.c

嗯,这可以工作。但是如你所见,我必须为每个文件夹编写一个 Rule.mk(初始化 FOBJS)和一个 Makefile。

我是 make 新手,我想找到一种更简洁的方法,我只需要为每个文件夹和一个主 Makefile 编写一个 Makefile。不再使用 Rule.mk

PS:我总是更改 myInclude 中的代码,所以我不想将其构建为库。

感谢您的帮助。

【问题讨论】:

    标签: c makefile


    【解决方案1】:

    这是一种只需一个 Makefile 即可完成的方法:

    CC        = gcc
    CPPFLAGS += -I myInclude/                             (1)
    CFLAGS   += -std=c99 -Wall                            (2)
    VPATH     = myInclude/ \                              (3)
                symbol_try/codeList_13.1/
    
    symbol: otherFunction.o error.o unit.o unitTest.o codeList_13.1.o  (4)
        $(CC) -o $@ $^                                    (5)
    
    .PHONY : clean
    clean:
        rm -f symbol *.o
    

    请注意,make 知道如何构建 C 文件并具有一些标准宏:CC、CPPFLGAS、CFLAGS

    1. 添加标题的包含路径。您可能在 myInclude 目录中有一些单独的目标文件的标头。
    2. 将编译器标志放在这里。
    3. 添加要构建的源文件的路径。
    4. 列出可执行文件所依赖的目标文件
    5. 由于没有名为symbol.c 的文件,您需要告诉make 如何使用规则创建symbol.o$@ 表示目标(此处为“符号”),$^ 表示所有先决条件(列出的目标文件)。

    这是我的测试目录中所有文件的列表:

    $ find . -type f
    .
    ./Makefile
    ./myInclude/error.c
    ./myInclude/header.h
    ./myInclude/otherFunction.c
    ./myInclude/unit.c
    ./myInclude/unitTest.c
    ./symbol_try/codeList_13.1/codeList_13.1.c
    

    以及构建输出:

    $ make
    gcc -std=c99 -Wall -I myInclude/  -c -o otherFunction.o myInclude/otherFunction.c
    gcc -std=c99 -Wall -I myInclude/  -c -o error.o myInclude/error.c
    gcc -std=c99 -Wall -I myInclude/  -c -o unit.o myInclude/unit.c
    gcc -std=c99 -Wall -I myInclude/  -c -o unitTest.o myInclude/unitTest.c
    gcc -std=c99 -Wall -I myInclude/  -c -o codeList_13.1.o symbol_try/codeList_13.1/codeList_13.1.c
    gcc -o symbol otherFunction.o error.o unit.o unitTest.o codeList_13.1.o
    

    【讨论】:

    • 添加后 CFLAGS += -std=c99 -Wall 出了点问题。一些结构和马可不起作用。我删除了那条线,一切正常,为什么会这样?
    • 如果你愿意,你可以删除这两个(即只有CFLAGS += )。但最好保留-Wall,以检查代码中的错误。 -Wall 打开正常的 gcc 警告,如果您的代码不正确,这可能会导致大量消息。 -std=c99 决定编译器将使用哪种风格的 C。还有其他设置,见gcc.gnu.org/onlinedocs/gcc/Standards.html
    【解决方案2】:

    为什么不从 myInclude 中的对象创建一个库,并在代码路径 (symbol_try/codeList_13.1) 中的 Makefile 中进行链接。无论如何,后者更好,因为所需的库(在您的情况下为-pthread -lpthread)可能会因其他一些代码而改变。 现在主 Makefile 将无事可做,只需在所有需要的子目录中调用 make。

    【讨论】:

      【解决方案3】:

      在每个文件夹中都有一个makefile

          SOURCES=sample.c sampletest.c
      
          OBJECTS=$(SOURCES:%.c=$(OBJDIR)/%.o)
      
          all: $(OBJECTS)
      
          $(OBJDIR)/%.o: %.c
              $(CC) $(CFLAGS) -o $@ $<
      

      在项目的根目录中,创建一个makefile,其中包含编译每个子文件夹的规则,如下所示。

          Dirs= path-to-rootdir
          objs:
          set -e ; \
          for i in $(Dirs) ; do \
            $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS_MODULE)" LDFLAGS="$(LDFLAGS)"  OBJDIR="$(OBJDIR)" -C $$i; \
      done
      

      然后你可以使用它通过添加规则来构建可执行文件

         EXE: objs
          $(CC)  -L./Path1 $(LIB_PATH)  -llib1  -o $(EXE_NAME) $(wildcard $(OBJDIR)/*.o) 
      

      希望对你有帮助!!!

      【讨论】:

        猜你喜欢
        • 2015-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-16
        • 2016-04-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多