Commit 31258ec5 authored by Christian Kandeler's avatar Christian Kandeler

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's avatarJoerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Nikolai Kosjar's avatarNikolai Kosjar <nikolai.kosjar@qt.io>
parent 1ce258d7
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;
}
var Environment = loadExtension("qbs.Environment") var Environment = loadExtension("qbs.Environment")
var File = loadExtension("qbs.File") var File = loadExtension("qbs.File")
var MinimumLLVMVersion = "3.6.2" 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)) { if (File.exists(llvmConfigCandidate)) {
var candidateVersion = version(llvmConfigCandidate, processOutputReader); var candidateVersion = version(llvmConfigCandidate);
if (candidateVersion && candidateVersion.length) if (candidateVersion && candidateVersion.length)
return qtcFunctions.versionIsAtLeast(candidateVersion, MinimumLLVMVersion) return qtcFunctions.versionIsAtLeast(candidateVersion, MinimumLLVMVersion)
} }
return false; return false;
} }
function llvmConfig(qbs, qtcFunctions, processOutputReader) function llvmConfig(qbs, qtcFunctions)
{ {
var llvmInstallDirFromEnv = Environment.getEnv("LLVM_INSTALL_DIR") var llvmInstallDirFromEnv = Environment.getEnv("LLVM_INSTALL_DIR")
var llvmConfigVariants = [ var llvmConfigVariants = [
...@@ -25,7 +36,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) ...@@ -25,7 +36,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader)
if (llvmInstallDirFromEnv) { if (llvmInstallDirFromEnv) {
for (var i = 0; i < llvmConfigVariants.length; ++i) { for (var i = 0; i < llvmConfigVariants.length; ++i) {
var variant = llvmInstallDirFromEnv + "/bin/" + llvmConfigVariants[i] + suffix; var variant = llvmInstallDirFromEnv + "/bin/" + llvmConfigVariants[i] + suffix;
if (isSuitableLLVMConfig(variant, qtcFunctions, processOutputReader)) if (isSuitableLLVMConfig(variant, qtcFunctions))
return variant; return variant;
} }
} }
...@@ -37,7 +48,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) ...@@ -37,7 +48,7 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader)
for (var i = 0; i < llvmConfigVariants.length; ++i) { for (var i = 0; i < llvmConfigVariants.length; ++i) {
for (var j = 0; j < pathList.length; ++j) { for (var j = 0; j < pathList.length; ++j) {
var variant = pathList[j] + "/" + llvmConfigVariants[i] + suffix; var variant = pathList[j] + "/" + llvmConfigVariants[i] + suffix;
if (isSuitableLLVMConfig(variant, qtcFunctions, processOutputReader)) if (isSuitableLLVMConfig(variant, qtcFunctions))
return variant; return variant;
} }
} }
...@@ -45,20 +56,19 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader) ...@@ -45,20 +56,19 @@ function llvmConfig(qbs, qtcFunctions, processOutputReader)
return undefined; 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"]) return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1")
.replace(/(\d+\.\d+\.\d+).*/, "$1")
} }
function libraries(targetOS) function libraries(targetOS)
......
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";
}
}
import qbs import qbs
import qbs.File import qbs.FileInfo
import QtcClangInstallation as Clang
import QtcFunctions
import QtcProcessOutputReader
QtcPlugin { QtcPlugin {
name: "ClangCodeModel" name: "ClangCodeModel"
...@@ -14,24 +11,22 @@ QtcPlugin { ...@@ -14,24 +11,22 @@ QtcPlugin {
Depends { name: "TextEditor" } Depends { name: "TextEditor" }
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "ClangBackEndIpc" } Depends { name: "ClangBackEndIpc" }
Depends { name: "libclang"; required: false }
pluginTestDepends: [ pluginTestDepends: [
"CppEditor", "CppEditor",
"QmakeProjectManager", "QmakeProjectManager",
] ]
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) condition: libclang.present
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"))
cpp.defines: { cpp.defines: {
var defines = base; var defines = base;
// The following defines are used to determine the clang include path for intrinsics. // The following defines are used to determine the clang include path for intrinsics.
defines.push('CLANG_VERSION="' + llvmVersion + '"'); defines.push('CLANG_VERSION="' + libclang.llvmVersion + '"');
defines.push('CLANG_RESOURCE_DIR="' + llvmLibDir + '/clang/' + llvmVersion + '/include"'); var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
return defines; return defines;
} }
......
import qbs 1.0 import qbs 1.0
import qbs.File
import QtcClangInstallation as Clang
import QtcFunctions
import QtcProcessOutputReader
QtcTool { QtcTool {
name: "clangbackend" name: "clangbackend"
Depends { name: "ClangBackEndIpc" } Depends { name: "ClangBackEndIpc" }
Depends { name: "libclang"; required: false }
Group { Group {
prefix: "ipcsource/" prefix: "ipcsource/"
...@@ -19,17 +16,12 @@ QtcTool { ...@@ -19,17 +16,12 @@ QtcTool {
files: [ "clangbackendmain.cpp" ] files: [ "clangbackendmain.cpp" ]
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) condition: libclang.present
property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
property stringList llvmLibs: Clang.libraries(qbs.targetOS)
condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")) cpp.includePaths: base.concat(["ipcsource", libclang.llvmIncludeDir])
cpp.libraryPaths: base.concat(libclang.llvmLibDir)
cpp.includePaths: base.concat(["ipcsource", llvmIncludeDir]) cpp.dynamicLibraries: base.concat(libclang.llvmLibs)
cpp.libraryPaths: base.concat(llvmLibDir) cpp.rpaths: base.concat(libclang.llvmLibDir)
cpp.dynamicLibraries: base.concat(llvmLibs)
cpp.rpaths: base.concat(llvmLibDir)
Properties { Properties {
condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("osx") condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("osx")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment