From 5006226e945fc645e6d9b21252c9eee53cc191cc Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 23 Sep 2018 12:22:37 +0200 Subject: Fix various things, add generated zig header files to global include Fix compile_commands.json missing build steps. Fix c includes -> zig includes flags. Fix crash when running sibs new/init without defining lang. Add generated zig header files to global include so they can be used from c/c++. Add zig and zig/c (using zig and c in the same project) examples. --- .gitignore | 3 + .vscode/c_cpp_properties.json | 7 +- .vscode/settings.json | 35 ++++---- backend/ninja/Ninja.cpp | 144 ++++++++++++++++++++------------ cmake/build_debug.sh | 10 +++ depends/libninja | 2 +- examples/hello_world/.gitignore | 5 -- examples/hello_world/project.conf | 6 -- examples/hello_world/src/main.cpp | 7 -- examples/hello_world/tests/main.cpp | 7 -- examples/hello_world_c_zig/.gitignore | 5 ++ examples/hello_world_c_zig/project.conf | 8 ++ examples/hello_world_c_zig/src/foo.zig | 8 ++ examples/hello_world_c_zig/src/main.c | 14 ++++ examples/hello_world_c_zig/tests/main.c | 7 ++ examples/hello_world_cpp/.gitignore | 5 ++ examples/hello_world_cpp/project.conf | 6 ++ examples/hello_world_cpp/src/main.cpp | 7 ++ examples/hello_world_cpp/tests/main.cpp | 7 ++ examples/hello_world_zig/.gitignore | 5 ++ examples/hello_world_zig/project.conf | 5 ++ examples/hello_world_zig/src/main.zig | 6 ++ include/FileUtil.hpp | 1 + src/FileUtil.cpp | 30 ++++++- src/main.cpp | 9 +- 25 files changed, 242 insertions(+), 107 deletions(-) create mode 100755 cmake/build_debug.sh delete mode 100644 examples/hello_world/.gitignore delete mode 100644 examples/hello_world/project.conf delete mode 100644 examples/hello_world/src/main.cpp delete mode 100644 examples/hello_world/tests/main.cpp create mode 100644 examples/hello_world_c_zig/.gitignore create mode 100644 examples/hello_world_c_zig/project.conf create mode 100644 examples/hello_world_c_zig/src/foo.zig create mode 100644 examples/hello_world_c_zig/src/main.c create mode 100644 examples/hello_world_c_zig/tests/main.c create mode 100644 examples/hello_world_cpp/.gitignore create mode 100644 examples/hello_world_cpp/project.conf create mode 100644 examples/hello_world_cpp/src/main.cpp create mode 100644 examples/hello_world_cpp/tests/main.cpp create mode 100644 examples/hello_world_zig/.gitignore create mode 100644 examples/hello_world_zig/project.conf create mode 100644 examples/hello_world_zig/src/main.zig diff --git a/.gitignore b/.gitignore index e2f4b7a..b086a97 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ build/ cmake/build/ cmake-build-debug/ .vs/ +.vscode/ compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 7748b8f..6ffabe5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -6,12 +6,11 @@ "${workspaceFolder}/**" ], "defines": [], - "compilerPath": "/usr/bin/gcc", + "compilerPath": "/opt/cuda/bin/gcc", "cStandard": "c11", - "cppStandard": "c++14", + "cppStandard": "c++17", "intelliSenseMode": "clang-x64", - "compileCommands": "${workspaceFolder}/compile_commands.json", - "configurationProvider": "vector-of-bool.cmake-tools" + "compileCommands": "${workspaceFolder}/compile_commands.json" } ], "version": 4 diff --git a/.vscode/settings.json b/.vscode/settings.json index a06c734..57115ea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,19 @@ { "files.associations": { + "bitset": "cpp", + "vector": "cpp", + "optional": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "variant": "cpp", + "array": "cpp", + "initializer_list": "cpp", + "utility": "cpp", + "hash_map": "cpp", + "valarray": "cpp", + "*.tcc": "cpp", "cctype": "cpp", "clocale": "cpp", "cmath": "cpp", @@ -11,11 +25,8 @@ "ctime": "cpp", "cwchar": "cpp", "cwctype": "cpp", - "array": "cpp", "atomic": "cpp", "strstream": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", "chrono": "cpp", "cinttypes": "cpp", "codecvt": "cpp", @@ -25,11 +36,10 @@ "deque": "cpp", "list": "cpp", "unordered_map": "cpp", - "vector": "cpp", + "unordered_set": "cpp", "exception": "cpp", "fstream": "cpp", "functional": "cpp", - "initializer_list": "cpp", "iomanip": "cpp", "iosfwd": "cpp", "iostream": "cpp", @@ -39,26 +49,15 @@ "mutex": "cpp", "new": "cpp", "numeric": "cpp", - "optional": "cpp", "ostream": "cpp", "ratio": "cpp", "sstream": "cpp", "stdexcept": "cpp", "streambuf": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "thread": "cpp", "type_traits": "cpp", "tuple": "cpp", - "typeindex": "cpp", "typeinfo": "cpp", - "utility": "cpp", - "variant": "cpp", "__config": "cpp", - "__nullptr": "cpp", - "hash_map": "cpp", - "valarray": "cpp", - "unordered_set": "cpp" - }, - "C_Cpp.configurationWarnings": "Disabled" + "__nullptr": "cpp" + } } \ No newline at end of file diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index e71b22a..2c76fd4 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -219,20 +219,14 @@ namespace backend { string filePathStr = filepath ? filepath : ""; if(filepath && !containsSourceFile(filePathStr)) - { sourceFiles.push_back({ language, filePathStr }); - //printf("Adding source file: %s\n", filepath); - } } void Ninja::addTestSourceDir(const char *dir) { string dirStr = dir ? dir : ""; if(dir && !containsTestSourceDir(dirStr)) - { testSourceDirs.emplace_back(dirStr); - //printf("Using test source directory: %s\n", dir); - } } void Ninja::addDependency(const std::string &binaryFile) @@ -440,26 +434,7 @@ namespace backend 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; - } - - static vector extractIncludesFromCFlag(Compiler compiler, const ninja::NinjaArg &cflag) + static vector extractIncludesFromCFlag(Compiler compiler, const string &cflag) { vector result; string includeStartStr; @@ -485,42 +460,52 @@ namespace backend while(index != string::npos) { char endChar = ' '; - size_t includeStartIndex = cflag.arg.find(includeStartStr, index); + size_t includeStartIndex = cflag.find(includeStartStr, index); if(includeStartIndex == string::npos) break; else if(includeStartIndex > 0) { - if(cflag.arg[includeStartIndex - 1] == '"' || cflag.arg[includeStartIndex - 1] == '\'') - endChar = cflag.arg[includeStartIndex - 1]; + if(cflag[includeStartIndex - 1] == '"' || cflag[includeStartIndex - 1] == '\'') + endChar = cflag[includeStartIndex - 1]; } includeStartIndex += includeStartStr.length(); - size_t includeEndIndex = cflag.arg.find(endChar, includeStartIndex); + size_t includeEndIndex = cflag.find(endChar, includeStartIndex); index = includeEndIndex; if(includeEndIndex == string::npos) - includeEndIndex = cflag.arg.length(); + includeEndIndex = cflag.length(); - result.push_back(ninja::NinjaArg::createRaw(cflag.arg.substr(includeStartIndex, includeEndIndex - includeStartIndex))); + result.push_back(ninja::NinjaArg::createRaw(cflag.substr(includeStartIndex, includeEndIndex - includeStartIndex))); } return result; } - static vector extractIncludesFromCFlags(Compiler compiler, const vector &cflags) + static vector extractIncludesFromCFlags(Compiler compiler, const vector &cflags) { vector result; for(const ninja::NinjaArg &cflag : cflags) { - vector subCFlags = extractIncludesFromCFlag(compiler, cflag); + vector subCFlags = extractIncludesFromCFlag(compiler, cflag.arg); result.insert(result.end(), subCFlags.begin(), subCFlags.end()); } return result; } + static string convertCIncludeSyntaxToZigInclude(Compiler compiler, const string &cIncludes) + { + vector result = extractIncludesFromCFlag(compiler, cIncludes); + string resultStr; + for(ninja::NinjaArg &include : result) + { + resultStr += "-isystem \"" + include.arg + "\""; + } + return resultStr; + } + static vector convertCFlagsIncludesToZigIncludes(Compiler compiler, const vector &cflags) { - vector result; - result = extractIncludesFromCFlags(compiler, cflags); + vector result = extractIncludesFromCFlags(compiler, cflags); for(ninja::NinjaArg &include : result) { include.arg = "-isystem \"" + include.arg + "\""; @@ -596,14 +581,34 @@ namespace backend return result; } - Result Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) + static int getFilenameLength(const string &filepath) { - if (!sourceFiles.empty()) + for(int i = filepath.size(); i >= 0; --i) { - Result createBuildDirResult = createDirectoryRecursive(savePath); - if (createBuildDirResult.isErr()) - return createBuildDirResult; + char c = filepath[i]; + if(c == '/' || c == '\\') + return filepath.size() - i; } + return filepath.size(); + } + + Result Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) + { + Result createBuildDirResult = createDirectoryRecursive(savePath); + if (!createBuildDirResult) + return createBuildDirResult; + + FileString generatedHeadersDir = config.getProjectPath() + TINYDIR_STRING("/sibs-build/generated-headers"); + Result createGeneratedHeadersDirResult = createDirectoryRecursive(generatedHeadersDir.c_str()); + if (!createGeneratedHeadersDirResult) + return createGeneratedHeadersDirResult; + + FileString generatedZigHeadersDir = generatedHeadersDir + TINYDIR_STRING("/zig"); + Result createGeneratedZigHeadersDirResult = createDirectory(generatedZigHeadersDir.c_str()); + if (!createGeneratedZigHeadersDirResult) + return createGeneratedZigHeadersDirResult; + + string generatedZigHeaderDirUtf8 = toUtf8(generatedZigHeadersDir); LibraryType libraryType = getNinjaLibraryType(config.getPackageType()); @@ -701,6 +706,7 @@ namespace backend } globalIncDir += dependencyExportIncludeDirs; + globalIncDir += TINYDIR_STRING(" ") + getIncludeOptionFlag(config.getCompiler(), toUtf8(generatedHeadersDir)); ninjaBuildFile.defineGlobalVariable("globalIncDir", globalIncDir); // TODO: Find a better way to convert includes, this could be slow... ninjaBuildFile.defineGlobalVariable("globalIncDirZig", convertCIncludeSyntaxToZigInclude(config.getCompiler(), globalIncDir)); @@ -881,8 +887,10 @@ namespace backend // TODO: Convert sibs defines to const variables in a zig file that other zig files can include (like a config file). // TODO: Remove --library c if project does not depend on c libraries or project only has .zig files + + ninja::NinjaVariable zigHeaderFile("headerFile"); vector zigTestArgs = { - ninja::NinjaArg::createRaw("zig test $in --output $out -isystem ../../ --color on --library c $globalIncDirZig") + ninja::NinjaArg::createRaw("zig test $in --output $out --output-h $headerFile -isystem ../../ --color on --library c $globalIncDirZig") }; // TODO: Find a way to do this more efficiently @@ -891,6 +899,7 @@ namespace backend ninja::NinjaArg::createRaw("zig build-obj"), ninja::NinjaArg::createRaw("$in"), ninja::NinjaArg::createRaw("--output $out"), + ninja::NinjaArg::createRaw("--output-h $headerFile"), 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 @@ -934,6 +943,38 @@ namespace backend vector objectNames; objectNames.reserve(sourceFiles.size()); + vector zigBuilds; + // TODO(Urgent): Instead of adding zig builds as dependencies for all c/c++ builds, generate two ninja files; one for zig and one for c/c++. + // Then build run zig ninja file first and then c/c++ ninja file. + // That would be more efficient as you dont need to add every single zig build as dependency for all c/c++ builds... + for(const sibs::SourceFile &sourceFile : sourceFiles) + { + if(sourceFile.language == sibs::Language::ZIG) + { + // TODO: Remove this and use NinjaBuilds to get object names + string objectName = config.getPackageName() + "@exe/" + sourceFile.filepath; + objectName += getObjectFileExtension(config.getCompiler()); + objectNames.emplace_back(objectName); + + // TODO: Optimize this by checking if directory has already been created with a hash map + int filenameLength = getFilenameLength(sourceFile.filepath); + string zigSourceDirRelative = sourceFile.filepath.substr(0, sourceFile.filepath.size() - filenameLength); + FileString zigHeaderFileDir = toFileString(generatedZigHeaderDirUtf8 + '/' + zigSourceDirRelative); + Result createZigHeaderFileDirResult = createDirectoryRecursive(zigHeaderFileDir.c_str()); + if(!createZigHeaderFileDirResult) + return createZigHeaderFileDirResult; + + string headerName = sourceFile.filepath.substr(sourceFile.filepath.size() - filenameLength, filenameLength - 4) + ".h"; + ninja::NinjaArgValue zigHeaderFileValue = { zigHeaderFile, '"' + toUtf8(zigHeaderFileDir) + '/' + headerName + '"' }; + ninja::NinjaBuild *ninjaBuild = nullptr; + if(zigTest) + ninjaBuild = testZigRule->build("../../" + sourceFile.filepath, objectName, { zigHeaderFileValue }); + else + ninjaBuild = compileZigRule->build("../../" + sourceFile.filepath, objectName, { zigHeaderFileValue }); + zigBuilds.push_back(ninjaBuild); + } + } + for(const sibs::SourceFile &sourceFile : sourceFiles) { string objectName; @@ -943,7 +984,7 @@ namespace backend { objectName += config.getPackageName() + "@exe/" + sourceFile.filepath; objectName += getObjectFileExtension(config.getCompiler()); - ninjaBuildFile.build(compileCRule, "../../" + sourceFile.filepath, objectName, {}); + compileCRule->build("../../" + sourceFile.filepath, objectName, {}, zigBuilds); usesCFiles = true; break; } @@ -951,18 +992,13 @@ namespace backend { objectName += config.getPackageName() + "@exe/" + sourceFile.filepath; objectName += getObjectFileExtension(config.getCompiler()); - ninjaBuildFile.build(compileCppRule, "../../" + sourceFile.filepath, objectName, {}); + compileCppRule->build("../../" + sourceFile.filepath, objectName, {}, zigBuilds); usesCppFiles = true; break; } case sibs::Language::ZIG: { - objectName += "zig-cache/" + sourceFile.filepath; - objectName += getObjectFileExtension(config.getCompiler()); - if(zigTest) - ninjaBuildFile.build(testZigRule, "../../" + sourceFile.filepath, objectName, {}); - else - ninjaBuildFile.build(compileZigRule, "../../" + sourceFile.filepath, objectName, {}); + // Already built above break; } default: @@ -1041,7 +1077,7 @@ namespace backend buildExeArgs.push_back(ninja::NinjaArg::createRaw(allLinkerFlags)); ninja::NinjaRule *buildExeRule = ninjaBuildFile.createRule("build_exec", buildExeArgs); - ninjaBuildFile.build(buildExeRule, join(objectNames, " "), config.getPackageName(), {}); + buildExeRule->build(join(objectNames, " "), config.getPackageName(), {}); projectGeneratedBinary += config.getPackageName(); #if OS_FAMILY == OS_FAMILY_WINDOWS @@ -1079,7 +1115,7 @@ namespace backend } ninja::NinjaRule *buildStaticRule = ninjaBuildFile.createRule("build_static", buildStaticArgs); - ninjaBuildFile.build(buildStaticRule, join(objectNames, " "), generatedFile, {}); + buildStaticRule->build(join(objectNames, " "), generatedFile, {}); projectGeneratedBinary += generatedFile; projectGeneratedBinary += "\""; @@ -1149,7 +1185,7 @@ namespace backend buildDynamicArgs.push_back(ninja::NinjaArg::createRaw(allLinkerFlags)); ninja::NinjaRule *buildDynamicRule = ninjaBuildFile.createRule("build_dynamic", buildDynamicArgs); - ninjaBuildFile.build(buildDynamicRule, join(objectNames, " "), generatedFile, {}); + buildDynamicRule->build(join(objectNames, " "), generatedFile, {}); projectGeneratedBinary += generatedFile; projectGeneratedBinary += "\""; @@ -1348,7 +1384,7 @@ namespace backend { FileString command = TINYDIR_STRING("ninja -C \""); command += buildFilePath; - command += TINYDIR_STRING("\" -t compdb c_COMPILER cpp_COMPILER BUILD_EXEC BUILD_STATIC BUILD_DYNAMIC > \""); + command += TINYDIR_STRING("\" -t compdb compile_c compile_cpp compile_zig > \""); command += saveDir; command += TINYDIR_STRING("/compile_commands.json\""); Result execResult = exec(command.c_str(), false); diff --git a/cmake/build_debug.sh b/cmake/build_debug.sh new file mode 100755 index 0000000..45dceeb --- /dev/null +++ b/cmake/build_debug.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +scriptpath="$(dirname "$0")" +mkdir -p "$scriptpath/build/debug" +cd "$scriptpath/build/debug" +cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ../../../ +ninja +echo "Debug build success" diff --git a/depends/libninja b/depends/libninja index efd1bdf..2698cbc 160000 --- a/depends/libninja +++ b/depends/libninja @@ -1 +1 @@ -Subproject commit efd1bdf5576ddcff21fecc0ff5efa4d53aa8d08d +Subproject commit 2698cbc14f8a2a108a3252f03e053cb47b8b5101 diff --git a/examples/hello_world/.gitignore b/examples/hello_world/.gitignore deleted file mode 100644 index 636c6b9..0000000 --- a/examples/hello_world/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Compiled sibs files -sibs-build/ -compile_commands.json -tests/sibs-build/ -tests/compile_commands.json diff --git a/examples/hello_world/project.conf b/examples/hello_world/project.conf deleted file mode 100644 index 4c05ce5..0000000 --- a/examples/hello_world/project.conf +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "hello_world" -type = "executable" -version = "0.1.0" -platforms = ["any"] -tests = "tests" diff --git a/examples/hello_world/src/main.cpp b/examples/hello_world/src/main.cpp deleted file mode 100644 index 28bab08..0000000 --- a/examples/hello_world/src/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main(int argc, char **argv) -{ - printf("hello, world!\n"); - return 0; -} diff --git a/examples/hello_world/tests/main.cpp b/examples/hello_world/tests/main.cpp deleted file mode 100644 index 28bab08..0000000 --- a/examples/hello_world/tests/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main(int argc, char **argv) -{ - printf("hello, world!\n"); - return 0; -} diff --git a/examples/hello_world_c_zig/.gitignore b/examples/hello_world_c_zig/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/examples/hello_world_c_zig/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/examples/hello_world_c_zig/project.conf b/examples/hello_world_c_zig/project.conf new file mode 100644 index 0000000..fa006cd --- /dev/null +++ b/examples/hello_world_c_zig/project.conf @@ -0,0 +1,8 @@ +[package] +name = "hello_world_c_zig" +type = "executable" +version = "0.1.0" +platforms = ["linux64"] +tests = "tests" + +[dependencies] diff --git a/examples/hello_world_c_zig/src/foo.zig b/examples/hello_world_c_zig/src/foo.zig new file mode 100644 index 0000000..464eadd --- /dev/null +++ b/examples/hello_world_c_zig/src/foo.zig @@ -0,0 +1,8 @@ +const warn = @import("std").debug.warn; + +extern fn baz() void; + +export fn foo() void { + warn("zig called from c!\n"); + baz(); +} diff --git a/examples/hello_world_c_zig/src/main.c b/examples/hello_world_c_zig/src/main.c new file mode 100644 index 0000000..aeaeae4 --- /dev/null +++ b/examples/hello_world_c_zig/src/main.c @@ -0,0 +1,14 @@ +#include +#include + +void baz() +{ + printf("c called from zig!\n"); +} + +int main(int argc, char **argv) +{ + printf("inside c\n"); + foo(); + return 0; +} diff --git a/examples/hello_world_c_zig/tests/main.c b/examples/hello_world_c_zig/tests/main.c new file mode 100644 index 0000000..9ad80a6 --- /dev/null +++ b/examples/hello_world_c_zig/tests/main.c @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + printf("hello, world!\n"); + return 0; +} diff --git a/examples/hello_world_cpp/.gitignore b/examples/hello_world_cpp/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/examples/hello_world_cpp/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/examples/hello_world_cpp/project.conf b/examples/hello_world_cpp/project.conf new file mode 100644 index 0000000..4c05ce5 --- /dev/null +++ b/examples/hello_world_cpp/project.conf @@ -0,0 +1,6 @@ +[package] +name = "hello_world" +type = "executable" +version = "0.1.0" +platforms = ["any"] +tests = "tests" diff --git a/examples/hello_world_cpp/src/main.cpp b/examples/hello_world_cpp/src/main.cpp new file mode 100644 index 0000000..28bab08 --- /dev/null +++ b/examples/hello_world_cpp/src/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + printf("hello, world!\n"); + return 0; +} diff --git a/examples/hello_world_cpp/tests/main.cpp b/examples/hello_world_cpp/tests/main.cpp new file mode 100644 index 0000000..28bab08 --- /dev/null +++ b/examples/hello_world_cpp/tests/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + printf("hello, world!\n"); + return 0; +} diff --git a/examples/hello_world_zig/.gitignore b/examples/hello_world_zig/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/examples/hello_world_zig/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/examples/hello_world_zig/project.conf b/examples/hello_world_zig/project.conf new file mode 100644 index 0000000..6ad2e1b --- /dev/null +++ b/examples/hello_world_zig/project.conf @@ -0,0 +1,5 @@ +[package] +name = "hello_world_zig" +type = "executable" +version = "0.1.0" +platforms = ["any"] diff --git a/examples/hello_world_zig/src/main.zig b/examples/hello_world_zig/src/main.zig new file mode 100644 index 0000000..c74a3de --- /dev/null +++ b/examples/hello_world_zig/src/main.zig @@ -0,0 +1,6 @@ +const warn = @import("std").debug.warn; + +pub fn main() void +{ + warn("Hello, world!\n"); +} diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp index b808573..aa2b82f 100644 --- a/include/FileUtil.hpp +++ b/include/FileUtil.hpp @@ -53,6 +53,7 @@ namespace sibs Result fileOverwrite(const _tinydir_char_t *filepath, StringView data); Result getHomeDir(); Result getCwd(); + Result createDirectory(const _tinydir_char_t *path); // Note: Will not delete created directories if this operation fails for some reason Result createDirectoryRecursive(const _tinydir_char_t *path); Result getRealPath(const _tinydir_char_t *path); diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp index aca2778..53430c4 100644 --- a/src/FileUtil.cpp +++ b/src/FileUtil.cpp @@ -288,6 +288,31 @@ namespace sibs return Result::Err(strerror(errno)); } + Result createDirectory(const _tinydir_char_t *path) + { + size_t pathLength = strlen(path); + if(pathLength > _TINYDIR_PATH_MAX - 1) + { + string errMsg = "Directory path too long: "; + errMsg += string(path, pathLength); + return Result::Err(errMsg, ENAMETOOLONG); + } + + if(mkdir(path, S_IRWXU) != 0) + { + int error = errno; + if(error != EEXIST) + { + string errMsg = "Failed to create directory: "; + errMsg += toUtf8(path); + errMsg += "; reason: "; + errMsg += strerror(error); + return Result::Err(errMsg, error); + } + } + return Result::Ok(true); + } + Result createDirectoryRecursive(const _tinydir_char_t *path) { char pathBuffer[_TINYDIR_PATH_MAX]; @@ -303,7 +328,8 @@ namespace sibs char *p = pathBuffer; for(size_t i = 0; i < pathLength; ++i) { - if(i > 0 && *p == '/') + char c = *p; + if(i > 0 && (c == '/' || c == '\\')) { *p = '\0'; if(mkdir(pathBuffer, S_IRWXU) != 0) @@ -318,7 +344,7 @@ namespace sibs return Result::Err(errMsg, error); } } - *p = '/'; + *p = c; } ++p; } diff --git a/src/main.cpp b/src/main.cpp index b232d93..0d29a75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -701,6 +701,9 @@ int initProject(int argc, const _tinydir_char_t **argv) ferr << "Error: Project type not defined, expected to be either --exec, --static or --dynamic" << endl; usageInit(); } + + if(!lang) + lang = TINYDIR_STRING("c++"); string projectTypeConf; if(_tinydir_strcmp(projectType, TINYDIR_STRING("--exec")) == 0) @@ -714,9 +717,6 @@ int initProject(int argc, const _tinydir_char_t **argv) ferr << "Expected project type to be either --exec, --static or --dynamic; was: " << projectType << endl << endl; usageInit(); } - - if(!lang) - lang = TINYDIR_STRING("c++"); // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found if(projectPath.empty()) @@ -920,6 +920,9 @@ int newProject(int argc, const _tinydir_char_t **argv) ferr << "Error: Project type not defined, expected to be either --exec, --static or --dynamic" << endl; usageNew(); } + + if(!lang) + lang = TINYDIR_STRING("c++"); string projectTypeConf; if(_tinydir_strcmp(projectType, TINYDIR_STRING("--exec")) == 0) -- cgit v1.2.3