aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-10-04 00:47:48 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:39:33 +0200
commit48ad8c87fd6cc901a4616f3ef02e7f163459a4c5 (patch)
tree9a56cea822d74e4d0772482e48bb561272de706c /src
parent3374901c0392a561bc107287bbf5ad54f52c9d71 (diff)
Add --bundle-install option to reduce distributable package size
* Downloads libraries from internet if they are missing from the system * Libraries are shared among all sibs projects as long as they use same library versions
Diffstat (limited to 'src')
-rw-r--r--src/Conf.cpp41
-rw-r--r--src/main.cpp33
2 files changed, 67 insertions, 7 deletions
diff --git a/src/Conf.cpp b/src/Conf.cpp
index fa92bf5..aabb957 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -461,12 +461,30 @@ namespace sibs
// Do not free file content (fileContentResult) on purpose, since we are using the data and sibs is short lived
Result<bool> parseResult = Parser::parse(code, config);
if(!parseResult)
- return Result<bool>::Err("Failed to read config, reason: " + parseResult.getErrMsg());
+ {
+ string errMsg = "Failed while parsing project.conf for project ";
+ errMsg += config.isTest() ? "tests" : config.getPackageName();
+ errMsg += ", reason: " + parseResult.getErrMsg();
+ return Result<bool>::Err(errMsg);
+ }
if(!config.isTest())
{
if(config.getPackageName().empty())
- return Result<bool>::Err("project.conf is missing required field package.name");
+ {
+ string errMsg = "The project ";
+ errMsg += config.getPackageName();
+ errMsg += " is missing required field package.name is project.conf";
+ return Result<bool>::Err(errMsg);
+ }
+
+ if(config.version.empty())
+ {
+ string errMsg = "The project ";
+ errMsg += config.getPackageName();
+ errMsg += " is missing required field package.version is project.conf";
+ return Result<bool>::Err(errMsg);
+ }
if (!containsPlatform(config.getPlatforms(), SYSTEM_PLATFORM))
{
@@ -668,6 +686,17 @@ namespace sibs
return result;
}
+ static bool isVersionStringValid(const string &version)
+ {
+ for(char c : version)
+ {
+ bool isValidChar = (c == '.' || (c >= '0' && c <= '9'));
+ if(!isValidChar)
+ return false;
+ }
+ return true;
+ }
+
void SibsConfig::processObject(StringView name)
{
currentObject = name;
@@ -713,7 +742,13 @@ namespace sibs
}
else if(name.equals("version"))
{
- // TODO: Use version for info output when building
+ if (value.isSingle())
+ version = string(value.asSingle().data, value.asSingle().size);
+ else
+ throw ParserException("Expected package.version to be a single value, was a list");
+
+ if(!isVersionStringValid(version))
+ throw ParserException("package.version is in invalid format. Version string can only contain numbers and dots");
}
else if(name.equals("authors"))
{
diff --git a/src/main.cpp b/src/main.cpp
index 6a807f0..e55014e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -184,12 +184,14 @@ static void usageInit()
static void usagePackage()
{
- printf("Usage: sibs package [project_path] <--static|--bundle>\n\n");
+ printf("Usage: sibs package [project_path] <--static|--bundle|--bundle-install>\n\n");
printf("Create a redistributable package from a sibs project. Note: Redistributable packages can't use system packages to build if packaging using --static\n\n");
printf("Options:\n");
printf(" project_path\t\tThe directory containiung a project.conf file - Optional (default: current directory)\n");
printf(" --static\t\tPackage project by building everything statically. Note: can't use system packages when using this option (meaning no pkg-config support)\n\n");
printf(" --bundle\t\tPackage project by copying all dynamic libraries into one location and creating an archive of all files. The executable is patched to use the dynamic libraries in the same directory. Note: if your project loads dynamic libraries at runtime (for example using dlopen) then you need to manually copy those libraries to the archive\n\n");
+ printf(" --bundle-install\t\tPackage project by copying all dynamic libraries into one location, except libraries that can automatically be downloaded online by the user. Then create an archive of all files - Use this option if you want to reduce the size of the distributed package and also if user already has some of the libraries installed/downloaded on their system, then they are used."
+ "Note: if your project loads dynamic libraries at runtime (for example using dlopen) then you need to manually copy those libraries to the archive");
printf("Examples:\n");
printf(" sibs package --static\n");
printf(" sibs package dirA/dirB --bundle\n");
@@ -937,7 +939,8 @@ enum class PackagingType
{
NONE,
STATIC,
- BUNDLE
+ BUNDLE,
+ BUNDLE_INSTALL
};
static const char* asString(PackagingType packagingType)
@@ -1025,6 +1028,15 @@ static int packageProject(int argc, const _tinydir_char_t **argv)
}
packagingType = PackagingType::BUNDLE;
}
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("--bundle-install")) == 0)
+ {
+ if(packagingType != PackagingType::NONE)
+ {
+ ferr << "Error: Project packaging type was defined more than once. First as " << asString(packagingType) << " then as " << "bundle-install" << endl;
+ usagePackage();
+ }
+ packagingType = PackagingType::BUNDLE_INSTALL;
+ }
else
{
if(!projectPath.empty())
@@ -1073,7 +1085,7 @@ static int packageProject(int argc, const _tinydir_char_t **argv)
SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_RELEASE, false);
sibsConfig.showWarnings = true;
sibsConfig.packaging = packagingType == PackagingType::STATIC;
- sibsConfig.bundling = packagingType == PackagingType::BUNDLE;
+ sibsConfig.bundling = (packagingType == PackagingType::BUNDLE) || (packagingType == PackagingType::BUNDLE_INSTALL);
int result = buildProject(projectPath, projectConfFilePath, sibsConfig);
if(result != 0)
return result;
@@ -1087,11 +1099,24 @@ static int packageProject(int argc, const _tinydir_char_t **argv)
break;
}
case PackagingType::BUNDLE:
+ case PackagingType::BUNDLE_INSTALL:
{
+ const char *bundleType = nullptr;
+ switch(packagingType)
+ {
+ case PackagingType::BUNDLE:
+ bundleType = "--bundle";
+ break;
+ case PackagingType::BUNDLE_INSTALL:
+ bundleType = "--bundle-install";
+ break;
+ }
+
string packagePath = toUtf8(projectPath + TINYDIR_STRING("/sibs-build/package"));
string executablePath = toUtf8(projectPath + TINYDIR_STRING("/sibs-build/release/") + sibsConfig.getPackageName());
printf("Creating a package from project and dependencies...\n");
- FileString cmd = "python3 \"" + packageScriptPath + "\" \"" + executablePath + "\" \"" + packagePath + "\"";
+ // args: executable_path program_version destination_path <--bundle|--bundle-install>
+ FileString cmd = "python3 \"" + packageScriptPath + "\" \"" + executablePath + "\" \"" + sibsConfig.version + "\" \"" + packagePath + "\" " + bundleType;
Result<ExecResult> bundleResult = exec(cmd.c_str(), true);
if(!bundleResult)
{