From a36012d727bb0f755b349e64af481d315c06bd56 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 28 Oct 2015 18:57:11 -0700 Subject: Introduce new assembler-related properties. This adds: - cpp.assemblerName - cpp.assemblerPath - cpp.assemblerFlags - cpp.platformAssemblerFlags Users can now, for example, use nasm instead of GNU as (default). Task-number: QBS-891 Change-Id: I8501abea494b327ac95f02f3cded263dbe72f12f Reviewed-by: Christian Kandeler --- doc/reference/modules/cpp-module.qdoc | 18 +++++++++ share/qbs/imports/qbs/ModUtils/utils.js | 9 ++++- share/qbs/modules/cpp/CppModule.qbs | 9 +++++ share/qbs/modules/cpp/GenericGCC.qbs | 35 ++++++++++++----- share/qbs/modules/cpp/gcc.js | 70 +++++++++++++++++++++++++++++---- share/qbs/modules/cpp/windows-msvc.qbs | 6 ++- src/app/qbs-setup-toolchains/probe.cpp | 1 + tests/auto/blackbox/tst_blackbox.cpp | 2 +- 8 files changed, 128 insertions(+), 22 deletions(-) diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc index 6b0bf30a8..a9d39ebb6 100644 --- a/doc/reference/modules/cpp-module.qdoc +++ b/doc/reference/modules/cpp-module.qdoc @@ -229,6 +229,12 @@ \li 1.4 \li undefined \li The patch level component of the compiler version. + \row + \li assemblerFlags + \li \c{stringList} + \li 1.5 + \li undefined + \li Additional flags for the assembler. \row \li cppFlags \li \c{stringList} @@ -298,6 +304,18 @@ \li 1.2 \li \c{undefined} \li List of linker script files. + \row + \li assemblerName + \li \c{string} + \li 1.5 + \li determined by qbs-setup-toolchains + \li Name of the assembler binary. This is set in the build profile. + \row + \li assemblerPath + \li \c{string} + \li 1.5 + \li determined by qbs-setup-toolchains + \li Full path of the assembler binary. This is set in the build profile. \row \li compilerName \li \c{string} diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js index 5d9d9d5c1..a190d31dc 100644 --- a/share/qbs/imports/qbs/ModUtils/utils.js +++ b/share/qbs/imports/qbs/ModUtils/utils.js @@ -93,6 +93,11 @@ function languagePropertyName(propertyName, fileTag) { if (!fileTag) fileTag = "common"; + var asm = { + "flags": "assemblerFlags", + "platformFlags": "platformAssemblerFlags" + }; + var map = { "c": { "flags": "cFlags", @@ -118,7 +123,9 @@ function languagePropertyName(propertyName, fileTag) { "flags": "commonCompilerFlags", "platformFlags": "platformCommonCompilerFlags", "precompiledHeader": "precompiledHeader" - } + }, + "asm": asm, + "asm_cpp": asm }; var lang = map[fileTag]; diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs index e671b1cae..3ee0cf088 100644 --- a/share/qbs/modules/cpp/CppModule.qbs +++ b/share/qbs/modules/cpp/CppModule.qbs @@ -135,6 +135,8 @@ Module { property pathList frameworkPaths property pathList systemFrameworkPaths property pathList linkerScripts + property string assemblerName + property string assemblerPath: assemblerName property string compilerName property string compilerPath: compilerName property var compilerPathByLanguage @@ -158,6 +160,12 @@ Module { property stringList rpaths property bool useRPaths: true + property stringList assemblerFlags + PropertyOptions { + name: "assemblerFlags" + description: "additional flags for the assembler" + } + property stringList cppFlags PropertyOptions { name: "cppFlags" @@ -248,6 +256,7 @@ Module { // Platform properties. Those are intended to be set by the toolchain setup // and are prepended to the corresponding user properties. + property stringList platformAssemblerFlags property stringList platformCommonCompilerFlags property stringList platformCFlags property stringList platformCxxFlags diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index 8b08b349e..86788352c 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -56,6 +56,7 @@ CppModule { property stringList transitiveSOs property string toolchainPrefix property path toolchainInstallPath + assemblerName: 'as' compilerName: cxxCompilerName linkerName: cxxCompilerName property string archiverName: 'ar' @@ -95,15 +96,15 @@ CppModule { + (qbs.toolchain.contains("clang") ? "clang++" : "g++") + executableSuffix - compilerPathByLanguage: { - return { - "c": toolchainPathPrefix + cCompilerName, - "cpp": toolchainPathPrefix + cxxCompilerName, - "objc": toolchainPathPrefix + cCompilerName, - "objcpp": toolchainPathPrefix + cxxCompilerName - }; - } + compilerPathByLanguage: ({ + "c": toolchainPathPrefix + cCompilerName, + "cpp": toolchainPathPrefix + cxxCompilerName, + "objc": toolchainPathPrefix + cCompilerName, + "objcpp": toolchainPathPrefix + cxxCompilerName, + "asm_cpp": toolchainPathPrefix + cCompilerName + }) + assemblerPath: toolchainPathPrefix + assemblerName compilerPath: toolchainPathPrefix + compilerName linkerPath: toolchainPathPrefix + linkerName property path archiverPath: { return toolchainPathPrefix + archiverName } @@ -335,13 +336,13 @@ CppModule { Rule { id: compiler - inputs: ["cpp", "c", "objcpp", "objc", "asm", "asm_cpp"] + inputs: ["cpp", "c", "objcpp", "objc", "asm_cpp"] auxiliaryInputs: ["hpp"] explicitlyDependsOn: ["c_pch", "cpp_pch", "objc_pch", "objcpp_pch"] Artifact { fileTags: ["obj"] - filePath: ".obj/" + qbs.getHash(input.baseDir) + "/" + input.fileName + ".o" + filePath: FileInfo.joinPaths(".obj", qbs.getHash(input.baseDir), input.fileName + ".o") } prepare: { @@ -349,6 +350,20 @@ CppModule { } } + Rule { + id: assembler + inputs: ["asm"] + + Artifact { + fileTags: ["obj"] + filePath: FileInfo.joinPaths(".obj", qbs.getHash(input.baseDir), input.fileName + ".o") + } + + prepare: { + return Gcc.prepareAssembler.apply(this, arguments); + } + } + Transformer { condition: cPrecompiledHeader !== undefined inputs: cPrecompiledHeader diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index bb26ec17b..3f1e65b2e 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -263,7 +263,7 @@ function configFlags(config) { return args; } -function languageTagFromFileExtension(fileName) { +function languageTagFromFileExtension(toolchain, fileName) { var i = fileName.lastIndexOf('.'); if (i === -1) return; @@ -277,13 +277,14 @@ function languageTagFromFileExtension(fileName) { "m" : "objc", "mm" : "objcpp", "s" : "asm", - "S" : "asm_cpp", - "sx" : "asm_cpp" + "S" : "asm_cpp" }; + if (!toolchain.contains("clang")) + m["sx"] = "asm_cpp"; // clang does NOT recognize .sx return m[fileName.substring(i + 1)]; } -function effectiveCompilerInfo(input, output) { +function effectiveCompilerInfo(toolchain, input, output) { var compilerPath, language; var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags)); @@ -293,7 +294,7 @@ function effectiveCompilerInfo(input, output) { var compilerPathByLanguage = ModUtils.moduleProperty(input, "compilerPathByLanguage"); if (compilerPathByLanguage) compilerPath = compilerPathByLanguage[tag]; - if (!compilerPath || tag !== languageTagFromFileExtension(input.fileName)) + if (!compilerPath || tag !== languageTagFromFileExtension(toolchain, input.fileName)) language = languageName(tag) + (pchOutput ? '-header' : ''); if (!compilerPath) // fall back to main compiler @@ -331,10 +332,11 @@ function compilerFlags(product, input, output) { // Determine which C-language we're compiling var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags)); - if (!["c", "cpp", "objc", "objcpp", "asm", "asm_cpp"].contains(tag)) + if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].contains(tag)) throw ("unsupported source language: " + tag); - var compilerInfo = effectiveCompilerInfo(input, output); + var compilerInfo = effectiveCompilerInfo(product.moduleProperty("qbs", "toolchain"), + input, output); var args = additionalCompilerAndLinkerFlags(product); @@ -552,8 +554,60 @@ function languageName(fileTag) { return 'assembler-with-cpp'; } +function prepareAssembler(project, product, inputs, outputs, input, output) { + var assemblerPath = ModUtils.moduleProperty(product, "assemblerPath"); + + var includePaths = ModUtils.moduleProperties(input, 'includePaths'); + var systemIncludePaths = ModUtils.moduleProperties(input, 'systemIncludePaths'); + + var args = []; + if (haveTargetOption(product)) { + args.push("-target", product.moduleProperty("cpp", "target")); + } else { + var arch = product.moduleProperty("cpp", "targetArch"); + if (product.moduleProperty("qbs", "targetOS").contains("darwin")) + args.push("-arch", arch); + else if (arch === 'x86_64') + args.push('--64'); + else if (arch === 'i386') + args.push('--32'); + } + + if (ModUtils.moduleProperty(input, "debugInformation")) + args.push('-g'); + + var warnings = ModUtils.moduleProperty(input, "warningLevel") + if (warnings === 'none') + args.push('-W'); + + var tag = "asm"; + if (tag !== languageTagFromFileExtension(product.moduleProperty("qbs", "toolchain"), + input.fileName)) + // Only push '-x language' if we have to. + args.push("-x", languageName(tag)); + + args = args.concat(ModUtils.moduleProperties(input, 'platformFlags', tag), + ModUtils.moduleProperties(input, 'flags', tag)); + + var allIncludePaths = []; + if (systemIncludePaths) + allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths); + if (includePaths) + allIncludePaths = allIncludePaths.uniqueConcat(includePaths); + args = args.concat(allIncludePaths.map(function(path) { return '-I' + path })); + + args.push("-o", output.filePath); + args.push(input.filePath); + + var cmd = new Command(assemblerPath, args); + cmd.description = "assembling " + input.fileName; + cmd.highlight = "compiler"; + return cmd; +} + function prepareCompiler(project, product, inputs, outputs, input, output) { - var compilerInfo = effectiveCompilerInfo(input, output); + var compilerInfo = effectiveCompilerInfo(product.moduleProperty("qbs", "toolchain"), + input, output); var compilerPath = compilerInfo.path; var pchOutput = output.fileTags.contains(compilerInfo.tag + "_pch"); diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs index 04fc3da5c..f5dd19d5d 100644 --- a/share/qbs/modules/cpp/windows-msvc.qbs +++ b/share/qbs/modules/cpp/windows-msvc.qbs @@ -54,7 +54,7 @@ CppModule { compilerDefines: ['_WIN32'] warningLevel: "default" compilerName: "cl.exe" - property string assemblerName: { + assemblerName: { switch (qbs.architecture) { case "armv7": return "armasm.exe"; @@ -330,7 +330,9 @@ CppModule { FileInfo.toWindowsSeparators(input.filePath)]; if (ModUtils.moduleProperty(product, "debugInformation")) args.push("/Zi"); - var cmd = new Command(ModUtils.moduleProperty(product, "assemblerName"), args); + args = args.concat(ModUtils.moduleProperties(input, 'platformFlags', 'asm'), + ModUtils.moduleProperties(input, 'flags', 'asm')); + var cmd = new Command(ModUtils.moduleProperty(product, "assemblerPath"), args); cmd.description = "assembling " + input.fileName; cmd.inputFileName = input.fileName; cmd.stdoutFilterFunction = function(output) { diff --git a/src/app/qbs-setup-toolchains/probe.cpp b/src/app/qbs-setup-toolchains/probe.cpp index f15b3d6c9..d6aa2ff89 100644 --- a/src/app/qbs-setup-toolchains/probe.cpp +++ b/src/app/qbs-setup-toolchains/probe.cpp @@ -212,6 +212,7 @@ static Profile createGccProfile(const QString &compilerFilePath, Settings *setti profile.value(QStringLiteral("cpp.toolchainPrefix")) .toString()); toolPathSetup.apply(QLatin1String("ar"), QLatin1String("cpp.archiverPath")); + toolPathSetup.apply(QLatin1String("as"), QLatin1String("cpp.assemblerPath")); toolPathSetup.apply(QLatin1String("nm"), QLatin1String("cpp.nmPath")); if (profile.value(QStringLiteral("qbs.targetOS")) .toStringList().contains(QStringLiteral("darwin"))) diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index eed5e1438..9ebab4b24 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -2574,7 +2574,7 @@ void TestBlackbox::assembly() bool haveMSVC = profile.value("qbs.toolchain").toStringList().contains("msvc"); QDir::setCurrent(testDataDir + "/assembly"); QVERIFY(runQbs() == 0); - QCOMPARE((bool)m_qbsStdout.contains("compiling testa.s"), haveGcc); + QCOMPARE((bool)m_qbsStdout.contains("assembling testa.s"), haveGcc); QCOMPARE((bool)m_qbsStdout.contains("compiling testb.S"), haveGcc); QCOMPARE((bool)m_qbsStdout.contains("compiling testc.sx"), haveGcc); QCOMPARE((bool)m_qbsStdout.contains("creating libtesta.a"), haveGcc); -- cgit v1.2.3