简体   繁体   English

如何编写更简洁的Makefile(带有sub Makfile)

[英]How can I write Makefile (with sub Makfile ) more concise

When I do practice , I have a practice path. 当我练习时,我就有了练习路径。

Under this path , I have an Include path named myInclude (I have some useful function is this folder and I always use it.) 在此路径下,我有一个名为myInclude的包含路径(我有一些有用的功能是此文件夹,并且我总是使用它。)

And a code path named symbol_try .I always make add new folder (with ac file and main function in it) in symbol_try and compile it. 并命名为代码路径symbol_try 。我总是在添加新的文件夹(使用AC文件和主要功能吧) symbol_try和编译。

Each time I have to compile it by gcc in terminal .Its a boring work , so I write a Makefile. 每次我必须在终端中用gcc编译它。这是一项无聊的工作,因此我编写了一个Makefile。

Here is an example: 这是一个例子:

the main Makefile in practice path: 练习路径中的主要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   

In the myInclude/Rule.mk 在myInclude / Rule.mk中

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

In the symbol_try/codeList_13.1/Rule.mk 在symbol_try / codeList_13.1 / Rule.mk中

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

In myInclude/Makefile: 在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

In symbol_try/codeList_13.1/Makefile: 在symbol_try / codeList_13.1 / Makefile中:

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

Well.That can work. 好吧,那行得通。 But as you see , I have to write a Rule.mk(to initialize the FOBJS) and a Makefile for each folder. 但是如您所见,我必须为每个文件夹编写一个Rule.mk(以初始化FOBJS)和一个Makefile。

I am new for make , I want find a way more concise , witch I only need write one Makefile for each folder and a main Makefile. 我是make的新手,我想找到一种更简洁的方法,我只需要为每个文件夹编写一个Makefile和一个主Makefile。 No Rule.mk any more . 没有Rule.mk了

PS: I always change the code in myInclude ,so I don't want to build it a library. PS:我总是更改myInclude中的代码,所以我不想将其构建为库。

Thanks for any help. 谢谢你的帮助。

Here's one way you can do it with just one Makefile: 这是仅使用一个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

Note that make knows how to build C files and has some standard macros: CC, CPPFLGAS, CFLAGS 请注意, make知道如何构建C文件并具有一些标准宏:CC,CPPFLGAS,CFLAGS

  1. Add the include paths of your headers. 添加标头的包含路径。 You presumably have some headers for the individual object files in the myInclude directory. 大概在myInclude目录中有一些单独对象文件的myInclude
  2. Put the compiler flags here. 将编译器标志放在这里。
  3. Add the paths to the source files you want to build. 将路径添加到要构建的源文件。
  4. List the object files that the executable depends upon 列出可执行文件所依赖的目标文件
  5. As there is no file called symbol.c you need to tell make how to create symbol.o with a rule. 由于没有名为symbol.c文件, symbol.c您需要告诉make如何使用规则创建symbol.o $@ means the target ('symbol', here), and $^ means all of the prerequisites (the object files listed). $@表示目标(此处为'symbol'), $^表示所有先决条件(列出的目标文件)。

Here's a list of all of the files in my test directories for this: 这是我的测试目录中所有文件的列表:

$ 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

And the build output: 并生成输出:

$ 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

Why don't you create a library from the objects in myInclude and do the linking in the Makefile in your code path (symbol_try/codeList_13.1). 为什么不从myInclude中的对象创建库,并在代码路径(symbol_try / codeList_13.1)中的Makefile中进行链接。 The latter is better anyway because the needed libraries ( -pthread -lpthread in your case) might change as well for some other code. 无论如何,后者会更好,因为对于某些其他代码,所需的库(在您的情况下为-pthread -lpthread )可能也会发生变化。 The main Makefile now would have got nothing to do but call make in all needed subdirectories. 现在,除了在所有需要的子目录中调用make之外,主Makefile无需执行任何操作。

In each folder have a makefile with 在每个文件夹中都有一个带有

    SOURCES=sample.c sampletest.c

    OBJECTS=$(SOURCES:%.c=$(OBJDIR)/%.o)

    all: $(OBJECTS)

    $(OBJDIR)/%.o: %.c
        $(CC) $(CFLAGS) -o $@ $<

In the root directory of a project, create a makefile with a rule to compile every sub-folder like the below. 在项目的根目录中,创建带有规则的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

And then you could use it build the executable by adding a rule 然后您可以使用它通过添加规则来构建可执行文件

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

Hope this helps!!! 希望这可以帮助!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM