forked from qt-creator/qt-creator
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 <joerg.bornemann@qt.io> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,29 @@
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
||||||
33
qbs/modules/libclang/libclang.qbs
Normal file
33
qbs/modules/libclang/libclang.qbs
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
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 {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
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 {
|
|||||||
|
|
||||||
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")
|
||||||
|
|||||||
Reference in New Issue
Block a user