diff options
author | dec05eba <dec05eba@protonmail.com> | 2017-12-16 04:21:33 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2017-12-16 04:21:44 +0100 |
commit | 94caff5f66cacdd21e5a93cd3de9150a22eeaa3a (patch) | |
tree | b3b7689e5a25c908369bb5fad5a59e085253b76e /src | |
parent | 28d6b571139998915bce147abb58617884431192 (diff) |
Add support for sub project (unit tests)
Diffstat (limited to 'src')
-rw-r--r-- | src/Conf.cpp | 53 | ||||
-rw-r--r-- | src/FileUtil.cpp | 21 | ||||
-rw-r--r-- | src/GlobalLib.cpp | 38 | ||||
-rw-r--r-- | src/main.cpp | 37 |
4 files changed, 130 insertions, 19 deletions
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; |