zoukankan      html  css  js  c++  java
  • Makefile入门

    Makefile语法:

    targets : prerequisites
        command

    为了演示Makefile,这里创建一个工程。工程结构如下:

    源代码如下:

    // ./src/aa.hpp
    void func_a();
    
    // ./src/aa.cpp
    void func_a()
    {
        printf("call func_a
    ");
    }
    
    // ./src/base/bb.hpp
    void func_b();
    
    struct Person {
        int age;
    //    double score;
    //    double weight;
    };
    
    // ./src/base/bb.cpp
    void func_b() {
        printf("call func_b
    ");
    }
    
    // ./src/main.cpp
    #include <iostream>
    #include "aa.hpp"
    #include "base/bb.hpp"
    using namespace std;
    
    int main(int argc, const char * argv[])
    {
        func_a();
        func_b();
        Person person;
        cout << "person size: " << sizeof(person) << endl;
        return 0;
    }

    Makefile内容如下:

    BIN_NAME := foo
    CXX ?= g++
    SRC_EXT = cpp
    SRC_PATH = ./src
    BUILD_PATH = ./build
    
    SHELL = /bin/bash
    SOURCES := $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)')
    OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o)
    
    .PHONY: all dirs clean
    
    all: dirs $(BIN_NAME)
    
    dirs:
        mkdir -p $(dir $(OBJECTS))
    
    $(BIN_NAME): $(OBJECTS)
        @echo "compiling $@"
        $(CXX) -o $@ $^
    
    $(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT)
        @echo "compiling $@"
        $(CXX) -c $< -o $@
    
    test: 
        @echo $(SOURCES)
        @echo $(OBJECTS)
    
    clean:
        @$(RM) $(BIN_NAME)
        @$(RM) -r $(BUILD_PATH)

    虽然这个Makefile能用,但是有一个问题:如果修改了头文件,再次make无效。

    改进版:

    BIN_NAME := foo
    CXX ?= g++
    SRC_EXT = cpp
    SRC_PATH = ./src
    BUILD_PATH = ./build
    
    SHELL = /bin/bash
    SOURCES := $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)')
    OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o)
    DEPS = $(OBJECTS:.o=.d)
    
    .PHONY: all dirs clean
    
    all: dirs $(BIN_NAME)
    
    dirs:
        mkdir -p $(dir $(OBJECTS))
    
    $(BIN_NAME): $(OBJECTS)
        @echo "compiling $@"
        $(CXX) -o $@ $^
    
    -include $(DEPS)
    
    $(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT)
        @echo "compiling $@"
        $(CXX) -MP -MMD -c $< -o $@
    
    test: 
        @echo $(SOURCES)
        @echo $(OBJECTS)
    
    clean:
        @$(RM) $(BIN_NAME)
        @$(RM) -r $(BUILD_PATH)

    修改的地方用绿色标明了。 此时,如果修改头文件,再次make有效。

    关于gcc的编译选项,啰嗦几句:

    -M,列出文件需要的头文件,输出中包含系统头文件

    -MM,列出文件需要的头文件,但不包含系统头文件

    -MMD, 与-o结合使用,将文件的依赖关系输出到.d文件中

    -MP, 为文件的依赖文件建立一个target,

     

    来个实战,不带-MP:

     g++ -MMD -c main.cpp -o main.o

    目录下会生成main.d文件,其中内容为:

    main.o: main.cpp aa.hpp base/bb.hpp

    如果带-MP:

    g++ -MP -MMD -c main.cpp -o main.o

    main.d中的内容就会变成:

    main.o: main.cpp aa.hpp base/bb.hpp
    
    aa.hpp:
    
    base/bb.hpp:

    参考资料:

    https://github.com/mbcrawfo/GenericMakefile

    Makefile中的wildcard用法

  • 相关阅读:
    第十三周
    意见评论
    第十二周
    冲刺10
    冲刺9
    冲刺8
    团队冲刺第二十二天-KeepRunningAPP
    找水王
    第十四周总结
    搜狗输入法评价
  • 原文地址:https://www.cnblogs.com/gattaca/p/6826103.html
Copyright © 2011-2022 走看看