【问题标题】:make file with source subdirectories使用源子目录制作文件
【发布时间】:2017-10-14 06:37:49
【问题描述】:

我的最新项目是 C++,我使用的是 GNU Make。 项目目录布局如下:

project
|-src
  |-subdir1
  |-subdir2 (containing tests)
|-doc
|-bin

我希望能够在顶级目录中调用make(即在项目目录中需要一个makefile)来编译两个“src”子目录中的所有源并将生成的二进制文件放在“bin”目录中.

最好的方法是什么?如果我不必为每个源文件添加一个 make 规则,而只为目录中的所有 .cc 和 .h 文件添加一个规则,那也很棒。

【问题讨论】:

    标签: makefile


    【解决方案1】:

    Make 允许您概括规则,因此您无需为每个文件创建一个。

    project
    |-src
      |-subdir1
      |-subdir2 (containing tests)
    |-doc
    |-bin
    

    你可以试试这样的:

    #This finds all your cc files and places then into SRC. It's equivalent would be
    # SRC = src/main.cc src/folder1/func1.cc src/folder1/func2.cc src/folder2/func3.cc
    
    SRC = $(shell find . -name *.cc)
    
    #This tells Make that somewhere below, you are going to convert all your source into 
    #objects, so this is like:
    # OBJ =  src/main.o src/folder1/func1.o src/folder1/func2.o src/folder2/func3.o
    
    OBJ = $(SRC:%.cc=%.o)
    
    #Tells make your binary is called artifact_name_here and it should be in bin/
    BIN = bin/artifact_name_here
    
    # all is the target (you would run make all from the command line). 'all' is dependent
    # on $(BIN)
    all: $(BIN)
    
    #$(BIN) is dependent on objects
    $(BIN): $(OBJ)
        g++ <link options etc>
    
    #each object file is dependent on its source file, and whenever make needs to create
    # an object file, to follow this rule:
    %.o: %.cc
        g++ -c $< -o $@
    

    【讨论】:

      【解决方案2】:

      使用一次 make run 进行构建(我不喜欢递归 make)。不要使用$(shell),因为它会影响性能。将构建产品放入临时目录。

      草图:

      subdir1-srcs := $(addprefix subdir1/,1.cc 2.cc 3.cc)
      subdir1-objs := ${subdir1-srcs:subdir1/%.cc=subdir1/obj/%.o)
      bin/prog1: ${subdir1-objs} ; gcc $^ -o $@
      ${subdir1-objs}: subdir1/obj/%.o: subdir1/%.cc # Static pattern rules rule
          gcc -c $< -o $@
      ${subdir1-objs}: subdir1/obj/.mkdir # Need to create folder before compiling
      subdir1/obj/.mkdir:
          mkdir -p ${@D}
          touch $@
      

      你能看到这里的样板吗?一些函数和$(eval) 应该允许你写:

      $(call build,bin/prog1,subdir1,1.cc 2.cc 3.cc)
      $(call build,bin/prog2,subdir2,a.cc b.cc c.cc d.cc)
      

      这些目标自动添加为虚假all 的依赖项,并且很好地兼容-j(只需输入make -j5 all 即可构建)。

      【讨论】:

        【解决方案3】:

        您必须在目录中制作子makefile,并使用命令将g++编译的文件输出到您想要的目录中。 (使用 makefile 变量等...)

        您会发现关于递归 Makefile 的精彩介绍 here

        Makefile 允许您使用一些通用规则,例如:

        %.o:%.cpp
            gcc blahblahblah
        

        您还可以使用include 包含来自另一个的全局makefile。

        如果您还 google makefile,您会发现很多关于该主题的操作方法。

        【讨论】:

          猜你喜欢
          • 2016-12-09
          • 1970-01-01
          • 2016-04-20
          • 1970-01-01
          • 1970-01-01
          • 2014-07-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多