diff options
Diffstat (limited to 'share/qbs/modules/cpp/keil.js')
-rw-r--r-- | share/qbs/modules/cpp/keil.js | 146 |
1 files changed, 87 insertions, 59 deletions
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js index 1e8169853..27e4e12d7 100644 --- a/share/qbs/modules/cpp/keil.js +++ b/share/qbs/modules/cpp/keil.js @@ -168,7 +168,7 @@ function objectSuffix(qbs) { + architecture + "'"; } -function mapFileSuffix(qbs) { +function linkerMapSuffix(qbs) { var architecture = qbs.architecture; if (isMcs51Architecture(architecture)) return ".m51"; @@ -507,14 +507,6 @@ function dumpDefaultPaths(compilerFilePath, nullDevice) { return { "includePaths": includePaths }; } -function adjustPathsToWindowsSeparators(sourcePaths) { - var resulingPaths = []; - sourcePaths.forEach(function(path) { - resulingPaths.push(FileInfo.toWindowsSeparators(path)); - }); - return resulingPaths; -} - function collectLibraryDependencies(product) { var seen = {}; var result = []; @@ -534,7 +526,7 @@ function collectLibraryDependencies(product) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); @@ -590,19 +582,24 @@ function filterC166Output(output) { return filteredLines.join('\n'); }; -function compilerOutputArtifacts(input, useListing) { +function compilerOutputArtifacts(input, isCompilerArtifacts) { var artifacts = []; artifacts.push({ fileTags: ["obj"], filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + input.cpp.objectSuffix }); - if (useListing) { + if (isCompilerArtifacts && input.cpp.generateCompilerListingFiles) { artifacts.push({ fileTags: ["lst"], filePath: Utilities.getHash(input.baseDir) + "/" - + (isArmCCCompiler(input.cpp.compilerPath) ? input.baseName : input.fileName) - + ".lst" + + input.fileName + input.cpp.compilerListingSuffix + }); + } else if (!isCompilerArtifacts && input.cpp.generateAssemblerListingFiles) { + artifacts.push({ + fileTags: ["lst"], + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.assemblerListingSuffix }); } return artifacts; @@ -619,7 +616,7 @@ function applicationLinkerOutputArtifacts(product) { fileTags: ["mem_map"], filePath: FileInfo.joinPaths( product.destinationDirectory, - product.targetName + product.cpp.mapFileSuffix) + product.targetName + product.cpp.linkerMapSuffix) }; return [app, mem_map]; } @@ -661,20 +658,18 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { var architecture = input.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { // Input. - args.push(FileInfo.toWindowsSeparators(input.filePath)); + args.push(input.filePath); // Output. - args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")"); + args.push("OBJECT (" + outputs.obj[0].filePath + ")"); // Defines. if (allDefines.length > 0) args = args.concat("DEFINE (" + allDefines.join(",") + ")"); // Includes. - if (allIncludePaths.length > 0) { - var adjusted = adjustPathsToWindowsSeparators(allIncludePaths); - args = args.concat("INCDIR (" + adjusted.join(";") + ")"); - } + if (allIncludePaths.length > 0) + args = args.concat("INCDIR (" + allIncludePaths.join(";") + ")"); // Debug information flags. if (input.cpp.debugInformation) @@ -709,7 +704,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { if (!input.cpp.generateCompilerListingFiles) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")"); + args.push("PRINT(" + outputs.lst[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Input. args.push("-c", input.filePath); @@ -897,20 +892,18 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { var architecture = input.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { // Input. - args.push(FileInfo.toWindowsSeparators(input.filePath)); + args.push(input.filePath); // Output. - args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")"); + args.push("OBJECT (" + outputs.obj[0].filePath + ")"); // Defines. if (allDefines.length > 0) args = args.concat("DEFINE (" + allDefines.join(",") + ")"); // Includes. - if (allIncludePaths.length > 0) { - var adjusted = adjustPathsToWindowsSeparators(allIncludePaths); + if (allIncludePaths.length > 0) args = args.concat("INCDIR (" + adjusted.join(";") + ")"); - } // Debug information flags. if (input.cpp.debugInformation) @@ -923,7 +916,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { if (!input.cpp.generateAssemblerListingFiles) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")"); + args.push("PRINT(" + outputs.lst[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Input. args.push(input.filePath); @@ -982,39 +975,50 @@ function disassemblerFlags(project, product, input, outputs, explicitlyDependsOn function linkerFlags(project, product, inputs, outputs) { var args = []; + // Library paths. + var libraryPaths = product.cpp.libraryPaths; + var architecture = product.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { - // Note: The C51/256/166 linker does not distinguish an object files and + // Note: The C51, C251, or C166 linker does not distinguish an object files and // a libraries, it interpret all this stuff as an input objects, // so, we need to pass it together in one string. - var allObjectPaths = []; - function addObjectPath(obj) { - allObjectPaths.push(obj.filePath); - } // Inputs. if (inputs.obj) - inputs.obj.map(function(obj) { addObjectPath(obj) }); + inputs.obj.map(function(obj) { allObjectPaths.push(obj.filePath) }); // Library dependencies. var libraryObjects = collectLibraryDependencies(product); - libraryObjects.forEach(function(dep) { addObjectPath(dep); }) + allObjectPaths = allObjectPaths.concat(libraryObjects.map(function(lib) { + // Semi-intelligent handling the library paths. + // We need to add the full path prefix to the library file if this + // file is not absolute or not relative. Reason is that the C51, C251, + // and C166 linkers does not support the library paths. + var filePath = lib.filePath; + if (FileInfo.isAbsolutePath(filePath)) + return filePath; + for (var i = 0; i < libraryPaths.length; ++i) { + var fullPath = FileInfo.joinPaths(libraryPaths[i], filePath); + if (File.exists(fullPath)) + return fullPath; + } + return filePath; + })); // Add all input objects as arguments (application and library object files). - var adjusted = adjustPathsToWindowsSeparators(allObjectPaths); - args = args.concat(adjusted.join(",")); + if (allObjectPaths.length > 0) + args = args.concat(allObjectPaths.join(",")); // Output. - // Note: We need to wrap an output file name with quotes. Otherwise - // the linker will ignore a specified file name. - args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.application[0].filePath) + '"'); + args.push("TO", outputs.application[0].filePath); // Map file generation flag. if (!product.cpp.generateLinkerMapFile) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.mem_map[0].filePath) + ")"); + args.push("PRINT(" + outputs.mem_map[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Inputs. if (inputs.obj) @@ -1023,8 +1027,6 @@ function linkerFlags(project, product, inputs, outputs) { // Output. args.push("--output", outputs.application[0].filePath); - // Library paths. - var libraryPaths = product.cpp.libraryPaths; if (libraryPaths) args.push("--userlibpath=" + libraryPaths.join(",")); @@ -1074,13 +1076,11 @@ function archiverFlags(project, product, inputs, outputs) { inputs.obj.map(function(obj) { addObjectPath(obj) }); // Add all input objects as arguments. - var adjusted = adjustPathsToWindowsSeparators(allObjectPaths); - args = args.concat(adjusted.join(",")); + if (allObjectPaths.length > 0) + args = args.concat(allObjectPaths.join(",")); // Output. - // Note: We need to wrap a output file name with quotes. Otherwise - // the linker will ignore a specified file name. - args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath) + '"'); + args.push("TO", outputs.staticlibrary[0].filePath); } else if (isArmArchitecture(architecture)) { // Note: The ARM archiver command line expect the output file // first, and then a set of input objects. @@ -1100,6 +1100,38 @@ function archiverFlags(project, product, inputs, outputs) { return args; } +// The ARMCLANG compiler does not support generation +// for the listing files: +// * https://www.keil.com/support/docs/4152.htm +// So, we generate the listing files from the object files +// using the disassembler. +function generateClangCompilerListing(project, product, inputs, outputs, input, output) { + if (isArmClangCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) { + var args = disassemblerFlags(project, product, input, outputs, explicitlyDependsOn); + var disassemblerPath = input.cpp.disassemblerPath; + var cmd = new Command(disassemblerPath, args); + cmd.silent = true; + return cmd; + } +} + +// The ARMCC compiler generates the listing files only in a short form, +// e.g. to 'module.lst' instead of 'module.{c|cpp}.lst', that complicates +// the auto-tests. Therefore we need to rename generated listing files +// with correct unified names. +function generateArmccCompilerListing(project, product, inputs, outputs, input, output) { + if (isArmCCCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) { + var listingPath = FileInfo.path(outputs.lst[0].filePath); + var cmd = new JavaScriptCommand(); + cmd.oldListing = FileInfo.joinPaths(listingPath, input.baseName + ".lst"); + cmd.newListing = FileInfo.joinPaths( + listingPath, input.fileName + input.cpp.compilerListingSuffix); + cmd.silent = true; + cmd.sourceCode = function() { File.move(oldListing, newListing); }; + return cmd; + } +} + function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var cmds = []; var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn); @@ -1117,18 +1149,14 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli } cmds.push(cmd); - // The ARMCLANG compiler does not support generation - // for the listing files: - // * https://www.keil.com/support/docs/4152.htm - // So, we generate the listing files from the object files - // using the disassembler. - if (isArmClangCompiler(compilerPath) && input.cpp.generateCompilerListingFiles) { - args = disassemblerFlags(project, product, input, outputs, explicitlyDependsOn); - var disassemblerPath = input.cpp.disassemblerPath; - cmd = new Command(disassemblerPath, args); - cmd.silent = true; + cmd = generateClangCompilerListing(project, product, inputs, outputs, input, output); + if (cmd) cmds.push(cmd); - } + + cmd = generateArmccCompilerListing(project, product, inputs, outputs, input, output); + if (cmd) + cmds.push(cmd); + return cmds; } |