Makefile生成器,使用C++和Boost实现

今天学习了一下Boost的文件遍历功能,同一时候发现GNU编译器有-MM选项。能够自己主动生成依赖关系,于是利用以上两点写了一个Makefile生成器。

能够生成一般的单个可运行文件的Makefile。使用的是Windows+Mingw+boost环境。假设使用Linux,仅仅需在程序中的两个System系统调用处和clean标签生成处将del 改成rm相关操作就好了。

如今更改成了Linux版本号。下载的版本号是Windows的。

以下是源码:

makemake.cpp:

#include <iostream>  
#include <fstream>  
#include <cstdlib>  
#include <vector>  
#include <string>  
#include <exception>  
#include <boost/filesystem/operations.hpp>  
#include <boost/filesystem/path.hpp>  
#include <boost/algorithm/string.hpp>  
#include <boost/program_options.hpp>  

using namespace std;  
namespace po = boost::program_options;  
using namespace boost::filesystem;  
using namespace boost;  

void getFiles(vector<string>& src);  

const string head = string(  
"######################################################################\n")+  
"# This makefile is generated by makemake.                            #\n"+  
"# By Eric Brown.                                                     #\n"+  
"# 2014/10/27                                                         #\n"+  
"######################################################################\n";  

int main(int argc, char* argv[])  
{  
    vector<string> src;  
    string compiler = "g++";  
    string target = "a";  
    vector<string> objs;  
    bool debug = false;  

    try  
    {  
        po::options_description desc("---Help---");  
        desc.add_options()  
            ("help,h", "print this message.")  
            ("gcc,c", "use gcc compiler. Program uses g++ default.")  
            ("debug,g", "use debug option(-g) in makefile.")  
            ("out,o", po::value<string>(), "the target file name.");  
        po::positional_options_description p;  
        p.add("out", -1);  
        po::variables_map vm;  
        po::store(po::command_line_parser(argc, argv).options(desc).  
                positional(p).run(), vm);  
        po::notify(vm);  

        if (vm.count("help"))  
        {  
            cout << desc << endl;  
            return 0;  
        }  
        if (vm.count("gcc"))  
            compiler = "gcc";  
        if (vm.count("out"))  
            target = vm["out"].as<string>();  
        if (vm.count("debug"))  
            debug = true;  
    } catch(std::exception& e) {  
        cout << e.what() << endl;  
        return 1;  
    }  

    getFiles(src);  

    ofstream make;  
    make.open("Makefile", ios_base::out);  

    make << head << endl;  
    make << "CC = " << compiler << endl;  
    make << "Flags = " << endl;  
    make << "LIBS = ";
    if (debug)  
        make << "-g";  

    make << endl;  

    make << "src = ";  
    for (int i = 0; i < src.size(); ++i)  
    {  
        make << src[i] << ‘ ‘;  
        std::system(string(compiler + " -MM \"" + src[i] + "\" >> .temp~").c_str());  
    }  

    make << "\nObjs = ";  
    for (int i = 0; i < src.size(); ++i)  
    {  
        if (ends_with(src[i], ".cpp"))  
            objs.push_back(replace_last_copy(src[i], ".cpp", ".o"));  
        if (ends_with(src[i], ".c"))  
            objs.push_back(replace_last_copy(src[i], ".c", ".o"));  
        make << objs[i] << ‘ ‘;  
    }  
    make << endl;  

    make << ‘\n‘ << target << ": $(Objs)" << endl;  
    make << "\t$(CC) $(Flags) $(Objs) -o " << target << " ${LIBS}" << endl;  
    make << "$(Objs): $<" << endl;
    make << "\t$(CC) $(Flags) $< -c\n" << endl;  

    ifstream in(".temp~");  
    string line;  
    while(getline(in, line))  
        make << line << endl;  
    make << endl;  

    make << "clean:" << endl;  
    make << "\trm -f ${Objs}" << endl;  
    make << "cleanbak:" << endl;  
    make << "\trm -f *~" << endl;  
    in.close();  

    std::system("rm -f .temp~");  

    make.close();  

    return 0;  
}  

void getFiles(vector<string>& src)  
{  
    path p = current_path();  
    directory_iterator beg(p);  
    directory_iterator end;  
    for (; beg != end; beg++)  
    {  
        string name = beg->path().filename().string();  
        if (ends_with(name, ".cpp") ||  
                ends_with(name, ".c"))  
            src.push_back(name);  
    }  
}  

