From a4e3a1191949449d1fda319771c725fdaa6f8b75 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 5 May 2018 15:11:17 +0200 Subject: Build compilation database (clangdb) when compiling --- backend/ninja/Ninja.cpp | 65 +++++++++++++++++++++++++++++++++++++++++-------- backend/ninja/Ninja.hpp | 1 + include/Conf.hpp | 14 ++++++++++- src/CmakeModule.cpp | 1 + src/main.cpp | 6 ++++- 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index 28e4ea1..78ac68b 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -512,7 +512,7 @@ namespace backend result += " depfile = $out.d\n"; result += " command = ccache c++ $ARGS -c $in -o $out\n\n"; - result += "rule cpp_BUILD_EXEC\n"; + result += "rule BUILD_EXEC\n"; result += " depfile = $out.d\n"; result += " command = ccache c++ $ARGS -o $out $in $LINK_ARGS $aliasing\n\n"; @@ -526,7 +526,7 @@ namespace backend result += "rule cpp_COMPILER\n"; result += " command = cl.exe $ARGS /c $in /Fo$out\n\n"; - result += "rule cpp_BUILD_EXEC\n"; + result += "rule BUILD_EXEC\n"; result += " command = cl.exe $ARGS $in /Fe$out $LINK_ARGS\n\n"; result += "rule c_COMPILER\n"; @@ -535,7 +535,7 @@ namespace backend } } - buildJob = "cpp_BUILD_EXEC"; + buildJob = "BUILD_EXEC"; break; } case LibraryType::STATIC: @@ -548,7 +548,7 @@ namespace backend result += " depfile = $out.d\n"; result += " command = ccache c++ $ARGS -c -fPIC $in -o $out\n\n"; - result += "rule cpp_BUILD_STATIC\n"; + result += "rule BUILD_STATIC\n"; result += " command = ar rcs lib"; result += config.getPackageName(); result += ".a"; @@ -564,7 +564,7 @@ namespace backend result += "rule cpp_COMPILER\n"; result += " command = cl.exe $ARGS /c $in /Fo$out\n\n"; - result += "rule cpp_BUILD_STATIC\n"; + result += "rule BUILD_STATIC\n"; result += " command = lib.exe /OUT:$out $in\n\n"; result += "rule c_COMPILER\n"; @@ -573,7 +573,7 @@ namespace backend } } - buildJob = "cpp_BUILD_STATIC"; + buildJob = "BUILD_STATIC"; break; } case LibraryType::DYNAMIC: @@ -587,7 +587,7 @@ namespace backend result += " command = ccache c++ $ARGS -c -fPIC $in -o $out\n\n"; // --whole-archive - result += "rule cpp_BUILD_DYNAMIC\n"; + result += "rule BUILD_DYNAMIC\n"; result += " depfile = $out.d\n"; result += " command = ccache c++ $in -shared -o $out $LINK_ARGS $aliasing\n\n"; @@ -601,10 +601,10 @@ namespace backend result += "rule cpp_COMPILER\n"; result += " command = cl.exe $ARGS /c $in /Fo$out\n\n"; - //result += "rule cpp_BUILD_DYNAMIC\n"; + //result += "rule BUILD_DYNAMIC\n"; //result += " command = cl.exe /LD $in /Fe$out $LINK_ARGS\n\n"; - result += "rule cpp_BUILD_DYNAMIC\n"; + result += "rule BUILD_DYNAMIC\n"; result += " command = lib.exe /OUT:$out $in\n\n"; result += "rule c_COMPILER\n"; @@ -613,7 +613,7 @@ namespace backend } } - buildJob = "cpp_BUILD_DYNAMIC"; + buildJob = "BUILD_DYNAMIC"; break; } default: @@ -895,6 +895,13 @@ namespace backend Result buildResult = compile(savePath); if (!buildResult) return buildResult; + + if(config.isMainProject()) + { + buildResult = buildCompilationDatabase(savePath); + if(!buildResult) + return buildResult; + } } // TODO: If tests are being run (sibs test) and root project is an executable, do not run compile (above code) as executable. @@ -984,6 +991,14 @@ namespace backend if (!buildResult) return buildResult; + // Convenient to have project setup to tests as well + if(config.isMainProject()) + { + buildResult = buildCompilationDatabase(buildPath.c_str()); + if(!buildResult) + return buildResult; + } + FileString testExecutableName = buildPath; testExecutableName += TINYDIR_STRING("/"); testExecutableName += toFileString(sibsTestConfig.getPackageName()); @@ -1025,4 +1040,34 @@ namespace backend else return Result::Err(""); } + + Result Ninja::buildCompilationDatabase(const _tinydir_char_t *buildFilePath) + { + FileString command = TINYDIR_STRING("ninja -C \""); + command += buildFilePath; + command += TINYDIR_STRING("\" -t compdb c_COMPILER cpp_COMPILER BUILD_EXEC BUILD_STATIC BUILD_DYNAMIC > \""); + command += buildFilePath; + command += TINYDIR_STRING("/compile_commands.json\""); + Result execResult = exec(command.c_str(), false); + if(execResult.isOk()) + { + if(execResult.unwrap().exitCode == 0) + { + //printf("%s\n", execResult.unwrap().execStdout.c_str()); + return Result::Ok(true); + } + else + { + string errMsg = "Failed to build compilation database, reason: "; + errMsg += execResult.unwrap().execStdout; + return Result::Err(errMsg); + } + } + else + { + string errMsg = "Failed to build compilation database, reason: "; + errMsg += execResult.getErrMsg(); + return Result::Err(errMsg); + } + } } diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp index 7bbff51..575a9bc 100644 --- a/backend/ninja/Ninja.hpp +++ b/backend/ninja/Ninja.hpp @@ -56,6 +56,7 @@ namespace backend bool containsDependency(const std::string &dependency) const; sibs::Result getLinkerFlags(const sibs::SibsConfig &config, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback, sibs::CflagsCallbackFunc cflagsCallbackFunc) const; sibs::Result compile(const _tinydir_char_t *buildFilePath); + sibs::Result buildCompilationDatabase(const _tinydir_char_t *buildFilePath); private: std::string customGlobalIncludeDirs; std::vector sourceFiles; diff --git a/include/Conf.hpp b/include/Conf.hpp index 6a6d07c..9a9cacf 100644 --- a/include/Conf.hpp +++ b/include/Conf.hpp @@ -212,7 +212,8 @@ namespace sibs useCmake(false), buildTests(_buildTests), cVersion(CVersion::C11), - cppVersion(CPPVersion::CPP14) + cppVersion(CPPVersion::CPP14), + mainProject(false) { cmakeDirGlobal = projectPath; cmakeDirStatic = cmakeDirGlobal; @@ -377,6 +378,16 @@ namespace sibs this->packageType = packageType; } + bool isMainProject() const + { + return mainProject; + } + + void setMainProject(bool mainProject) + { + this->mainProject = mainProject; + } + virtual bool isDefined(const std::string &name) const; virtual bool define(const std::string &name, const std::string &value); virtual const std::unordered_map& getDefines() const; @@ -428,6 +439,7 @@ namespace sibs bool useCmake; bool buildTests; bool finishedProcessing; + bool mainProject; }; class SibsTestConfig : public SibsConfig diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index 99be269..6313eb0 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -141,6 +141,7 @@ namespace sibs } } //cmd += TINYDIR_STRING(" -DCMAKE_SKIP_RPATH=\"1\""); + cmd += TINYDIR_STRING(" -DCMAKE_EXPORT_COMPILE_COMMANDS"); cmd += TINYDIR_STRING(" \"-B"); cmd += buildPath; cmd += TINYDIR_STRING("\" \"-H"); diff --git a/src/main.cpp b/src/main.cpp index 441ec2f..db57648 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,12 +79,16 @@ using namespace std::chrono; // This is to include lgpl dependencies as dynamic libraries and give error if you are using gpl dependencies in a non gpl project. // If the license type is custom, then the ways the library can be used should be defined in such a way that dependent projects can determinate // if the dependency can be used without breaking compatibility between licenses. +// License notice has to be in a file called LICENSE or COPYING in the root directory of the project and these files will be combined automatically +// for all dependencies when releasing your software, as including license with software is often required. // TODO: Dynamically link libgit2 (sibs dependency) since it's under lgpl license. Optionally implement git clone/pull with MIT license. // TODO: Auto export all symbols under windows (https://stackoverflow.com/questions/225432/export-all-symbols-when-creating-a-dll) // TODO: Fix issue where when you have a dependency on a cmake project with dynamic library, the dynamic library wont be found at runtime for whatever reason +// TODO: Add program command for generating compile_commands.json without compiling code, without using Ninja + #if OS_FAMILY == OS_FAMILY_POSIX #define ferr std::cerr #else @@ -259,7 +263,7 @@ int buildProject(const FileString &projectPath, const FileString &projectConfFil } backend::BackendUtils::collectSourceFiles(projectPath.c_str(), &ninja, sibsConfig); - + sibsConfig.setMainProject(true); Result buildFileResult = ninja.build(sibsConfig, buildPath.c_str()); if(buildFileResult.isErr()) { -- cgit v1.2.3