From 99570d3fa5abf548d4e8e5e479d82ee66898b602 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 10 Dec 2017 04:05:20 +0100 Subject: Add support for recursive global lib dependencies --- backend/ninja/Ninja.cpp | 77 +++++++++++++++++++++++++++++++++++++------------ backend/ninja/Ninja.hpp | 6 ++-- include/GlobalLib.hpp | 3 +- include/Linker.hpp | 11 +++++++ src/GlobalLib.cpp | 5 ++-- 5 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 include/Linker.hpp diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index 3df4e41..20e2374 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -76,7 +76,7 @@ namespace backend // TODO: First check if pkg-config is installed. If it's not, only check dependencies that exists in the dependencies sub directory. // If pkg-config is installed and dependency is not installed, check in dependencies sub directory. - Result Ninja::getLinkerFlags(const vector &dependencies) const + Result Ninja::getLinkerFlags(const vector &dependencies, LinkerFlagCallbackFunc linkerFlagCallbackFunc) const { if(dependencies.empty()) return Result::Ok(""); @@ -96,7 +96,7 @@ namespace backend else { printf("%s, trying global lib\n", pkgConfigDependencyValidation.getErrMsg().c_str()); - Result globalLibLinkerFlagsResult = GlobalLib::getDynamicLibsLinkerFlags(globalLibDir, dependency.name, dependency.version); + Result globalLibLinkerFlagsResult = GlobalLib::getStaticLibsLinkerFlags(globalLibDir, dependency.name, dependency.version, linkerFlagCallbackFunc); if(globalLibLinkerFlagsResult.isErr()) return globalLibLinkerFlagsResult; @@ -110,12 +110,14 @@ namespace backend if(pkgConfigLinkerFlagsResult.isErr()) return pkgConfigLinkerFlagsResult; + linkerFlagCallbackFunc(pkgConfigLinkerFlagsResult.unwrap()); + string allLinkerFlags = pkgConfigLinkerFlagsResult.unwrap(); allLinkerFlags += globalLibLinkerFlags; return Result::Ok(allLinkerFlags); } - Result Ninja::createBuildFile(const std::string &packageName, const vector &dependencies, const char *savePath) + Result Ninja::createBuildFile(const std::string &packageName, const vector &dependencies, const char *savePath, LinkerFlagCallbackFunc linkerFlagCallbackFunc) { if(sourceFiles.empty()) return Result::Err("No source files provided"); @@ -126,7 +128,12 @@ namespace backend string result; result.reserve(16384); - result += "cflags = -Wall -Werror\n\n"; + string globalLibDir = getHomeDir(); + globalLibDir += "/.sibs/lib"; + + result += "globalLibDir = '-I"; + result += globalLibDir; + result += "'\n\n"; result += "rule cpp_COMPILER\n"; result += " command = ccache c++ $ARGS -c $in -o $out\n\n"; @@ -159,6 +166,12 @@ namespace backend vector objectNames; 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"; @@ -167,23 +180,51 @@ namespace backend result += ": cpp_COMPILER ../../"; result += sourceFile; result += "\n"; - // TODO: Create .deps directory if it doesn't exist. Should be a symlink to homedir/.sibs/lib - result += " ARGS = '-I../../.deps' '-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" + packageName + "@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); } - Result linkerFlags = getLinkerFlags(dependencies); - if(linkerFlags.isErr()) - return Result::Err(linkerFlags.getErrMsg()); - - result += "build "; - result += packageName; - result += ": " + linkerJob + " "; - result += join(objectNames, " "); - result += "\n"; - result += " LINK_ARGS = '-Wl,--no-undefined' '-Wl,--as-needed' "; - result += linkerFlags.unwrap(); - result += "\n\n"; + switch(libraryType) + { + case LibraryType::EXECUTABLE: + { + string allLinkerFlags; + Result linkerFlags = getLinkerFlags(dependencies, [&allLinkerFlags](const string &linkerFlag) + { + allLinkerFlags += " "; + allLinkerFlags += linkerFlag; + }); + if(linkerFlags.isErr()) + return Result::Err(linkerFlags.getErrMsg()); + + result += "build "; + result += packageName; + result += ": " + linkerJob + " "; + result += join(objectNames, " "); + result += "\n"; + result += " LINK_ARGS = '-Wl,--no-undefined' '-Wl,--as-needed' "; + result += allLinkerFlags; + result += "\n\n"; + break; + } + case LibraryType::STATIC: + { + string allLinkerFlags; + Result linkerFlags = getLinkerFlags(dependencies, linkerFlagCallbackFunc); + if(linkerFlags.isErr()) + return Result::Err(linkerFlags.getErrMsg()); + + result += "build "; + result += packageName; + result += ": " + linkerJob + " "; + result += join(objectNames, " "); + result += "\n\n"; + break; + } + default: + assert(false); + return Result::Err("NOT IMPLEMENTED YET!"); + } bool fileOverwritten = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size())); if(!fileOverwritten) diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp index 9ca6ace..71b12a5 100644 --- a/backend/ninja/Ninja.hpp +++ b/backend/ninja/Ninja.hpp @@ -3,8 +3,10 @@ #include "../../include/Dependency.hpp" #include "../../include/Result.hpp" +#include "../../include/Linker.hpp" #include #include +#include namespace backend @@ -22,11 +24,11 @@ namespace backend Ninja(LibraryType libraryType = LibraryType::EXECUTABLE); void addSourceFile(const char *filepath); - sibs::Result createBuildFile(const std::string &packageName, const std::vector &dependencies, const char *savePath); + sibs::Result createBuildFile(const std::string &packageName, const std::vector &dependencies, const char *savePath, sibs::LinkerFlagCallbackFunc linkerFlagCallbackFunc = nullptr); sibs::Result build(const char *buildFilePath); private: bool containsSourceFile(const char *filepath) const; - sibs::Result getLinkerFlags(const std::vector &dependencies) const; + sibs::Result getLinkerFlags(const std::vector &dependencies, sibs::LinkerFlagCallbackFunc linkerFlagCallbackFunc) const; private: std::vector sourceFiles; LibraryType libraryType; diff --git a/include/GlobalLib.hpp b/include/GlobalLib.hpp index e5a9374..d5e21d1 100644 --- a/include/GlobalLib.hpp +++ b/include/GlobalLib.hpp @@ -2,6 +2,7 @@ #define SIBS_GLOBALLIB_HPP #include "Result.hpp" +#include "Linker.hpp" namespace sibs { @@ -9,7 +10,7 @@ namespace sibs { public: static Result validatePackageExists(const std::string &globalLibRootDir, const std::string &name); - static Result getDynamicLibsLinkerFlags(const std::string &globalLibRootDir, const std::string &name, const std::string &version); + static Result getStaticLibsLinkerFlags(const std::string &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc linkerFlagCallbackFunc); }; } diff --git a/include/Linker.hpp b/include/Linker.hpp new file mode 100644 index 0000000..7ea7b48 --- /dev/null +++ b/include/Linker.hpp @@ -0,0 +1,11 @@ +#ifndef SIBS_LINKER_HPP +#define SIBS_LINKER_HPP + +#include + +namespace sibs +{ + using LinkerFlagCallbackFunc = std::function; +} + +#endif //SIBS_LINKER_HPP diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp index 0ed34c7..41e26c1 100644 --- a/src/GlobalLib.cpp +++ b/src/GlobalLib.cpp @@ -53,7 +53,7 @@ namespace sibs return false; } - Result GlobalLib::getDynamicLibsLinkerFlags(const string &globalLibRootDir, const string &name, const string &version) + Result GlobalLib::getStaticLibsLinkerFlags(const string &globalLibRootDir, const string &name, const string &version, LinkerFlagCallbackFunc linkerFlagCallbackFunc) { Result packageExistsResult = validatePackageExists(globalLibRootDir, name); if(packageExistsResult.isErr()) @@ -126,7 +126,7 @@ namespace sibs // TODO: Create build path if it doesn't exist string debugBuildPath = packageDir + "/build/debug"; - Result buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str()); + Result buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str(), linkerFlagCallbackFunc); if(buildFileResult.isErr()) return Result::Err(buildFileResult.getErrMsg()); @@ -138,6 +138,7 @@ namespace sibs staticLibPath += "/lib"; staticLibPath += name; staticLibPath += ".a"; + linkerFlagCallbackFunc(staticLibPath); return Result::Ok(staticLibPath); } } \ No newline at end of file -- cgit v1.2.3