make 学习笔记

在学习make以前,咱们要知道为何要使用make。在一个项目中,当咱们改变某一个源程序时,若源文件较少,咱们对其进行编译连接并生成新的目标文件并不复杂;然而,若咱们的源文件不少,在一个大型的项目中时,若从新对这个项目进行编译连接无疑是耗时耗力,且其中不少的程序已经编译,无需再从新编译。make能够根据makefile文件提供的文件依赖,决定哪些须要从新编译,即利用其中的一个时间戳(在后面会讲到),从而节省时间。linux

例如,咱们有一个test.h头文件,一个test.cpp源文件,还有一个main.cpp源文件,咱们下面就讲解如何用make和makefile 生成一个可执行的目标文件;ios

首先,tesh.h头文件中声明了一个func函数:git

#ifndef TEST_H
#define TEST_H

void func(char a);
#endif

 test.cpp源文件中对func函数进行定义:github

#include <iostream>
#include "test.h"
using namespace std;

void func(char a)
{
      cout<<a<<endl;
}

 再定义一个main文件:vim

#include "test.h"
#include<iostream>
using namespace std;

int main()
{
  cout<<"please enter a char "<<endl;
  char ch;
  cin>>ch;
  cout<<"func(char)="<<func(ch)<<endl;
  return 0;
}

 上面定义了test.h头文件,及test.cpp和main.cpp的.cpp文件,下面首先经过g++命令编译看其结果:浏览器

若单纯的用g++,咱们能够首先使用命令函数

g++ test.cpp -fPIC -shared -o test.so

生成test.so的动态连接库,而后连接这个库生成可执行目标文件:学习

g++ main.cpp -L. -ltest -I. -o test

这样咱们就能够生成一个test的可执行文件。其中的一些参数你们能够去google或man g++查看其中的意义。google

下面讲解如何经过make和makefile的搭配来实现:spa

咱们要在源文件所在的目录中建立一个Makefile的文件,能够经过vim Makefile 命令实现。针对上面的例子咱们能够写出Makefile以下:

CPP = g++
OBJS = main.cpp test.cpp
test :$(OBJS)
        $(CPP) $(OBJS) -o $@

而后执行

make 
./test

就能够生成了如同上面同样的结果。你们能够看出,Makefile的本质其实仍是使用g++完成了编译过程。其中的CPP和OBJS至关于变量,方便咱们添加文件。而$@表明的是第一个目标文件即test目标文件。而test :$(OBJS)表示test依赖于OBJS里的源文件。当make时,发现(OBJS)中的文件比test中更新,则更新test。这里面就涉及了linux的时间戳文件,你们能够去看CSDN中一篇博文<linux Makefile时间戳>.楼主浏览器貌似不能插入网址,不知道缘由。。里面对linux的时间戳进行了详细的说明。关于Makefile时间戳的一个函数能够以下:

time_t GetModifiedTimestamp(char *path)
{
    struct stat attr;
    if(stat(path,&attr) == -1)
        return 0;
    return attr.st_mtime;
}

上面的代码是参考Cyberspace_TechNode的博文中的关于时间戳的函数。相应的咱们也能够写个Makefile用于生成test.so的动态连接库。在此楼主就不写了。

关于Makefile模板,你们能够参考github上的一个个人师兄徐陈峰写的Makefile 模板。经过简单修改其中的一点参数便可简单的生成对应的如lib,bin等。其中的readme.txt有详细说明。

还有个师兄提议是否是能够考虑选择Cmake替代,由于Cmake是跨平台的,目前对Cmake的了解不是太多,但愿你们可以给予意见及帮助!

相关文章
相关标签/搜索