#include #include "Ninja.hpp" #include "../../include/FileUtil.hpp" using namespace std; namespace backend { string join(const vector &list, const char *joinStr) { if(list.empty()) return ""; string result; long stringSize = 0; long joinStrLen = strlen(joinStr); int i = 0; for(const string &str : list) { stringSize += str.size(); if(!str.empty() && i > 0) stringSize += joinStrLen; ++i; } result.reserve(stringSize); i = 0; for(const string &str : list) { if(i > 0); result += joinStr; result += str; ++i; } return move(result); } void Ninja::addSourceFile(const char *filepath) { if(filepath && !containsSourceFile(filepath)) sourceFiles.emplace_back(filepath); } bool Ninja::containsSourceFile(const char *filepath) const { for(const string &sourceFile : sourceFiles) { if(sourceFile == filepath) return true; } return false; } void Ninja::build(const std::string &packageName, const char *savePath) { if(sourceFiles.empty()) return; printf("Package name: %s\n", packageName.c_str()); string result; result.reserve(16384); result += "cflags = -Wall -Werror\n\n"; result += "rule cpp_COMPILER\n"; result += " command = ccache c++ $ARGS -c $in -o $out\n\n"; result += "rule cpp_LINKER\n"; result += " command = ccache c++ $ARGS -o $out $in $LINK_ARGS $aliasing\n\n"; vector objectNames; for(const string &sourceFile : sourceFiles) { //string sourceFileEncoded = sourceFile; //replace(sourceFileEncoded, '/', '@'); string objectName = packageName + "@exe/" + sourceFile + ".o"; result += "build "; result += objectName; result += ": cpp_COMPILER ../../"; result += sourceFile; result += "\n"; result += " ARGS = '-I" + packageName + "@exe' '-I.' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-O0' '-g'\n\n"; objectNames.emplace_back(objectName); } result += "build "; result += packageName; result += ": cpp_LINKER "; result += join(objectNames, " "); result += "\n"; result += " LINK_ARGS = '-Wl,--no-undefined' '-Wl,--as-needed'\n\n"; sibs::fileOverwrite(savePath, sibs::StringView(result.data(), result.size())); printf("Created ninja build file: %s\n", savePath); } }