aboutsummaryrefslogtreecommitdiff
path: root/src/GlobalLib.cpp
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/GlobalLib.cpp
parentb7b7b3d359765e3ffb011dc34ff928e614766666 (diff)
Add git dependencies
Diffstat (limited to 'src/GlobalLib.cpp')
-rw-r--r--src/GlobalLib.cpp158
1 files changed, 119 insertions, 39 deletions
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);
+ }
}