makefile编写

在实际开发中,项目的源代码文件比较多,按类型、功能、模块分别存放在不同的目录和文件中,哪些文件需要先编译,那些文件后编译,那些文件需要重新编译,还有更多更复杂的操作。

make是一个强大的实用工具,用于管理项目的编译和链接。make需要一个编译规则文件makefile,可实现自动化编译。

一、app/demo01.cpp

#include "public.h"  // 包含通用函数和类的头文件。
#include "myapi.h"     // 包含另一个通用函数和类的头文件。
using namespace std;

int main()
{
  func();    // 调用通用的函数。

  func1();   // 调用另一个通用的函数。

  AA a;      // 用通用类声明对象。
  a.show();  // 调用对象的方法。

  BB b;      // 用另一个通用类声明对象。
  b.show();  // 调用对象的方法。
}

二、app/makefile

INCLUDEDIR=-I/home/wucz/tools -I/home/wucz/api

LIBDIR=-L/home/wucz/tools -L/home/wucz/api



all:demo01 demo02 demo03



demo01:demo01.cpp

        g++ -o demo01 demo01.cpp $(INCLUDEDIR) $(LIBDIR) -lpublic -lmyapi

        cp demo01 /tmp/.



demo02:demo02.cpp

        g++ -o demo02 demo02.cpp $(INCLUDEDIR) $(LIBDIR) -lpublic -lmyapi



demo03:demo03.cpp

        g++ -o demo03 demo03.cpp $(INCLUDEDIR) $(LIBDIR) -lpublic -lmyapi



clean:

        rm -f demo01 demo02 demo03

这段代码是一个简单的 Makefile,用于编译和链接三个 C++ 源文件(demo01.cpp,demo02.cpp,demo03.cpp),并生成对应的可执行文件。

让我来解释一下每个部分的含义:

1. `INCLUDEDIR=-I/home/wucz/tools -I/home/wucz/api`:定义了包含文件的路径,-I 选项告诉编译器在哪里搜索头文件。

2. `LIBDIR=-L/home/wucz/tools -L/home/wucz/api`:定义了库文件的路径,-L 选项告诉链接器在哪里搜索库文件。

3. `all:demo01 demo02 demo03`:声明了一个名为 "all" 的伪目标,它依赖于 demo01、demo02 和 demo03 这三个目标,表示当我们运行 `make all` 时,会依次编译这三个目标。

4. `demo01:demo01.cpp`:定义了一个目标 demo01,它依赖于 demo01.cpp 文件。当 demo01.cpp 文件被修改时,make 会重新编译 demo01。

5. 接下来的几行是编译和链接的命令,通过使用 `g++` 命令编译对应的源文件,并指定了包含文件路径 (`$(INCLUDEDIR)`) 和库文件路径 (`$(LIBDIR)`),以及所需要链接的库文件 (`-lpublic -lmyapi`)。

6. `cp demo01 /tmp/.`:将生成的可执行文件 demo01 复制到 /tmp 目录下。

7. 类似的规则也适用于 demo02 和 demo03。

8. `clean:`:定义了一个名为 "clean" 的目标,用于清理生成的可执行文件。执行 `make clean` 时,会删除所有生成的可执行文件。

这就是这个 Makefile 的基本结构和功能。

三、tools/public.h

// 通用函数和类的头文件。

#include <iostream>

// 声明一个通用的函数。

void func();

// 声明一个通用的类。

class AA

{

public:

  void show();

};

四、tools/public.cpp

// 通用函数和类的代码实现文件。

#include "public.h"

using namespace std;

// 通用函数的代码实现。

void func()

{

  cout << "升级了调用了func()函数。\n";

}

// 通用类的代码实现。

void AA::show()

{

  cout << "升级了我是一只傻傻鸟。\n";

}

五、tools/makefile

# 指定编译的目标文件是libpublic.a和libpublic.so

all:libpublic.a \

    libpublic.so

# 编译libpublic.a需要依赖public.h和public.cpp

# 如果被依赖文件内容发生了变化,将重新编译libpublic.a

libpublic.a:public.h public.cpp

        g++ -c -o libpublic.a public.cpp

libpublic.so:public.h public.cpp

        g++ -fPIC -shared -o libpublic.so public.cpp

# clean用于清理编译目标文件,仅在make clean才会执行。

clean:

        rm -f libpublic.a libpublic.so

六、api/myapi.h

// 另一个通用函数和类的头文件。

#include <iostream>

// 声明一个通用的函数。

void func1();

// 声明一个通用的类。

class BB

{

public:

  void show();

};

七、api/myapi.cpp

// 另一个通用函数和类的代码实现文件。

#include "myapi.h"

using namespace std;

// 通用函数的代码实现。

void func1()

{

  cout << "调用了func1()函数。\n";

}

// 通用类的代码实现。

void BB::show()

{

  cout << "你是一只傻傻鸟。\n";

}

八、api/makefile

# 指定编译的目标文件是libmyapi.a和libmyapi.so

all:libmyapi.a libmyapi.so

# 编译libmyapi.a需要依赖myapi.h和myapi.cpp

# 如果被依赖文件内容发生了变化,将重新编译libmyapi.a

libmyapi.a:myapi.h myapi.cpp

        g++ -c -o libmyapi.a myapi.cpp

libmyapi.so:myapi.h myapi.cpp

        g++ -fPIC -shared -o libmyapi.so myapi.cpp

# clean用于清理编译目标文件,仅在make clean才会执行。

clean:

        rm -f libmyapi.a libmyapi.so

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值