diff options
author | Ivan Komissarov <abbapoh@gmail.com> | 2019-12-12 20:47:27 +0100 |
---|---|---|
committer | Ivan Komissarov <ABBAPOH@gmail.com> | 2020-01-24 09:11:04 +0000 |
commit | 9c282ff7bd13b25118da3e6d7a46e75fe78caf4c (patch) | |
tree | 84bbea00869bd2902e91ffdd464b4ff27db339ce /tests | |
parent | 1e7875f00e406b762065f0ea2fe30836829fdd42 (diff) |
MSVC: Use compiler driver for linking
To be able to use cpp.driverFlags and cpp.driverLinkerFlags with clang-
cl. This patchset makes possible to use clang-cl with "-
fsanitize=address" flag without passing the sanitizer libraries manually
to the linker
There's also a behavior change in which linker is used - clang-cl uses
native linker by default. Old behavior can be restored by setting
cpp.linkerVariant to "lld"
Fixes: QBS-1522
Change-Id: I9528ce40aa5fdfab987672b15fffd830fa2d6376
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'tests')
6 files changed, 70 insertions, 0 deletions
diff --git a/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs b/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs index 815e64853..8c971a747 100644 --- a/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs +++ b/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs @@ -2,11 +2,14 @@ Project { CppApplication { name: "app-map" files: ["main.cpp"] + // lld-link has different flag for map files, test it by switching to "lld" linkerVariant + Properties { condition: qbs.toolchain.contains("clang-cl"); cpp.linkerVariant: "lld" } cpp.generateLinkerMapFile: true } CppApplication { name: "app-nomap" files: ["main.cpp"] + Properties { condition: qbs.toolchain.contains("clang-cl"); cpp.linkerVariant: "lld" } cpp.generateLinkerMapFile: false } CppApplication { diff --git a/tests/auto/blackbox/testdata/response-files/response-files.qbs b/tests/auto/blackbox/testdata/response-files/response-files.qbs index fbb6f0518..1750ead3b 100644 --- a/tests/auto/blackbox/testdata/response-files/response-files.qbs +++ b/tests/auto/blackbox/testdata/response-files/response-files.qbs @@ -38,6 +38,9 @@ Project { Product { name: "lotsofobjects" type: ["dynamiclibrary"] + // clang-cl does not use response file internally, thus linker complains that command is + // too long. This can be worked around by calling the linker directly + cpp.linkerMode: qbs.toolchain.contains("clang-cl") ? "manual" : original Depends { name: "cpp" } Rule { multiplex: true diff --git a/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp b/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp new file mode 100644 index 000000000..4a7c3ee32 --- /dev/null +++ b/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp @@ -0,0 +1,4 @@ +int main(int argc, char *argv[]) +{ + return 0; +} diff --git a/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs b/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs new file mode 100644 index 000000000..0aa8ed964 --- /dev/null +++ b/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs @@ -0,0 +1,28 @@ +CppApplication { + property string sanitizer + + property bool supportsSanitizer: { + if (qbs.toolchain.contains("clang-cl")) + // only these are supported + return sanitizer === "address" || sanitizer === "undefined"; + if (!qbs.toolchain.contains("gcc")) + return false; + return true; + } + + condition: { + if (!sanitizer) + return true; + if (!supportsSanitizer) + console.info("Compiler does not support sanitizer"); + return supportsSanitizer; + } + qbs.buildVariant: "release" + cpp.cxxLanguageVersion: "c++11" + cpp.minimumMacosVersion: "10.8" + consoleApplication: true + cpp.runtimeLibrary: "static" + cpp.driverFlags: sanitizer ? ["-fsanitize=" + sanitizer] : [] + cpp.debugInformation: true + files: "sanitizer.cpp" +} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 586471e61..3526881d2 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -2435,6 +2435,36 @@ void TestBlackbox::ruleWithNonRequiredInputs() QVERIFY2(m_qbsStdout.contains("Generating"), m_qbsStdout.constData()); } +void TestBlackbox::sanitizer_data() +{ + QTest::addColumn<QString>("sanitizer"); + QTest::newRow("none") << QString(); + QTest::newRow("address") << QStringLiteral("address"); + QTest::newRow("undefined") << QStringLiteral("undefined"); + QTest::newRow("thread") << QStringLiteral("thread"); +} + +void TestBlackbox::sanitizer() +{ + QFETCH(QString, sanitizer); + QDir::setCurrent(testDataDir + "/sanitizer"); + rmDirR(relativeBuildDir()); + QbsRunParameters params("build", {"--command-echo-mode", "command-line"}); + if (!sanitizer.isEmpty()) { + params.arguments.append( + {QStringLiteral("products.sanitizer.sanitizer:\"") + sanitizer + "\""}); + } + QCOMPARE(runQbs(params), 0); + if (m_qbsStdout.contains(QByteArrayLiteral("Compiler does not support sanitizer"))) + QSKIP("Compiler does not support the specified sanitizer"); + if (!sanitizer.isEmpty()) { + QVERIFY2(m_qbsStdout.contains(QByteArrayLiteral("-fsanitize=") + sanitizer.toLatin1()), + qPrintable(m_qbsStdout)); + } else { + QVERIFY2(!m_qbsStdout.contains(QByteArrayLiteral("-fsanitize=")), qPrintable(m_qbsStdout)); + } +} + void TestBlackbox::scannerItem() { QDir::setCurrent(testDataDir + "/scanner-item"); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 35656f3f1..9842ded39 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -266,6 +266,8 @@ private slots: void ruleCycle(); void ruleWithNoInputs(); void ruleWithNonRequiredInputs(); + void sanitizer_data(); + void sanitizer(); void scannerItem(); void setupBuildEnvironment(); void setupRunEnvironment(); |