Commit 5e063954 authored by Ulf Hermann's avatar Ulf Hermann

Add some sanity to the clang detection code for qmake build

llvm-config can usually be found in PATH on systems which have standard
paths at all. There is no need to specify LLVM_INSTALL_DIR then.
Furthermore, llvm-config has an option --bindir which will tell us the
directory where clang can be found (if installed). No need to apply
strange heuristics based on LLVM_INSTALL_DIR. Finally, we can check
within each .pro file for the conditions to be met using qmake's
require() function. This way we don't need to fiddle with
LLVM_INSTALL_DIR in unrelated places.

Change-Id: I1a6ab092b06de40dfbfa4a9e7053451360fd24c8
Reviewed-by: Nikolai Kosjar's avatarNikolai Kosjar <nikolai.kosjar@qt.io>
parent b0137c3a
......@@ -31,7 +31,7 @@ The installed toolchains have to match the one Qt was compiled with.
You can build Qt Creator with
# Optional, needed for the Clang Code Model:
# Optional, needed for the Clang Code Model if llvm-config is not in PATH:
export LLVM_INSTALL_DIR=/path/to/llvm (or "set" on Windows)
# Optional, needed to let the QbsProjectManager plugin use system Qbs:
export QBS_INSTALL_DIR=/path/to/qbs
......@@ -129,7 +129,7 @@ For detailed information on the supported compilers, see
* Install LLVM/Clang - see the section "Get LLVM/Clang for the Clang
Code Model".
* Set the environment variable LLVM_INSTALL_DIR to the LLVM/Clang
installation directory.
installation directory if llvm-config is not in PATH.
* When you launch Qt Creator, activate the Clang Code Model plugin as
described in doc/src/editors/creator-clang-codemodel.qdoc.
......
......@@ -3,6 +3,8 @@ include(../../shared/clang/clang_installation.pri)
include(../../shared/clang/clang_defines.pri)
requires(!isEmpty(LLVM_VERSION))
SOURCES += \
clangactivationsequencecontextprocessor.cpp \
clangactivationsequenceprocessor.cpp \
......
......@@ -96,21 +96,15 @@ exists(../shared/qbs/qbs.pro)|!isEmpty(QBS_INSTALL_DIR): \
SUBDIRS += \
qbsprojectmanager
# prefer qmake variable set on command line over env var
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
exists($$LLVM_INSTALL_DIR) {
SUBDIRS += clangcodemodel
SUBDIRS += \
clangcodemodel
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoring
SUBDIRS += clangpchmanager
} else {
warning("Building the Clang refactoring and the pch manager plugins are disabled.")
}
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoring
SUBDIRS += clangpchmanager
} else {
warning("Set LLVM_INSTALL_DIR to build the Clang Code Model. " \
"For details, see doc/src/editors/creator-clang-codemodel.qdoc.")
warning("Building the Clang refactoring and the pch manager plugins are disabled.")
}
isEmpty(IDE_PACKAGE_MODE) {
......
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
LLVM_INSTALL_DIR = $$clean_path($$LLVM_INSTALL_DIR)
isEmpty(LLVM_INSTALL_DIR): error("No LLVM_INSTALL_DIR provided")
!exists($$LLVM_INSTALL_DIR): error("LLVM_INSTALL_DIR does not exist: $$LLVM_INSTALL_DIR")
!isEmpty(LLVM_INSTALL_DIR):!exists($$LLVM_INSTALL_DIR) {
error("Explicitly given LLVM_INSTALL_DIR does not exist: $$LLVM_INSTALL_DIR")
}
defineReplace(llvmWarningOrError) {
warningText = $$1
errorText = $$2
isEmpty(errorText): errorText = $$warningText
isEmpty(LLVM_INSTALL_DIR): warning($$warningText)
else: error($$errorText)
return(false)
}
# Expected input: "3.9.1", "5.0.0svn", "5.0.1git-81029f14223"
defineReplace(extractVersion) { return($$replace(1, ^(\\d+\\.\\d+\\.\\d+).*$, \\1)) }
......@@ -69,20 +80,6 @@ defineReplace(findClangLibInLibDir) {
}
}
defineReplace(findClangOnWindows) {
FILE_EXTS = a dll
msvc: FILE_EXTS = lib dll
for (suffix, $$list(lib bin)) {
for (libname, $$list(clang libclang)) {
for (ext, FILE_EXTS) {
exists("$${LLVM_INSTALL_DIR}/$${suffix}/$${libname}.$${ext}") {
return($${LLVM_INSTALL_DIR}/$${suffix}/)
}
}
}
}
}
CLANGTOOLING_LIBS=-lclangTooling -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangToolingCore -lclangAST -lclangLex -lclangBasic
......@@ -91,65 +88,87 @@ win32:CLANGTOOLING_LIBS += -lversion
BIN_EXTENSION =
win32: BIN_EXTENSION = .exe
llvm_config = $$system_quote($$LLVM_INSTALL_DIR/bin/llvm-config)
requires(exists($$llvm_config$$BIN_EXTENSION))
#message("llvm-config found, querying it for paths and version")
LLVM_LIBDIR = $$quote($$system($$llvm_config --libdir, lines))
LLVM_INCLUDEPATH = $$system($$llvm_config --includedir, lines)
isEmpty(LLVM_INSTALL_DIR) {
llvm_config = llvm-config
} else {
llvm_config = $$system_quote($$LLVM_INSTALL_DIR/bin/llvm-config)
requires(exists($$llvm_config$$BIN_EXTENSION))
}
output = $$system($$llvm_config --version, lines)
LLVM_VERSION = $$extractVersion($$output)
msvc {
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --libnames, lines)
isEmpty(LLVM_VERSION) {
$$llvmWarningOrError(\
"Cannot determine clang version. Set LLVM_INSTALL_DIR to build the Clang Code Model",\
"LLVM_INSTALL_DIR does not contain a valid llvm-config, candidate: $$llvm_config")
} else:!versionIsAtLeast($$LLVM_VERSION, 5, 0, 0): {
# CLANG-UPGRADE-CHECK: Adapt minimum version numbers.
$$llvmWarningOrError(\
"LLVM/Clang version >= 5.0.0 required, version provided: $$LLVM_VERSION")
LLVM_VERSION =
} else {
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --libs, lines)
}
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --system-libs, lines)
LLVM_STATIC_LIBS = $$split(LLVM_STATIC_LIBS_STRING, " ")
LIBCLANG_MAIN_HEADER = $$LLVM_INCLUDEPATH/clang-c/Index.h
!exists($$LIBCLANG_MAIN_HEADER): error("Cannot find libclang's main header file, candidate: $$LIBCLANG_MAIN_HEADER")
!exists($$LLVM_LIBDIR): error("Cannot detect lib dir for clang, candidate: $$LLVM_LIBDIR")
CLANG_LIB = $$findClangLibInLibDir($$LLVM_LIBDIR)
isEmpty(CLANG_LIB): error("Cannot find Clang shared library in $$LLVM_LIBDIR")
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): LIBCLANG_LIBS = -L$${LLVM_LIBDIR}
LIBCLANG_LIBS += $${CLANG_LIB}
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
QTC_FORCE_CLANG_LIBTOOLING = $$(QTC_FORCE_CLANG_LIBTOOLING)
versionIsEqual($$LLVM_VERSION, 5, 0)|!isEmpty(QTC_FORCE_CLANG_LIBTOOLING) {
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): LIBTOOLING_LIBS = -L$${LLVM_LIBDIR}
LIBTOOLING_LIBS += $$CLANGTOOLING_LIBS $$LLVM_STATIC_LIBS
contains(QMAKE_DEFAULT_INCDIRS, $$LLVM_INCLUDEPATH): LLVM_INCLUDEPATH =
LLVM_LIBDIR = $$quote($$system($$llvm_config --libdir, lines))
LLVM_BINDIR = $$quote($$system($$llvm_config --bindir, lines))
LLVM_INCLUDEPATH = $$system($$llvm_config --includedir, lines)
msvc {
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --libnames, lines)
} else {
warning("Clang LibTooling is disabled because only version 5.0 is supported.")
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --libs, lines)
}
} else {
warning("Clang LibTooling is disabled.")
}
LLVM_STATIC_LIBS_STRING += $$system($$llvm_config --system-libs, lines)
isEmpty(LLVM_VERSION): error("Cannot determine clang version at $$LLVM_INSTALL_DIR")
!versionIsAtLeast($$LLVM_VERSION, 5, 0, 0): { # CLANG-UPGRADE-CHECK: Adapt minimum version numbers.
error("LLVM/Clang version >= 5.0.0 required, version provided: $$LLVM_VERSION")
}
LLVM_STATIC_LIBS = $$split(LLVM_STATIC_LIBS_STRING, " ")
LIBCLANG_MAIN_HEADER = $$LLVM_INCLUDEPATH/clang-c/Index.h
!exists($$LIBCLANG_MAIN_HEADER) {
$$llvmWarningOrError(\
"Cannot find libclang's main header file, candidate: $$LIBCLANG_MAIN_HEADER")
}
!exists($$LLVM_LIBDIR) {
$$llvmWarningOrError("Cannot detect lib dir for clang, candidate: $$LLVM_LIBDIR")
}
!exists($$LLVM_BINDIR) {
$$llvmWarningOrError("Cannot detect bin dir for clang, candidate: $$LLVM_BINDIR")
}
CLANG_LIB = $$findClangLibInLibDir($$LLVM_LIBDIR)
isEmpty(CLANG_LIB) {
$$llvmWarningOrError("Cannot find Clang shared library in $$LLVM_LIBDIR")
}
# Remove unwanted flags. It is a workaround for linking. It is not intended for cross compiler linking.
LLVM_CXXFLAGS = $$system($$llvm_config --cxxflags, lines)
LLVM_CXXFLAGS ~= s,-fno-exceptions,
LLVM_CXXFLAGS ~= s,-std=c++11,
LLVM_CXXFLAGS ~= s,-std=c++0x,
LLVM_CXXFLAGS ~= s,-O\S*,
LLVM_CXXFLAGS ~= s,/O\S*,
LLVM_CXXFLAGS ~= s,/W4,
LLVM_CXXFLAGS ~= s,/EH\S*,
LLVM_CXXFLAGS ~= s,-Werror=date-time,
LLVM_CXXFLAGS ~= s,-Wcovered-switch-default,
LLVM_CXXFLAGS ~= s,-fPIC,
LLVM_CXXFLAGS ~= s,-pedantic,
LLVM_CXXFLAGS ~= s,-Wstring-conversion,
# split-dwarf needs objcopy which does not work via icecc out-of-the-box
LLVM_CXXFLAGS ~= s,-gsplit-dwarf,
LLVM_IS_COMPILED_WITH_RTTI = $$system($$llvm_config --has-rtti, lines)
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): LIBCLANG_LIBS = -L$${LLVM_LIBDIR}
LIBCLANG_LIBS += $${CLANG_LIB}
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
QTC_FORCE_CLANG_LIBTOOLING = $$(QTC_FORCE_CLANG_LIBTOOLING)
versionIsEqual($$LLVM_VERSION, 5, 0)|!isEmpty(QTC_FORCE_CLANG_LIBTOOLING) {
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): LIBTOOLING_LIBS = -L$${LLVM_LIBDIR}
LIBTOOLING_LIBS += $$CLANGTOOLING_LIBS $$LLVM_STATIC_LIBS
contains(QMAKE_DEFAULT_INCDIRS, $$LLVM_INCLUDEPATH): LLVM_INCLUDEPATH =
} else {
warning("Clang LibTooling is disabled because only version 5.0 is supported.")
}
} else {
warning("Clang LibTooling is disabled.")
}
# Remove unwanted flags. It is a workaround for linking.
# It is not intended for cross compiler linking.
LLVM_CXXFLAGS = $$system($$llvm_config --cxxflags, lines)
LLVM_CXXFLAGS ~= s,-fno-exceptions,
LLVM_CXXFLAGS ~= s,-std=c++11,
LLVM_CXXFLAGS ~= s,-std=c++0x,
LLVM_CXXFLAGS ~= s,-O\S*,
LLVM_CXXFLAGS ~= s,/O\S*,
LLVM_CXXFLAGS ~= s,/W4,
LLVM_CXXFLAGS ~= s,/EH\S*,
LLVM_CXXFLAGS ~= s,-Werror=date-time,
LLVM_CXXFLAGS ~= s,-Wcovered-switch-default,
LLVM_CXXFLAGS ~= s,-fPIC,
LLVM_CXXFLAGS ~= s,-pedantic,
LLVM_CXXFLAGS ~= s,-Wstring-conversion,
# split-dwarf needs objcopy which does not work via icecc out-of-the-box
LLVM_CXXFLAGS ~= s,-gsplit-dwarf,
LLVM_IS_COMPILED_WITH_RTTI = $$system($$llvm_config --has-rtti, lines)
}
......@@ -6,6 +6,8 @@ include(../../qtcreatortool.pri)
include(../../shared/clang/clang_installation.pri)
include(source/clangbackendclangipc-source.pri)
requires(!isEmpty(LLVM_VERSION))
QT += core network
QT -= gui
......
......@@ -33,4 +33,4 @@ unix {
!disable_external_rpath: QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${LLVM_LIBDIR})
}
DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_INSTALL_DIR/bin/clang)xxx\\\"\"
DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($${LLVM_BINDIR}/clang)xxx\\\"\"
......@@ -20,17 +20,14 @@ mac {
SUBDIRS += iostool
}
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
exists($$LLVM_INSTALL_DIR) {
SUBDIRS += clangbackend
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoringbackend
SUBDIRS += clangpchmanagerbackend
} else {
warning("Building the Clang refactoring back end and the pch manager plugins are disabled.")
}
SUBDIRS += clangbackend
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoringbackend
SUBDIRS += clangpchmanagerbackend
} else {
warning("Building the Clang refactoring back end and the pch manager plugins are disabled.")
}
isEmpty(BUILD_CPLUSPLUS_TOOLS):BUILD_CPLUSPLUS_TOOLS=$$(BUILD_CPLUSPLUS_TOOLS)
......
TEMPLATE=subdirs
SUBDIRS += auto manual tools
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
exists($$LLVM_INSTALL_DIR):SUBDIRS += unit
SUBDIRS += auto manual tools unit
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
!isEmpty(LLVM_INSTALL_DIR) {
include(../../../src/shared/clang/clang_installation.pri)
requires(!isEmpty(LIBCLANG_LIBS))
equals(LLVM_IS_COMPILED_WITH_RTTI, "NO") : message("LLVM needs to be compiled with RTTI!")
requires(equals(LLVM_IS_COMPILED_WITH_RTTI, "YES"))
!isEmpty(LLVM_VERSION) {
requires(!isEmpty(LIBCLANG_LIBS))
equals(LLVM_IS_COMPILED_WITH_RTTI, "NO") : message("LLVM needs to be compiled with RTTI!")
requires(equals(LLVM_IS_COMPILED_WITH_RTTI, "YES"))
DEFINES += CLANG_UNIT_TESTS
INCLUDEPATH += $$LLVM_INCLUDEPATH
win32 {
LIBS += -lVersion
DEFINES += CLANG_UNIT_TESTS
INCLUDEPATH += $$LLVM_INCLUDEPATH
win32 {
LIBS += -lVersion
# set run path for clang.dll dependency
bin_path = $$LLVM_INSTALL_DIR/bin
bin_path ~= s,/,\\,g
# the below gets added to later by testcase.prf
check.commands = cd . & set PATH=$$bin_path;%PATH%& cmd /c
}
# set run path for clang.dll dependency
bin_path = $$LLVM_BINDIR
bin_path ~= s,/,\\,g
# the below gets added to later by testcase.prf
check.commands = cd . & set PATH=$$bin_path;%PATH%& cmd /c
}
LIBS += $$LIBTOOLING_LIBS $$LIBCLANG_LIBS
QMAKE_RPATHDIR += $$LLVM_LIBDIR
LIBS += $$LIBTOOLING_LIBS $$LIBCLANG_LIBS
QMAKE_RPATHDIR += $$LLVM_LIBDIR
LLVM_CXXFLAGS ~= s,-g\d?,
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS
}
LLVM_CXXFLAGS ~= s,-g\d?,
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS
DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_INSTALL_DIR/bin/clang)xxx\\\"\"
DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_BINDIR/clang)xxx\\\"\"
}
......@@ -14,7 +14,7 @@ include($$PWD/../../../src/plugins/clangrefactoring/clangrefactoring-source.pri)
include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
include(cplusplus.pri)
!isEmpty(LLVM_INSTALL_DIR) {
!isEmpty(LLVM_VERSION) {
include($$PWD/../../../src/shared/clang/clang_defines.pri)
include($$PWD/../../../src/tools/clangbackend/source/clangbackendclangipc-source.pri)
include($$PWD/../../../src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri)
......
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