zoukankan      html  css  js  c++  java
  • Linux 开发:Makefile基本使用

    在桌面系统上开发常使用VS、eclipse、Keil等IDE,编译点一下按钮,就可以完成。但在无桌面的服务器上开发,改怎么做?而编译内部是怎么实现的?改动文件后如何增量文件?掌握Makefile文件写法就可以得到答案。

    1、Makefile是什么

    Makefile定义了整个工程的编译规则,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。不同厂商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。

    2、Makefile的主要架构

    3、一个简单Makefile示例

    TARGET := test
     
    CC := g++ 
     
    #注意每行后面不要有空格,否则会算到目录名里面,导致问题
    SRC_DIR = src
    BUILD_DIR = tmp
    OBJ_DIR = $(BUILD_DIR)/obj
    DEPS_DIR  = $(BUILD_DIR)/deps
     
    #这里添加其他头文件路径
    INC_DIR = 
    	-I./include 
    	-I./src 
    	
    #这里添加编译参数
    CC_FLAGS := $(INC_DIR) -g -std=c++11
    LNK_FLAGS := 
    	-L/usr/local/lib 
     
    #这里递归遍历3级子目录
    DIRS := $(shell find $(SRC_DIR) -maxdepth 3 -type d)
     
    #将每个子目录添加到搜索路径
    VPATH = $(DIRS)
     
    #查找src_dir下面包含子目录的所有cpp文件
    SOURCES   = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))  
    OBJS   = $(addprefix $(OBJ_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES))))  
    DEPS  = $(addprefix $(DEPS_DIR)/, $(patsubst %.cpp,%.d,$(notdir $(SOURCES))))  
    
    $(TARGET):$(OBJS)
    	$(CC) $^ $(LNK_FLAGS) -o $@
    
    #编译之前要创建OBJ目录,确保目录存在
    $(OBJ_DIR)/%.o:%.cpp
    	@if [ ! -d $(OBJ_DIR) ]; then mkdir -p $(OBJ_DIR); fi;
    	$(CC) -c $(CC_FLAGS) -o $@ $<
    
    #编译之前要创建DEPS目录,确保目录存在
    #前面加@表示隐藏命令的执行打印
    $(DEPS_DIR)/%.d:%.cpp
    	@if [ ! -d $(DEPS_DIR) ]; then mkdir -p $(DEPS_DIR); fi;
    	set -e; rm -f $@;
    	$(CC) -MM $(CC_FLAGS) $< > $@.$$$$;
    	sed 's,($*).o[ :]*,$(OBJ_DIR)/1.o $@ : ,g' < $@.$$$$ > $@;
    	rm -f $@.$$$$
    #前面加-表示忽略错误
    
    -include $(DEPS)
    .PHONY : clean
    clean:
    	rm -rf $(BUILD_DIR) $(TARGET)
    

    参考文档2 中的例子,中间文件放在tmp目录下,直接在根目录执行make;

    root@ubuntu:~/projects/MakeFileProject1# tree .
    .
    ├── makefile
    ├── src
    │   └── main.cpp
    ├── test
    └── tmp
        ├── deps
        │   └── main.d
        └── obj
            └── main.o

    4、Reference

    玩转Makefile | 系列综述
    makefile将中间文件生成到临时目录
    Makefile教程(绝对经典,所有问题看这一篇足够了)

  • 相关阅读:
    Mybatis源代码分析之类型转换
    eclipse中对于@override注解的函数报父类没有该方法
    Mybatis源代码分析之metadata包
    Android GC
    有道单词本导出xml转换.
    广播的接收与U盘广播
    Bitmap和Drawable相互转换方法
    如何提交程序到Android Market
    error parsing xml:unbound prefix
    android获取屏幕尺寸、密度
  • 原文地址:https://www.cnblogs.com/wnwin/p/11179960.html
Copyright © 2011-2022 走看看