今天学习了一下Boost的文件遍历功能,同时发现GNU编译器有-MM选项,可以自动生成依赖关系,于是利用以上两点写了一个Makefile生成器。可以生成一般的单个可执行文件的Makefile,使用的是Windows+Mingw+boost环境。如果使用Linux,只需在程序中的两个System系统调用处和clean标签生成处将del 改成rm相关操作就好了。
下面是源代码:
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 = "; 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 << ".exe: $(Objs)" << endl; make << "\t$(CC) $(Flags) $(Objs) -o " << target << ".exe" << 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 << "\tdel *.o" << endl; make << "cleanbak:" << endl; make << "\tdel *~" << endl; in.close(); std::system("del .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。
原文地址:http://blog.csdn.net/pdcxs007/article/details/40540153