diff --git a/Makefile b/Makefile index b5b319e..1f62278 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# This Makefile was generated using MakeGen v1.1.3 made by Tim HÃ¥kansson +# This Makefile was generated using MakeGen v1.1.4 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++ @@ -13,15 +13,16 @@ LIBDIR= LDFLAGS= LIBS=$(LIBDIR) OUTPUT=$(BIN)makegen -.PHONY: all directories rebuild clean dependencies -all: dependencies directories $(OUTPUT) -dependencies: +.PHONY: all directories rebuild clean run +all: directories $(OUTPUT) directories: $(BIN) $(OBJPATH) $(BIN): $(info Creating output directories) @$(MKDIR_P) $(BIN) $(OBJPATH): @$(MKDIR_P) $(OBJPATH) +run: all + @./$(OUTPUT) rebuild: clean all clean: $(info Removing intermediates) diff --git a/src/Common.h b/src/Common.h index e11e286..bb34caf 100755 --- a/src/Common.h +++ b/src/Common.h @@ -13,12 +13,19 @@ // Release , should be backwards compatible with any minor version #define MAKEGEN_VERSION_RELEASE 1 // Minor changes, should be compatible with any other minor version with same major and release. -#define MAKEGEN_VERSION_MINOR 3 +#define MAKEGEN_VERSION_MINOR 4 #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_CLEAN = BIT(3); +const static unsigned int FLAG_MAKE = BIT(4); +const static unsigned int FLAG_RUN = BIT(5); +const static unsigned int FLAG_INSTALL = BIT(6); +const static unsigned int FLAG_REBUILD = BIT(7); +const static unsigned int FLAG_SINGLE_THREAD = BIT(8); +const static unsigned int FLAG_DEPENDENCY = BIT(9); #define LOG_INFO(...) Log(__VA_ARGS__); std::cout << std::endl diff --git a/src/FileUtils.h b/src/FileUtils.h index 3232f29..66b0bab 100644 --- a/src/FileUtils.h +++ b/src/FileUtils.h @@ -1,16 +1,32 @@ #pragma once -#include -#include -#include #include "Common.h" -#include -#include #include +#include +#include +#include +#include #include +#include +#include struct FileUtils { + static bool HasPath(const std::string& path) + { + struct stat info; + + if(stat(path.c_str(), &info) != 0) + return false; + else + return true; + } + + static bool CreateDirectory(const std::string& path) + { + return mkdir(path.c_str(), 0777); + } + static std::string GetRealPath(const std::string& filename) { #if defined(__linux__) diff --git a/src/Makefile.cpp b/src/Makefile.cpp index 1b5d8ba..a598091 100755 --- a/src/Makefile.cpp +++ b/src/Makefile.cpp @@ -94,39 +94,51 @@ void Makefile::Save(const ConfigFile& conf) } } outputFile << "OUTPUT=$(BIN)" << conf.outputname << std::endl; - outputFile << ".PHONY: all directories rebuild clean dependencies" << std::endl; - outputFile << "all: dependencies directories $(OUTPUT)" << std::endl; - //outputFile << "\t$(info ------------------------)" << std::endl; - //outputFile << "\t$(info ---- Done Compiling ----)" << std::endl; - //outputFile << "\t$(info ------------------------)" << std::endl; + outputFile << ".PHONY: all directories rebuild clean run" << std::endl; - outputFile << "dependencies:" << std::endl; - if(!conf.dependencies.empty()) - { - //outputFile << "\t$(info Building dependencies)" << std::endl; - //outputFile << "\t@for dep in $(DEPENDENCIES); do\\" << std::endl; - //outputFile << "\t\tmakegen -C $$dep;\\" << std::endl; - //outputFile << "\tdone" << std::endl; - } + // All + outputFile << "all: directories $(OUTPUT)" << std::endl; + + // Directories outputFile << "directories: $(BIN) $(OBJPATH)" << std::endl; + + // Bin path outputFile << "$(BIN):" << std::endl; outputFile << "\t$(info Creating output directories)" << std::endl; outputFile << "\t@$(MKDIR_P) $(BIN)" << std::endl; + + // Object path outputFile << "$(OBJPATH):" << std::endl; outputFile << "\t@$(MKDIR_P) $(OBJPATH)" << std::endl; + + // Run + outputFile << "run: all" << std::endl; + if(conf.executable) + { + outputFile << "\t@./$(OUTPUT)" << std::endl; + } + + // Rebuild outputFile << "rebuild: clean all" << std::endl; + + // Clean outputFile << "clean:" << std::endl; outputFile << "\t$(info Removing intermediates)" << std::endl; outputFile << "\trm -rf $(OBJPATH)/*.o" << std::endl; + + // Output file outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl; outputFile << "\t$(info Generating output file)" << std::endl; if(conf.executable) outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl; else outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl; + + // Install outputFile << "install: all" << std::endl; outputFile << "\t$(info Installing " << conf.projectname <<" to /usr/bin/)" << std::endl; outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.outputname << std::endl; + std::map dependencies; size_t i = 0; for(auto it = cppFiles.begin(); it!=cppFiles.end();++it) @@ -139,6 +151,7 @@ void Makefile::Save(const ConfigFile& conf) 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->Output(outputFile, conf); outputFile << std::endl; diff --git a/src/main.cpp b/src/main.cpp index 24ff04f..3bc4808 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,28 +1,55 @@ -#include -#include -#include -#include -#include -#include -#include #include "Common.h" -#include "IncludeDeps.h" #include "ConfigFile.h" -#include "Makefile.h" +#include "FileUtils.h" #include "HFileGen.h" +#include "IncludeDeps.h" +#include "Makefile.h" #include "Timer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RETURN_IF(x, b) \ + if(x)\ + return b; + void PrintHelp() { + LOG_INFO("MakeGen ", MAKEGEN_VERSION); + LOG_INFO(""); + LOG_INFO("MakeGen is a utility tool to generate and run Makefiles in a simple manner.\nBy default it always compiles code with parallell jobs."); + LOG_INFO(""); LOG_INFO("Usage: makegen [options]"); - LOG_INFO(" Options:"); - LOG_INFO(" --help\tDisplays this information"); - LOG_INFO(" --conf\tGenerate a config file for the project"); - LOG_INFO(" --version\tDisplays the version of this program"); - LOG_INFO(" install\tGenerates a Makefile and runs make install"); - LOG_INFO(" clean\t\tGenerates a Makefile and runs make clean"); - LOG_INFO(" rebuild\tGenerates a Makefile and runs make rebuild"); - LOG_INFO(" If no option is given it will run default make"); + LOG_INFO(""); + LOG_INFO(" Options:"); + LOG_INFO(" -h, --help Displays this information"); + LOG_INFO(" --conf Prompt the user to enter information to create config"); + LOG_INFO(" file"); + LOG_INFO(" -v, --version Displays the version of this program"); + LOG_INFO(" -m,-a, make,all Generates a Makefile and runs"); + LOG_INFO(" make all"); + LOG_INFO(" -i, install Generates a Makefile and runs"); + LOG_INFO(" make all && make install"); + LOG_INFO(" -c, clean Generates a Makefile and runs"); + LOG_INFO(" make clean"); + LOG_INFO(" -r, rebuild Generates a Makefile and runs"); + LOG_INFO(" make clean && make all"); + LOG_INFO(" -e, run, execute Generates a Makefile and runs"); + LOG_INFO(" make all && make run"); + LOG_INFO(" -s, single Runs additional makegen options as single thread"); + LOG_INFO(" (no --jobs=X flag)"); + LOG_INFO(""); + LOG_INFO(" If no option is given it will run \"make all\""); + LOG_INFO(""); + LOG_INFO(" If multiple make options are given it will run in the following order:"); + LOG_INFO(" clean all install run, rebuild will be translated to \"clean make\""); } std::optional GetConfigFile(const std::string& filepath) @@ -47,36 +74,91 @@ void GenMakefile(const ConfigFile& conf) unsigned int ReadFlags(int argc, char** argv) { unsigned int flags = 0; + bool make = true; for(int i = 1;i 1) { - if(argv[i][0] == '-' && argv[i][1] == '-') + std::string flag(argv[i]); + if(flag == "-h" || flag == "--help") { - std::string flag(argv[i]); - if(flag == "--help") - { - flags |= FLAG_HELP; - } - else if(flag == "--conf") - { - flags |= FLAG_GEN; - } - else if(flag == "--version") - { - flags |= FLAG_VERSION; - } + flags |= FLAG_HELP; + } + else if(flag == "--conf") + { + flags |= FLAG_GEN; + } + else if(flag == "-v" || flag == "--version") + { + flags |= FLAG_VERSION; + } + else if(flag == "make" || flag == "-m" || flag == "all" || flag == "-a") + { + flags |= FLAG_MAKE; + } + else if(flag == "clean" || flag == "-c") + { + make = false; + flags |= FLAG_CLEAN; + } + else if(flag == "run" || flag == "-e" || flag == "execute") + { + flags |= FLAG_RUN; + } + else if(flag == "install" || flag == "-i") + { + flags |= FLAG_INSTALL; + } + else if(flag == "rebuild" || flag == "-r") + { + flags |= FLAG_CLEAN; + flags |= FLAG_MAKE; + } + else if(flag == "single" || flag == "-s") + { + flags |= FLAG_SINGLE_THREAD; + } + else if(flag != "") + { + LOG_ERROR("Unknown argument ", flag); + return FLAG_HELP; } } } + if(make) + flags |= FLAG_MAKE; return flags; } -bool MakeGen(const std::string& filepath, const std::string& args, const ConfigFile& conf) +bool RunMake(const std::string& filepath, unsigned int flags, const ConfigFile& conf) +{ + std::string make = "make --no-print-directory -C " + filepath; + if(!(flags & FLAG_SINGLE_THREAD)) + make += " -j" + std::to_string(std::thread::hardware_concurrency()) + " "; + if(flags & FLAG_CLEAN) + { + RETURN_IF(system(std::string(make + " clean").c_str()) != 0, false); + } + if(flags & FLAG_MAKE) + { + RETURN_IF(system(std::string(make + " all").c_str()) != 0, false); + } + if(flags & FLAG_INSTALL) + { + RETURN_IF(system(std::string(make + " install").c_str()) != 0, false); + } + if(flags & FLAG_RUN && conf.executable) + { + RETURN_IF(system(std::string(make + " run").c_str()) != 0, false); + } + return true; +} + +bool MakeGen(const std::string& filepath, unsigned int flags, const ConfigFile& conf) { for(size_t i = 0;i