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) --- README.md | 5 +-- backend/BackendUtils.cpp | 3 ++ backend/ninja/Ninja.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++--- include/Conf.hpp | 3 +- 4 files changed, 92 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 171e0fb..d32a934 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Simple Build System for Native Languages -Sibs is still in very early testing phase, should only be used if you want to toy around with it. Every new release currently has changes that break backwards compatibility since the design has not been decided yet. +Sibs is still in very early testing phase, should only be used if you want to toy around with it. Every new release can have changes that break backwards compatibility since the design has not been decided yet. -Sibs is inspired by [Cargo](https://github.com/rust-lang/cargo/), you can think of it like a C/C++ version of Cargo. +Sibs is inspired by [Cargo](https://github.com/rust-lang/cargo/), you can think of it like a C/C++/Zig version of Cargo. +Zig support has not been tested properly yet and currently always links to c library and requires a C/C++ compiler to build (for linking). The CMakeLists.txt is only for development purpose and only compiles on linux. diff --git a/backend/BackendUtils.cpp b/backend/BackendUtils.cpp index 6bb0ace..b790978 100644 --- a/backend/BackendUtils.cpp +++ b/backend/BackendUtils.cpp @@ -44,6 +44,9 @@ namespace backend return sibs::Language::CPP; } + if(_tinydir_strcmp(TINYDIR_STRING("zig"), file->extension) == 0) + return sibs::Language::ZIG; + return sibs::Language::NONE; } 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()) { diff --git a/include/Conf.hpp b/include/Conf.hpp index 1d714b6..278acf2 100644 --- a/include/Conf.hpp +++ b/include/Conf.hpp @@ -144,7 +144,8 @@ namespace sibs { NONE, C, - CPP + CPP, + ZIG }; struct SourceFile -- cgit v1.2.3