From 1d3e221a7a20bfd03517e3ae1e35e4a309a69b6a Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 10 Dec 2017 01:10:48 +0100 Subject: Add support for dependencies in global lib dir Global lib dir is located at ~/.sibs/lib TODO: If global lib dir doesn't exist, download it from github/server --- src/GlobalLib.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/GlobalLib.cpp (limited to 'src/GlobalLib.cpp') diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp new file mode 100644 index 0000000..0ed34c7 --- /dev/null +++ b/src/GlobalLib.cpp @@ -0,0 +1,143 @@ +#include "../include/GlobalLib.hpp" +#include "../include/FileUtil.hpp" +#include "../backend/ninja/Ninja.hpp" +#include "../include/Conf.hpp" + +using namespace std; + +namespace sibs +{ + Result GlobalLib::validatePackageExists(const string &globalLibRootDir, const string &name) + { + string packageDir = globalLibRootDir + "/"; + packageDir += name; + FileType packageDirFileType = getFileType(packageDir.c_str()); + switch(packageDirFileType) + { + case FileType::FILE_NOT_FOUND: + { + string errMsg = "Global lib dependency not found: "; + errMsg += name; + return Result::Err(errMsg); + } + case FileType::REGULAR: + { + string errMsg = "Corrupt library directory. "; + errMsg += packageDir; + errMsg += " is a file, expected it to be a directory"; + return Result::Err(errMsg); + } + case FileType::DIRECTORY: + { + return Result::Ok(true); + } + default: + { + return Result::Err("Unexpected error!"); + } + } + } + + const char *sourceFileExtensions[] = { "c", "cc", "cpp", "cxx" }; + bool isSourceFile(tinydir_file *file) + { + if(!file->is_reg) + return false; + + for(const char *sourceFileExtension : sourceFileExtensions) + { + if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0) + return true; + } + + return false; + } + + Result GlobalLib::getDynamicLibsLinkerFlags(const string &globalLibRootDir, const string &name, const string &version) + { + Result packageExistsResult = validatePackageExists(globalLibRootDir, name); + if(packageExistsResult.isErr()) + return Result::Err(packageExistsResult.getErrMsg()); + + string packageDir = globalLibRootDir + "/"; + packageDir += name; + + // TODO: Instead of checking if version is exact match, check if package has same major version + // and same or newer minor version + string foundVersion; + walkDir(packageDir.c_str(), [&foundVersion, &version](tinydir_file *file) + { + if(file->is_dir) + { + printf("version: %s\n", file->name); + if(_tinydir_strcmp(version.c_str(), file->name) == 0) + foundVersion = file->name; + } + }); + + if(foundVersion.empty()) + return Result::Err("Global lib dependency found, but version doesn't match dependency version"); + + packageDir += "/"; + packageDir += version; + + string projectConfFilePath = packageDir; + projectConfFilePath += "/project.conf"; + + FileType projectConfFileType = getFileType(projectConfFilePath.c_str()); + switch(projectConfFileType) + { + case FileType::FILE_NOT_FOUND: + { + string errMsg = "Global lib dependency found: "; + errMsg += packageDir; + errMsg += ", but it's missing a project.conf file"; + return Result::Err(errMsg); + } + case FileType::DIRECTORY: + { + string errMsg = "Global lib dependency found: "; + errMsg += packageDir; + errMsg += ", but it's corrupt (Found directory instead of file)"; + return Result::Err(errMsg); + } + } + + SibsConfig sibsConfig; + Result result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); + if(result.isErr()) + return Result::Err(result.getErrMsg()); + + if(sibsConfig.getPackageName().empty()) + return Result::Err("project.conf is missing required field package.name"); + + backend::Ninja ninja(backend::Ninja::LibraryType::STATIC); + walkDirFilesRecursive(packageDir.c_str(), [&ninja, &packageDir](tinydir_file *file) + { + if (isSourceFile(file)) + { + printf("Adding source file: %s\n", file->path + packageDir.size() + 1); + ninja.addSourceFile(file->path + packageDir.size() + 1); + } else + { + //printf("Ignoring non-source file: %s\n", file->path + packageDir.size() + 1); + } + }); + + // TODO: Create build path if it doesn't exist + string debugBuildPath = packageDir + "/build/debug"; + Result buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str()); + if(buildFileResult.isErr()) + return Result::Err(buildFileResult.getErrMsg()); + + Result buildResult = ninja.build(debugBuildPath.c_str()); + if(buildResult.isErr()) + return Result::Err(buildResult.getErrMsg()); + + string staticLibPath = debugBuildPath; + staticLibPath += "/lib"; + staticLibPath += name; + staticLibPath += ".a"; + return Result::Ok(staticLibPath); + } +} \ No newline at end of file -- cgit v1.2.3