1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 4 using System; 5 using System.IO; 6 using Microsoft.Build.Framework; 7 using Microsoft.Build.Utilities; 8 using Microsoft.Build.Shared; 9 using Microsoft.Build.Tasks.Deployment.ManifestUtilities; 10 11 namespace Microsoft.Build.Tasks 12 { 13 /// <summary> 14 /// The License Compiler task 15 /// </summary> 16 public class LC : ToolTaskExtension 17 { 18 #region Constructors 19 20 /// <summary> 21 /// public constructor 22 /// </summary> LC()23 public LC() 24 { 25 // do nothing 26 } 27 28 #endregion 29 30 #region Input/output properties 31 32 /// <summary> 33 /// Specifies the items that contain licensed components that need to be included in the .licenses file 34 /// </summary> 35 [Required] 36 public ITaskItem[] Sources 37 { 38 set { Bag["Sources"] = value; } 39 get { return (ITaskItem[])Bag["Sources"]; } 40 } 41 42 /// <summary> 43 /// The name of the .licenses file, output only. It's inferred from LicenseTarget and OutputDirectory. 44 /// </summary> 45 [Output] 46 public ITaskItem OutputLicense 47 { 48 set { Bag["OutputLicense"] = value; } 49 get { return (ITaskItem)Bag["OutputLicense"]; } 50 } 51 52 /// <summary> 53 /// Specifies the executable for which the .licenses files are being generated 54 /// </summary> 55 [Required] 56 public ITaskItem LicenseTarget 57 { 58 set { Bag["LicenseTarget"] = value; } 59 get { return (ITaskItem)Bag["LicenseTarget"]; } 60 } 61 62 /// <summary> 63 /// Output directory for the generated .licenses file 64 /// </summary> 65 /// <value></value> 66 public string OutputDirectory 67 { 68 set { Bag["OutputDirectory"] = value; } 69 get { return (string)Bag["OutputDirectory"]; } 70 } 71 72 /// <summary> 73 /// Specifies the referenced components (licensed controls and possibly their dependent assemblies) 74 /// to load when generating the .license file. 75 /// </summary> 76 public ITaskItem[] ReferencedAssemblies 77 { 78 set { Bag["ReferencedAssemblies"] = value; } 79 get { return (ITaskItem[])Bag["ReferencedAssemblies"]; } 80 } 81 82 /// <summary> 83 /// Suppresses the display of the startup banner 84 /// </summary> 85 public bool NoLogo 86 { 87 set { Bag["NoLogo"] = value; } 88 get { return GetBoolParameterWithDefault("NoLogo", false); } 89 } 90 91 public string SdkToolsPath 92 { 93 set { Bag["SdkToolsPath"] = value; } 94 get { return (string)Bag["SdkToolsPath"]; } 95 } 96 97 /// <summary> 98 /// Targeted version of the framework (i.e. 4.5 or 2.0, etc.) 99 /// </summary> 100 [Required] 101 public string TargetFrameworkVersion 102 { 103 get; set; 104 } 105 #endregion 106 107 #region Class properties 108 109 /// <summary> 110 /// The name of the tool to execute 111 /// </summary> 112 protected override string ToolName 113 { 114 get 115 { 116 return "lc.exe"; 117 } 118 } 119 120 #endregion 121 122 #region Methods 123 124 /// <summary> 125 /// Validate the task arguments, log any warnings/errors 126 /// </summary> 127 /// <returns>true if arguments are corrent enough to continue processing, false otherwise</returns> ValidateParameters()128 protected override bool ValidateParameters() 129 { 130 // if all the Required attributes are set, we're good to go. 131 return true; 132 } 133 134 /// <summary> 135 /// Determing the path to lc.exe 136 /// </summary> 137 /// <returns>path to lc.exe, null if not found</returns> GenerateFullPathToTool()138 protected override string GenerateFullPathToTool() 139 { 140 string pathToTool = SdkToolsPathUtility.GeneratePathToTool(SdkToolsPathUtility.FileInfoExists, Microsoft.Build.Utilities.ProcessorArchitecture.CurrentProcessArchitecture, SdkToolsPath, ToolExe, Log, true); 141 return pathToTool; 142 } 143 144 /// <summary> 145 /// Generates arguments to be passed to lc.exe 146 /// </summary> 147 /// <param name="commandLine">command line builder class to add arguments to</param> AddCommands(CommandLineBuilderExtension commandLine)148 private void AddCommands(CommandLineBuilderExtension commandLine) 149 { 150 commandLine.AppendSwitchIfNotNull("/target:", LicenseTarget.ItemSpec); 151 152 foreach (ITaskItem item in Sources) 153 { 154 commandLine.AppendSwitchIfNotNull("/complist:", item.ItemSpec); 155 } 156 157 commandLine.AppendSwitchIfNotNull("/outdir:", OutputDirectory); 158 159 if (ReferencedAssemblies != null) 160 { 161 foreach (ITaskItem item in ReferencedAssemblies) 162 { 163 commandLine.AppendSwitchIfNotNull("/i:", item.ItemSpec); 164 } 165 } 166 167 commandLine.AppendWhenTrue("/nologo", Bag, "NoLogo"); 168 169 // generate the output file name 170 string outputPath = LicenseTarget.ItemSpec + ".licenses"; 171 172 if (OutputDirectory != null) 173 outputPath = Path.Combine(OutputDirectory, outputPath); 174 175 OutputLicense = new TaskItem(outputPath); 176 } 177 178 179 /// <summary> 180 /// Generates response file with arguments for lc.exe 181 /// Used when targeting framework version is 4.6 or later 182 /// </summary> 183 /// <param name="commandLine">command line builder class to add arguments to the response file</param> AddResponseFileCommands(CommandLineBuilderExtension commandLine)184 protected internal override void AddResponseFileCommands(CommandLineBuilderExtension commandLine) 185 { 186 Version targetFramework = Util.GetTargetFrameworkVersion(TargetFrameworkVersion); 187 // Don't generate response file on versions of the framework < 4.6 188 // They will use an older lc.exe which does not understand response files 189 if (targetFramework.CompareTo(new Version("4.6")) < 0) 190 { 191 return; 192 } 193 194 AddCommands(commandLine); 195 } 196 197 /// <summary> 198 /// Generates command line arguments for lc.exe 199 /// Used when targeting framework version is less than 4.6 200 /// </summary> 201 /// <param name="commandLine">command line builder class to add arguments to the command line</param> AddCommandLineCommands(CommandLineBuilderExtension commandLine)202 protected internal override void AddCommandLineCommands(CommandLineBuilderExtension commandLine) 203 { 204 Version targetFramework = Util.GetTargetFrameworkVersion(TargetFrameworkVersion); 205 // If the target framework version is < 4.6, we will be using lc.exe from an older SDK 206 // In this case, we want to use command line parameters instead of a response file 207 if (targetFramework.CompareTo(new Version("4.6")) >= 0) 208 { 209 return; 210 } 211 212 AddCommands(commandLine); 213 } 214 215 #endregion 216 } 217 } 218