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的瞭解不是太多,但願你們可以給予意見及幫助!

相關文章
相關標籤/搜索