aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2022-02-19 17:07:41 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2022-02-21 11:49:36 +0000
commit5a7aac60df8000bd4c5ed255f69eaf4b9d5b92db (patch)
tree319c41d0a90e659f2d2d3afb0b473a254b579c65
parentdb584fbfc491b5bb065913699d604f68ef58673e (diff)
baremetal: Add simple test for linking with shared libraries
As we use the baremetal tests for non-baremetal compilers (for example, for `watcom` and `dmc`), then we need a test for linking the application and the shared library. We cannot use the existing tests for `watcom` and `dmc` toolchains, because these toolchains have specific behavior and also do not fully support the STL. Therefore, the simplest dependency linking test is used here. Also fixed the shared library creation for these toolchains. Change-Id: I0e5d5ede39fa0c9b4bf7db54adc3f161e0aea91c Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--share/qbs/modules/cpp/dmc.js40
-rw-r--r--share/qbs/modules/cpp/dmc.qbs2
-rw-r--r--share/qbs/modules/cpp/watcom.js13
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c12
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs34
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c19
-rw-r--r--tests/auto/blackbox/tst_blackboxbaremetal.cpp14
-rw-r--r--tests/auto/blackbox/tst_blackboxbaremetal.h2
8 files changed, 103 insertions, 33 deletions
diff --git a/share/qbs/modules/cpp/dmc.js b/share/qbs/modules/cpp/dmc.js
index 1137a0c0a..a398d6581 100644
--- a/share/qbs/modules/cpp/dmc.js
+++ b/share/qbs/modules/cpp/dmc.js
@@ -357,12 +357,17 @@ function linkerFlags(project, product, inputs, outputs) {
args.push("-L/SUBSYSTEM:" + (product.consoleApplication ? "CONSOLE" : "WINDOWS"));
} else if (product.type.contains("dynamiclibrary")) {
args.push("-o" + FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath));
+ if (product.qbs.targetPlatform === "windows" && product.qbs.architecture === "x86") {
+ args.push("kernel32.lib");
+ args.push("-L/IMPLIB:" + FileInfo.toWindowsSeparators(
+ outputs.dynamiclibrary_import[0].filePath));
+ }
}
if (product.cpp.debugInformation)
- args.push("/DEBUG");
+ args.push("-L/DEBUG");
- args.push("/NOLOGO", "/SILENT");
+ args.push("-L/NOLOGO", "-L/SILENT");
}
// Misc flags.
@@ -432,20 +437,10 @@ function renameLinkerMapFile(project, product, inputs, outputs, input, output) {
cmd.newMapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix);
cmd.oldMapFilePath = buildLinkerMapFilePath(target, ".map");
cmd.silent = true;
- cmd.sourceCode = function() { File.move(oldMapFilePath, newMapFilePath); };
- return cmd;
-}
-
-// It is a workaround to generate the import library file from the dynamic library.
-// Because the DMC compiler use the separate `implib.exe` tool for that.
-function createImportLib(project, product, inputs, outputs, input, output) {
- var args = [
- FileInfo.toWindowsSeparators(outputs.dynamiclibrary_import[0].filePath),
- FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath)
- ];
- var cmd = new Command(input.cpp.implibPath, args);
- cmd.workingDirectory = product.buildDirectory;
- cmd.silent = true;
+ cmd.sourceCode = function() {
+ if (oldMapFilePath !== newMapFilePath)
+ File.move(oldMapFilePath, newMapFilePath);
+ };
return cmd;
}
@@ -482,16 +477,11 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
cmd.jobPool = "linker";
cmds.push(cmd);
- if (outputs.dynamiclibrary
- || (outputs.application && !product.cpp.generateLinkerMapFile)) {
- if (outputs.dynamiclibrary)
- cmds.push(createImportLib(project, product, inputs, outputs, input, output));
- cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
- } else if (outputs.application
- && product.cpp.generateLinkerMapFile
- && (product.cpp.linkerMapSuffix !== ".map")) {
+ if (product.cpp.generateLinkerMapFile)
cmds.push(renameLinkerMapFile(project, product, inputs, outputs, input, output));
- }
+ else
+ cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
+
return cmds;
}
diff --git a/share/qbs/modules/cpp/dmc.qbs b/share/qbs/modules/cpp/dmc.qbs
index f7f75169b..db9e6b2fb 100644
--- a/share/qbs/modules/cpp/dmc.qbs
+++ b/share/qbs/modules/cpp/dmc.qbs
@@ -84,8 +84,6 @@ CppModule {
property string archiverName: "lib.exe"
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
- property string implibName: "implib.exe"
- property string implibPath: FileInfo.joinPaths(toolchainInstallPath, implibName)
property string rccCompilerName: "rcc.exe"
property string rccCompilerPath: FileInfo.joinPaths(toolchainInstallPath, rccCompilerName)
diff --git a/share/qbs/modules/cpp/watcom.js b/share/qbs/modules/cpp/watcom.js
index 20ba2dbe3..005780c7d 100644
--- a/share/qbs/modules/cpp/watcom.js
+++ b/share/qbs/modules/cpp/watcom.js
@@ -80,13 +80,14 @@ function targetFlag(platform, architecture, type) {
else if (architecture === "x86")
return "-bos2v2";
} else if (platform === "windows") {
- if (architecture === "x86_16")
+ if (architecture === "x86_16") {
+ if (type.contains("dynamiclibrary"))
+ return "-bwindows_dll";
return "-bwindows";
- else if (architecture === "x86") {
- if (type.contains("application"))
- return "-bnt";
- else if (type.contains("dynamiclibrary"))
+ } else if (architecture === "x86") {
+ if (type.contains("dynamiclibrary"))
return "-bnt_dll";
+ return "-bnt";
}
} else if (platform === "linux") {
return "-blinux";
@@ -427,7 +428,7 @@ function linkerFlags(project, product, inputs, outputs) {
if (product.cpp.generateLinkerMapFile)
args.push("-fm=" + FileInfo.toNativeSeparators(outputs.mem_map[0].filePath));
} else if (product.type.contains("dynamiclibrary")) {
- if (targetPlatform === "windows") {
+ if (product.qbs.targetPlatform === "windows") {
args.push("-Wl, option implib=" + FileInfo.toNativeSeparators(
outputs.dynamiclibrary_import[0].filePath));
}
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c b/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c
new file mode 100644
index 000000000..f2ecb5f55
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c
@@ -0,0 +1,12 @@
+#include "../dllexport.h"
+
+#include <stdio.h>
+
+DLL_IMPORT void foo(void);
+
+int main(void)
+{
+ printf("Hello from app\n");
+ foo();
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs
new file mode 100644
index 000000000..f55b4d400
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs
@@ -0,0 +1,34 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+Project {
+ condition: {
+ if (qbs.targetPlatform === "windows" && qbs.architecture === "x86") {
+ if (qbs.toolchainType === "watcom")
+ return true;
+ if (qbs.toolchainType === "dmc")
+ return true;
+ }
+
+ if (qbs.toolchainType === "msvc")
+ return true;
+ if (qbs.toolchainType === "gcc")
+ return true;
+
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ destinationDirectory: "bin"
+ name: "shared"
+ files: ["shared.c"]
+ }
+ BareMetalApplication {
+ Depends { name: "shared" }
+ destinationDirectory: "bin"
+ name: "app"
+ files: ["app.c"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c
new file mode 100644
index 000000000..ab0c110fb
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c
@@ -0,0 +1,19 @@
+#include "../dllexport.h"
+
+#include <stdio.h>
+
+#ifdef __DMC__
+#include <windows.h>
+#define EXPORT_FUN _export
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+ return TRUE;
+}
+#else
+#define EXPORT_FUN
+#endif // __DMC__
+
+DLL_EXPORT void EXPORT_FUN foo(void)
+{
+ printf("Hello from lib\n");
+}
diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.cpp b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
index fda544b8b..740b9c463 100644
--- a/tests/auto/blackbox/tst_blackboxbaremetal.cpp
+++ b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
@@ -139,6 +139,20 @@ void TestBlackboxBareMetal::externalStaticLibraries()
QCOMPARE(runQbs(), 0);
}
+void TestBlackboxBareMetal::sharedLibraries()
+{
+ QDir::setCurrent(testDataDir + "/shared-libraries");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ QCOMPARE(runQbs(QbsRunParameters("build")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(runQbs(QbsRunParameters("run")), 0);
+ QVERIFY2(m_qbsStdout.contains("Hello from app"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("Hello from lib"), m_qbsStdout.constData());
+}
+
void TestBlackboxBareMetal::userIncludePaths()
{
QDir::setCurrent(testDataDir + "/user-include-paths");
diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.h b/tests/auto/blackbox/tst_blackboxbaremetal.h
index 39d2f36c9..8e9e29e8b 100644
--- a/tests/auto/blackbox/tst_blackboxbaremetal.h
+++ b/tests/auto/blackbox/tst_blackboxbaremetal.h
@@ -49,6 +49,8 @@ private slots:
void staticLibraryDependencies();
void externalStaticLibraries();
+ void sharedLibraries();
+
void userIncludePaths();
void systemIncludePaths();
void distributionIncludePaths();