aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-01-14 18:36:20 +0100
committerdec05eba <dec05eba@protonmail.com>2018-01-26 09:13:15 +0100
commit91ab79f1475371e6e57d00f24f98bccb7749d15a (patch)
tree40fa847c783ecdc165ad1fc6b7c5cd2a026d25b9 /src
parentb7b7b3d359765e3ffb011dc34ff928e614766666 (diff)
Add git dependencies
Diffstat (limited to 'src')
-rw-r--r--src/CmakeModule.cpp8
-rw-r--r--src/Conf.cpp129
-rw-r--r--src/GitRepository.cpp101
-rw-r--r--src/GlobalLib.cpp158
-rw-r--r--src/PkgConfig.cpp23
-rw-r--r--src/main.cpp17
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;