aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-16 04:21:33 +0100
committerdec05eba <dec05eba@protonmail.com>2017-12-16 04:21:44 +0100
commit94caff5f66cacdd21e5a93cd3de9150a22eeaa3a (patch)
treeb3b7689e5a25c908369bb5fad5a59e085253b76e
parent28d6b571139998915bce147abb58617884431192 (diff)
Add support for sub project (unit tests)
-rw-r--r--backend/ninja/Ninja.cpp177
-rw-r--r--backend/ninja/Ninja.hpp12
-rw-r--r--include/Conf.hpp51
-rw-r--r--include/FileUtil.hpp1
-rw-r--r--src/Conf.cpp53
-rw-r--r--src/FileUtil.cpp21
-rw-r--r--src/GlobalLib.cpp38
-rw-r--r--src/main.cpp37
8 files changed, 329 insertions, 61 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index d8345a4..6a6eafd 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -47,8 +47,28 @@ namespace backend
void Ninja::addSourceFile(const char *filepath)
{
- if(filepath && !containsSourceFile(filepath))
- sourceFiles.emplace_back(filepath);
+ string filePathStr = filepath ? filepath : "";
+ if(filepath && !containsSourceFile(filePathStr))
+ {
+ sourceFiles.emplace_back(filePathStr);
+ printf("Adding source file: %s\n", filepath);
+ }
+ }
+
+ void Ninja::addTestSourceDir(const char *dir)
+ {
+ string dirStr = dir ? dir : "";
+ if(dir && !containsTestSourceDir(dirStr))
+ {
+ testSourceDirs.emplace_back(dirStr);
+ printf("Adding test source directory: %s\n", dir);
+ }
+ }
+
+ void Ninja::addDependency(const std::string &binaryFile)
+ {
+ if(!containsDependency(binaryFile))
+ binaryDependencies.emplace_back(binaryFile);
}
const std::vector<std::string>& Ninja::getSourceFiles() const
@@ -56,7 +76,7 @@ namespace backend
return sourceFiles;
}
- bool Ninja::containsSourceFile(const char *filepath) const
+ bool Ninja::containsSourceFile(const string &filepath) const
{
for(const string &sourceFile : sourceFiles)
{
@@ -66,6 +86,26 @@ namespace backend
return false;
}
+ bool Ninja::containsTestSourceDir(const string &dir) const
+ {
+ for(const string &testSourceDir : testSourceDirs)
+ {
+ if(testSourceDir == dir)
+ return true;
+ }
+ return false;
+ }
+
+ bool Ninja::containsDependency(const string &dependency) const
+ {
+ for(const string &binaryDependency : binaryDependencies)
+ {
+ if(binaryDependency == dependency)
+ return true;
+ }
+ return false;
+ }
+
Result<bool> validatePkgConfigPackageVersionExists(const Dependency &dependency)
{
Result<bool> dependencyValidationResult = PkgConfig::validatePackageExists(dependency.name);
@@ -156,7 +196,7 @@ namespace backend
return Result<bool>::Ok(true);
}
- Result<bool> Ninja::createBuildFile(const std::string &packageName, const vector<Dependency> &dependencies, const char *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback)
+ Result<bool> Ninja::createBuildFile(const SibsConfig &config, const char *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback)
{
// TODO: Do not quit here if no source files are provided. The source-less project could have dependencies
if(sourceFiles.empty())
@@ -199,7 +239,7 @@ namespace backend
result += "rule cpp_BUILD_STATIC\n";
result += " command = ar rcs lib";
- result += packageName;
+ result += config.getPackageName();
result += ".a";
result += " $in\n\n";
buildJob = "cpp_BUILD_STATIC";
@@ -225,25 +265,28 @@ namespace backend
objectNames.reserve(sourceFiles.size());
for(const string &sourceFile : sourceFiles)
{
- // TODO: Handle tests differently.
- // Maybe test directory should have project file and sub directories with project files
- // should be their own project?
- if(_tinydir_strncmp(sourceFile.c_str(), "tests", 5) == 0)
- continue;
-
//string sourceFileEncoded = sourceFile;
//replace(sourceFileEncoded, '/', '@');
- string objectName = packageName + "@exe/" + sourceFile + ".o";
+ string objectName = config.getPackageName() + "@exe/" + sourceFile + ".o";
result += "build ";
result += objectName;
result += ": cpp_COMPILER ../../";
result += sourceFile;
result += "\n";
- result += " ARGS = $globalLibDir '-I" + packageName + "@exe' '-I.' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-O0' '-g'\n\n";
+ result += " ARGS = $globalLibDir '-I" + config.getPackageName() + "@exe' '-I.' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-O0' '-g'\n\n";
objectNames.emplace_back(objectName);
}
string allLinkerFlags;
+
+ // TODO: Somehow check loading order, because it has to be correct to work.. Or does it for dynamic libraries?
+ // Anyways it's required for static libraries (especially on Windows)
+ for(const string &binaryDependency : binaryDependencies)
+ {
+ allLinkerFlags += " ";
+ allLinkerFlags += binaryDependency;
+ }
+
if(!staticLinkerFlagCallbackFunc || libraryType == LibraryType::DYNAMIC)
{
staticLinkerFlagCallbackFunc = [&allLinkerFlags](const string &linkerFlag)
@@ -260,16 +303,20 @@ namespace backend
allLinkerFlags += linkerFlag;
};
+ Result<bool> linkerFlags = getLinkerFlags(config.getDependencies(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ if(linkerFlags.isErr())
+ return Result<bool>::Err(linkerFlags.getErrMsg());
+
+ string projectGeneratedBinary = allLinkerFlags;
+ projectGeneratedBinary += " '";
+ projectGeneratedBinary += savePath;
+ projectGeneratedBinary += "/";
switch(libraryType)
{
case LibraryType::EXECUTABLE:
{
- Result<bool> linkerFlags = getLinkerFlags(dependencies, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
- if(linkerFlags.isErr())
- return Result<bool>::Err(linkerFlags.getErrMsg());
-
result += "build ";
- result += packageName;
+ result += config.getPackageName();
result += ": " + buildJob + " ";
result += join(objectNames, " ");
result += "\n";
@@ -279,29 +326,23 @@ namespace backend
result += allLinkerFlags;
}
result += "\n\n";
+ projectGeneratedBinary += config.getPackageName();
break;
}
case LibraryType::STATIC:
{
- Result<bool> linkerFlags = getLinkerFlags(dependencies, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
- if(linkerFlags.isErr())
- return linkerFlags;
-
result += "build ";
- result += packageName;
+ result += config.getPackageName();
result += ": " + buildJob + " ";
result += join(objectNames, " ");
result += "\n\n";
+ projectGeneratedBinary += config.getPackageName() + ".a";
break;
}
case LibraryType::DYNAMIC:
{
- Result<bool> linkerFlags = getLinkerFlags(dependencies, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
- if(linkerFlags.isErr())
- return Result<bool>::Err(linkerFlags.getErrMsg());
-
result += "build lib";
- result += packageName;
+ result += config.getPackageName();
result += ".so: " + buildJob + " ";
result += join(objectNames, " ");
result += "\n";
@@ -312,18 +353,93 @@ namespace backend
//result += " '-Wl,--no-whole-archive'";
}
result += "\n\n";
+ projectGeneratedBinary += "lib" + config.getPackageName() + ".so";
break;
}
default:
assert(false);
return Result<bool>::Err("Unexpected error");
}
+ projectGeneratedBinary += "'";
Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
if(fileOverwriteResult.isErr())
return fileOverwriteResult;
printf("Created ninja build file: %s\n", ninjaBuildFilePath.c_str());
+
+ Result<bool> buildTestResult = buildTests(projectGeneratedBinary);
+ if(!buildTestResult)
+ return buildTestResult;
+
+ return Result<bool>::Ok(true);
+ }
+
+ const char *sourceFileExtensions[] = { "c", "cc", "cpp", "cxx" };
+ bool isSourceFile(tinydir_file *file)
+ {
+ if(!file->is_reg)
+ return false;
+
+ for(const char *sourceFileExtension : sourceFileExtensions)
+ {
+ if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary)
+ {
+ if(testSourceDirs.empty())
+ return Result<bool>::Ok(true);
+
+ // TODO: Include executable as dependency??? or compile project as dynamic library even if it's not a library
+ if(libraryType == LibraryType::EXECUTABLE)
+ return Result<bool>::Err("Unit tests are currently only supported in projects that compile to static/dynamic library");
+
+ for(const string &testSourceDir : testSourceDirs)
+ {
+ string projectConfFilePath = testSourceDir;
+ projectConfFilePath += "/project.conf";
+
+ FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
+ SibsTestConfig sibsTestConfig(testSourceDir);
+ if(projectConfFileType == FileType::REGULAR)
+ {
+ Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
+ if(!result)
+ return result;
+ }
+
+ backend::Ninja ninja;
+ ninja.addDependency(projectGeneratedBinary);
+ walkDirFilesRecursive(testSourceDir.c_str(), [&ninja, &sibsTestConfig](tinydir_file *file)
+ {
+ if (isSourceFile(file))
+ {
+ ninja.addSourceFile(file->path + sibsTestConfig.getProjectPath().size() + 1);
+ }
+ else
+ {
+ //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ }
+ });
+
+ if(!ninja.getSourceFiles().empty())
+ {
+ string debugBuildPath = testSourceDir + "/sibs-build/debug";
+ Result<bool> buildFileResult = ninja.createBuildFile(sibsTestConfig, debugBuildPath.c_str());
+ if (!buildFileResult)
+ return buildFileResult;
+
+ Result<bool> buildResult = ninja.build(debugBuildPath.c_str());
+ if (!buildResult)
+ return buildResult;
+ }
+ }
+
return Result<bool>::Ok(true);
}
@@ -332,14 +448,11 @@ namespace backend
string command = "ninja -C '";
command += buildFilePath;
command += "'";
- Result<ExecResult> execResult = exec(command.c_str());
+ Result<ExecResult> execResult = exec(command.c_str(), true);
if(execResult.isOk())
{
if(execResult.unwrap().exitCode == 0)
- {
- printf("%s", execResult.unwrap().execStdout.c_str());
return Result<bool>::Ok(true);
- }
else
return Result<bool>::Err(execResult.unwrap().execStdout);
}
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index a0239d2..7013f78 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -4,6 +4,7 @@
#include "../../include/Dependency.hpp"
#include "../../include/Result.hpp"
#include "../../include/Linker.hpp"
+#include "../../include/Conf.hpp"
#include <vector>
#include <string>
#include <functional>
@@ -24,14 +25,21 @@ namespace backend
Ninja(LibraryType libraryType = LibraryType::EXECUTABLE);
void addSourceFile(const char *filepath);
+ void addTestSourceDir(const char *dir);
+ void addDependency(const std::string &binaryFile);
const std::vector<std::string>& getSourceFiles() const;
- sibs::Result<bool> createBuildFile(const std::string &packageName, const std::vector<sibs::Dependency> &dependencies, const char *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr);
+ sibs::Result<bool> createBuildFile(const sibs::SibsConfig &config, const char *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr);
sibs::Result<bool> build(const char *buildFilePath);
private:
- bool containsSourceFile(const char *filepath) const;
+ sibs::Result<bool> buildTests(const std::string &projectGeneratedBinary);
+ bool containsSourceFile(const std::string &filepath) const;
+ bool containsTestSourceDir(const std::string &dir) const;
+ bool containsDependency(const std::string &dependency) const;
sibs::Result<bool> getLinkerFlags(const std::vector<sibs::Dependency> &dependencies, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const;
private:
std::vector<std::string> sourceFiles;
+ std::vector<std::string> testSourceDirs;
+ std::vector<std::string> binaryDependencies;
LibraryType libraryType;
};
}
diff --git a/include/Conf.hpp b/include/Conf.hpp
index c792075..8da352e 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -70,6 +70,8 @@ namespace sibs
class ConfigCallback
{
friend class Parser;
+ public:
+ virtual ~ConfigCallback(){}
protected:
virtual void processObject(StringView name) = 0;
virtual void processField(StringView name, const ConfigValue &value) = 0;
@@ -85,35 +87,68 @@ namespace sibs
class SibsConfig : public ConfigCallback
{
public:
- SibsConfig() : finishedProcessing(false), packageType((PackageType)-1) {}
+ SibsConfig(const std::string &_projectPath) : projectPath(_projectPath), finishedProcessing(false), packageType((PackageType)-1) {}
+ virtual ~SibsConfig(){}
- const std::string& getPackageName() const
+ virtual const std::string& getPackageName() const
{
assert(finishedProcessing);
return packageName;
}
- PackageType getPackageType() const
+ virtual PackageType getPackageType() const
{
assert(finishedProcessing);
return packageType;
}
- const std::vector<Dependency>& getDependencies() const
+ virtual const std::string& getTestPath() const
+ {
+ return testPath;
+ }
+
+ virtual const std::vector<Dependency>& getDependencies() const
{
return dependencies;
}
+
+ virtual const std::string& getProjectPath() const
+ {
+ return projectPath;
+ }
+ protected:
+ virtual void processObject(StringView name) override;
+ virtual void processField(StringView name, const ConfigValue &value) override;
+ virtual void finished() override;
protected:
- void processObject(StringView name) override;
- void processField(StringView name, const ConfigValue &value) override;
- void finished() override;
- private:
StringView currentObject;
+ std::string projectPath;
std::string packageName;
+ std::string testPath;
PackageType packageType;
std::vector<Dependency> dependencies;
bool finishedProcessing;
};
+
+ class SibsTestConfig : public SibsConfig
+ {
+ public:
+ SibsTestConfig(const std::string &_projectPath) : SibsConfig(_projectPath)
+ {
+ packageName = "test";
+ }
+
+ virtual ~SibsTestConfig(){}
+
+ PackageType getPackageType() const override
+ {
+ return PackageType::EXECUTABLE;
+ }
+ protected:
+ void processObject(StringView name) override;
+ void processField(StringView name, const ConfigValue &value) override;
+ void finished() override;
+ };
}
#endif //SIBS_CONF_HPP
diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp
index 5b91aad..5d1594a 100644
--- a/include/FileUtil.hpp
+++ b/include/FileUtil.hpp
@@ -27,6 +27,7 @@ namespace sibs
Result<std::string> getCwd();
// Note: Will not delete created directories if this operation fails for some reason
Result<bool> createDirectoryRecursive(const char *path);
+ Result<std::string> getRealPath(const char *path);
}
#endif //SIBS_FILEUTIL_HPP
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 1f439cd..b1e05bb 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -394,6 +394,25 @@ namespace sibs
else
throw ParserException("Expected package.type to be a single value, was a list");
}
+ else if(name.equals("tests"))
+ {
+ if (value.isSingle())
+ {
+ testPath = projectPath;
+ testPath += "/";
+ testPath += string(value.asSingle().data, value.asSingle().size);
+ Result<string> testRealPathResult = getRealPath(testPath.c_str());
+ if(!testRealPathResult)
+ {
+ string errMsg = "Failed to resolve package.tests path: ";
+ errMsg += testRealPathResult.getErrMsg();
+ throw ParserException(errMsg);
+ }
+ testPath = testRealPathResult.unwrap();
+ }
+ else
+ throw ParserException("Expected package.tests to be a single value, was a list");
+ }
}
else if(currentObject.equals("dependencies"))
{
@@ -416,4 +435,38 @@ namespace sibs
throw ParserException("Missing required config package.type. Expected to be one either 'executable', 'static', 'dynamic' or 'library'");
finishedProcessing = true;
}
+
+ void SibsTestConfig::processObject(StringView name)
+ {
+ currentObject = name;
+ }
+
+ void SibsTestConfig::processField(StringView name, const ConfigValue &value)
+ {
+ 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");
+ }
+ else
+ {
+ string errMsg = "project.conf: Expected category to be 'dependencies', was: '";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += "'";
+ throw ParserException(errMsg);
+ }
+ }
+
+ void SibsTestConfig::finished()
+ {
+ finishedProcessing = true;
+ }
} \ No newline at end of file
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index 899a1af..7248537 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -206,7 +206,26 @@ namespace sibs
return Result<bool>::Ok(true);
}
+
+ Result<string> getRealPath(const char *path)
+ {
+ // TODO: Verify NULL can be passed as 'resolved' argument with different compilers and operating systems (clang, freebsd etc)
+ char *resolved = realpath(path, nullptr);
+ if(!resolved)
+ {
+ int error = errno;
+ string errMsg = "Failed to get real path for \"";
+ errMsg += path;
+ errMsg += "\": ";
+ errMsg += strerror(error);
+ return Result<string>::Err(errMsg, error);
+ }
+
+ string result = resolved;
+ free(resolved);
+ return Result<string>::Ok(resolved);
+ }
#else
-#error "TODO: Implement createDirectoryRecursive on windows"
+#error "TODO: Implement createDirectoryRecursive and getRealPath on windows"
#endif
} \ No newline at end of file
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index a07e23d..c38e22f 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -55,6 +55,11 @@ namespace sibs
return false;
}
+ bool isPathSubPathOf(const char *path, const string &subPathOf)
+ {
+ return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
+ }
+
Result<string> GlobalLib::getLibsLinkerFlags(const string &globalLibRootDir, const string &name, const string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
{
Result<bool> packageExistsResult = validatePackageExists(globalLibRootDir, name);
@@ -105,7 +110,7 @@ namespace sibs
}
}
- SibsConfig sibsConfig;
+ SibsConfig sibsConfig(packageDir);
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
return Result<string>::Err(result.getErrMsg());
@@ -137,18 +142,33 @@ namespace sibs
}
backend::Ninja ninja(libraryType);
- walkDirFilesRecursive(packageDir.c_str(), [&ninja, &packageDir](tinydir_file *file)
+ FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
{
- if (isSourceFile(file))
+ if(file->is_reg)
{
- printf("Adding source file: %s\n", file->path + packageDir.size() + 1);
- ninja.addSourceFile(file->path + packageDir.size() + 1);
- } else
+ if (isSourceFile(file))
+ {
+ ninja.addSourceFile(file->path + sibsConfig.getProjectPath().size() + 1);
+ }
+ else
+ {
+ //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ }
+ }
+ else
{
- //printf("Ignoring non-source file: %s\n", file->path + packageDir.size() + 1);
+ // TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests...
+ // OR I believe there is no reason to run tests in dependencies. The main projects tests should cover that?
+ // But you might want to know exactly which dependency is causing issue and which part of it...
+ if(!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
+ ninja.addTestSourceDir(file->path);
+ else
+ walkDir(file->path, collectSourceFiles);
}
- });
+ };
+ walkDir(packageDir.c_str(), collectSourceFiles);
+ // TODO: Dont do this. Unit tests wont be built. Need to call the below ninja.createBuildFile
if(ninja.getSourceFiles().empty())
{
return Result<string>::Ok("No source files in dependency (header only library?)");
@@ -183,7 +203,7 @@ namespace sibs
if(createBuildDirResult.isErr())
return Result<string>::Err(createBuildDirResult);
- Result<bool> buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc);
+ Result<bool> buildFileResult = ninja.createBuildFile(sibsConfig, debugBuildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc);
if (buildFileResult.isErr())
return Result<string>::Err(buildFileResult.getErrMsg());
diff --git a/src/main.cpp b/src/main.cpp
index 9d6c88e..c1ce277 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -18,6 +18,8 @@ using namespace sibs;
// Either do not follow the symlinks or use a hash map with every searched directory
// to only go inside a directory once
+// TODO: Places that use PATH_MAX should be modified. A path CAN be longer than PATH_MAX... (does this include replacing tinydir.h?)
+
void usage()
{
printf("Usage: sibs COMMAND\n\n");
@@ -91,6 +93,11 @@ bool isSourceFile(tinydir_file *file)
return false;
}
+bool isPathSubPathOf(const char *path, const string &subPathOf)
+{
+ return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
+}
+
int buildProject(int argc, const char **argv)
{
if(argc > 1)
@@ -113,7 +120,7 @@ int buildProject(int argc, const char **argv)
projectConfFilePath += "/project.conf";
validateFilePath(projectConfFilePath.c_str());
- SibsConfig sibsConfig;
+ SibsConfig sibsConfig(projectPath);
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
{
@@ -147,20 +154,32 @@ int buildProject(int argc, const char **argv)
}
backend::Ninja ninja(libraryType);
- walkDirFilesRecursive(projectPath.c_str(), [&ninja, &projectPath](tinydir_file *file)
+ FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
{
- if (isSourceFile(file))
+ if(file->is_reg)
{
- printf("Adding source file: %s\n", file->path + projectPath.size());
- ninja.addSourceFile(file->path + projectPath.size());
- } else
+ if (isSourceFile(file))
+ {
+ ninja.addSourceFile(file->path + sibsConfig.getProjectPath().size());
+ }
+ else
+ {
+ //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ }
+ }
+ else
{
- //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ // TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests
+ if(!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
+ ninja.addTestSourceDir(file->path);
+ else
+ walkDir(file->path, collectSourceFiles);
}
- });
+ };
+ walkDir(projectPath.c_str(), collectSourceFiles);
string debugBuildPath = projectPath + "/sibs-build/debug";
- Result<bool> buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str());
+ Result<bool> buildFileResult = ninja.createBuildFile(sibsConfig, debugBuildPath.c_str());
if(buildFileResult.isErr())
{
cerr << "Failed to build ninja file: " << buildFileResult.getErrMsg() << endl;