概念

【编译】

把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File。

——编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。

——有时我们会对某些中间目标文件打个包便与复用,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

【链接】

大量的Object File合成执行文件,这个动作叫作链接(link)。

——在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码。

【makefile基本规则】

target ... : prerequisites ...
\tcommand

——target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)

——prerequisites就是,要生成那个target所需要的文件或是目标。

——command也就是make需要执行的命令。(任意的Shell命令)

基础版本

先来看个例子,用来实现接收命令行参数并打印。CmdLine类用来解析存储参数,SwmPack用来打印。

//main.cpp
//程序入口

#include <iostream>
#include "CmdLine.h"
#include "SwmPack.h"

int main(int argc, char* argv[])
{
    CmdLine cmdLine;
    cmdLine.Parse(argc, argv);
    SwmPack swmPack;
    swmPack.Run(cmdLine);

    return 0;
}

 

//CmdLine.h
//命令行解析头文件

#ifndef TMAKE_CMDLINE_H
#define TMAKE_CMDLINE_H

#include <vector>
#include <string>
using namespace std;

class CmdLine 
{
public:
    CmdLine() = default;
    void Parse(int argc, char* argv[]);
    vector<string> Get() const;
private:
    vector<string> vargs_;
};

#endif


//CmdLine.cpp
//命令行解析实现

#include "CmdLine.h"

void CmdLine::Parse(int argc, char* argv[])
{
    vargs_.clear();
    for (auto index = 0; index < argc; index++) {
        vargs_.push_back(*(argv+index));
    }
}

vector<string> CmdLine::Get() const
{
    return vargs_;
}

 

//SwmPack.h
//操作头文件

#ifndef TMAKE_SWMPACK_H
#define TMAKE_SWMPACK_H
#include "CmdLine.h"

class SwmPack
{
public:
    SwmPack() = default;
    void Run(const CmdLine& cmdLine);
};
#endif


//SwmPack.cpp
//操作实现

#include <iostream>
#include "SwmPack.h"

using namespace std;


void SwmPack::Run(const CmdLine& cmdLine)
{
    vector<string> vargs = std::move(cmdLine.Get());
    for (auto arg : vargs) {
        cout<<arg<<endl;
    }
}

 

//makefile

main : main.o CmdLine.o SwmPack.o
    g++ -o main main.o CmdLine.o SwmPack.o -g -Wall -std=c++11
main.o : main.cpp CmdLine.h SwmPack.h
    g++ -c main.cpp -g -Wall -std=c++11
CmdLine.o : CmdLine.cpp
    g++ -c CmdLine.cpp -g -Wall -std=c++11
SwmPack.o : SwmPack.cpp CmdLine.h
    g++ -c SwmPack.cpp -g -Wall -std=c++11
clean:
    rm -rf main.o CmdLine.o SwnPack.o main

 使用变量

通过“变量名= XXX”的方式定义变量

通过“$(变量名)”的方式使用变量

$@  表示目标文件

$^  表示所有的依赖文件

$<  表示第一个依赖文件

$?  表示比目标还要新的依赖文件列表

.cpp.o表示:目标文件:同名cpp

所以上面的makefile可以写成

TARGET = main
OBJS = main.o CmdLine.o SwmPack.o

$(TARGET) : $(OBJS)
    g++ -o $@ $^ -g -Wall -std=c++11
.cpp.o:
    g++ -c $<
clean:
    rm -rf  $(TARGET) $(OBJS)