aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/ninja/Ninja.cpp26
-rw-r--r--include/Conf.hpp4
-rw-r--r--src/CmakeModule.cpp4
-rw-r--r--src/Conf.cpp25
-rw-r--r--src/GlobalLib.cpp1
-rw-r--r--src/main.cpp71
6 files changed, 120 insertions, 11 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 53b1667..943e090 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -316,8 +316,8 @@ namespace backend
vector<PackageListDependency*> pkgConfigDependencies;
for(PackageListDependency *dependency : packageListDependencies)
{
- Result<bool> pkgConfigDependencyValidation = PkgConfig::validatePkgConfigPackageVersionExists(dependency);
- if(pkgConfigDependencyValidation.isOk())
+ // PkgConfig libraries, even the static ones are most likely not built statically against libgcc/libc++, so we don't use them
+ if(!config.packaging && PkgConfig::validatePkgConfigPackageVersionExists(dependency))
{
pkgConfigDependencies.push_back(dependency);
}
@@ -662,6 +662,11 @@ namespace backend
string generatedZigHeaderDirUtf8 = toUtf8(generatedZigHeadersDir);
LibraryType libraryType = getNinjaLibraryType(config.getPackageType());
+ // TODO: Instead of statically linking everything, maybe we should build everything as they prefer to be built
+ // and then copy the files if they are shared libraries to the same directory as the root project executable
+ // so they can be packaged into an archive that can be distributed?
+ if(config.packaging && !config.isMainProject())
+ libraryType = LibraryType::STATIC;
string savePathUtf8 = toUtf8(savePath);
string projectPathUtf8 = toUtf8(config.getProjectPath());
@@ -1077,6 +1082,23 @@ namespace backend
objectNames.emplace_back(move(objectName));
}
+ if(config.packaging)
+ {
+ switch(config.getCompiler())
+ {
+ case Compiler::GCC:
+ {
+ allLinkerFlags += " -static-libgcc -static-libstdc++";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ // We always statically link using /MT so there is no need to do it here
+ break;
+ }
+ }
+ }
+
// TODO: For now zig projects (zig object files) are built with c/c++ compiler,
// they should be built with zig if project only contains zig files.
// But how to combine object files with zig? build-exe only wants to accept .zig files
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 87f4fad..7a29624 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -301,7 +301,8 @@ namespace sibs
mainProject(false),
sanitize(false),
showWarnings(false),
- zigTestAllFiles(false)
+ zigTestAllFiles(false),
+ packaging(false)
{
cmakeDirGlobal = projectPath;
cmakeDirStatic = cmakeDirGlobal;
@@ -499,6 +500,7 @@ namespace sibs
std::vector<FileString> zigTestFiles;
bool showWarnings;
bool zigTestAllFiles;
+ bool packaging;
protected:
virtual void processObject(StringView name) override;
virtual void processField(StringView name, const ConfigValue &value) override;
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp
index c512f87..1e873cd 100644
--- a/src/CmakeModule.cpp
+++ b/src/CmakeModule.cpp
@@ -15,6 +15,10 @@ namespace sibs
{
Result<bool> CmakeModule::compile(const SibsConfig &config, const FileString &buildPath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
+ // TODO: Make packaging work with cmake projects
+ if(config.packaging)
+ return Result<bool>::Err("Project " + config.getPackageName() + " is a cmake project, such projects are currently not supported when building a package");
+
Result<FileString> globalLibDirResult = getHomeDir();
if (!globalLibDirResult)
return Result<bool>::Err(globalLibDirResult);
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 090e1e1..d981794 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -487,6 +487,9 @@ namespace sibs
else
fprintf(stderr, "Warning: Project contains tests directory but we got an error while retrieving the full path to it\n");
}
+
+ if(config.packaging && (!config.getDebugStaticLibs().empty() || !config.getReleaseStaticLibs().empty()))
+ return Result<bool>::Err("Project " + config.getPackageName() + " contains external static libraries, such projects are not supported when building a package");
}
return parseResult;
@@ -502,14 +505,21 @@ namespace sibs
}
buildPath = projectPath + TINYDIR_STRING("/sibs-build/");
- switch(sibsConfig.getOptimizationLevel())
+ if(sibsConfig.packaging)
+ {
+ buildPath += TINYDIR_STRING("package");
+ }
+ else
{
- case OPT_LEV_DEBUG:
- buildPath += TINYDIR_STRING("debug");
- break;
- case OPT_LEV_RELEASE:
- buildPath += TINYDIR_STRING("release");
- break;
+ switch(sibsConfig.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ buildPath += TINYDIR_STRING("debug");
+ break;
+ case OPT_LEV_RELEASE:
+ buildPath += TINYDIR_STRING("release");
+ break;
+ }
}
}
@@ -1163,6 +1173,7 @@ namespace sibs
string SibsConfig::parsePlatformConfigStatic(const StringView &fieldName, const ConfigValue &fieldValue)
{
+ // TODO: Verify the library is actually a static library
if (fieldName.equals("lib"))
{
if (fieldValue.isSingle())
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index 916ba3e..99c783a 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -201,6 +201,7 @@ namespace sibs
}
SibsConfig sibsConfig(parentConfig.getCompiler(), packageDir, parentConfig.getOptimizationLevel(), false);
+ sibsConfig.packaging = parentConfig.packaging;
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if (result.isErr())
return result;
diff --git a/src/main.cpp b/src/main.cpp
index 290ed9e..eae90d0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -108,6 +108,7 @@ static void usage()
printf(" new\t\tCreate a new project\n");
printf(" init\t\tInitialize project in an existing directory\n");
printf(" test\t\tBuild and run tests for a sibs project\n");
+ printf(" package\t\tCreate a redistributable package from a sibs project. Note: Redistributable packages can't use system packages to build\n");
exit(1);
}
@@ -155,6 +156,9 @@ static void usageTest()
printf("Examples:\n");
printf(" sibs test\n");
printf(" sibs test dirA/dirB\n");
+ printf(" sibs test --no-sanitize\n");
+ printf(" sibs test --all-files\n");
+ printf(" sibs test --file src/foo.zig --file src/bar.zig\n");
exit(1);
}
@@ -163,7 +167,7 @@ static void usageInit()
printf("Usage: sibs init [project_path] <--exec|--static|--dynamic> [--lang c|c++|zig]\n\n");
printf("Create sibs project structure in an existing directory\n\n");
printf("Options:\n");
- printf(" project_path\t\tThe directory where you want to initialize sibs project - Optional (default: current directory)\n");
+ printf(" project_path\t\tThe directory where you want to initialize sibs project - Optional (default: current directory)\n");
printf(" --exec\t\t\tProject compiles to an executable\n");
printf(" --static\t\t\tProject compiles to a static library\n");
printf(" --dynamic\t\t\tProject compiles to a dynamic library\n");
@@ -174,6 +178,18 @@ static void usageInit()
exit(1);
}
+static void usagePackage()
+{
+ printf("Usage: sibs package [project_path]\n\n");
+ printf("Create a redistributable package from a sibs project. Note: Redistributable packages can't use system packages to build\n\n");
+ printf("Options:\n");
+ printf(" project_path\t\tThe directory containiung a project.conf file - Optional (default: current directory)\n");
+ printf("Examples:\n");
+ printf(" sibs package\n");
+ printf(" sibs package dirA/dirB");
+ exit(1);
+}
+
static void validateDirectoryPath(const _tinydir_char_t *projectPath)
{
FileType projectPathFileType = getFileType(projectPath);
@@ -911,6 +927,55 @@ static int initProject(int argc, const _tinydir_char_t **argv)
return 0;
}
+static int packageProject(int argc, const _tinydir_char_t **argv)
+{
+ if(argc > 1)
+ usagePackage();
+
+ FileString projectPath;
+ if(argc == 1)
+ projectPath = argv[0];
+
+ // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found
+ if(projectPath.empty())
+ projectPath = TINYDIR_STRING(".");
+
+ validateDirectoryPath(projectPath.c_str());
+ if(projectPath.back() != '/')
+ projectPath += TINYDIR_STRING("/");
+
+ Result<FileString> projectRealPathResult = getRealPath(projectPath.c_str());
+ if(!projectRealPathResult)
+ {
+ ferr << "Failed to get real path for: '" << projectPath.c_str() << "': " << toFileString(projectRealPathResult.getErrMsg()) << endl;
+ exit(40);
+ }
+ projectPath = projectRealPathResult.unwrap();
+
+ FileString projectConfFilePath = projectPath;
+ projectConfFilePath += TINYDIR_STRING("/project.conf");
+ validateFilePath(projectConfFilePath.c_str());
+
+ // TODO: Detect compiler to use at runtime. Should also be configurable
+ // by passing argument to `sibs package`
+#if OS_FAMILY == OS_FAMILY_POSIX
+ Compiler compiler = Compiler::GCC;
+#else
+ Compiler compiler = Compiler::MSVC;
+#endif
+
+ SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_RELEASE, false);
+ sibsConfig.showWarnings = true;
+ sibsConfig.packaging = true;
+ int result = buildProject(projectPath, projectConfFilePath, sibsConfig);
+ if(result != 0)
+ return result;
+
+ string packagePath = toUtf8(projectPath + TINYDIR_STRING("/sibs-build/package"));
+ printf("Project %s was successfully packaged and can be found at %s\n", sibsConfig.getPackageName().c_str(), packagePath.c_str());
+ return 0;
+}
+
static void newProjectCreateMainDir(const FileString &projectPath)
{
Result<bool> createProjectDirResult = createDirectoryRecursive(projectPath.c_str());
@@ -1138,6 +1203,10 @@ int wmain(int argc, const _tinydir_char_t **argv)
{
return initProject(subCommandArgCount, subCommandArgPtr);
}
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("package")) == 0)
+ {
+ return packageProject(subCommandArgCount, subCommandArgPtr);
+ }
else
{
ferr << "Expected command to be either 'build', 'new' or 'test', was: " << arg << endl << endl;