#include "BackendUtils.hpp" #include "../include/FileUtil.hpp" #include "ninja/Ninja.hpp" using namespace std; using namespace sibs; namespace backend { static bool isPathSubPathOf(const FileString &path, const FileString &subPathOf) { return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0; } const _tinydir_char_t *cFileExtensions[] = { TINYDIR_STRING("c"), TINYDIR_STRING("C"), TINYDIR_STRING("cc") }; const _tinydir_char_t *cppFileExtensions[] = { TINYDIR_STRING("cp"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx"), TINYDIR_STRING("c++") }; sibs::FileString BackendUtils::getFileExtension(const sibs::FileString &filepath) { size_t indexOfDot = filepath.find_last_of('.'); if(indexOfDot == sibs::FileString::npos) return TINYDIR_STRING(""); indexOfDot += 1; return filepath.substr(indexOfDot); } sibs::Language BackendUtils::getFileLanguage(const _tinydir_char_t *extension) { for(const _tinydir_char_t *sourceFileExtension : cFileExtensions) { if(_tinydir_strcmp(sourceFileExtension, extension) == 0) return sibs::Language::C; } for(const _tinydir_char_t *sourceFileExtension : cppFileExtensions) { if(_tinydir_strcmp(sourceFileExtension, extension) == 0) return sibs::Language::CPP; } if(_tinydir_strcmp(TINYDIR_STRING("zig"), extension) == 0) return sibs::Language::ZIG; return sibs::Language::NONE; } sibs::Language BackendUtils::getFileLanguage(tinydir_file *file) { if(!file->is_reg) return sibs::Language::NONE; return getFileLanguage(file->extension); } void BackendUtils::collectSourceFiles(const _tinydir_char_t *projectPath, Ninja *ninjaProject, const SibsConfig &sibsConfig, bool recursive) { walkDir(projectPath, [ninjaProject, &sibsConfig, recursive](tinydir_file *file) { FileString pathNative = file->path; #if OS_FAMILY == OS_FAMILY_WINDOWS replaceChar(pathNative, L'/', L'\\'); #endif if(file->is_reg) { sibs::Language fileLanguage = getFileLanguage(file); if (fileLanguage != sibs::Language::NONE) { string filePathUtf8 = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size()); ninjaProject->addSourceFile(fileLanguage, filePathUtf8.c_str()); } else { //printf("Ignoring non-source file: %s\n", file->path + projectPath.size()); } } else { if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath())) { string filePathUtf8 = toUtf8(pathNative.c_str()); ninjaProject->setTestSourceDir(filePathUtf8.c_str()); } else if(recursive && !directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs()) && _tinydir_strcmp(file->name, TINYDIR_STRING("sibs-build")) != 0) { FileString projectConfPath = file->path; #if OS_FAMILY == OS_FAMILY_WINDOWS projectConfPath += L'\\'; #else projectConfPath += '/'; #endif projectConfPath += TINYDIR_STRING("project.conf"); auto projectConfFileType = getFileType(projectConfPath.c_str()); if(!sibsConfig.isTest() && getFileType(projectConfPath.c_str()) == FileType::REGULAR) { backend::Ninja *subProject = new backend::Ninja(); SibsConfig *subProjectConfig = new SibsConfig(sibsConfig.getCompiler(), file->path, sibsConfig.getOptimizationLevel(), false); subProjectConfig->packaging = sibsConfig.packaging; subProjectConfig->platform = sibsConfig.platform; subProjectConfig->bundling = sibsConfig.bundling; FileString subProjectBuildPath; readSibsConfig(file->path, projectConfPath, *subProjectConfig, subProjectBuildPath); collectSourceFiles(file->path, subProject, *subProjectConfig, true); ninjaProject->addSubProject(subProject, subProjectConfig, move(subProjectBuildPath)); } else collectSourceFiles(file->path, ninjaProject, sibsConfig, true); } } return true; }); } }