可运行程序能够在这里下载:http://download.csdn.net/detail/pdcxs007/8090981。

时间: 2024-07-31 16:01:47

Makefile生成器,使用C++和Boost实现的相关文章

8 C++ Boost 日期 时间

目录: 1,日期 构造date 继续构造date对象 date特别的值 date能访问的函数 boost date_time 与tm转换 日期的加减运算 计算时间段 日期的迭代器 日期生成器 4月的第一个/最后一个星期一 日期生成器: 某月的第几个星期几,某天的前一个/后一个星期一 日期生成器算法 日历类 gregorian_calendar 2,时间 posix 时间的构造 时间的操作 时间段 操作 时间迭代器 1,日期 构造date [email protected]:~/boost$ ca

qmake和moc的功能(★firecat推荐★)

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://devbean.blog.51cto.com/448512/355100 前面我们说过,Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”.这里我们从Qt新增加的关键字就可以看出来:signals.slots 或者 emit.所以有人会觉得 Qt 的程序编译速度慢,这主要是因为在 Qt 将源代码交给标准 C++ 编译器,如 gcc 之前,需要事先将这些扩展

CMake命令:CMake构建系统的骨架

CMake命令:CMake构建系统的骨架 80个命令(转载自http://www.cnblogs.com/coderfenghc/archive/2012/06/16/CMake_ch_01.html#2996205) CMD#1: add_custom_command为生成的构建系统添加一条自定义的构建规则. add_custom_command命令有两种主要的功能:第一种是为了生成输出文件,添加一条自定义命令. add_custom_command(OUTPUT output1 [outpu

嵌入式linux QT开发(一)——QT简介

嵌入式linux QT开发(一)--QT简介 一.QT简介 1.QT简介 QT是一个跨平台的C++图形用户界面库,由挪威TrollTech公司出品,目前包括Qt Creator, QtEmbedded,Qt Designer快速开发工具,Qt Linguist国际化工具等部分,Qt支持所有Linux/Unix系统,还支持Windows平台. 2.QT优点 Qt是一个跨平台的C++图形用户界面应用程序框架,提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能.Qt很容易扩展,并且允许真正地组

NDK开发

1 CDT 是 Eclipse 插件,它将把 Eclipse 转换为功能强大的 C/C++ IDE. C/C++在Eclipse平台下的开发工具.它提供的功能包括:C/C++编辑器(一些基本的功能:语法高亮显示,代码编辑等),C/C++调试器,C/C++ Launcher,剖析器,内容提示,Makefile生成器等. 采集 #HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-

Java开源项目(备查)

转自:http://www.blogjava.net/Carter0618/archive/2008/08/11/221222.html Spring Framework  [Java开源 J2EE框架] Spring 是一个解决了许多在J2EE开发中常见的问题的强大框架. Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯.Spring的架构基础是基于使用JavaBean属性的 Inversion of Control容器.然而,这仅仅是完整图景中的一部分

C++开发安卓、windows下搭建Android NDK开发环境

1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个工具,我们可以把用C/C++代码编译成可以直接运行在Android平台上的本地代码,这些本地代码以动态链接库( *.so )的形式存在,也正因为这样,我们可以通过复用这些动态链接库从而复用本地代码. 那么,通过NDK这个开发工具包,那么我们是否可以将一个APK完全使用C/C++来编写呢? 答案是不可

陈梓涵:我们为什么要学习设计模式

先说点题外话.最近想做一个Computational Graph Database (https://github.com/vczh/vczh_toys/blob/master/PlayWithLinux/Database/draft),顺便练习一下Linux下写C++程序的技巧,深刻的体会到了一个道理.Linux下有这么多烂工具,每个人做了一个工具,都会有另外一个人觉得这个工具很烂,然后就做了一个更烂的来恶心他.我本着这种开源的精神,写了一个GayMake(误,于是就有了这次的贴图.倘若最后这

CMake 手册详解

CMake 手册详解 来源 http://www.cnblogs.com/coderfenghc/tag/cmake/ 公司的一个项目使用CMake作为跨平台构建工具:业务有需求,当然要好好研读一下官方的技术手册.目前的计划是先把官方手册翻译一下,了解清楚CMake中的各种命令.属性和变量的用法.同时在工作中也会阅读CMake的真实源码,后续会基于此陆续写一些工程中使用CMake的心得.CMake的版本也在不停更新,有些新的命令和变量会随着版本更新添加进来,这是后事了,暂且不管:现在锁定CMak