首页 文章

如何将makefile包含到其他makefile中?

提问于
浏览
3

我有一些C类,每个都有一个带有makefile的自己的文件夹,test.cpp用于测试目的等等 .

Main folder
 |-> Class1 folder
 |-> Class2 folder
      |-> Class2.1 folder
 |-> Class2 folder

我有一个主项目,必须包括这些类 . 我试图将所有子makefile包含在主makefile中 .

我试过“INCLUDE POO / makefile”,但这个解决方案有两个问题:

  • 子makefile的路径不正确,因此找不到文件("There is not rule to build the target 'Vector3D.cpp'") .

  • "test.cpp"文件被覆盖,可能是因为路径问题 . ("warning: overriding recipe for target ...")

我想所有的makefile都是独立的,所以我可以复制/通过类文件夹到一个新的项目,它仍然可以工作,或者我可以单独执行makefile而不需要对其进行更改 .

所以问题是:如何将(正确)makefile包含到其他makefile中?

Example, just for test purpose.

主要makefile(简化)

include Vector3D/makefile
include Color/makefile

CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0

all: main

main: main.o Vector3D.o Color.o
    $(CPP) main.o Vector3D.o Color.o -o main

main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(CXXFLAGS)

子makefile示例(简化)

#Vector3D
CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0


all: test

test: Vector3D.o test.o
    $(CPP) Vector3D.o test.o -o test

Vector3D/test.o: test.cpp
    $(CPP) -c test.cpp -o test.o $(CXXFLAGS)

Vector3D.o: Vector3D.cpp Vector3D.hpp
    $(CPP) -c Vector3D.cpp -o Vector3D.o $(CXXFLAGS)

类似于Color / makefile而不是Vector3D

2 回答

  • 1

    我希望所有的makefile都独立,所以我可以复制/通过类文件夹到一个新的项目,它仍然可以工作,或者我可以单独执行makefile而不需要对其进行更改 .

    我'm pretty sure that'不可能 . 你的makefile要么是独立的,在这种情况下你可以让顶级文件递归调用低级目录中的 make (所以不要 includeor 你可以通过包含其他makefile形成一个非递归的makefile . 我不可能同时做到这两点 .

    如何将(正确)makefile包含到其他makefile中?

    唯一有效的答案是“使用 include 指令" (other than the usual "它依赖” . )任何其他建议取决于makefile的结构 . 设计包含的Makefile显然更容易包含 . 只是包含一些随机的makefile并希望它可以工作...将无法正常工作 . 查看Implementing non-recursive makeBoilermake了解如何使非递归makefile工作 .

    请注意,不需要将它们包含在文件的顶部,这样做可能是个坏主意,因为默认目标成为包含文件中的第一个目标 .

  • 4

    感谢@ Jonathan-wakely为此解决方案提供初始概念 .

    可能有很多东西可以改进,但它确实有效 .

    要求摘要:

    • Makefile应该独立工作

    • 主makefile将包含子makefile

    • 不应出现冲突或路径问题 .

    一个简单的解决方案是调用递归makefile:

    • 为叶子文件创建"normal"脚本

    • 在":"之后使用 empty target 允许执行始终调用示例"sub-make:"而没有任何要求

    • 使用“ -C ”参数设置make调用的根目录 .

    • 使用子makefile创建的二进制文件创建最终链接 .

    主makefile的示例:

    #all make recursive calls
    sub-make:
        make -C Vector3D
        make -C Color
    
    #final linking
    CPP      = g++
    FLAGS = $(CXXINCS) -Wall -O0
    
    all: main
    
    main: main.o Vector3D/Vector3D.o Color/Color.o
        $(CPP) main.o Vector3D/Vector3D.o Color/Color.o -o main
    
    main.o: main.cpp
        $(CPP) -c main.cpp -o main.o $(FLAGS)
    

    可能有更好的方法在不编写所有完整路径的情况下向链接器提供* .o二进制文件,但这是另一个问题 .

    创建干净的目标 . 对于叶子makefile,没有特别的考虑因素,但对于主makefile,它必须调用sub-clean规则 .

    clean:
        make -C Vector3D clean
        make -C Color clean
        rm -f *.o main
    

    EDITING:

    这是我所做的makefile结构,因为它可能对任何人都有用 .

    要工作,所有类必须位于自己的文件夹中:

    • .hpp Headers

    • .cpp代码

    • main.cpp进行测试

    • 必需类(LIBS)目录使用与此makefile相关的"$(LIBSPATH)LibName"指定 .

    Makefile文件

    #Following configuration may be set with a parameter:
    #   e.g: make FLAGS="-Wall -O0"
    FLAGS = $(CXXINCS) -Wall -O0
    
    #Configurable variables
    EXEC     = main
    CLASS    = World
    LIBS     = Color Vector3D Triangle
    LIBSPATH = ../
    
    #Static content
    CPP      = g++
    OBJS     = $(foreach dir, $(LIBS), $(LIBSPATH)$(dir)/$(dir))
    
    all: $(EXEC)
    
    clean: 
        rm -f *.o $(EXEC)
        $(foreach dir,$(LIBS),make clean --no-print-directory -C $(LIBSPATH)$(dir);)
    
    $(EXEC): $(CLASS).o $(EXEC).o $(OBJS:=.o)
        $(CPP) $(CLASS).o $(OBJS:=.o) $(EXEC).o -o $(EXEC)
    
    $(EXEC).o: $(EXEC).cpp
        $(CPP) -c $(EXEC).cpp -o $(EXEC).o $(CXXFLAGS)
    
    $(CLASS).o: $(CLASS).cpp $(CLASS).hpp
        $(CPP) -c $(CLASS).cpp -o $(CLASS).o $(CXXFLAGS)
    
    $(OBJS:=.o): $(OBJS:=.cpp) $(OBJS:=.hpp)
        make --no-print-directory -C $(LIBSPATH)$(strip $(foreach dir,$(LIBS),$(if $(findstring $(dir),$@),$(dir))))
    

相关问题