多文件编译 makefile

参考

http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

工程文件

来自C++ Primer的第9章

包括coordin.h file1.cpp file2.cpp

coordin.h

// coordin.h -- structure templates and function prototypes
// structure templates
#ifndef COORDIN_H_
#define COORDIN_H_ 

struct polar
{
        double distance;
        double angle;
};

struct rect
{
        double x;
        double y;
};

polar rect_to_polar(rect xypos);
void show_polar(polar dapos);

#endif

file1.cpp

#include<iostream>
#include"coordin.h"
using namespace std;
int main()
{
        rect rplace;
        polar pplace;

        cout << "enter the x and y values: ";
        while (cin >> rplace.x >> rplace.y)
        {
                pplace = rect_to_polar(rplace);
                show_polar(pplace);
                cout << "next two numbers (q to quit):";
        }
        cout << "Bye!\n" ;
        return 0;
}

file2.cpp

#include <iostream>
#include <cmath>
#include "coordin.h"

polar rect_to_polar(rect xypos)
{
        using namespace std;
        polar answer;
        answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
        answer.angle = atan2(xypos.y, xypos.x);
        return answer;
}

void show_polar(polar dapos)
{
        using namespace std;
        const double Rad_to_deg = 57.29577951;
        cout << "distance = " << dapos.distance;
        cout << ", angle = " << dapos.angle * Rad_to_deg;
        cout << " degrees\n";
}

这样的情况下,使用的g++命令是

g++ file1.cpp file2.cpp -o a.out

makefile 可以这样写:

coordin.o: file2.cpp file1.cpp
        g++ file1.cpp file2.cpp -o coordin.o
clean:
        -rm *.o

但是如果这样写的话,.h文件修改了是不会重新编译的。

于是我们引入下面的一个makefile:

CC=g++
CFLAGS=-I.
DEPS=coordin.h
OBJ=file1.o file2.o

%.o: %.cpp $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

target: $(OBJ)
        $(CC) -o $@ $^ $(CFLAGS)

clean:
        -rm *.o
        -rm target

make之后有以下的输出:

g++ -c -o file1.o file1.cpp -I. 
g++ -c -o file2.o file2.cpp -I. 
g++ -o target file1.o file2.o -I. 

解释

用到了一些变量
CC代表用g++来编译
CFLAGS 使用-I.来表示在当前目录搜寻
DEPS 说明依赖文件是coordin.h
OBJ是两个.o文件

第一句命令:所有的.o文件依赖于相应的.cpp文件。在这里就像是for循环一样展开,因为有两个.o文件,所以会展开成两个命令。

其中$@表示循环目标文件,在这里是循环.o文件file1.ofile2.o

$<表示将$@.o去掉,再加上.cpp,在这里,就是将file1.o 去掉.o,加上.cpp,变成file1.cpp。同理循环得到file2.cpp,于是有以下转换:

%.o: %.cpp $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

<-->      

g++ -c -o file1.o file1.cpp -I. 
%.o: %.cpp $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

<-->      

g++ -c -o file2.o file2.cpp -I. 

然后还有一个@^是代表所有的依赖。在这里所有的依赖就是OBJ=file1.o file2.o,于是做简单的替换得到实际执行的命令:

target: $(OBJ)
        $(CC) -o $@ $^ $(CFLAGS)

<-->        

g++ -o target file1.o file2.o -I. 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值