From 9dd940a47e99becff4213e0abe38799da47771ac Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 20 Sep 2018 20:25:40 +0200 Subject: Add zig support (still primitive) --- backend/ninja/Ninja.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 4 deletions(-) (limited to 'backend/ninja') diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index 6516cfb..9d5dc42 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -91,6 +91,9 @@ namespace backend result += "\""; break; } + default: + assert(false); + break; } return result; } @@ -131,6 +134,9 @@ namespace backend result += objectFileName; break; } + default: + assert(false); + break; } return result; } @@ -422,6 +428,37 @@ namespace backend return {}; } + static string replaceAll(const string &input, const string &from, const string &to) + { + string result = input; + size_t index = 0; + while((index = result.find(from, index)) != string::npos) + { + result.replace(index, from.length(), to); + index += to.length(); + } + return result; + } + + static string convertCIncludeSyntaxToZigInclude(Compiler compiler, const string &cIncludes) + { + switch (compiler) + { + case Compiler::GCC: + { + return replaceAll(cIncludes, "-I", "-isystem "); + } + case Compiler::MSVC: + { + return replaceAll(cIncludes, "/I", "-isystem "); + } + default: + assert(false); + break; + } + return cIncludes; + } + Result Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) { if (!sourceFiles.empty()) @@ -528,6 +565,8 @@ namespace backend globalIncDir += dependencyExportIncludeDirs; ninjaBuildFile.defineGlobalVariable("globalIncDir", globalIncDir); + // TODO: Find a better way to convert includes, this could be slow... + ninjaBuildFile.defineGlobalVariable("globalIncDirZig", convertCIncludeSyntaxToZigInclude(config.getCompiler(), globalIncDir)); vector defines; for(const auto &definePair : config.getDefines()) @@ -564,6 +603,8 @@ namespace backend // TODO: Find equivalent -MMD -MP for other compilers than gcc. MMD is used to create "dependency files" -> if headers are modified then source files will be recompiled // when compiling next time... + // TODO: Verify compilers for language are installed when attempting to build a project that has source files of those types + vector compileCCommand; vector compileCppCommand; @@ -697,6 +738,34 @@ namespace backend ninja::NinjaRule *compileCppRule = ninjaBuildFile.createRule("compile_cpp", compileCppCommand); compileCppRule->depFile = "$out.d"; + // TODO: Specify -mconsole or -mwindows for windows. + // TODO: Convert sibs defines to const variables in a zig file that other zig files can include (like a config file) + vector compileZigArgs = { + ninja::NinjaArg::createRaw("zig build-obj"), + ninja::NinjaArg::createRaw("$in"), + ninja::NinjaArg::createRaw("--output $out"), + ninja::NinjaArg::createRaw("-isystem ."), + ninja::NinjaArg::createRaw("--color on"), + ninja::NinjaArg::createRaw("--library c"), // TODO: Remove this if project does not depend on c libraries or project only has .zig files + ninja::NinjaArg::createRaw("$globalIncDirZig") + }; + + if(config.getOptimizationLevel() == sibs::OPT_LEV_RELEASE) + { + // TODO: Specify a way to change these options, either in project.conf or argument to sibs build + compileZigArgs.insert(compileZigArgs.end(), { + ninja::NinjaArg::createRaw("--release-safe"), + ninja::NinjaArg::createRaw("--strip") + }); + } + + if(libraryType == LibraryType::STATIC) + compileZigArgs.push_back(ninja::NinjaArg::createRaw("--static")); + else if(libraryType == LibraryType::DYNAMIC) // TODO: Verify if this is the correct way to handle dynamic libraries in zig + compileZigArgs.push_back(ninja::NinjaArg::createRaw("-rdynamic")); + + ninja::NinjaRule *compileZigRule = ninjaBuildFile.createRule("compile_zig", compileZigArgs); + bool usesCFiles = false; bool usesCppFiles = false; @@ -704,31 +773,42 @@ namespace backend objectNames.reserve(sourceFiles.size()); for(const sibs::SourceFile &sourceFile : sourceFiles) { - string objectName = config.getPackageName() + "@exe/" + sourceFile.filepath; - objectName += getObjectFileExtension(config.getCompiler()); - + string objectName; switch(sourceFile.language) { case sibs::Language::C: { + objectName += config.getPackageName() + "@exe/" + sourceFile.filepath; + objectName += getObjectFileExtension(config.getCompiler()); ninjaBuildFile.build(compileCRule, "../../" + sourceFile.filepath, objectName, {}); usesCFiles = true; break; } case sibs::Language::CPP: { + objectName += config.getPackageName() + "@exe/" + sourceFile.filepath; + objectName += getObjectFileExtension(config.getCompiler()); ninjaBuildFile.build(compileCppRule, "../../" + sourceFile.filepath, objectName, {}); usesCppFiles = true; break; } + case sibs::Language::ZIG: + { + objectName += "zig-cache/" + sourceFile.filepath; + objectName += getObjectFileExtension(config.getCompiler()); + ninjaBuildFile.build(compileZigRule, "../../" + sourceFile.filepath, objectName, {}); + break; + } default: assert(false); break; } - objectNames.emplace_back(objectName); } + // TODO: For now zig projects (zig object files) are built with c/c++ compiler, + // they should be built with zig if project only contains zig files. + // But how to combine object files with zig? build-exe only wants to accept .zig files string projectGeneratedBinaryFlags; if (!sourceFiles.empty()) { -- cgit v1.2.3