From aecbe5c501716379660d411157e254f90e2a9168 Mon Sep 17 00:00:00 2001 From: Thraix Date: Wed, 30 Jan 2019 16:58:52 +0100 Subject: [PATCH] Add support for h file generation --- Makefile | 17 +++--- makegen.conf | 3 +- src/Common.h | 8 +-- src/ConfigFile.cpp | 131 ++++++++++++++++++++++++++------------------ src/ConfigFile.h | 6 +- src/FileUtils.h | 37 +++++++++++++ src/HFileGen.cpp | 31 +++++++++++ src/HFileGen.h | 10 ++++ src/IncludeDeps.cpp | 8 +-- src/IncludeDeps.h | 2 +- src/Makefile.cpp | 80 +++++++++------------------ src/Makefile.h | 5 +- src/main.cpp | 3 + 13 files changed, 213 insertions(+), 128 deletions(-) mode change 100755 => 100644 Makefile mode change 100755 => 100644 makegen.conf create mode 100644 src/FileUtils.h create mode 100644 src/HFileGen.cpp create mode 100644 src/HFileGen.h diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index bc1ebb9..5a6c2cc --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# This Makefile was generated using MakeGen v1.0.9 made by Tim HÃ¥kansson +# This Makefile was generated using MakeGen v1.1.0 made by Tim HÃ¥kansson # and is licensed under MIT. Full source of the project can be found at # https://github.com/Thraix/MakeGen CC=@g++ @@ -6,7 +6,7 @@ CO=@g++ -o BIN=bin/ OBJPATH=$(BIN)intermediates INCLUDES= -OBJECTS=$(OBJPATH)/ConfigFile.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/main.o +OBJECTS=$(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/main.o CFLAGS=$(INCLUDES) -std=c++17 -c -w -g3 -D_DEBUG LIBDIR= LDFLAGS= @@ -24,14 +24,17 @@ install: all $(info Installing MakeGen to /usr/bin/) @cp $(OUTPUT) /usr/bin/makegen $(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/Common.h src/ConfigFile.h - $(info -[25%]- $<) + $(info -[20%]- $<) + $(CC) $(CFLAGS) -o $@ $< +$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/HFileGen.h src/ConfigFile.h + $(info -[40%]- $<) $(CC) $(CFLAGS) -o $@ $< $(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/IncludeDeps.h - $(info -[50%]- $<) + $(info -[60%]- $<) $(CC) $(CFLAGS) -o $@ $< -$(OBJPATH)/Makefile.o : src/Makefile.cpp src/Common.h src/IncludeDeps.h src/Makefile.h src/ConfigFile.h - $(info -[75%]- $<) +$(OBJPATH)/Makefile.o : src/Makefile.cpp src/Common.h src/FileUtils.h src/IncludeDeps.h src/Makefile.h src/ConfigFile.h + $(info -[80%]- $<) $(CC) $(CFLAGS) -o $@ $< -$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigFile.h src/IncludeDeps.h src/Makefile.h src/Timer.h +$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigFile.h src/HFileGen.h src/IncludeDeps.h src/Makefile.h src/Timer.h $(info -[100%]- $<) $(CC) $(CFLAGS) -o $@ $< diff --git a/makegen.conf b/makegen.conf old mode 100755 new mode 100644 index a305e5f..5001666 --- a/makegen.conf +++ b/makegen.conf @@ -1,10 +1,11 @@ #libs #libdirs #includedirs -#srcdirs +#srcdir src/ #defines _DEBUG +#compileflags #outputdir bin/ #projectname diff --git a/src/Common.h b/src/Common.h index 208f21a..9b8942c 100755 --- a/src/Common.h +++ b/src/Common.h @@ -10,14 +10,14 @@ // Major changes, probably not be backwards compatible #define MAKEGEN_VERSION_MAJOR 1 // Release , should be backwards compatible with any minor version -#define MAKEGEN_VERSION_RELEASE 0 +#define MAKEGEN_VERSION_RELEASE 1 // Minor changes, should be compatible with any other minor version with same major and release. -#define MAKEGEN_VERSION_MINOR 9 +#define MAKEGEN_VERSION_MINOR 0 #define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR)) const static unsigned int FLAG_HELP = BIT(0); -const static unsigned int FLAG_GEN= BIT(1); -const static unsigned int FLAG_VERSION= BIT(2); +const static unsigned int FLAG_GEN = BIT(1); +const static unsigned int FLAG_VERSION = BIT(2); #define LOG_INFO(...) Log(__VA_ARGS__); std::cout << std::endl diff --git a/src/ConfigFile.cpp b/src/ConfigFile.cpp index 34af385..647b766 100755 --- a/src/ConfigFile.cpp +++ b/src/ConfigFile.cpp @@ -8,9 +8,8 @@ #define FLAG_STRING 2 #define FLAG_BOOL 3 ConfigFile::ConfigFile() - : outputdir("bin"), outputname("out.a"),executable(true), shared(true) + : outputdir("bin"), outputname("out.a"), hFile(""),executable(true), shared(true), generateHFile(false) { - } ConfigFile ConfigFile::Load(const std::string& filename) @@ -51,16 +50,16 @@ ConfigFile ConfigFile::Load(const std::string& filename) vec = &conf.flags; loadFlag = FLAG_VECTOR; } - else if(line == "#srcdirs") - { - vec = &conf.srcdirs; - loadFlag = FLAG_VECTOR; - } else if(line == "#defines") { vec = &conf.defines; loadFlag = FLAG_VECTOR; } + else if(line == "#srcdir") + { + s = &conf.srcdir; + loadFlag = FLAG_STRING; + } else if(line == "#outputdir") { s = &conf.outputdir; @@ -76,6 +75,11 @@ ConfigFile ConfigFile::Load(const std::string& filename) s = &conf.projectname; loadFlag = FLAG_STRING; } + else if(line == "#hfile") + { + s = &conf.hFile; + loadFlag = FLAG_STRING; + } else if(line == "#executable") { b = &conf.executable; @@ -86,6 +90,11 @@ ConfigFile ConfigFile::Load(const std::string& filename) b = &conf.shared; loadFlag = FLAG_BOOL; } + else if(line == "#generatehfile") + { + b = &conf.generateHFile; + loadFlag = FLAG_BOOL; + } else { LOG_ERROR("Invalid flag: ", line); @@ -111,7 +120,42 @@ ConfigFile ConfigFile::Load(const std::string& filename) } } } - return conf; + } + if(conf.hFile == "") + conf.hFile = conf.projectname+".h"; + + return conf; +} + +void ConfigFile::InputBoolean(const std::string& inputText, bool& b) +{ + std::string input; + while(true) + { + LOG_INFO(inputText); + std::getline(std::cin, input); + if(input.length() > 0) + { + if(input[0] == 'y' || input[0] == 'n') + { + b = input[0] == 'y'; + return; + } + } + } +} + +void ConfigFile::InputString(const std::string& inputText, std::string& str, bool needEnding, bool allowEmpty) +{ + str = ""; + while(true) + { + LOG_INFO(inputText); + std::getline(std::cin, str); + if(needEnding && str[str.length()-1] != '/' && !str.empty()) + str += '/'; + if(allowEmpty || !str.empty()) + return; } } @@ -120,12 +164,9 @@ void ConfigFile::InputMultiple(const std::string& inputText, std::vector libs; std::vector libdirs; std::vector includedirs; - std::vector srcdirs; std::vector defines; std::vector flags; std::string outputdir; + std::string srcdir; std::string outputname; std::string projectname; + std::string hFile; bool executable; bool shared; + bool generateHFile; public: ConfigFile(); void Save() const; static ConfigFile Gen(); static ConfigFile Load(const std::string& filename); private: + static void InputBoolean(const std::string& inputText, bool& b); static void InputMultiple(const std::string& inputText, std::vector& vec, bool needEnding); + static void InputString(const std::string& inputText, std::string& vec, bool needEnding, bool allowEmpty); }; diff --git a/src/FileUtils.h b/src/FileUtils.h new file mode 100644 index 0000000..1f830f4 --- /dev/null +++ b/src/FileUtils.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include "Common.h" +#include +#include + +struct FileUtils +{ + static void GetAllFiles(const std::string& folder, std::vector& files) + { + DIR* dp; + struct dirent *dirp; + if((dp = opendir(folder.c_str())) == NULL){ + LOG_ERROR(errno); + return; + } + while((dirp = readdir(dp)) != NULL) + { + if(dirp->d_type == DT_DIR) + { + if(strcmp(dirp->d_name,".") == 0) + continue; + if(strcmp(dirp->d_name,"..") == 0) + continue; + GetAllFiles(folder+dirp->d_name+"/", files); + } + else + { + files.push_back(folder+dirp->d_name); + } + } + closedir(dp); + } +}; diff --git a/src/HFileGen.cpp b/src/HFileGen.cpp new file mode 100644 index 0000000..1b111da --- /dev/null +++ b/src/HFileGen.cpp @@ -0,0 +1,31 @@ +#include "HFileGen.h" + +#include "FileUtils.h" +#include + +void HFileGen::Create(const ConfigFile& conf) +{ + std::set hFiles; + std::vector files; + FileUtils::GetAllFiles(conf.srcdir,files); + // include paramenter with the path of the file + // For example src/graphics/Window.h -> graphics/Window.h if src is a src folder + for(auto it = files.begin(); it!=files.end();++it) + { + size_t extensionPos = it->find_last_of("."); + if(extensionPos != std::string::npos) + { + std::string filename = it->substr(conf.srcdir.length()); + if(it->substr(extensionPos+1) == "h" && filename != conf.hFile) + { + // Make files sorted in alphabetical order + hFiles.emplace(filename); + } + } + } + + std::ofstream os(conf.srcdir+"/"+conf.hFile); + os << "#pragma once" << std::endl << std::endl; + for(auto&& hFile : hFiles) + os << "#include <" << hFile << ">" << std::endl; +} diff --git a/src/HFileGen.h b/src/HFileGen.h new file mode 100644 index 0000000..ab877fe --- /dev/null +++ b/src/HFileGen.h @@ -0,0 +1,10 @@ +#pragma once + +#include "ConfigFile.h" +#include + +class HFileGen +{ + public: + static void Create(const ConfigFile& conf); +}; diff --git a/src/IncludeDeps.cpp b/src/IncludeDeps.cpp index 3cd9d04..7ccc51a 100755 --- a/src/IncludeDeps.cpp +++ b/src/IncludeDeps.cpp @@ -2,7 +2,7 @@ std::set IncludeDeps::printSet; int IncludeDeps::printCounter = 0; -IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, const std::map& files, std::map& allDeps) +IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, const std::set& files, std::map& allDeps) : filepath(dir+filename) { if(filename[filename.length() - 1] =='h') @@ -20,11 +20,11 @@ IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, co auto it = files.find(include); if(it != files.end()) { - auto itD = allDeps.find(it->second + it->first); + auto itD = allDeps.find(dir + *it); if(itD == allDeps.end()) { - IncludeDeps* inc = new IncludeDeps(it->first, it->second,files,allDeps); - dependencies.emplace(it->second+ it->first, inc); + IncludeDeps* inc = new IncludeDeps(*it, dir,files,allDeps); + dependencies.emplace(dir + *it, inc); }else{ dependencies.emplace(itD->first, itD->second); } diff --git a/src/IncludeDeps.h b/src/IncludeDeps.h index 9e11c4b..9511072 100755 --- a/src/IncludeDeps.h +++ b/src/IncludeDeps.h @@ -17,7 +17,7 @@ class IncludeDeps static std::set printSet; static int printCounter; - IncludeDeps(const std::string& filename, const std::string& dir, const std::map& files, std::map& allDeps); + IncludeDeps(const std::string& filename, const std::string& dir, const std::set& files, std::map& allDeps); std::string GetIncludeFile(const std::string& line, size_t pos, const std::string& filename); diff --git a/src/Makefile.cpp b/src/Makefile.cpp index 86dbcb7..ba2e34c 100755 --- a/src/Makefile.cpp +++ b/src/Makefile.cpp @@ -6,37 +6,12 @@ #include #include "IncludeDeps.h" #include "Common.h" - -void Makefile::GetAllFiles(const std::string& folder, std::vector& files) -{ - DIR* dp; - struct dirent *dirp; - if((dp = opendir(folder.c_str())) == NULL){ - LOG_ERROR(errno); - return; - } - while((dirp = readdir(dp)) != NULL) - { - if(dirp->d_type == DT_DIR) - { - if(strcmp(dirp->d_name,".") == 0) - continue; - if(strcmp(dirp->d_name,"..") == 0) - continue; - GetAllFiles(folder+dirp->d_name+"/", files); - } - else - { - files.push_back(folder+dirp->d_name); - } - } - closedir(dp); -} +#include "FileUtils.h" void Makefile::Save(const ConfigFile& conf) { - std::map hFiles; - std::map cppFiles; + std::set hFiles; + std::set cppFiles; PreSave(conf,hFiles,cppFiles); std::ofstream outputFile("Makefile"); @@ -65,9 +40,9 @@ void Makefile::Save(const ConfigFile& conf) outputFile << "OBJECTS="; for(auto it = cppFiles.begin();it!=cppFiles.end();++it) { - size_t extensionPos = it->first.find_last_of("."); - size_t slash = it->first.find_last_of("/")+1; - outputFile << "$(OBJPATH)/" << it->first.substr(slash, extensionPos - slash) << ".o "; + size_t extensionPos = it->find_last_of("."); + size_t slash = it->find_last_of("/")+1; + outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o "; } outputFile << std::endl; if(conf.executable || !conf.shared) @@ -131,13 +106,13 @@ void Makefile::Save(const ConfigFile& conf) for(auto it = cppFiles.begin(); it!=cppFiles.end();++it) { i++; - auto itD = dependencies.find(it->first+it->second); + auto itD = dependencies.find(conf.srcdir + *it); if(itD == dependencies.end()) { - IncludeDeps* deps = new IncludeDeps(it->first, it->second,hFiles,dependencies); - size_t extensionPos = it->first.find_last_of("."); - size_t slash = it->first.find_last_of("/")+1; - std::string oFile = it->first.substr(slash, extensionPos - slash)+".o "; + IncludeDeps* deps = new IncludeDeps(*it, conf.srcdir,hFiles,dependencies); + size_t extensionPos = it->find_last_of("."); + size_t slash = it->find_last_of("/")+1; + std::string oFile = it->substr(slash, extensionPos - slash)+".o "; outputFile << "$(OBJPATH)/" << oFile << ": " << *deps << std::endl; outputFile << "\t$(info -[" << (int)(i / (float)cppFiles.size() * 100) << "%]- $<)" << std::endl; outputFile << "\t$(CC) $(CFLAGS) -o $@ $<" << std::endl; @@ -146,30 +121,25 @@ void Makefile::Save(const ConfigFile& conf) } } -void Makefile::PreSave(const ConfigFile& conf, std::map& hFiles, - std::map& cppFiles) +void Makefile::PreSave(const ConfigFile& conf, std::set& hFiles, std::set& cppFiles) { - for(auto itSrc = conf.srcdirs.begin();itSrc != conf.srcdirs.end();++itSrc) + std::vector files; + FileUtils::GetAllFiles(conf.srcdir,files); + // include paramenter with the path of the file + // For example src/graphics/Window.h -> graphics/Window.h if src is a src folder + for(auto it = files.begin(); it!=files.end();++it) { - std::vector files; - GetAllFiles(*itSrc,files); - // include paramenter with the path of the file - // For example src/graphics/Window.h -> graphics/Window.h if src is a src folder - for(auto it = files.begin(); it!=files.end();++it) + size_t extensionPos = it->find_last_of("."); + if(extensionPos != std::string::npos) { - size_t extensionPos = it->find_last_of("."); - if(extensionPos != std::string::npos) + if(it->substr(extensionPos+1) == "cpp") { - if(it->substr(extensionPos+1) == "cpp") - { - cppFiles.emplace(it->substr(itSrc->length()), *itSrc); - } - else - { - hFiles.emplace(it->substr(itSrc->length()), *itSrc); - } + cppFiles.emplace(it->substr(conf.srcdir.length())); + } + else + { + hFiles.emplace(it->substr(conf.srcdir.length())); } } } - } diff --git a/src/Makefile.h b/src/Makefile.h index 7c5ba9a..6f5805c 100755 --- a/src/Makefile.h +++ b/src/Makefile.h @@ -1,13 +1,12 @@ #pragma once #include "ConfigFile.h" -#include +#include class Makefile { public: static void Save(const ConfigFile& conf); private: - static void PreSave(const ConfigFile& conf, std::map& hFiles, std::map& cppFiles); - static void GetAllFiles(const std::string& folder, std::vector& files); + static void PreSave(const ConfigFile& conf, std::set& hFiles, std::set& cppFiles); }; diff --git a/src/main.cpp b/src/main.cpp index 9a29698..be71f80 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,6 +9,7 @@ #include "IncludeDeps.h" #include "ConfigFile.h" #include "Makefile.h" +#include "HFileGen.h" #include "Timer.h" void PrintHelp() @@ -30,6 +31,8 @@ bool GenMakefile() if(f.good()) { ConfigFile conf = ConfigFile::Load("makegen.conf"); + if(conf.generateHFile) + HFileGen::Create(conf); Makefile::Save(conf); return true; }