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 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)
......
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.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;
}
......
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")
......
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