diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-01-14 18:36:20 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2018-01-26 09:13:15 +0100 |
commit | 91ab79f1475371e6e57d00f24f98bccb7749d15a (patch) | |
tree | 40fa847c783ecdc165ad1fc6b7c5cd2a026d25b9 /src | |
parent | b7b7b3d359765e3ffb011dc34ff928e614766666 (diff) |
Add git dependencies
Diffstat (limited to 'src')
-rw-r--r-- | src/CmakeModule.cpp | 8 | ||||
-rw-r--r-- | src/Conf.cpp | 129 | ||||
-rw-r--r-- | src/GitRepository.cpp | 101 | ||||
-rw-r--r-- | src/GlobalLib.cpp | 158 | ||||
-rw-r--r-- | src/PkgConfig.cpp | 23 | ||||
-rw-r--r-- | src/main.cpp | 17 |
6 files changed, 360 insertions, 76 deletions
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index 106f2c6..35e4884 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -62,10 +62,10 @@ namespace sibs // CMakeLists.txt may contain: set(CMAKE_MODULE_PATH "PathToModules"). This needs to be replaced with list append, // otherwise our added module path is replaced. // It may work to do like vcpkg instead - to use -DCMAKE_TOOLCHAIN_FILE program argument to specify path to script (https://github.com/Microsoft/vcpkg/blob/master/docs/examples/using-sqlite.md) - vector<Dependency> globalLibDependencies; + vector<PackageListDependency*> globalLibDependencies; #if OS_FAMILY == OS_FAMILY_POSIX - vector<Dependency> pkgConfigDependencies; - for(const Dependency &dependency : config.getDependencies()) + vector<PackageListDependency*> pkgConfigDependencies; + for(PackageListDependency *dependency : config.getPackageListDependencies()) { Result<bool> pkgConfigDependencyValidation = PkgConfig::validatePkgConfigPackageVersionExists(dependency); if(pkgConfigDependencyValidation.isOk()) @@ -84,7 +84,7 @@ namespace sibs { printf("%s, using global lib...\n", pkgConfigLinkerFlagsResult.getErrMsg().c_str()); globalLibDependencies.reserve(globalLibDependencies.size() + pkgConfigDependencies.size()); - for (const Dependency &pkgConfigDependency : pkgConfigDependencies) + for (PackageListDependency *pkgConfigDependency : pkgConfigDependencies) { globalLibDependencies.push_back(pkgConfigDependency); } diff --git a/src/Conf.cpp b/src/Conf.cpp index 93ec6e7..41cc157 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -528,6 +528,22 @@ namespace sibs return true; } + SibsConfig::~SibsConfig() + { + // TODO: Fix this shit.. why does this cause segfault? + /* + for(PackageListDependency *dependency : packageListDependencies) + { + //delete dependency; + } + + for(GitDependency *dependency : gitDependencies) + { + //delete dependency; + } + */ + } + bool SibsConfig::isDefined(const std::string &name) const { return defines.find(name) != defines.end(); @@ -794,16 +810,7 @@ namespace sibs } else if(currentObject.equals("dependencies")) { - if(value.isSingle()) - { - // TODO: Validate version is number in correct format - Dependency dependency; - dependency.name = string(name.data, name.size); - dependency.version = string(value.asSingle().data, value.asSingle().size); - dependencies.emplace_back(dependency); - } - else - throw ParserException("Expected field under dependencies to be a single value, was a list"); + parseDependencies(name, value); } else if(currentObject.equals("define")) { @@ -897,6 +904,97 @@ namespace sibs } } + void SibsConfig::parseDependencies(const StringView &name, const ConfigValue &value) + { + if(value.isSingle()) + { + // TODO: Validate version is number in correct format + PackageListDependency *dependency = new PackageListDependency(); + dependency->name = string(name.data, name.size); + dependency->version = string(value.asSingle().data, value.asSingle().size); + packageListDependencies.emplace_back(dependency); + } + else if(value.isObject()) + { + enum class DepType + { + NONE, + GIT + }; + + DepType depType = DepType::NONE; + for(auto it : value.asObject()) + { + DepType fieldDepType = DepType::NONE; + if(it.first == "git" || it.first == "branch" || it.first == "revision") + fieldDepType = DepType::GIT; + + if(fieldDepType == DepType::NONE) + { + string errMsg = "Invalid dependency object field \""; + errMsg += it.first; + errMsg += "\""; + throw ParserException(errMsg); + } + + if(depType != DepType::NONE && fieldDepType != depType) + { + switch(depType) + { + case DepType::GIT: + { + string errMsg = "Invalid dependency object field \""; + errMsg += it.first; + errMsg += "\" is invalid for a git dependency"; + throw ParserException(errMsg); + } + default: + throw ParserException("Invalid dependency object"); + } + } + depType = fieldDepType; + } + + switch(depType) + { + case DepType::GIT: + { + auto gitIt = value.asObject().find("git"); + if(gitIt == value.asObject().end()) + { + throw ParserException("Required field \"git\" is missing from git dependency. Expected an url to location of git repository"); + } + + auto branchIt = value.asObject().find("branch"); + string branch; + if(branchIt == value.asObject().end()) + branch = "master"; + else + branch = string(branchIt->second.data, branchIt->second.size); + + auto revisionIt = value.asObject().find("revision"); + string revision; + if(revisionIt == value.asObject().end()) + revision = "HEAD"; + else + revision = string(revisionIt->second.data, revisionIt->second.size); + + GitDependency *dependency = new GitDependency(); + dependency->name = string(name.data, name.size); + dependency->url = string(gitIt->second.data, gitIt->second.size); + dependency->branch = branch; + dependency->revision = revision; + gitDependencies.emplace_back(dependency); + break; + } + default: + throw ParserException("Invalid dependency object"); + } + } + else + throw ParserException("Expected field under dependencies to be a single value or an object, was a list"); + } + void SibsConfig::parseCLang(const StringView &fieldName, const ConfigValue &fieldValue) { if(fieldName.equals("version")) @@ -1183,16 +1281,7 @@ namespace sibs { if(currentObject.equals("dependencies")) { - if(value.isSingle()) - { - // TODO: Validate version is number in correct format - Dependency dependency; - dependency.name = string(name.data, name.size); - dependency.version = string(value.asSingle().data, value.asSingle().size); - dependencies.emplace_back(dependency); - } - else - throw ParserException("Expected field under dependencies to be a single value, was a list"); + parseDependencies(name, value); } else { diff --git a/src/GitRepository.cpp b/src/GitRepository.cpp new file mode 100644 index 0000000..0a3b0a7 --- /dev/null +++ b/src/GitRepository.cpp @@ -0,0 +1,101 @@ +#include "../include/GitRepository.hpp" +#include "../include/Dependency.hpp" +#include <git2.h> +#include <string> +#include <cassert> + +using namespace std; + +static bool libgitInitialized = false; + +namespace sibs +{ + void gitInit() + { + if(!libgitInitialized) + { + libgitInitialized = true; + // TODO: Call git_libgit2_shutdown in destructor? dont really need to do that though + git_libgit2_init(); + } + } + + Result<bool> buildGitError(int error, const string &errorPrefix) + { + const git_error *e = giterr_last(); + string errMsg = errorPrefix; + errMsg += ": "; + errMsg += to_string(error); + errMsg += "/"; + errMsg += to_string(e->klass); + errMsg += ": "; + errMsg += e->message; + return Result<bool>::Err(errMsg, error); + } + + Result<bool> GitRepository::clone(GitDependency *gitDependency, const FileString &repoDirPath) + { + gitInit(); + git_repository *repo; + int error = git_clone(&repo, gitDependency->url.c_str(), toUtf8(repoDirPath).c_str(), NULL); + if(error != 0) + return buildGitError(error, "Failed to clone git repository"); + + git_repository_free(repo); + return Result<bool>::Ok(true); + } + + Result<bool> GitRepository::pull(GitDependency *gitDependency, const FileString &repoDirPath) + { + gitInit(); + int error; + + git_repository *repo; + error = git_repository_open(&repo, toUtf8(repoDirPath).c_str()); + if(error != 0) + return buildGitError(error, "Failed to open git repository"); + + git_remote *remote; + error = git_remote_lookup(&remote, repo, "origin"); + if(error != 0) + return buildGitError(error, "Failed to do remote lookup for git repository"); + + // TODO: Setup option to be able to use callback for progress (for output in console) and handling credentials + error = git_remote_fetch(remote, NULL, NULL, "pull"); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to do remote fetch for git repository"); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + git_reference *ref; + error = git_reference_dwim(&ref, repo, gitDependency->branch.c_str()); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to do reference lookup for git repository"); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + git_annotated_commit *annotatedCommit; + error = git_annotated_commit_from_ref(&annotatedCommit, repo, ref); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to get commit from ref"); + git_annotated_commit_free(annotatedCommit); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + assert(false); + + git_annotated_commit_free(annotatedCommit); + git_remote_free(remote); + git_repository_free(repo); + return Result<bool>::Ok(true); + } +} diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp index 3842388..eee37dd 100644 --- a/src/GlobalLib.cpp +++ b/src/GlobalLib.cpp @@ -5,6 +5,8 @@ #include "../include/curl.hpp" #include "../include/Archive.hpp" #include "../include/CmakeModule.hpp" +#include "../include/Dependency.hpp" +#include "../include/GitRepository.hpp" using namespace std; @@ -65,13 +67,13 @@ namespace sibs return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0; } - Result<bool> GlobalLib::getLibs(const std::vector<Dependency> &libs, const SibsConfig &parentConfig, const FileString &globalLibRootDir, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) + Result<bool> GlobalLib::getLibs(const std::vector<PackageListDependency*> &libs, const SibsConfig &parentConfig, const FileString &globalLibRootDir, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) { - for(const Dependency &globalLibDependency : libs) + for(PackageListDependency *globalLibDependency : libs) { - printf("Dependency %s is missing from pkg-config, trying global lib\n", globalLibDependency.name.c_str()); - Result<bool> globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); - if(globalLibLinkerFlagsResult.isErr()) + printf("Dependency %s is missing from pkg-config, trying global lib\n", globalLibDependency->name.c_str()); + Result<bool> globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, globalLibDependency->name, globalLibDependency->version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + if(!globalLibLinkerFlagsResult) { if(globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_NOT_FOUND || globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_VERSION_NO_MATCH) { @@ -86,16 +88,48 @@ namespace sibs // invalid package name/version. A check should be done if it is the name or version // that is invalid. Result<bool> downloadDependencyResult = GlobalLib::downloadDependency(globalLibDependency); - if(downloadDependencyResult.isErr()) + if(!downloadDependencyResult) return downloadDependencyResult; - globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); - if(globalLibLinkerFlagsResult.isErr()) - return Result<bool>::Err(globalLibLinkerFlagsResult); + globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, globalLibDependency->name, globalLibDependency->version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + if(!globalLibLinkerFlagsResult) + return globalLibLinkerFlagsResult; } else { - return Result<bool>::Err(globalLibLinkerFlagsResult); + return globalLibLinkerFlagsResult; + } + } + } + + for(GitDependency *gitDependency : parentConfig.getGitDependencies()) + { + Result<bool> gitLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, gitDependency, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + if(!gitLibLinkerFlagsResult) + { + if(gitLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_NOT_FOUND) + { + printf("Dependency %s not found in global lib, trying to download from git\n", gitDependency->name.c_str()); + // TODO: Download several dependencies at the same time by adding them to a list + // and then iterate them and download them all using several threads. + // All dependecies should be downloaded at the same time, this includes dependencies of dependencies. + // If a dependency is missing, fail build BEFORE downloading dependencies and before compiling anything. + // You do not want to possibly wait several minutes only for build to fail when there is no compilation error. + + // TODO: If return error is invalid url, then the message should be converted to + // invalid package name/version. A check should be done if it is the name or version + // that is invalid. + Result<bool> downloadDependencyResult = GlobalLib::downloadDependency(gitDependency); + if(!downloadDependencyResult) + return downloadDependencyResult; + + gitLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(parentConfig, globalLibRootDir, gitDependency, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + if(!gitLibLinkerFlagsResult) + return gitLibLinkerFlagsResult; + } + else + { + return gitLibLinkerFlagsResult; } } } @@ -138,28 +172,53 @@ namespace sibs packageDir += TINYDIR_STRING("/"); packageDir += versionPlatformNative; + return GlobalLib::getLibsLinkerFlagsCommon(parentConfig, packageDir, name, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + } + + Result<bool> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, GitDependency *gitDependency, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) + { + Result<bool> packageExistsResult = validatePackageExists(globalLibRootDir, gitDependency->name); + if (packageExistsResult.isErr()) + return packageExistsResult; + +#if OS_FAMILY == OS_FAMILY_POSIX + FileString namePlatformNative = gitDependency->name; + FileString versionPlatformNative = gitDependency->revision; +#else + FileString namePlatformNative = utf8To16(name); + FileString versionPlatformNative = utf8To16(version); +#endif + + FileString packageDir = globalLibRootDir + TINYDIR_STRING("/"); + packageDir += namePlatformNative; + packageDir += TINYDIR_STRING("/"); + packageDir += versionPlatformNative; + + // TODO: Check path is valid git repository by using git_repository_open_ext + + // TODO: Pull if revision == HEAD, fail build if there are conflicts. + // TODO: When building a sibs project, put a symlink in libs directory. + // This allows you to have dependency on a project and make changes to it without pushing + // to remote before the dependant project can see the changes. + //GitRepository gitRepo; + //gitRepo.pull(gitDependency, packageDir); + + return GlobalLib::getLibsLinkerFlagsCommon(parentConfig, packageDir, gitDependency->name, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); + } + + Result<bool> GlobalLib::getLibsLinkerFlagsCommon(const SibsConfig &parentConfig, const FileString &packageDir, const string &dependencyName, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) + { FileString projectConfFilePath = packageDir; projectConfFilePath += TINYDIR_STRING("/project.conf"); FileType projectConfFileType = getFileType(projectConfFilePath.c_str()); - switch(projectConfFileType) + if(projectConfFileType != FileType::REGULAR) { - case FileType::FILE_NOT_FOUND: - { - string errMsg = "Global lib dependency found: "; - errMsg += toUtf8(packageDir); - errMsg += ", but it's missing a project.conf file"; - return Result<bool>::Err(errMsg); - } - case FileType::DIRECTORY: - { - string errMsg = "Global lib dependency found: "; - errMsg += toUtf8(packageDir); - errMsg += ", but it's corrupt (Found directory instead of file)"; - return Result<bool>::Err(errMsg); - } + string errMsg = "Dependency not found: "; + errMsg += toUtf8(packageDir); + return Result<bool>::Err(errMsg, DependencyError::DEPENDENCY_NOT_FOUND); } - + SibsConfig sibsConfig(parentConfig.getCompiler(), packageDir, parentConfig.getOptimizationLevel(), false); Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); if (result.isErr()) @@ -171,7 +230,7 @@ namespace sibs if(sibsConfig.getPackageType() == PackageType::EXECUTABLE) { string errMsg = "The dependency "; - errMsg += name; + errMsg += dependencyName; errMsg += " is an executable. Only libraries can be dependencies"; return Result<bool>::Err(errMsg); } @@ -179,7 +238,7 @@ namespace sibs if (!containsPlatform(sibsConfig.getPlatforms(), SYSTEM_PLATFORM)) { string errMsg = "The dependency "; - errMsg += name; + errMsg += dependencyName; errMsg += " does not support your platform ("; errMsg += asString(SYSTEM_PLATFORM); errMsg += ")"; @@ -268,7 +327,7 @@ namespace sibs case Compiler::GCC: { libPath += "/lib"; - libPath += name; + libPath += dependencyName; if (sibsConfig.getPackageType() == PackageType::STATIC) { libPath += ".a"; @@ -290,7 +349,7 @@ namespace sibs case Compiler::MSVC: { libPath += "/"; - libPath += name; + libPath += dependencyName; if (sibsConfig.getPackageType() == PackageType::STATIC) { libPath += ".lib"; @@ -316,9 +375,9 @@ namespace sibs } } - Result<bool> GlobalLib::downloadDependency(const Dependency &dependency) + Result<bool> GlobalLib::downloadDependency(PackageListDependency *dependency) { - Result<string> packageUrlResult = Package::getPackageUrl(dependency.name.c_str(), dependency.version.c_str(), SYSTEM_PLATFORM_NAME); + Result<string> packageUrlResult = Package::getPackageUrl(dependency->name.c_str(), dependency->version.c_str(), SYSTEM_PLATFORM_NAME); if(!packageUrlResult) return Result<bool>::Err(packageUrlResult); @@ -329,28 +388,49 @@ namespace sibs return Result<bool>::Err(libPathResult); FileString libPath = libPathResult.unwrap(); libPath += TINYDIR_STRING("/.sibs/lib/"); - libPath += toFileString(dependency.name); + libPath += toFileString(dependency->name); libPath += TINYDIR_STRING("/"); - libPath += toFileString(dependency.version); + libPath += toFileString(dependency->version); FileString libArchivedFilePath = libPathResult.unwrap(); libArchivedFilePath += TINYDIR_STRING("/.sibs/archive/"); - libArchivedFilePath += toFileString(dependency.name); + libArchivedFilePath += toFileString(dependency->name); Result<bool> createArchiveDirResult = createDirectoryRecursive(libArchivedFilePath.c_str()); - if(createArchiveDirResult.isErr()) + if(!createArchiveDirResult) return createArchiveDirResult; libArchivedFilePath += TINYDIR_STRING("/"); - libArchivedFilePath += toFileString(dependency.version); + libArchivedFilePath += toFileString(dependency->version); Result<bool> downloadResult = curl::downloadFile(url.c_str(), libArchivedFilePath.c_str()); - if(downloadResult.isErr()) + if(!downloadResult) return downloadResult; // Create build path. This is done here because we dont want to create it if download fails Result<bool> createLibDirResult = createDirectoryRecursive(libPath.c_str()); - if(createLibDirResult.isErr()) + if(!createLibDirResult) return createLibDirResult; return Archive::extract(libArchivedFilePath.c_str(), libPath.c_str()); } + + Result<bool> GlobalLib::downloadDependency(GitDependency *dependency) + { + Result<FileString> libPathResult = getHomeDir(); + if (!libPathResult) + return Result<bool>::Err(libPathResult); + FileString libPath = libPathResult.unwrap(); + libPath += TINYDIR_STRING("/.sibs/lib/"); + libPath += toFileString(dependency->name); + + // We dont care if the directory already exists. Nothing will happen if it does + Result<bool> createLibDirResult = createDirectoryRecursive(libPath.c_str()); + if(!createLibDirResult) + return createLibDirResult; + + libPath += TINYDIR_STRING("/"); + libPath += toFileString(dependency->revision); + + GitRepository gitRepo; + return gitRepo.clone(dependency, libPath); + } } diff --git a/src/PkgConfig.cpp b/src/PkgConfig.cpp index 9a19387..42d0d13 100644 --- a/src/PkgConfig.cpp +++ b/src/PkgConfig.cpp @@ -1,6 +1,7 @@ #include "../include/PkgConfig.hpp" #if OS_FAMILY == OS_FAMILY_POSIX #include "../include/Exec.hpp" +#include "../include/Dependency.hpp" using namespace std; @@ -19,20 +20,18 @@ namespace sibs return ""; } -#if OS_FAMILY == OS_FAMILY_POSIX - Result<bool> PkgConfig::validatePkgConfigPackageVersionExists(const Dependency &dependency) + Result<bool> PkgConfig::validatePkgConfigPackageVersionExists(PackageListDependency *dependency) { - Result<bool> dependencyValidationResult = PkgConfig::validatePackageExists(dependency.name); + Result<bool> dependencyValidationResult = PkgConfig::validatePackageExists(dependency->name); if(dependencyValidationResult.isErr()) return Result<bool>::Err(dependencyValidationResult.getErrMsg()); - Result<bool> dependencyVersionValidationResult = PkgConfig::validatePackageVersionAtLeast(dependency.name, dependency.version); + Result<bool> dependencyVersionValidationResult = PkgConfig::validatePackageVersionAtLeast(dependency->name, dependency->version); if(dependencyVersionValidationResult.isErr()) return Result<bool>::Err(dependencyVersionValidationResult.getErrMsg()); return Result<bool>::Ok(true); } -#endif Result<bool> PkgConfig::validatePackageExists(const string &name) { @@ -101,15 +100,15 @@ namespace sibs return Result<bool>::Ok(true); } - Result<string> PkgConfig::getDynamicLibsLinkerFlags(const vector<Dependency> &libs) + Result<string> PkgConfig::getDynamicLibsLinkerFlags(const vector<PackageListDependency*> &libs) { if(libs.empty()) return Result<string>::Ok(""); string args; - for(const Dependency &lib : libs) + for(PackageListDependency *lib : libs) { args += " '"; - args += lib.name; + args += lib->name; args += "'"; } @@ -144,15 +143,15 @@ namespace sibs } } - Result<string> PkgConfig::getDynamicLibsCflags(const vector<Dependency> &libs) + Result<string> PkgConfig::getDynamicLibsCflags(const vector<PackageListDependency*> &libs) { if(libs.empty()) return Result<string>::Ok(""); string args; - for(const Dependency &lib : libs) + for(PackageListDependency *lib : libs) { args += " '"; - args += lib.name; + args += lib->name; args += "'"; } @@ -187,7 +186,7 @@ namespace sibs } } - Result<PkgConfigFlags> PkgConfig::getDynamicLibsFlags(const vector<Dependency> &libs) + Result<PkgConfigFlags> PkgConfig::getDynamicLibsFlags(const vector<PackageListDependency*> &libs) { PkgConfigFlags flags; diff --git a/src/main.cpp b/src/main.cpp index a2e6565..dcc38d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,6 +59,20 @@ using namespace std::chrono; // TODO: Make dependency/project names case insensitive. This means we can't use pkgconfig +// TODO: Fail build if dependency requires newer language version than dependant package. +// To make it work properly, should language version be required in project.conf? + +// TODO: Remove duplicate compiler options (include flags, linker flags etc...) to improve compilation speed. +// The compiler ignores duplicate symbols but it's faster to just remove duplicate options because we only have +// to compare strings. Duplicate options can happen if for example a project has two dependencies and both dependencies +// have dependency on the same package (would be common for example with boost libraries or libraries that dpepend on boost) + +// TODO: Create symlink to dependencies, for example if we have dependency on xxhash which has xxhash.h in its root directory, +// then you should be able to include it from dependant project by typing #include "xxhash/xxhash.h" +// that means we create a symlink with the dependency name to the dependency version directory. +// This will make it easier to prevent clashes in header file names and it's easier to see from the include statement +// what exactly we are including + #if OS_FAMILY == OS_FAMILY_POSIX #define ferr std::cerr #else @@ -503,7 +517,8 @@ int newProject(int argc, const _tinydir_char_t **argv) newProjectCreateConf(projectName, projectTypeConf, projectPath); createProjectSubDir(projectPath + TINYDIR_STRING("/src")); createProjectSubDir(projectPath + TINYDIR_STRING("/include")); - createProjectFile(projectPath + TINYDIR_STRING("/src/main.cpp"), "#include <cstdio>\n\nint main()\n{\n printf(\"hello, world!\\n\");\n return 0;\n}\n"); + createProjectSubDir(projectPath + TINYDIR_STRING("/tests")); + createProjectFile(projectPath + TINYDIR_STRING("/src/main.cpp"), "#include <cstdio>\n\nint main(int argc, char **argv)\n{\n printf(\"hello, world!\\n\");\n return 0;\n}\n"); // We are ignoring git init result on purpose. If it fails, just ignore it; not important gitInitProject(projectPath); return 0; |