aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorOla Røer Thorsen <ola@silentwings.no>2019-01-03 14:44:15 +0100
committerOla Røer Thorsen <ola@silentwings.no>2019-01-18 09:39:15 +0000
commit0be365894406cbca8ed54253419ea2ad6f961bdf (patch)
tree45a6286600bc61fc56769835d0ee2bb4a93790f0 /tests
parent9e55ddfa97619f7983ea66213ce6764ee0aed2d9 (diff)
Add recursive dependency scanning of GNU ld linkerscripts
Linkerscripts may contain INCLUDE and SEARCH_DIR commands that allows it to include other linkerscripts in a similary way as headers are included in C++. This commit adds a scanner that adds these additional dependencies. [ChangeLog] Added recursive dependency scanning of GNU ld linkerscripts that contain INCLUDE and SEARCH_DIR commands. Change-Id: I7549e27aad4fe7ade2a6a26eba14f66880261077 Reviewed-by: Ola Røer Thorsen <ola@silentwings.no> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/linkerscript_recursive1
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/linkerscript_to_include2
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs36
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/scripts/linkerscript_in_directory1
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp88
5 files changed, 116 insertions, 12 deletions
diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscript_recursive b/tests/auto/blackbox/testdata/linkerscripts/linkerscript_recursive
new file mode 100644
index 000000000..11bc411a5
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscript_recursive
@@ -0,0 +1 @@
+TEST_SYMBOL_FROM_RECURSIVE = 1;
diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscript_to_include b/tests/auto/blackbox/testdata/linkerscripts/linkerscript_to_include
new file mode 100644
index 000000000..68c67eb60
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscript_to_include
@@ -0,0 +1,2 @@
+TEST_SYMBOL_FROM_INCLUDE = 1;
+INCLUDE linkerscript_recursive
diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
index b30a498bb..9dd7bf5b2 100644
--- a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
+++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
@@ -1,13 +1,22 @@
+import qbs.TextFile
+
DynamicLibrary {
type: base.concat("custom")
Depends { name: "cpp" }
files: ["testlib.c"]
Group {
name: "linker scripts"
- files: ["linkerscript1", "linkerscript2"]
+ files: [
+ "linkerscript1",
+ "linkerscript2",
+ ]
fileTags: ["linkerscript"]
}
+ cpp.libraryPaths: [
+ product.sourceDirectory, // location of linkerscripts that are included
+ ]
+
Rule {
multiplex: true
outputFileTags: "custom"
@@ -21,6 +30,31 @@ DynamicLibrary {
}
}
+ Rule {
+ multiplex: true
+ requiresInputs: false
+ Artifact {
+ filePath: product.buildDirectory + "/linkerscript_with_includes"
+ fileTags: ["linkerscript"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.sourcePath = product.sourceDirectory;
+ cmd.buildPath = product.buildDirectory;
+ cmd.sourceCode = function() {
+ var file = new TextFile(buildPath + "/linkerscript_with_includes",
+ TextFile.WriteOnly);
+ file.write("SEARCH_DIR(" + sourcePath + "/scripts)\n" +
+ "INCLUDE linkerscript_to_include\n" +
+ "INCLUDE linkerscript_in_directory\n");
+ file.close();
+ }
+ cmd.highlight = "codegen";
+ cmd.description = "generating linkerscript with SEARCH_DIR and INCLUDE";
+ return [cmd];
+ }
+ }
+
qbs.installPrefix: ""
install: true
installDir: ""
diff --git a/tests/auto/blackbox/testdata/linkerscripts/scripts/linkerscript_in_directory b/tests/auto/blackbox/testdata/linkerscripts/scripts/linkerscript_in_directory
new file mode 100644
index 000000000..098156292
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linkerscripts/scripts/linkerscript_in_directory
@@ -0,0 +1 @@
+TEST_SYMBOL_FROM_DIRECTORY = 1;
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index df4a2066f..fbcd16eb8 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -4385,9 +4385,15 @@ void TestBlackbox::linkerScripts()
QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
if (!toolchain.contains("gcc") || targetOs() != HostOsInfo::HostOsLinux)
QSKIP("linker script test only applies to Linux ");
- QDir::setCurrent(testDataDir + "/linkerscripts");
- QCOMPARE(runQbs(QbsRunParameters(QStringList("-q")
- << ("qbs.installRoot:" + QDir::currentPath()))), 0);
+
+ QbsRunParameters runParams(QStringList()
+// << "--log-level" << "debug"
+ << ("qbs.installRoot:" + QDir::currentPath()));
+ const QString sourceDir = QDir::cleanPath(testDataDir + "/linkerscripts");
+ runParams.buildDirectory = sourceDir + "/build";
+ runParams.workingDir = sourceDir;
+
+ QCOMPARE(runQbs(runParams), 0);
const QString output = QString::fromLocal8Bit(m_qbsStderr);
QRegExp pattern(".*---(.*)---.*");
QVERIFY2(pattern.exactMatch(output), qPrintable(output));
@@ -4395,14 +4401,74 @@ void TestBlackbox::linkerScripts()
const QString nmPath = pattern.capturedTexts().at(1);
if (!QFile::exists(nmPath))
QSKIP("Cannot check for symbol presence: No nm found.");
- QProcess nm;
- nm.start(nmPath, QStringList(QDir::currentPath() + "/liblinkerscripts.so"));
- QVERIFY(nm.waitForStarted());
- QVERIFY(nm.waitForFinished());
- const QByteArray nmOutput = nm.readAllStandardOutput();
- QCOMPARE(nm.exitCode(), 0);
- QVERIFY2(nmOutput.contains("TEST_SYMBOL1"), nmOutput.constData());
- QVERIFY2(nmOutput.contains("TEST_SYMBOL2"), nmOutput.constData());
+
+ const auto verifySymbols = [nmPath](const QByteArrayList& symbols) -> bool {
+ QProcess nm;
+ nm.start(nmPath, QStringList(QDir::currentPath() + "/liblinkerscripts.so"));
+ if (!nm.waitForStarted()) {
+ qDebug() << "Wait for process started failed.";
+ return false;
+ }
+ if (!nm.waitForFinished()) {
+ qDebug() << "Wait for process finished failed.";
+ return false;
+ }
+ if (nm.exitCode() != 0) {
+ qDebug() << "nm returned exit code " << nm.exitCode();
+ return false;
+ }
+ const QByteArray nmOutput = nm.readAllStandardOutput();
+ for (const QByteArray& symbol : symbols) {
+ if (!nmOutput.contains(symbol)) {
+ qDebug() << "Expected symbol" << symbol
+ << "not found in" << nmOutput.constData();
+ return false;
+ }
+ }
+ return true;
+ };
+
+ QVERIFY(verifySymbols({"TEST_SYMBOL1",
+ "TEST_SYMBOL2",
+ "TEST_SYMBOL_FROM_INCLUDE",
+ "TEST_SYMBOL_FROM_DIRECTORY",
+ "TEST_SYMBOL_FROM_RECURSIVE"}));
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE(sourceDir + "/linkerscript_to_include",
+ "TEST_SYMBOL_FROM_INCLUDE = 1;",
+ "TEST_SYMBOL_FROM_INCLUDE_MODIFIED = 1;\n");
+ QCOMPARE(runQbs(runParams), 0);
+ QVERIFY2(m_qbsStdout.contains("linking liblinkerscripts.so"),
+ "No linking after modifying included file");
+ QVERIFY(verifySymbols({"TEST_SYMBOL1",
+ "TEST_SYMBOL2",
+ "TEST_SYMBOL_FROM_INCLUDE_MODIFIED",
+ "TEST_SYMBOL_FROM_DIRECTORY",
+ "TEST_SYMBOL_FROM_RECURSIVE"}));
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE(sourceDir + "/scripts/linkerscript_in_directory",
+ "TEST_SYMBOL_FROM_DIRECTORY = 1;\n",
+ "TEST_SYMBOL_FROM_DIRECTORY_MODIFIED = 1;\n");
+ QCOMPARE(runQbs(runParams), 0);
+ QVERIFY2(m_qbsStdout.contains("linking liblinkerscripts.so"),
+ "No linking after modifying file in directory");
+ QVERIFY(verifySymbols({"TEST_SYMBOL1",
+ "TEST_SYMBOL2",
+ "TEST_SYMBOL_FROM_INCLUDE_MODIFIED",
+ "TEST_SYMBOL_FROM_DIRECTORY_MODIFIED",
+ "TEST_SYMBOL_FROM_RECURSIVE"}));
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE(sourceDir + "/linkerscript_recursive",
+ "TEST_SYMBOL_FROM_RECURSIVE = 1;\n",
+ "TEST_SYMBOL_FROM_RECURSIVE_MODIFIED = 1;\n");
+ QCOMPARE(runQbs(runParams), 0);
+ QVERIFY2(m_qbsStdout.contains("linking liblinkerscripts.so"),
+ "No linking after modifying recursive file");
+ QVERIFY(verifySymbols({"TEST_SYMBOL1",
+ "TEST_SYMBOL2",
+ "TEST_SYMBOL_FROM_INCLUDE_MODIFIED",
+ "TEST_SYMBOL_FROM_DIRECTORY_MODIFIED",
+ "TEST_SYMBOL_FROM_RECURSIVE_MODIFIED"}));
}
void TestBlackbox::listProducts()