From 31258ec5555d929f4cd33e2836e24b470cf6908b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Jun 2016 12:11:22 +0200 Subject: [PATCH] qbs build: Introduce libclang module. This is The Right Way to detect libclang. Using a Probe will also slightly improve performance in qbs 1.6 due to the result caching. Change-Id: I063a8d108d02b620dda2df75dd8c014c84f27ec7 Reviewed-by: Joerg Bornemann Reviewed-by: Nikolai Kosjar --- .../procoutputreader.js | 11 ------ .../libclang}/functions.js | 34 ++++++++++++------- qbs/modules/libclang/libclang.qbs | 33 ++++++++++++++++++ src/plugins/clangcodemodel/clangcodemodel.qbs | 19 ++++------- src/tools/clangbackend/clangbackend.qbs | 20 ++++------- 5 files changed, 68 insertions(+), 49 deletions(-) delete mode 100644 qbs/imports/QtcProcessOutputReader/procoutputreader.js rename qbs/{imports/QtcClangInstallation => modules/libclang}/functions.js (65%) create mode 100644 qbs/modules/libclang/libclang.qbs diff --git a/qbs/imports/QtcProcessOutputReader/procoutputreader.js b/qbs/imports/QtcProcessOutputReader/procoutputreader.js deleted file mode 100644 index 695a61ec88..0000000000 --- a/qbs/imports/QtcProcessOutputReader/procoutputreader.js +++ /dev/null @@ -1,11 +0,0 @@ -var Process = loadExtension("qbs.Process") - -function readOutput(executable, args) -{ - var p = new Process(); - var output = ""; - if (p.exec(executable, args, false) !== -1) - output = p.readStdOut().trim(); // Trailing newline. - p.close(); - return output; -} diff --git a/qbs/imports/QtcClangInstallation/functions.js b/qbs/modules/libclang/functions.js similarity index 65% rename from qbs/imports/QtcClangInstallation/functions.js rename to qbs/modules/libclang/functions.js index 4c2019f149..daa240b853 100644 --- a/qbs/imports/QtcClangInstallation/functions.js +++ b/qbs/modules/libclang/functions.js @@ -1,18 +1,29 @@ var Environment = loadExtension("qbs.Environment") var File = loadExtension("qbs.File") var MinimumLLVMVersion = "3.6.2" +var Process = loadExtension("qbs.Process") -function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions, processOutputReader) +function readOutput(executable, args) +{ + var p = new Process(); + var output = ""; + if (p.exec(executable, args, false) !== -1) + output = p.readStdOut().trim(); // Trailing newline. + p.close(); + return output; +} + +function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions) { if (File.exists(llvmConfigCandidate)) { - var candidateVersion = version(llvmConfigCandidate, processOutputReader); + var candidateVersion = version(llvmConfigCandidate); if (candidateVersion && candidateVersion.length) return qtcFunctions.versionIsAtLeast(candidateVersion, MinimumLLVMVersion) } return false; } -function llvmConfig(qbs, qtcFunctions, processOutputReader) +function llvmConfig(qbs, qtcFunctions) { var llvmInstallDirFromEnv = Environment.getEnv("LLVM_INSTALL_DIR") var llvmConfigVariants = [ @@ -25,7 +36,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) if (llvmInstallDirFromEnv) { for (var i = 0; i < llvmConfigVariants.length; ++i) { var variant = llvmInstallDirFromEnv + "/bin/" + llvmConfigVariants[i] + suffix; - if (isSuitableLLVMConfig(variant, qtcFunctions, processOutputReader)) + if (isSuitableLLVMConfig(variant, qtcFunctions)) return variant; } } @@ -37,7 +48,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) for (var i = 0; i < llvmConfigVariants.length; ++i) { for (var j = 0; j < pathList.length; ++j) { var variant = pathList[j] + "/" + llvmConfigVariants[i] + suffix; - if (isSuitableLLVMConfig(variant, qtcFunctions, processOutputReader)) + if (isSuitableLLVMConfig(variant, qtcFunctions)) return variant; } } @@ -45,20 +56,19 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) return undefined; } -function includeDir(llvmConfig, processOutputReader) +function includeDir(llvmConfig) { - return processOutputReader.readOutput(llvmConfig, ["--includedir"]) + return readOutput(llvmConfig, ["--includedir"]) } -function libDir(llvmConfig, processOutputReader) +function libDir(llvmConfig) { - return processOutputReader.readOutput(llvmConfig, ["--libdir"]) + return readOutput(llvmConfig, ["--libdir"]) } -function version(llvmConfig, processOutputReader) +function version(llvmConfig) { - return processOutputReader.readOutput(llvmConfig, ["--version"]) - .replace(/(\d+\.\d+\.\d+).*/, "$1") + return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1") } function libraries(targetOS) diff --git a/qbs/modules/libclang/libclang.qbs b/qbs/modules/libclang/libclang.qbs new file mode 100644 index 0000000000..eaadeb3bfa --- /dev/null +++ b/qbs/modules/libclang/libclang.qbs @@ -0,0 +1,33 @@ +import qbs +import qbs.File +import QtcFunctions +import "functions.js" as ClangFunctions + +Module { + Probe { + id: clangProbe + + property string llvmConfig + property string llvmIncludeDir + property string llvmLibDir + property stringList llvmLibs + + configure: { + llvmConfig = ClangFunctions.llvmConfig(qbs, QtcFunctions); + llvmIncludeDir = ClangFunctions.includeDir(llvmConfig); + llvmLibDir = ClangFunctions.libDir(llvmConfig); + llvmLibs = ClangFunctions.libraries(qbs.targetOS); + found = llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")); + } + } + + property string llvmConfig: clangProbe.llvmConfig + property string llvmIncludeDir: clangProbe.llvmIncludeDir + property string llvmLibDir: clangProbe.llvmLibDir + property stringList llvmLibs: clangProbe.llvmLibs + + validate: { + if (!clangProbe.found) + throw "No usable libclang found"; + } +} diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index d88f1d3e51..509e75963d 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -1,8 +1,5 @@ import qbs -import qbs.File -import QtcClangInstallation as Clang -import QtcFunctions -import QtcProcessOutputReader +import qbs.FileInfo QtcPlugin { name: "ClangCodeModel" @@ -14,24 +11,22 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "Utils" } Depends { name: "ClangBackEndIpc" } + Depends { name: "libclang"; required: false } pluginTestDepends: [ "CppEditor", "QmakeProjectManager", ] - property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) - property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader) - property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader) - property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader) - - condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")) + condition: libclang.present cpp.defines: { var defines = base; // The following defines are used to determine the clang include path for intrinsics. - defines.push('CLANG_VERSION="' + llvmVersion + '"'); - defines.push('CLANG_RESOURCE_DIR="' + llvmLibDir + '/clang/' + llvmVersion + '/include"'); + defines.push('CLANG_VERSION="' + libclang.llvmVersion + '"'); + var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion, + "include"); + defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"'); return defines; } diff --git a/src/tools/clangbackend/clangbackend.qbs b/src/tools/clangbackend/clangbackend.qbs index 59fdc5b7dd..83684c17f9 100644 --- a/src/tools/clangbackend/clangbackend.qbs +++ b/src/tools/clangbackend/clangbackend.qbs @@ -1,13 +1,10 @@ import qbs 1.0 -import qbs.File -import QtcClangInstallation as Clang -import QtcFunctions -import QtcProcessOutputReader QtcTool { name: "clangbackend" Depends { name: "ClangBackEndIpc" } + Depends { name: "libclang"; required: false } Group { prefix: "ipcsource/" @@ -19,17 +16,12 @@ QtcTool { files: [ "clangbackendmain.cpp" ] - property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) - property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader) - property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader) - property stringList llvmLibs: Clang.libraries(qbs.targetOS) + condition: libclang.present - condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")) - - cpp.includePaths: base.concat(["ipcsource", llvmIncludeDir]) - cpp.libraryPaths: base.concat(llvmLibDir) - cpp.dynamicLibraries: base.concat(llvmLibs) - cpp.rpaths: base.concat(llvmLibDir) + cpp.includePaths: base.concat(["ipcsource", libclang.llvmIncludeDir]) + cpp.libraryPaths: base.concat(libclang.llvmLibDir) + cpp.dynamicLibraries: base.concat(libclang.llvmLibs) + cpp.rpaths: base.concat(libclang.llvmLibDir) Properties { condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("osx") -- GitLab