From 1fde3a2423a42e4b85cd7e86f5c8cbae1ab240ee Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Thu, 20 Oct 2016 09:02:55 -0700 Subject: [PATCH 001/223] Add precision for detecting when running tests. (#1219) Previously we assumed that if the entry point for our code was a test runner that we were running as part of our unit test suite and had a few code path differences (specifically around loading toolsets from config file). The test was too broad and would detect when we were in a unit test not associated with MSBuild and cause the build to fail. This change first detects if we're in a known test runner (as it did before) and then also checks to ensure that one of our known test assemblies is loaded. Fixes #1218 --- src/Shared/BuildEnvironmentHelper.cs | 27 +++++++++++++++++++++++++-- src/Shared/InternalErrorException.cs | 25 ++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs index d815d7a997d..02a63b5377f 100644 --- a/src/Shared/BuildEnvironmentHelper.cs +++ b/src/Shared/BuildEnvironmentHelper.cs @@ -25,6 +25,13 @@ internal class BuildEnvironmentHelper "VSTESTHOST", "QTAGENT32", "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST" }; + private static readonly string[] s_testAssemblies = + { + "Microsoft.Build.Tasks.UnitTests", "Microsoft.Build.Engine.UnitTests", "Microsoft.Build.Utilities.UnitTests", + "Microsoft.Build.CommandLine.UnitTests", "Microsoft.Build.Engine.OM.UnitTests", + "Microsoft.Build.Framework.UnitTests" + }; + /// /// Name of the Visual Studio (and Blend) process. /// @@ -74,8 +81,7 @@ private static BuildEnvironment Initialize() // Check if our current process name is in the list of own test runners - var runningTests = IsProcessInList(processNameCommandLine, s_testRunners) || - IsProcessInList(processNameCurrentProcess, s_testRunners); + var runningTests = CheckIfRunningTests(processNameCommandLine, processNameCurrentProcess); // Check to see if we're running inside of Visual Studio bool runningInVisualStudio; @@ -168,6 +174,23 @@ private static bool IsValidMSBuildPath(string path) File.Exists($"{path}.config"); } + private static bool CheckIfRunningTests(string processNameCommandLine, string processNameCurrentProcess) + { + // First check if we're running in a known test runner. + if (IsProcessInList(processNameCommandLine, s_testRunners) || + IsProcessInList(processNameCurrentProcess, s_testRunners)) + { + // If we are, then ensure we're running MSBuild's tests by seeing if any of our assemblies are loaded. + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + if (s_testAssemblies.Any(item => item.Equals(assembly.GetName().Name, StringComparison.InvariantCultureIgnoreCase))) + return true; + } + } + + return false; + } + /// /// Look for Visual Studio /// diff --git a/src/Shared/InternalErrorException.cs b/src/Shared/InternalErrorException.cs index adde17d8806..869349eaca1 100644 --- a/src/Shared/InternalErrorException.cs +++ b/src/Shared/InternalErrorException.cs @@ -140,9 +140,28 @@ private static bool RunningTests() "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST" }; - // Check if our current process name is in the list of own test runners - return IsProcessInList(Environment.GetCommandLineArgs()[0], testRunners) || - IsProcessInList(Process.GetCurrentProcess().MainModule.FileName, testRunners); + string[] testAssemblies = + { + "Microsoft.Build.Tasks.UnitTests", "Microsoft.Build.Engine.UnitTests", + "Microsoft.Build.Utilities.UnitTests", "Microsoft.Build.CommandLine.UnitTests", + "Microsoft.Build.Engine.OM.UnitTests", "Microsoft.Build.Framework.UnitTests" + }; + var processNameCommandLine = Environment.GetCommandLineArgs()[0]; + var processNameCurrentProcess = Process.GetCurrentProcess().MainModule.FileName; + + // First check if we're running in a known test runner. + if (IsProcessInList(processNameCommandLine, testRunners) || + IsProcessInList(processNameCurrentProcess, testRunners)) + { + // If we are, then ensure we're running MSBuild's tests by seeing if any of our assemblies are loaded. + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + if (testAssemblies.Any(item => item.Equals(assembly.GetName().Name, StringComparison.InvariantCultureIgnoreCase))) + return true; + } + } + + return false; } private static bool IsProcessInList(string processName, string[] processList) From 04ac938aa77dba925fc798e57fc740548ffa1f5d Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 7 Oct 2016 14:13:32 -0700 Subject: [PATCH 002/223] IncludeOperation perf --- .../LazyItemEvaluator.IncludeOperation.cs | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs index 13a1fcde082..ad2d0ac5511 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs @@ -58,6 +58,8 @@ protected override ICollection SelectItems(ImmutableList.Builder li } } + ISet excludePatternsForGlobs = null; + foreach (var fragment in _itemSpec.Fragments) { if (fragment is ItemExpressionFragment) @@ -91,12 +93,21 @@ protected override ICollection SelectItems(ImmutableList.Builder li else if (fragment is GlobFragment) { string glob = ((GlobFragment)fragment).ItemSpecFragment; + + if (excludePatternsForGlobs == null) + { + excludePatternsForGlobs = BuildExcludePatternsForGlobs(globsToIgnore, excludePatterns); + } + string[] includeSplitFilesEscaped = EngineFileUtilities.GetFileListEscaped( _rootDirectory, glob, - excludePatterns.Count > 0 ? (IEnumerable) excludePatterns.Concat(globsToIgnore) : globsToIgnore + excludePatternsForGlobs ); + // itemsToAdd might grow 0 or more times during the following iteration. Proactively increase its capacity to ensure only one growth happens + IncreaseListCapacityIfNecessary(itemsToAdd, includeSplitFilesEscaped.Length); + foreach (string includeSplitFileEscaped in includeSplitFilesEscaped) { itemsToAdd.Add(_itemFactory.CreateItem(includeSplitFileEscaped, glob, _itemElement.ContainingProject.FullPath)); @@ -111,6 +122,29 @@ protected override ICollection SelectItems(ImmutableList.Builder li return itemsToAdd; } + private static ISet BuildExcludePatternsForGlobs(ImmutableHashSet globsToIgnore, ImmutableList.Builder excludePatterns) + { + var anyExcludes = excludePatterns.Count > 0; + var anyGlobstoIgnore = globsToIgnore.Count > 0; + + if (anyGlobstoIgnore && anyExcludes) + { + return excludePatterns.Concat(globsToIgnore).ToImmutableHashSet(); + } + + return anyExcludes ? excludePatterns.ToImmutableHashSet() : globsToIgnore; + } + + private void IncreaseListCapacityIfNecessary(List list, int itemsToAdd) + { + var newLength = list.Count + itemsToAdd; + + if (list.Capacity < newLength) + { + list.Capacity = newLength; + } + } + protected override void MutateItems(ICollection items) { DecorateItemsWithMetadata(items, _metadata); @@ -118,7 +152,10 @@ protected override void MutateItems(ICollection items) protected override void SaveItems(ICollection items, ImmutableList.Builder listBuilder) { - listBuilder.AddRange(items.Select(item => new ItemData(item, _elementOrder, _conditionResult))); + foreach (var item in items) + { + listBuilder.Add(new ItemData(item, _elementOrder, _conditionResult)); + } } } From 04104918b3495f66c9d0e8808f511bd4bb066f1a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Mon, 10 Oct 2016 18:59:09 -0700 Subject: [PATCH 003/223] Cache GetItems Computation So an operation is computed at most once. - for referenced operations the number of applies should be equal to the number of cache keys - non referenced operations should not be cached, and their apply count should be equal to the cache keys of the immediate dominator operations that is referenced Update mutates cloned instead of original items Otherwise future update operations mutate the cached items of past operations, thus causing item references to see the future. --- src/XMakeBuildEngine/Evaluation/Evaluator.cs | 3 + src/XMakeBuildEngine/Evaluation/ItemSpec.cs | 20 +- .../LazyItemEvaluator.IItemOperation.cs | 15 ++ .../LazyItemEvaluator.IncludeOperation.cs | 2 +- .../LazyItemEvaluator.LazyItemOperation.cs | 49 ++-- .../LazyItemEvaluator.RemoveOperation.cs | 2 +- .../LazyItemEvaluator.UpdateOperation.cs | 25 ++- .../Evaluation/LazyItemEvaluator.cs | 212 +++++++++++++++--- src/XMakeBuildEngine/Microsoft.Build.csproj | 1 + .../Evaluation/ItemEvaluation_Tests.cs | 147 ++++++++++-- .../Definition/Project_Tests.cs | 20 ++ 11 files changed, 407 insertions(+), 89 deletions(-) create mode 100644 src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IItemOperation.cs diff --git a/src/XMakeBuildEngine/Evaluation/Evaluator.cs b/src/XMakeBuildEngine/Evaluation/Evaluator.cs index ecce95b69ee..eaeddd8879a 100644 --- a/src/XMakeBuildEngine/Evaluation/Evaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/Evaluator.cs @@ -847,6 +847,9 @@ private IDictionary Evaluate() _data.AddItemIgnoringCondition(itemData.Item); } } + + // lazy evaluator can be collected now, the rest of evaluation does not need it anymore + lazyEvaluator = null; } #if (!STANDALONEBUILD) diff --git a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs index 081bebc4773..ae1d8628bb7 100644 --- a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs +++ b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs @@ -147,7 +147,17 @@ private ItemExpressionFragment ProcessItemExpression(string expression, IE /// public IEnumerable FilterItems(IEnumerable items) { - return items.Where(i => Fragments.Any(f => f.ItemMatches(i.EvaluatedInclude) > 0)); + return items.Where(MatchesItem); + } + + /// + /// Return true if the given matches this itemspec + /// + /// + /// + public bool MatchesItem(I item) + { + return Fragments.Any(f => f.MatchCount(item.EvaluatedInclude) > 0); } /// @@ -163,7 +173,7 @@ public IEnumerable FragmentsMatchingItem(string itemToMatch, out i foreach (var fragment in Fragments) { - var itemMatches = fragment.ItemMatches(itemToMatch); + var itemMatches = fragment.MatchCount(itemToMatch); if (itemMatches > 0) { @@ -209,7 +219,7 @@ protected ItemFragment(string itemSpecFragment, string projectPath, LazyThe number of times the appears in this fragment - public virtual int ItemMatches(string itemToMatch) + public virtual int MatchCount(string itemToMatch) { return FileMatcher.Value(itemToMatch) ? 1 : 0; } @@ -250,7 +260,7 @@ public ItemExpressionFragment(ExpressionShredder.ItemExpressionCapture capture, _expander = _containingItemSpec.Expander; } - public override int ItemMatches(string itemToMatch) + public override int MatchCount(string itemToMatch) { // cache referenced items as long as the expander does not change // reference equality works for now since the expander cannot mutate its item state (hopefully it stays that way) @@ -264,7 +274,7 @@ public override int ItemMatches(string itemToMatch) _itemValueFragments = itemsFromCapture.Select(i => new ValueFragment(i.Item1, ProjectPath)).ToList(); } - return _itemValueFragments.Count(v => v.ItemMatches(itemToMatch) > 0); + return _itemValueFragments.Count(v => v.MatchCount(itemToMatch) > 0); } } } \ No newline at end of file diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IItemOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IItemOperation.cs new file mode 100644 index 00000000000..66f927b4025 --- /dev/null +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IItemOperation.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Immutable; + +namespace Microsoft.Build.Evaluation +{ + internal partial class LazyItemEvaluator + { + internal interface IItemOperation + { + void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore); + } + } +} \ No newline at end of file diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs index ad2d0ac5511..6e460298a08 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs @@ -154,7 +154,7 @@ protected override void SaveItems(ICollection items, ImmutableList. { foreach (var item in items) { - listBuilder.Add(new ItemData(item, _elementOrder, _conditionResult)); + listBuilder.Add(new ItemData(item, _itemElement, _elementOrder, _conditionResult)); } } } diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.LazyItemOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.LazyItemOperation.cs index 91844dc555a..657664dc3b0 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.LazyItemOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.LazyItemOperation.cs @@ -11,13 +11,14 @@ namespace Microsoft.Build.Evaluation { internal partial class LazyItemEvaluator { - abstract class LazyItemOperation + private abstract class LazyItemOperation : IItemOperation { + private readonly string _itemType; + private readonly ImmutableDictionary _referencedItemLists; + private readonly LazyItemEvaluator _lazyEvaluator; + protected readonly ProjectItemElement _itemElement; - protected readonly string _itemType; protected readonly ItemSpec _itemSpec; - protected readonly ImmutableDictionary _referencedItemLists; - protected readonly LazyItemEvaluator _lazyEvaluator; protected readonly EvaluatorData _evaluatorData; protected readonly Expander _expander; @@ -25,7 +26,7 @@ abstract class LazyItemOperation // the items and then removes them protected readonly IItemFactory _itemFactory; - public LazyItemOperation(OperationBuilder builder, LazyItemEvaluator lazyEvaluator) + protected LazyItemOperation(OperationBuilder builder, LazyItemEvaluator lazyEvaluator) { _itemElement = builder.ItemElement; _itemType = builder.ItemType; @@ -41,22 +42,6 @@ public LazyItemOperation(OperationBuilder builder, LazyItemEvaluator _itemSpec.Expander = _expander; } - IList GetReferencedItems(string itemType, ImmutableHashSet globsToIgnore) - { - LazyItemList itemList; - if (_referencedItemLists.TryGetValue(itemType, out itemList)) - { - return itemList.GetItems(globsToIgnore) - .Where(ItemData => ItemData.ConditionResult) - .Select(itemData => itemData.Item) - .ToList(); - } - else - { - return ImmutableList.Empty; - } - } - public virtual void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore) { var items = SelectItems(listBuilder, globsToIgnore).ToList(); @@ -76,6 +61,22 @@ protected virtual void MutateItems(ICollection items) { } protected virtual void SaveItems(ICollection items, ImmutableList.Builder listBuilder) { } + private IList GetReferencedItems(string itemType, ImmutableHashSet globsToIgnore) + { + LazyItemList itemList; + if (_referencedItemLists.TryGetValue(itemType, out itemList)) + { + return itemList.GetItems(globsToIgnore) + .Where(ItemData => ItemData.ConditionResult) + .Select(itemData => itemData.Item) + .ToList(); + } + else + { + return ImmutableList.Empty; + } + } + protected void DecorateItemsWithMetadata(ICollection items, ImmutableList metadata) { if (metadata.Any()) @@ -222,11 +223,9 @@ protected void DecorateItemsWithMetadata(ICollection items, ImmutableList /// Collects all the items of this item element's type that match the items (represented as operations) /// - protected ICollection SelectItemsMatchingItemSpec(ImmutableList.Builder listBuilder, IElementLocation elementLocation) + protected IEnumerable SelectItemsMatchingItemSpec(ImmutableList.Builder listBuilder, IElementLocation elementLocation) { - return _itemSpec - .FilterItems(listBuilder.Select(itemData => itemData.Item)) - .ToImmutableHashSet(); + return _itemSpec.FilterItems(listBuilder.Select(itemData => itemData.Item)); } } } diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.RemoveOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.RemoveOperation.cs index fe5f4b784bb..462a4e2ee49 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.RemoveOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.RemoveOperation.cs @@ -18,7 +18,7 @@ public RemoveOperation(OperationBuilder builder, LazyItemEvaluator l protected override ICollection SelectItems(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore) { - return SelectItemsMatchingItemSpec(listBuilder, _itemElement.RemoveLocation); + return SelectItemsMatchingItemSpec(listBuilder, _itemElement.RemoveLocation).ToList(); } protected override void SaveItems(ICollection items, ImmutableList.Builder listBuilder) diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.UpdateOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.UpdateOperation.cs index dec7cbdf573..00fb3a8bf26 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.UpdateOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.UpdateOperation.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Microsoft.Build.Construction; using System.Collections.Immutable; +using System.Linq; namespace Microsoft.Build.Evaluation { @@ -19,14 +20,26 @@ public UpdateOperation(OperationBuilderWithMetadata builder, LazyItemEvaluator

SelectItems(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore) + public override void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore) { - return SelectItemsMatchingItemSpec(listBuilder, _itemElement.UpdateLocation); - } + var matchedItems = ImmutableList.CreateBuilder(); - protected override void MutateItems(ICollection items) - { - DecorateItemsWithMetadata(items, _metadata); + for (int i = 0; i < listBuilder.Count; i++) + { + var itemData = listBuilder[i]; + + if (_itemSpec.MatchesItem(itemData.Item)) + { + // item lists should be deep immutable, so clone and replace items before mutating them + // otherwise, with GetItems caching enabled, future operations would mutate the state of past operations + var clonedItemData = listBuilder[i].Clone(_itemFactory, _itemElement); + listBuilder[i] = clonedItemData; + + matchedItems.Add(clonedItemData.Item); + } + } + + DecorateItemsWithMetadata(matchedItems, _metadata); } } } diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs index ecef8d62167..73529924f24 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Globalization; using System.Linq; @@ -117,53 +118,190 @@ private static string GetCurrentDirectoryForConditionEvaluation(ProjectElement e public struct ItemData { - private I _item; - private int _elementOrder; - private bool _conditionResult; + public ItemData(I item, ProjectItemElement originatingItemElement, int elementOrder, bool conditionResult) + { + Item = item; + OriginatingItemElement = originatingItemElement; + ElementOrder = elementOrder; + ConditionResult = conditionResult; + } - public ItemData(I item, int elementOrder, bool conditionResult) + public ItemData Clone(IItemFactory itemFactory, ProjectItemElement initialItemElementForFactory) { - _item = item; - _elementOrder = elementOrder; - _conditionResult = conditionResult; + // setting the factory's item element to the original item element that produced the item + // otherwise you get weird things like items that appear to have been produced by update elements + itemFactory.ItemElement = OriginatingItemElement; + var clonedItem = itemFactory.CreateItem(Item, OriginatingItemElement.ContainingProject.FullPath); + itemFactory.ItemElement = initialItemElementForFactory; + + return new ItemData(clonedItem, OriginatingItemElement, ElementOrder, ConditionResult); } - public I Item { get { return _item; } } - public int ElementOrder { get { return _elementOrder; } } - public bool ConditionResult { get { return _conditionResult; } } + public I Item { get; } + public ProjectItemElement OriginatingItemElement { get; } + public int ElementOrder { get; } + public bool ConditionResult { get; } } + private class MemoizedOperation : IItemOperation + { + public IItemOperation Operation { get; } + private Dictionary, ImmutableList> _cache; + + private bool _isReferenced; +#if DEBUG + private int _applyCalls; +#endif + + public MemoizedOperation(IItemOperation operation) + { + Operation = operation; + } + + public void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet globsToIgnore) + { +#if DEBUG + CheckInvariant(); +#endif + + Operation.Apply(listBuilder, globsToIgnore); + + // cache results if somebody is referencing this operation + if (_isReferenced) + { + AddItemsToCache(globsToIgnore, listBuilder.ToImmutable()); + } +#if DEBUG + _applyCalls++; + CheckInvariant(); +#endif + } + + private void CheckInvariant() + { + if (_isReferenced) + { + var cacheCount = _cache?.Count ?? 0; + Debug.Assert(_applyCalls == cacheCount, "Apply should only be called once per globsToIgnore. Otherwise caching is not working"); + } + else + { + // non referenced operations should not be cached + // non referenced operations should have as many apply calls as the number of cache keys of the immediate dominator with _isReferenced == true + Debug.Assert(_cache == null); + } + } + + public bool TryGetFromCache(ISet globsToIgnore, out ImmutableList items) + { + if (_cache != null) + { + return _cache.TryGetValue(globsToIgnore, out items); + } + + items = null; + return false; + } + + ///

+ /// Somebody is referencing this operation + /// + public void MarkAsReferenced() + { + _isReferenced = true; + } + + private void AddItemsToCache(ImmutableHashSet globsToIgnore, ImmutableList items) + { + if (_cache == null) + { + _cache = new Dictionary, ImmutableList>(); + } + + _cache[globsToIgnore] = items; + } + + private bool IsCached(ISet globsToIgnore) + { + return _cache != null && _cache.ContainsKey(globsToIgnore); + } + } private class LazyItemList { private readonly LazyItemList _previous; - private readonly LazyItemOperation _operation; + private readonly MemoizedOperation _memoizedOperation; public LazyItemList(LazyItemList previous, LazyItemOperation operation) { _previous = previous; - _operation = operation; + _memoizedOperation = new MemoizedOperation(operation); } public ImmutableList.Builder GetItems(ImmutableHashSet globsToIgnore) { - // TODO: Check for cached results + // Cache results only on the LazyItemOperations whose results are required by an external caller (via GetItems). This means: + // - Callers of GetItems who have announced ahead of time that they would reference an operation (via MarkAsReferenced()) + // This includes: item references (Include="@(foo)") and metadata conditions (Condition="@(foo->Count()) == 0") + // Without ahead of time notifications more computation is done than needed when the results of a future operation are requested + // The future operation is part of another item list referencing this one (making this operation part of the tail). + // The future operation will compute this list but since no ahead of time notifications have been made by callers, it won't cache the + // intermediary operations that would be requested by those callers. + // - Callers of GetItems that cannot announce ahead of time. This includes item referencing conditions on + // Item Groups and Item Elements. However, those conditions are performed eagerly outside of the LazyItemEvaluator, so they will run before + // any item referencing operations from inside the LazyItemEvaluator. This + // + // If the head of this LazyItemList is uncached, then the tail may contain cached and un-cached nodes. + // In this case we have to compute the head plus the part of the tail up to the first cached operation. + // + // The cache is based on a couple of properties: + // - uses immutable lists for structural sharing between multiple cached nodes (multiple include operations won't have duplicated memory for the common items) + // - if an operation is cached for a certain set of globsToIgnore, then the entire operation tail can be reused. This is because (i) the structure of LazyItemLists + // does not mutate: one can add operations on top, but the base never changes, and (ii) the globsToIgnore passed to the tail is the concatenation between + // the globsToIgnore received as an arg, and the globsToIgnore produced by the head (if the head is a Remove operation) + + ImmutableList items; + if (_memoizedOperation.TryGetFromCache(globsToIgnore, out items)) + { + return items.ToBuilder(); + } + else + { + // tell the cache that this operation's result is needed by an external caller + // this is required for callers that cannot tell the item list ahead of time that + // they would be using an operation + MarkAsReferenced(); + + return ComputeItems(this, globsToIgnore); + } - return GetItemsImplementation(this, globsToIgnore); } - static ImmutableList.Builder GetItemsImplementation(LazyItemList lazyItemList, ImmutableHashSet globsToIgnore) + private static ImmutableList.Builder ComputeItems(LazyItemList lazyItemList, ImmutableHashSet globsToIgnore) { + // Stack of operations up to the first one that's cached (exclusive) Stack itemListStack = new Stack(); - // Keep a separate stack of lists of globs to ignore that only gets modified for Remove operations + ImmutableList.Builder items = null; + + // Keep a separate stack of lists of globs to ignore that only gets modified for Remove operations Stack> globsToIgnoreStack = null; for (var currentList = lazyItemList; currentList != null; currentList = currentList._previous) { + var globsToIgnoreFromFutureOperations = globsToIgnoreStack?.Peek() ?? globsToIgnore; + + ImmutableList itemsFromCache; + if (currentList._memoizedOperation.TryGetFromCache(globsToIgnoreFromFutureOperations, out itemsFromCache)) + { + // the base items on top of which to apply the uncached operations are the items of the first operation that is cached + items = itemsFromCache.ToBuilder(); + break; + } + // If this is a remove operation, then add any globs that will be removed // to a list of globs to ignore in previous operations - var removeOperation = currentList._operation as RemoveOperation; + var removeOperation = currentList._memoizedOperation.Operation as RemoveOperation; if (removeOperation != null) { if (globsToIgnoreStack == null) @@ -171,8 +309,6 @@ static ImmutableList.Builder GetItemsImplementation(LazyItemList lazyI globsToIgnoreStack = new Stack>(); } - var globsToIgnoreFromFutureOperations = globsToIgnoreStack.Count > 0 ? globsToIgnoreStack.Peek() : globsToIgnore; - var globsToIgnoreForPreviousOperations = removeOperation.GetRemovedGlobs(); foreach (var globToRemove in globsToIgnoreFromFutureOperations) { @@ -185,7 +321,11 @@ static ImmutableList.Builder GetItemsImplementation(LazyItemList lazyI itemListStack.Push(currentList); } - ImmutableList.Builder items = ImmutableList.CreateBuilder(); + if (items == null) + { + items = ImmutableList.CreateBuilder(); + } + ImmutableHashSet currentGlobsToIgnore = globsToIgnoreStack == null ? globsToIgnore : globsToIgnoreStack.Peek(); // Walk back down the stack of item lists applying operations @@ -195,19 +335,23 @@ static ImmutableList.Builder GetItemsImplementation(LazyItemList lazyI // If this is a remove operation, then it could modify the globs to ignore, so pop the potentially // modified entry off the stack of globs to ignore - var removeOperation = currentList._operation as RemoveOperation; + var removeOperation = currentList._memoizedOperation.Operation as RemoveOperation; if (removeOperation != null) { globsToIgnoreStack.Pop(); currentGlobsToIgnore = globsToIgnoreStack.Count == 0 ? globsToIgnore : globsToIgnoreStack.Peek(); } - currentList._operation.Apply(items, currentGlobsToIgnore); - // TODO: Cache result of operation (possibly only if it involved executing globs) + currentList._memoizedOperation.Apply(items, currentGlobsToIgnore); } return items; } + + public void MarkAsReferenced() + { + _memoizedOperation.MarkAsReferenced(); + } } private class OperationBuilder @@ -234,6 +378,16 @@ public OperationBuilderWithMetadata(ProjectItemElement itemElement) : base(itemE } } + private void AddReferencedItemList(string itemType, IDictionary referencedItemLists) + { + var itemList = GetItemList(itemType); + if (itemList != null) + { + itemList.MarkAsReferenced(); + referencedItemLists[itemType] = itemList; + } + } + private LazyItemList GetItemList(string itemType) { LazyItemList ret; @@ -362,11 +516,7 @@ private void ProcessMetadataElements(ProjectItemElement itemElement, OperationBu { foreach (var itemType in itemsAndMetadataFound.Items) { - var itemList = GetItemList(itemType); - if (itemList != null) - { - operationBuilder.ReferencedItemLists[itemType] = itemList; - } + AddReferencedItemList(itemType, operationBuilder.ReferencedItemLists); } } } @@ -404,11 +554,7 @@ private void AddReferencedItemLists(OperationBuilder operationBuilder, Expressio { if (match.ItemType != null) { - var itemList = GetItemList(match.ItemType); - if (itemList != null) - { - operationBuilder.ReferencedItemLists[match.ItemType] = itemList; - } + AddReferencedItemList(match.ItemType, operationBuilder.ReferencedItemLists); } if (match.Captures != null) { diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index f9f3a16573d..2f61c6ca9c2 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -176,6 +176,7 @@ + diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/ItemEvaluation_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/ItemEvaluation_Tests.cs index 82a5806895e..c92354ac37d 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/ItemEvaluation_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/ItemEvaluation_Tests.cs @@ -7,6 +7,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using Microsoft.Build.Evaluation; using Xunit; using System.Text; @@ -47,44 +49,75 @@ public void IncludeShouldPreserveIntermediaryReferences() - + m1_updated m2_updated "; - IList items = ObjectModelHelpers.GetItemsFromFragment(content); + IList items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); - var expectedMetadata = new Dictionary + var mI2_1 = new Dictionary { {"m1", "m1_contents"}, {"m2", "m2_contents"}, }; - ObjectModelHelpers.AssertItems(new [] {"a", "b", "c"}, items, expectedMetadata); + var itemsForI = items.Where(i => i.ItemType == "i").ToList(); + ObjectModelHelpers.AssertItems(new [] {"a", "b", "c"}, itemsForI, mI2_1); + + var mI2_2 = new Dictionary + { + {"m1", "m1_updated"}, + {"m2", "m2_updated"}, + }; + + var itemsForI2 = items.Where(i => i.ItemType == "i2").ToList(); + ObjectModelHelpers.AssertItems( + new[] { "a", "b", "c", "d", "e", "f", "a", "b", "c" }, + itemsForI2, + new [] { mI2_1, mI2_1 , mI2_1, mI2_2, mI2_2, mI2_2, mI2_2, mI2_2, mI2_2 }); } - [Fact] - public void RemoveShouldPreserveIntermediaryReferences() - { - var content = @" - - m1_contents - m2_contents - + [Theory] + // remove the items by referencing each one + [InlineData( + @" + + m1_contents + m2_contents + - + + + " + )] + // remove the items via a glob + [InlineData( + @" + + m1_contents + m2_contents + - "; + - IList items = ObjectModelHelpers.GetItemsFromFragment(content); + " + )] + public void RemoveShouldPreserveIntermediaryReferences(string content) + { + IList items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); var expectedMetadata = new Dictionary { {"m1", "m1_contents"}, {"m2", "m2_contents"} }; + + var itemsForI = items.Where(i => i.ItemType == "i").ToList(); + ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, itemsForI, expectedMetadata); - ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, items, expectedMetadata); + var itemsForI2 = items.Where(i => i.ItemType == "i2").ToList(); + ObjectModelHelpers.AssertItems(new string[0], itemsForI2); } [Fact] @@ -108,7 +141,8 @@ public void UpdateShouldPreserveIntermediaryReferences() m4_updated "; - IList items = ObjectModelHelpers.GetItemsFromFragment(content); + IList items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); + var a = new Dictionary { @@ -134,7 +168,84 @@ public void UpdateShouldPreserveIntermediaryReferences() {"m4", "m4_contents"}, }; - ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, items, new [] {a, b, c}); + var itemsForI = items.Where(i => i.ItemType == "i").ToList(); + ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, itemsForI, new [] {a, b, c}); + + var metadataForI2 = new Dictionary() + { + {"m1", "m1_updated"}, + {"m2", "m2_updated"}, + {"m3", "m3_updated"}, + {"m4", "m4_updated"} + }; + + var itemsForI2 = items.Where(i => i.ItemType == "i2").ToList(); + ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, itemsForI2, metadataForI2); + } + + [Fact] + public void MultipleInterItemDependenciesOnSameItemOperation() + { + var content = @" + + + i1 + + + + + + + + + i2 + + + + + + + "; + + IList items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); + + var i1BaseMetadata = new Dictionary() + { + {"m", "i1"} + }; + + //i1 items: i1_1; i1_3; i1_4; i1_6 + var i1Metadata = new Dictionary[] + { + i1BaseMetadata, + i1BaseMetadata, + i1BaseMetadata, + new Dictionary() + }; + + var i1Items = items.Where(i => i.ItemType == "i1").ToList(); + ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_3", "i1_4", "i1_6" }, i1Items, i1Metadata); + + //i2 items: i1_1; i1_2; i1_3 + var i2Metadata = new Dictionary[] + { + new Dictionary() + { + {"m", "i2"} + }, + i1BaseMetadata, + i1BaseMetadata + }; + + var i2Items = items.Where(i => i.ItemType == "i2").ToList(); + ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_2", "i1_3" }, i2Items, i2Metadata); + + //i3 items: i1_1; i1_2; i1_4 + var i3Items = items.Where(i => i.ItemType == "i3").ToList(); + ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_2", "i1_4" }, i3Items, i1BaseMetadata); + + var i_condItems = items.Where(i => i.ItemType == "i_cond").ToList(); + ObjectModelHelpers.AssertItems(new[] { "i1 has 4 items" }, i_condItems); } [Fact] diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs index 5f739e4dd76..8be3357284c 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs @@ -2710,6 +2710,26 @@ public static IEnumerable GetItemProvenanceByProjectItemTestData { get { + // Provenance for an item in the first element with multiple matching updates + yield return new object[] + { + @" + + + + + ", + "a", + 0, // first item 'a' from the include + new ProvenanceResultTupleList() + { + Tuple.Create("A", Operation.Include, Provenance.StringLiteral, 2), + Tuple.Create("A", Operation.Update, Provenance.StringLiteral, 1), + Tuple.Create("A", Operation.Update, Provenance.Glob, 1), + Tuple.Create("A", Operation.Update, Provenance.StringLiteral | Provenance.Glob, 2) + } + }; + // Provenance for an item in the last element. Nothing matches yield return new object[] { From e5f3cd576154e1c25bd96de94ebb943665423d0f Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 20 Oct 2016 12:23:07 -0700 Subject: [PATCH 004/223] Update NuGet package versioning to support wildcards. (#1209) * Update NuGet package versioning to support wildcards. Set build number to 0 Use git commit height and build revision as a suffix to the prerelease tag New version will be something like: 15.1.0-preview-000333-01 Closes #557 Closes #1156 --- build/NuGetPackages/CreateNuGetPackages.proj | 35 +++++++++++++++++--- version.json | 4 +-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/build/NuGetPackages/CreateNuGetPackages.proj b/build/NuGetPackages/CreateNuGetPackages.proj index 5585f6e78b3..c3f62cf055f 100644 --- a/build/NuGetPackages/CreateNuGetPackages.proj +++ b/build/NuGetPackages/CreateNuGetPackages.proj @@ -3,7 +3,7 @@ - + Debug http://go.microsoft.com/fwlink/?LinkId=329770 @@ -22,7 +22,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -58,5 +58,32 @@ - + + + + + <_BuildRevisionRegex>\d{8}\.(?<Revision>\d{1,2}) + + + + + + + + 0 + + 00 + + + $([System.Int32]::Parse($([System.Text.RegularExpressions.Regex]::Match($(BUILD_NUMBER), $(_BuildRevisionRegex)).Groups["Revision"].Value)).ToString('D2')) + + $(PrereleaseVersion)-$([System.Int32]::Parse($(BuildVersionNumberComponent)).ToString('D6'))-$(BuildRevision) + + + $(MajorMinorVersion).$(BuildNumber)$(PrereleaseVersion) + + diff --git a/version.json b/version.json index 4b2715fe92f..3b28acd8163 100644 --- a/version.json +++ b/version.json @@ -1,7 +1,7 @@ { - "version": "15.1-preview5", + "version": "15.1-preview", "publicReleaseRefSpec": [ "^refs/heads/master$", - "refs/heads/xplat*" + "^refs/heads/xplat$" ] } From 9615bd2a41ef7aa44a6465474300a3aaa586c303 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Thu, 20 Oct 2016 12:40:36 -0700 Subject: [PATCH 005/223] Automated commit of revision number value 00068. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 128c165281b..47e4834e1da 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00067 + 00068 \ No newline at end of file From 9e72b056afe17e982902d6bb682f92b2dfa72569 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Thu, 20 Oct 2016 12:47:26 -0700 Subject: [PATCH 006/223] Automated commit of revision number value 00069. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 47e4834e1da..cbe54761421 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00068 + 00069 \ No newline at end of file From a42fbeadd9b5e5f10bf9eb2deb1bd73ab4075857 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Thu, 20 Oct 2016 12:54:55 -0700 Subject: [PATCH 007/223] Enable VisualStudioSetup Feature (#1220) - This was missed when the feature was merged to xplat. The feature flag was added to the code but not defined in the build. --- dir.props | 1 + .../Microsoft.Build.Tasks.Core.cs | 65 +++++++++++++++++++ .../Microsoft.Build.Utilities.Core.cs | 65 +++++++++++++++++++ ref/net46/Microsoft.Build/Microsoft.Build.cs | 65 +++++++++++++++++++ 4 files changed, 196 insertions(+) diff --git a/dir.props b/dir.props index 5fd1003c5f5..b4c083c87c6 100644 --- a/dir.props +++ b/dir.props @@ -338,6 +338,7 @@ $(DefineConstants);FEATURE_DEBUG_LAUNCH $(DefineConstants);FEATURE_WIN32_REGISTRY $(DefineConstants);FEATURE_WORKINGSET + $(DefineConstants);FEATURE_VISUALSTUDIOSETUP diff --git a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs index e47aae0f5a0..a8322b5298b 100644 --- a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs +++ b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs @@ -2503,6 +2503,71 @@ public void ReplaceToolSwitch(Microsoft.Build.Tasks.Xaml.CommandLineToolSwitch s protected override bool ValidateParameters() { throw null; } } } +namespace Microsoft.VisualStudio.Setup.Configuration +{ + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface IEnumSetupInstances + { + void Next(int celt, Microsoft.VisualStudio.Setup.Configuration.ISetupInstance[] rgelt, out int pceltFetched); + } + [System.FlagsAttribute] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.TypeIdentifierAttribute("310100ba-5f84-4103-abe0-e8132ae862d9", "Microsoft.VisualStudio.Setup.Configuration.InstanceState")] + public enum InstanceState : uint + { + Complete = (uint)4294967295, + Local = (uint)1, + None = (uint)0, + NoRebootRequired = (uint)4, + Registered = (uint)2, + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration + { + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration2 : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration + { + void _VtblGap1_3() { } + Microsoft.VisualStudio.Setup.Configuration.IEnumSetupInstances EnumAllInstances(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("B41463C3-8866-43B5-BC33-2B0676F7F42E")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance + { + void _VtblGap1_3() { } + string GetDisplayName(int lcid=0); + string GetInstallationPath(); + string GetInstallationVersion(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("89143C9A-05AF-49B0-B717-72E218A2185C")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance2 : Microsoft.VisualStudio.Setup.Configuration.ISetupInstance + { + void _VtblGap1_8() { } + Microsoft.VisualStudio.Setup.Configuration.InstanceState GetState(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.CoClassAttribute(typeof(object))] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface SetupConfiguration : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration, Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration2 + { + } +} namespace System.Deployment.Internal.CodeSigning { public sealed partial class RSAPKCS1SHA256SignatureDescription : System.Security.Cryptography.SignatureDescription diff --git a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index b165e1f5fc2..eba1dfb0304 100644 --- a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -570,3 +570,68 @@ public enum VisualStudioVersion VersionLatest = 4, } } +namespace Microsoft.VisualStudio.Setup.Configuration +{ + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface IEnumSetupInstances + { + void Next(int celt, Microsoft.VisualStudio.Setup.Configuration.ISetupInstance[] rgelt, out int pceltFetched); + } + [System.FlagsAttribute] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.TypeIdentifierAttribute("310100ba-5f84-4103-abe0-e8132ae862d9", "Microsoft.VisualStudio.Setup.Configuration.InstanceState")] + public enum InstanceState : uint + { + Complete = (uint)4294967295, + Local = (uint)1, + None = (uint)0, + NoRebootRequired = (uint)4, + Registered = (uint)2, + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration + { + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration2 : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration + { + void _VtblGap1_3() { } + Microsoft.VisualStudio.Setup.Configuration.IEnumSetupInstances EnumAllInstances(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("B41463C3-8866-43B5-BC33-2B0676F7F42E")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance + { + void _VtblGap1_3() { } + string GetDisplayName(int lcid=0); + string GetInstallationPath(); + string GetInstallationVersion(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("89143C9A-05AF-49B0-B717-72E218A2185C")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance2 : Microsoft.VisualStudio.Setup.Configuration.ISetupInstance + { + void _VtblGap1_8() { } + Microsoft.VisualStudio.Setup.Configuration.InstanceState GetState(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.CoClassAttribute(typeof(object))] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface SetupConfiguration : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration, Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration2 + { + } +} diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 0b356a3667a..da90078155a 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -1404,3 +1404,68 @@ public LoggerDescription(string loggerClassName, string loggerAssemblyName, stri } public delegate void WriteHandler(string message); } +namespace Microsoft.VisualStudio.Setup.Configuration +{ + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface IEnumSetupInstances + { + void Next(int celt, Microsoft.VisualStudio.Setup.Configuration.ISetupInstance[] rgelt, out int pceltFetched); + } + [System.FlagsAttribute] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.TypeIdentifierAttribute("310100ba-5f84-4103-abe0-e8132ae862d9", "Microsoft.VisualStudio.Setup.Configuration.InstanceState")] + public enum InstanceState : uint + { + Complete = (uint)4294967295, + Local = (uint)1, + None = (uint)0, + NoRebootRequired = (uint)4, + Registered = (uint)2, + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration + { + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupConfiguration2 : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration + { + void _VtblGap1_3() { } + Microsoft.VisualStudio.Setup.Configuration.IEnumSetupInstances EnumAllInstances(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("B41463C3-8866-43B5-BC33-2B0676F7F42E")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance + { + void _VtblGap1_3() { } + string GetDisplayName(int lcid=0); + string GetInstallationPath(); + string GetInstallationVersion(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.GuidAttribute("89143C9A-05AF-49B0-B717-72E218A2185C")] + [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface ISetupInstance2 : Microsoft.VisualStudio.Setup.Configuration.ISetupInstance + { + void _VtblGap1_8() { } + Microsoft.VisualStudio.Setup.Configuration.InstanceState GetState(); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute] + [System.Runtime.InteropServices.CoClassAttribute(typeof(object))] + [System.Runtime.InteropServices.GuidAttribute("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [System.Runtime.InteropServices.TypeIdentifierAttribute] + public partial interface SetupConfiguration : Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration, Microsoft.VisualStudio.Setup.Configuration.ISetupConfiguration2 + { + } +} From 9cdea7f3daf2ee5f530b5d3956d962b500157f87 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 21 Oct 2016 08:29:28 -0700 Subject: [PATCH 008/223] Change --bootstrap-only switch to cibuild (#1229) Introduce a new switch `--build-only` which will do the first build only. `--bootstrap-only` now does the first build and then creates the bootstrap folder. Also removed an erroneous `echo on` in `cibuild.cmd` --- cibuild.cmd | 10 +++++++--- cibuild.sh | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cibuild.cmd b/cibuild.cmd index 92d93e2305e..efc5921ac72 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -6,6 +6,7 @@ if "%1"=="" goto doneParsingArguments if /i "%1"=="--scope" set SCOPE=%2&& shift && shift && goto parseArguments if /i "%1"=="--target" set TARGET=%2&& shift && shift && goto parseArguments if /i "%1"=="--host" set HOST=%2&& shift && shift && goto parseArguments +if /i "%1"=="--build-only" set BUILD_ONLY=true&& shift && goto parseArguments if /i "%1"=="--bootstrap-only" set BOOTSTRAP_ONLY=true&& shift && goto parseArguments if /i "%1"=="--localized-build" set LOCALIZED_BUILD=true&& shift && goto parseArguments if /i "%1"=="--sync-xlf" set SYNC_XLF=true&& shift && goto parseArguments @@ -84,8 +85,7 @@ if %ERRORLEVEL% NEQ 0 ( echo Bootstrap build failed with errorlevel %ERRORLEVEL% 1>&2 goto :error ) -echo on -if "%BOOTSTRAP_ONLY%"=="true" goto :success +if "%BUILD_ONLY%"=="true" goto :success :: Move initial build to bootstrap directory @@ -104,6 +104,8 @@ if %ERRORLEVEL% NEQ 0 ( echo Failed to create bootstrap folder with errorlevel %ERRORLEVEL% 1>&2 goto :error ) +if "%BOOTSTRAP_ONLY%"=="true" goto :success + set MSBUILD_ARGS= :: Rebuild with bootstrapped msbuild @@ -146,7 +148,9 @@ echo Options echo --scope ^ Scope of the build ^(Compile / Test^) echo --target ^ CoreCLR or Desktop ^(default: Desktop^) echo --host ^ CoreCLR or Desktop ^(default: Desktop^) -echo --bootstrap-only Do not rebuild msbuild with local binaries +echo --build-only Only build using a downloaded copy of MSBuild but do not bootstrap + or build again with those binaries +echo --bootstrap-only Build and bootstrap MSBuild but do not build again with those binaries echo --localized-build Do a localized build echo --sync-xlf Synchronize xlf files from resx files exit /b 1 diff --git a/cibuild.sh b/cibuild.sh index 7972f338ca4..bc66ddb4fea 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -8,7 +8,9 @@ usage() echo " --scope Scope of the build (Compile / Test)" echo " --target CoreCLR or Mono (default: CoreCLR)" echo " --host CoreCLR or Mono (default: CoreCLR)" - echo " --bootstrap-only Do not rebuild msbuild with local binaries" + echo " --bootstrap-only Build and bootstrap MSBuild but do not build again with those binaries" + echo " --build-only Only build using a downloaded copy of MSBuild but do not bootstrap" + echo " or build again with those binaries" } restoreBuildTools(){ @@ -172,6 +174,11 @@ do shift 2 ;; + --build-only) + BUILD_ONLY=true + shift 1 + ;; + --bootstrap-only) BOOTSTRAP_ONLY=true shift 1 @@ -273,7 +280,7 @@ echo echo "** Rebuilding MSBuild with downloaded binaries" runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_EXE" "/t:Rebuild $BUILD_MSBUILD_ARGS" "$BOOTSTRAP_BUILD_LOG_PATH" -if [[ $BOOTSTRAP_ONLY = true ]]; then +if [[ $BUILD_ONLY = true ]]; then exit $? fi @@ -282,6 +289,10 @@ echo "** Moving bootstrapped MSBuild to the bootstrap folder" MOVE_MSBUILD_ARGS="$BOOTSTRAP_FILE_ARG /p:OS=$OS_ARG /p:Configuration=$CONFIGURATION /p:OverrideToolHost=$RUNTIME_HOST /verbosity:minimal" runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_EXE" "$MOVE_MSBUILD_ARGS" "$MOVE_LOG_PATH" +if [[ $BOOTSTRAP_ONLY = true ]]; then + exit $? +fi + echo echo "** Rebuilding MSBuild with locally built binaries" runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_BOOTSTRAPPED_EXE" "/t:$TARGET_ARG $BUILD_MSBUILD_ARGS" "$LOCAL_BUILD_LOG_PATH" From bf9b21cc7869b96ea2289ff31f6aaa5e1d525a26 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 21 Oct 2016 13:59:33 -0700 Subject: [PATCH 009/223] Re-order assrmebly search paths in RAR (#1231) We should select the AssemblyFolder.config before the AssemblyFolderEx since the former will be used for new assemblies in Visual Studio "15" going forward. If the registry implementation is searched first we risk resolving assemblies from previous versions of Visual Studio before the newer assemblies are considered. Closes #1174 --- src/XMakeTasks/Microsoft.Common.CurrentVersion.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets index 167f1b7bfa1..e0dc14c5470 100644 --- a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets @@ -552,8 +552,8 @@ Copyright (C) Microsoft Corporation. All rights reserved. $(ReferencePath); {HintPathFromItem}; {TargetFrameworkDirectory}; - {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)}; $(AssemblyFoldersConfigFileSearchPath) + {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)}; {AssemblyFolders}; {GAC}; {RawFileName}; From e5f7c86cc190560c2321d568694bb6429a7f823b Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 21 Oct 2016 16:23:41 -0700 Subject: [PATCH 010/223] Fix build break in Release configuration. (#1234) --- src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs index 95e34e1a079..4ba6145995b 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs @@ -180,6 +180,7 @@ public void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet< #endif } +#if DEBUG private void CheckInvariant() { if (_isReferenced) @@ -194,6 +195,7 @@ private void CheckInvariant() Debug.Assert(_cache == null); } } +#endif public bool TryGetFromCache(ISet globsToIgnore, out ImmutableList items) { From e700b5dcd13bea02fa774735e14cfb3c7b010c33 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Mon, 24 Oct 2016 18:32:59 -0700 Subject: [PATCH 011/223] Fix build break in Release configuration. (#1234) (#1238) --- src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs index 73529924f24..04db228cc7b 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.cs @@ -177,6 +177,7 @@ public void Apply(ImmutableList.Builder listBuilder, ImmutableHashSet< #endif } +#if DEBUG private void CheckInvariant() { if (_isReferenced) @@ -191,6 +192,7 @@ private void CheckInvariant() Debug.Assert(_cache == null); } } +#endif public bool TryGetFromCache(ISet globsToIgnore, out ImmutableList items) { From c2dd3b9be18675b90d2597c94e1b19cc83b00a62 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 25 Oct 2016 07:32:42 -0700 Subject: [PATCH 012/223] Revert "Disable stdout redirection of netcore test execution. (#1159)" (#1241) This reverts commit 4d4add4c43e6a13335ebb922c4e969414c22fafe. --- dir.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dir.targets b/dir.targets index 77ab10371e3..5041f823b7f 100644 --- a/dir.targets +++ b/dir.targets @@ -98,7 +98,7 @@ Condition="'$(NetCoreBuild)' != 'true'" /> - From dace2e74691ac6e4b02e203b4c5eddacbcf9cbba Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 25 Oct 2016 11:02:36 -0700 Subject: [PATCH 013/223] Fix more build warnings because of missing xml doc comments (#1243) Fix more build warnings because of missing xml doc comments --- src/Shared/FileMatcher.cs | 2 ++ .../Construction/ProjectRootElement.cs | 16 ++++++++++++++++ src/XMakeBuildEngine/Definition/Project.cs | 3 +++ src/XMakeBuildEngine/Definition/Toolset.cs | 7 ++++++- src/XMakeBuildEngine/Evaluation/Expander.cs | 8 +++++++- src/XMakeBuildEngine/Evaluation/ItemSpec.cs | 9 +++++---- .../Evaluation/ProjectRootElementCache.cs | 1 + .../Utilities/EngineFileUtilities.cs | 4 ++-- 8 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Shared/FileMatcher.cs b/src/Shared/FileMatcher.cs index 506a5453c60..5c2347d8b0b 100644 --- a/src/Shared/FileMatcher.cs +++ b/src/Shared/FileMatcher.cs @@ -1336,6 +1336,7 @@ string fileToMatch /// /// The project directory. /// Get files that match the given file spec. + /// Exclude files that match this file spec. /// The array of files. internal static string[] GetFiles ( @@ -1491,6 +1492,7 @@ static string[] CreateArrayWithSingleItemIfNotExcluded(string filespecUnescaped, /// /// The project directory. /// Get files that match the given file spec. + /// Exclude files that match this file spec. /// Get files that match the given file spec. /// Determine whether a directory exists. /// The array of files. diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 09e296793ba..0c06ca276cc 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -937,6 +937,10 @@ public static ProjectRootElement Create() return Create(ProjectCollection.GlobalProjectCollection, Project.DefaultNewProjectTemplateOptions); } + /// + /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later using the specified . + /// Uses the global project collection. + /// public static ProjectRootElement Create(NewProjectFileOptions projectFileOptions) { return Create(ProjectCollection.GlobalProjectCollection, projectFileOptions); @@ -951,6 +955,9 @@ public static ProjectRootElement Create(ProjectCollection projectCollection) return Create(projectCollection.ProjectRootElementCache); } + /// + /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later using the specified and . + /// public static ProjectRootElement Create(ProjectCollection projectCollection, NewProjectFileOptions projectFileOptions) { ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection"); @@ -968,6 +975,10 @@ public static ProjectRootElement Create(string path) return Create(path, ProjectCollection.GlobalProjectCollection, Project.DefaultNewProjectTemplateOptions); } + /// + /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later using the specified path and . + /// Uses the global project collection. + /// public static ProjectRootElement Create(string path, NewProjectFileOptions newProjectFileOptions) { return Create(path, ProjectCollection.GlobalProjectCollection, newProjectFileOptions); @@ -1051,6 +1062,10 @@ public static ProjectRootElement Open(string path, ProjectCollection projectColl preserveFormatting: false); } + /// + /// Initialize a ProjectRootElement instance by loading from the specified file path. + /// Uses the specified project collection and preserves the formatting of the document if specified. + /// public static ProjectRootElement Open(string path, ProjectCollection projectCollection, bool preserveFormatting) { ErrorUtilities.VerifyThrowArgumentLength(path, "path"); @@ -2006,6 +2021,7 @@ bool preserveFormatting /// Does NOT add to the ProjectRootElementCache. Caller should add after verifying subsequent MSBuild parsing succeeds. /// /// The full path to the document to load. + /// true to preserve the formatting of the document, otherwise false. private XmlDocumentWithLocation LoadDocument(string fullPath, bool preserveFormatting) { ErrorUtilities.VerifyThrowInternalRooted(fullPath); diff --git a/src/XMakeBuildEngine/Definition/Project.cs b/src/XMakeBuildEngine/Definition/Project.cs index 78ab6219b78..a2e8efdc1ed 100644 --- a/src/XMakeBuildEngine/Definition/Project.cs +++ b/src/XMakeBuildEngine/Definition/Project.cs @@ -210,6 +210,9 @@ public Project(IDictionary globalProperties, string toolsVersion /// Project will be added to the specified project collection when it is named. /// /// Global properties to evaluate with. May be null in which case the containing project collection's global properties will be used. + /// Tools version to evaluate with. May be null + /// The the project is added to. + /// The to use for the new project. public Project(IDictionary globalProperties, string toolsVersion, ProjectCollection projectCollection, NewProjectFileOptions newProjectFileOptions) : this(ProjectRootElement.Create(projectCollection, newProjectFileOptions), globalProperties, toolsVersion, projectCollection) { diff --git a/src/XMakeBuildEngine/Definition/Toolset.cs b/src/XMakeBuildEngine/Definition/Toolset.cs index a9f025e17b0..a112a81ae4f 100644 --- a/src/XMakeBuildEngine/Definition/Toolset.cs +++ b/src/XMakeBuildEngine/Definition/Toolset.cs @@ -297,7 +297,12 @@ internal Toolset(string toolsVersion, string toolsPath, PropertyDictionary - /// Map of parameter name to for use during Import. + /// A containing the environment properties. + /// A containing the global properties. + /// A list of to use. + /// The override tasks path. + /// ToolsVersion to use as the default ToolsVersion for this version of MSBuild. + /// Map of parameter name to property search paths for use during Import. internal Toolset(string toolsVersion, string toolsPath, PropertyDictionary buildProperties, PropertyDictionary environmentProperties, PropertyDictionary globalProperties, IDictionary subToolsets, string msbuildOverrideTasksPath, string defaultOverrideToolsVersion, Dictionary importSearchPathsTable = null) : this(toolsVersion, toolsPath, environmentProperties, globalProperties, msbuildOverrideTasksPath, defaultOverrideToolsVersion) { diff --git a/src/XMakeBuildEngine/Evaluation/Expander.cs b/src/XMakeBuildEngine/Evaluation/Expander.cs index 989e71a1473..faabbc8d3e6 100644 --- a/src/XMakeBuildEngine/Evaluation/Expander.cs +++ b/src/XMakeBuildEngine/Evaluation/Expander.cs @@ -1718,7 +1718,7 @@ internal static IList ExpandExpressionCaptureIntoItems( /// /// Returns true if ExpanderOptions.BreakOnNotEmpty was passed, expression was going to be non-empty, and so it broke out early. /// - /// + /// /// /// List of items. /// @@ -1728,6 +1728,12 @@ internal static IList ExpandExpressionCaptureIntoItems( /// Item1 differs from Item2's string when it is coming from a transform /// /// + /// The expander whose state will be used to expand any transforms + /// The representing the structure of an item expression + /// to provide the inital items (which may get subsequently transformed, if is a transform expression)> + /// Location of the xml element containing the + /// expander options + /// Wether to include items that evaluated to empty / null internal static bool ExpandExpressionCapture( Expander expander, ExpressionShredder.ItemExpressionCapture expressionCapture, diff --git a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs index ae1d8628bb7..d6ca4b4a0e4 100644 --- a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs +++ b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs @@ -151,9 +151,9 @@ public IEnumerable FilterItems(IEnumerable items) } /// - /// Return true if the given matches this itemspec + /// Return true if the given matches this itemspec /// - /// + /// The item to attempt to find a match for. /// public bool MatchesItem(I item) { @@ -161,10 +161,11 @@ public bool MatchesItem(I item) } /// - /// Return the fragments that match against the given + /// Return the fragments that match against the given /// + /// The item to match. /// - /// Total number of matches. Some fragments match more than once (item expression may contain multiple instances of ) + /// Total number of matches. Some fragments match more than once (item expression may contain multiple instances of ) /// public IEnumerable FragmentsMatchingItem(string itemToMatch, out int matches) { diff --git a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs index cb1c1b0fe53..a9c877448b7 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs @@ -191,6 +191,7 @@ internal ProjectRootElementCache(bool autoReloadFromDisk) /// The project file which contains the ProjectRootElement. Must be a full path. /// The delegate to use to load if necessary. May be null. /// true if the project is explicitly loaded, otherwise false. + /// true to the project was loaded with the formated preserved, otherwise false. /// The ProjectRootElement instance if one exists. Null otherwise. internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openProjectRootElement, bool isExplicitlyLoaded, bool preserveFormatting) diff --git a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs index 2d0f4a90e75..6e61defca2a 100644 --- a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs +++ b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs @@ -48,7 +48,7 @@ string filespecEscaped /// /// The directory to evaluate, escaped. /// The filespec to evaluate, escaped. - /// + /// Filespecs to exclude, escaped. /// Array of file paths, escaped. internal static string[] GetFileListEscaped ( @@ -97,7 +97,7 @@ private static bool FilespecHasWildcards(string filespecEscaped) /// The directory to evaluate, escaped. /// The filespec to evaluate, escaped. /// true to return escaped specs. - /// The exclude specification, unescaped. + /// The exclude specification, escaped. /// Array of file paths. private static string[] GetFileList ( From 1bfaf01003e593e550572ec2266327f3493ca633 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 25 Oct 2016 12:03:44 -0700 Subject: [PATCH 014/223] Implement telemetry as another log message type (#1226) 1. Telemetry is available to us via the LoggingService 2. Telemetry is available to task authors via IBuildEngine5.LogTelemetry() or TaskLoggingHelper.LogTelemetry() 3. Telemetry is available to target authors via the task. To receive telemetry, consumers will need to implement an ILogger and attach to the TelemetrySent. They can specify loggers to constructors in the object model or specify them at the command-line. Closes #1191 --- .../Microsoft.Build.Tasks.Core.cs | 8 ++ .../Microsoft.Build.Utilities.Core.cs | 1 + .../Microsoft.Build.Tasks.Core.cs | 8 ++ .../Microsoft.Build.Utilities.Core.cs | 1 + src/Framework/IBuildEngine5.cs | 20 ++++ src/Framework/IEventSource.cs | 12 ++- .../Microsoft.Build.Framework.csproj | 4 +- src/Framework/TelemetryEventArgs.cs | 27 +++++ src/OrcasEngine/Engine/EventSource.cs | 6 ++ src/Shared/TaskLoggingHelper.cs | 15 +++ .../UnitTests/BuildEventArgsExtension.cs | 15 +-- src/Shared/UnitTests/MockEngine.cs | 22 ++++- src/Utilities/MuxLogger.cs | 46 +++++++++ .../Logging/CentralForwardingLogger.cs | 3 + .../Components/Logging/EventSourceSink.cs | 46 ++++++++- .../Components/Logging/ILoggingService.cs | 10 ++ .../Logging/LoggingServiceLogMethods.cs | 27 +++++ .../Components/RequestBuilder/TaskHost.cs | 38 ++++++- .../Definition/ProjectCollection.cs | 25 +++++ .../BackEnd/LoggingServicesLogMethod_Tests.cs | 66 +++++++++++++ .../UnitTests/BackEnd/MockLoggingService.cs | 10 ++ .../Microsoft.Build.CommonTypes.xsd | 10 ++ src/XMakeCommandLine/OutOfProcTaskHostNode.cs | 21 +++- src/XMakeTasks/Microsoft.Build.Tasks.csproj | 8 +- src/XMakeTasks/Microsoft.Common.tasks | 1 + src/XMakeTasks/Resources/Strings.resx | 12 ++- src/XMakeTasks/Telemetry.cs | 56 +++++++++++ .../Microsoft.Build.Tasks.UnitTests.csproj | 3 +- .../UnitTests/TelemetryTaskTests.cs | 99 +++++++++++++++++++ 29 files changed, 602 insertions(+), 18 deletions(-) create mode 100644 src/Framework/IBuildEngine5.cs create mode 100644 src/Framework/TelemetryEventArgs.cs create mode 100644 src/XMakeTasks/Telemetry.cs create mode 100644 src/XMakeTasks/UnitTests/TelemetryTaskTests.cs diff --git a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs index a8322b5298b..4a847d796d7 100644 --- a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs +++ b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs @@ -1068,6 +1068,14 @@ public TaskLoggingHelperExtension(Microsoft.Build.Framework.ITask taskInstance, public System.Resources.ResourceManager TaskSharedResources { get { throw null; } set { } } public override string FormatResourceString(string resourceName, params object[] args) { throw null; } } + public sealed partial class Telemetry : Microsoft.Build.Tasks.TaskExtension + { + public Telemetry() { } + public string EventData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + [Microsoft.Build.Framework.RequiredAttribute] + public string EventName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public override bool Execute() { throw null; } + } public abstract partial class ToolTaskExtension : Microsoft.Build.Utilities.ToolTask { internal ToolTaskExtension() { } diff --git a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index eba1dfb0304..0cac78593ed 100644 --- a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -405,6 +405,7 @@ public void LogMessageFromResources(string messageResourceName, params object[] public bool LogMessagesFromFile(string fileName) { throw null; } public bool LogMessagesFromFile(string fileName, Microsoft.Build.Framework.MessageImportance messageImportance) { throw null; } public bool LogMessagesFromStream(System.IO.TextReader stream, Microsoft.Build.Framework.MessageImportance messageImportance) { throw null; } + public void LogTelemetry(string eventName, System.Collections.Generic.IDictionary properties) { } public void LogWarning(string message, params object[] messageArgs) { } public void LogWarning(string subcategory, string warningCode, string helpKeyword, string file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber, string message, params object[] messageArgs) { } public void LogWarningFromException(System.Exception exception) { } diff --git a/ref/netstandard1.3/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs b/ref/netstandard1.3/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs index 2706d340bb9..e569acd46be 100644 --- a/ref/netstandard1.3/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs +++ b/ref/netstandard1.3/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs @@ -564,6 +564,14 @@ public TaskLoggingHelperExtension(Microsoft.Build.Framework.ITask taskInstance, public System.Resources.ResourceManager TaskSharedResources { get { throw null; } set { } } public override string FormatResourceString(string resourceName, params object[] args) { throw null; } } + public sealed partial class Telemetry : Microsoft.Build.Tasks.TaskExtension + { + public Telemetry() { } + public string EventData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + [Microsoft.Build.Framework.RequiredAttribute] + public string EventName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public override bool Execute() { throw null; } + } public abstract partial class ToolTaskExtension : Microsoft.Build.Utilities.ToolTask { internal ToolTaskExtension() { } diff --git a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index 20432e1118e..c36e608a5c4 100644 --- a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -247,6 +247,7 @@ public void LogMessageFromResources(string messageResourceName, params object[] public bool LogMessagesFromFile(string fileName) { throw null; } public bool LogMessagesFromFile(string fileName, Microsoft.Build.Framework.MessageImportance messageImportance) { throw null; } public bool LogMessagesFromStream(System.IO.TextReader stream, Microsoft.Build.Framework.MessageImportance messageImportance) { throw null; } + public void LogTelemetry(string eventName, System.Collections.Generic.IDictionary properties) { } public void LogWarning(string message, params object[] messageArgs) { } public void LogWarning(string subcategory, string warningCode, string helpKeyword, string file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber, string message, params object[] messageArgs) { } public void LogWarningFromException(System.Exception exception) { } diff --git a/src/Framework/IBuildEngine5.cs b/src/Framework/IBuildEngine5.cs new file mode 100644 index 00000000000..642c121997a --- /dev/null +++ b/src/Framework/IBuildEngine5.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace Microsoft.Build.Framework +{ + /// + /// This interface extends IBuildEngine to log telemetry. + /// + public interface IBuildEngine5 : IBuildEngine4 + { + /// + /// Logs telemetry. + /// + /// The event name. + /// The event properties. + void LogTelemetry(string eventName, IDictionary properties); + } +} \ No newline at end of file diff --git a/src/Framework/IEventSource.cs b/src/Framework/IEventSource.cs index 07943a2cba5..0f18ed337c9 100644 --- a/src/Framework/IEventSource.cs +++ b/src/Framework/IEventSource.cs @@ -75,6 +75,11 @@ namespace Microsoft.Build.Framework /// public delegate void AnyEventHandler(object sender, BuildEventArgs e); + /// + /// Type of handler for TelemetryLogged events + /// + public delegate void TelemetryEventHandler(object sender, TelemetryEventArgs e); + /// /// This interface defines the events raised by the build engine. /// Loggers use this interface to subscribe to the events they @@ -148,8 +153,13 @@ public interface IEventSource event BuildStatusEventHandler StatusEventRaised; /// - /// this event is raised to log any build event + /// this event is raised to log any build event. These events do not include telemetry. To receive telemetry, you must attach to the event. /// event AnyEventHandler AnyEventRaised; + + /// + /// this event is raised to when telemetry is logged. + /// + event TelemetryEventHandler TelemetryLogged; } } diff --git a/src/Framework/Microsoft.Build.Framework.csproj b/src/Framework/Microsoft.Build.Framework.csproj index a935042f363..b731d51a2cb 100644 --- a/src/Framework/Microsoft.Build.Framework.csproj +++ b/src/Framework/Microsoft.Build.Framework.csproj @@ -17,7 +17,7 @@ - + @@ -60,6 +60,7 @@ + @@ -138,6 +139,7 @@ true + diff --git a/src/Framework/TelemetryEventArgs.cs b/src/Framework/TelemetryEventArgs.cs new file mode 100644 index 00000000000..e38b9f15c49 --- /dev/null +++ b/src/Framework/TelemetryEventArgs.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; + +namespace Microsoft.Build.Framework +{ + /// + /// Arguments for telemetry events. + /// +#if FEATURE_BINARY_SERIALIZATION + [Serializable] +#endif + public sealed class TelemetryEventArgs : BuildEventArgs + { + /// + /// Gets or sets the name of the event. + /// + public string EventName { get; set; } + + /// + /// Gets or sets a list of properties associated with the event. + /// + public IDictionary Properties { get; set; } = new Dictionary(); + } +} \ No newline at end of file diff --git a/src/OrcasEngine/Engine/EventSource.cs b/src/OrcasEngine/Engine/EventSource.cs index 99454be7fa2..483c0810f9d 100644 --- a/src/OrcasEngine/Engine/EventSource.cs +++ b/src/OrcasEngine/Engine/EventSource.cs @@ -644,5 +644,11 @@ internal void RaiseStronglyTypedEvent(BuildEventArgs e) /// /// t-jeffv, sumedhk public event AnyEventHandler AnyEventRaised; + + /// + /// This event is not used in OrcasEngine + /// + [Obsolete("This event is not available for the older engine.")] + public event TelemetryEventHandler TelemetryLogged; } } diff --git a/src/Shared/TaskLoggingHelper.cs b/src/Shared/TaskLoggingHelper.cs index 749de3d322b..b5cf31f7fd8 100644 --- a/src/Shared/TaskLoggingHelper.cs +++ b/src/Shared/TaskLoggingHelper.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; @@ -1359,6 +1360,20 @@ public bool LogMessageFromText(string lineOfText, MessageImportance messageImpor #endregion + #region Telemetry logging methods + + /// + /// Logs telemetry with the specified event name and properties. + /// + /// The event name. + /// The list of properties associated with the event. + public void LogTelemetry(string eventName, IDictionary properties) + { + (BuildEngine as IBuildEngine5)?.LogTelemetry(eventName, properties); + } + + #endregion + #if FEATURE_APPDOMAIN #region AppDomain Code diff --git a/src/Shared/UnitTests/BuildEventArgsExtension.cs b/src/Shared/UnitTests/BuildEventArgsExtension.cs index 46330e780da..cdce6d9da06 100644 --- a/src/Shared/UnitTests/BuildEventArgsExtension.cs +++ b/src/Shared/UnitTests/BuildEventArgsExtension.cs @@ -58,13 +58,16 @@ public static bool IsEquivalent(this BuildEventArgs args, BuildEventArgs other) return false; } - // Just in case we're matching chk against ret or vice versa, make sure the message still registers as the same - string fixedArgsMessage = args.Message.Replace("\r\nThis is an unhandled exception from a task -- PLEASE OPEN A BUG AGAINST THE TASK OWNER.", String.Empty); - string fixedOtherMessage = other.Message.Replace("\r\nThis is an unhandled exception from a task -- PLEASE OPEN A BUG AGAINST THE TASK OWNER.", String.Empty); - - if (!String.Equals(fixedArgsMessage, fixedOtherMessage, StringComparison.OrdinalIgnoreCase)) + if (!String.IsNullOrEmpty(args.Message)) { - return false; + // Just in case we're matching chk against ret or vice versa, make sure the message still registers as the same + string fixedArgsMessage = args.Message.Replace("\r\nThis is an unhandled exception from a task -- PLEASE OPEN A BUG AGAINST THE TASK OWNER.", String.Empty); + string fixedOtherMessage = other.Message.Replace("\r\nThis is an unhandled exception from a task -- PLEASE OPEN A BUG AGAINST THE TASK OWNER.", String.Empty); + + if (!String.Equals(fixedArgsMessage, fixedOtherMessage, StringComparison.OrdinalIgnoreCase)) + { + return false; + } } if (!String.Equals(args.SenderName, other.SenderName, StringComparison.OrdinalIgnoreCase)) diff --git a/src/Shared/UnitTests/MockEngine.cs b/src/Shared/UnitTests/MockEngine.cs index 87600c85231..fe229d5f992 100644 --- a/src/Shared/UnitTests/MockEngine.cs +++ b/src/Shared/UnitTests/MockEngine.cs @@ -26,7 +26,7 @@ namespace Microsoft.Build.UnitTests * is somewhat of a no-no for task assemblies. * **************************************************************************/ - sealed internal class MockEngine : IBuildEngine4 + sealed internal class MockEngine : IBuildEngine5 { private bool _isRunningMultipleNodes; private int _messages = 0; @@ -130,6 +130,26 @@ public void LogMessageEvent(BuildMessageEventArgs eventArgs) ++_messages; } + public void LogTelemetry(string eventName, IDictionary properties) + { + if (_logToConsole) + { + Console.WriteLine($"Received telemetry event '{eventName}'"); + } + _log += $"Received telemetry event '{eventName}'{Environment.NewLine}"; + if (properties != null) + { + foreach (string key in properties.Keys) + { + if (_logToConsole) + { + Console.WriteLine($" Property '{key}' = '{properties[key]}'{Environment.NewLine}"); + } + _log += $" Property '{key}' = '{properties[key]}'{Environment.NewLine}"; + } + } + } + public bool ContinueOnError { get diff --git a/src/Utilities/MuxLogger.cs b/src/Utilities/MuxLogger.cs index 972b2a8b5ef..a2a0448bd22 100644 --- a/src/Utilities/MuxLogger.cs +++ b/src/Utilities/MuxLogger.cs @@ -442,6 +442,12 @@ private class SubmissionRecord : /// Handle warning events /// private BuildWarningEventHandler _buildWarningEventHandler = null; + + /// + /// Handle telemetry events. + /// + private TelemetryEventHandler _telemetryEventHandler; + #endregion /// @@ -535,6 +541,11 @@ internal SubmissionRecord(int submissionId, IEventSource buildEventSource, Build /// public event AnyEventHandler AnyEventRaised; + /// + /// This event is raised when telemetry is sent. + /// + public event TelemetryEventHandler TelemetryLogged; + #endregion #region Internal Methods @@ -1239,6 +1250,37 @@ internal void RaiseAnyEvent(object sender, BuildEventArgs buildEvent) } } } + + /// + /// Raises a telemetry event to all registered loggers. + /// + internal void RaiseTelemetryEvent(object sender, TelemetryEventArgs buildEvent) + { + lock (_syncLock) + { + if (TelemetryLogged != null) + { + try + { + TelemetryLogged(sender, buildEvent); + } + catch (LoggerException) + { + // if a logger has failed politely, abort immediately + // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings + // if a fellow logger is throwing in an event handler. + this.UnregisterAllEventHandlers(); + throw; + } + catch (Exception) + { + // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings + // if a fellow logger is throwing in an event handler. + this.UnregisterAllEventHandlers(); + } + } + } + } #endregion #region private methods @@ -1261,6 +1303,7 @@ private void InitializeInternalEventSource() _taskFinishedEventHandler = new TaskFinishedEventHandler(RaiseTaskFinishedEvent); _taskStartedEventHandler = new TaskStartedEventHandler(RaiseTaskStartedEvent); _buildWarningEventHandler = new BuildWarningEventHandler(RaiseWarningEvent); + _telemetryEventHandler = new TelemetryEventHandler(RaiseTelemetryEvent); _eventSourceForBuild.AnyEventRaised += _anyEventHandler; _eventSourceForBuild.BuildFinished += _buildFinishedEventHandler; @@ -1276,6 +1319,7 @@ private void InitializeInternalEventSource() _eventSourceForBuild.TaskFinished += _taskFinishedEventHandler; _eventSourceForBuild.TaskStarted += _taskStartedEventHandler; _eventSourceForBuild.WarningRaised += _buildWarningEventHandler; + _eventSourceForBuild.TelemetryLogged += _telemetryEventHandler; } /// @@ -1297,6 +1341,7 @@ private void UnregisterAllEventHandlers() _eventSourceForBuild.TaskFinished -= _taskFinishedEventHandler; _eventSourceForBuild.TaskStarted -= _taskStartedEventHandler; _eventSourceForBuild.WarningRaised -= _buildWarningEventHandler; + _eventSourceForBuild.TelemetryLogged -= _telemetryEventHandler; MessageRaised = null; ErrorRaised = null; @@ -1312,6 +1357,7 @@ private void UnregisterAllEventHandlers() CustomEventRaised = null; StatusEventRaised = null; AnyEventRaised = null; + TelemetryLogged = null; } #endregion } diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs index 64f05fc4bd2..27d860553d4 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs @@ -86,6 +86,9 @@ public void Initialize(IEventSource eventSource) { ErrorUtilities.VerifyThrow(eventSource != null, "eventSource is null"); eventSource.AnyEventRaised += new AnyEventHandler(EventSource_AnyEventRaised); + + // Telemetry events aren't part of "all" so they need to be forwarded separately + eventSource.TelemetryLogged += EventSource_AnyEventRaised; } /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs index 65197c0499c..203cb423214 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs @@ -94,7 +94,11 @@ internal sealed class EventSourceSink : /// occurred. It is raised on every event. /// public event AnyEventHandler AnyEventRaised; - + + /// + /// This event is raised to log telemetry. + /// + public event TelemetryEventHandler TelemetryLogged; #endregion #region Properties @@ -205,6 +209,10 @@ public void Consume(BuildEventArgs buildEvent) { this.RaiseErrorEvent(null, (BuildErrorEventArgs)buildEvent); } + else if (buildEvent is TelemetryEventArgs) + { + this.RaiseTelemetryEvent(null, (TelemetryEventArgs) buildEvent); + } else { ErrorUtilities.VerifyThrow(false, "Unknown event args type."); @@ -241,6 +249,7 @@ internal void UnregisterAllEventHandlers() CustomEventRaised = null; StatusEventRaised = null; AnyEventRaised = null; + TelemetryLogged = null; } #endregion @@ -844,6 +853,41 @@ private void RaiseAnyEvent(object sender, BuildEventArgs buildEvent) } } + /// + /// Raises the a telemetry event to all registered loggers. + /// + private void RaiseTelemetryEvent(object sender, TelemetryEventArgs buildEvent) + { + if (TelemetryLogged != null) + { + try + { + TelemetryLogged(sender, buildEvent); + } + catch (LoggerException) + { + // if a logger has failed politely, abort immediately + // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings + // if a fellow logger is throwing in an event handler. + this.UnregisterAllEventHandlers(); + throw; + } + catch (Exception exception) + { + // first unregister all loggers, since other loggers may receive remaining events in unexpected orderings + // if a fellow logger is throwing in an event handler. + this.UnregisterAllEventHandlers(); + + if (ExceptionHandling.IsCriticalException(exception)) + { + throw; + } + + InternalLoggerException.Throw(exception, buildEvent, "FatalErrorWhileLogging", false); + } + } + } + #endregion #endregion } diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs index 0a60f456433..6aab65dfc10 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs @@ -401,6 +401,16 @@ bool RunningOnRemoteNode /// True of the task finished successfully, false otherwise. void LogTaskFinished(BuildEventContext taskBuildEventContext, string taskName, string projectFile, string projectFileOfTaskNode, bool success); #endregion + + #region Log telemetry + /// + /// Logs telemetry. + /// + /// The event context of the task which sent the telemetry. + /// The event name. + /// The list of properties associated with the event. + void LogTelemetry(BuildEventContext buildEventContext, string eventName, IDictionary properties); + #endregion } /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingServiceLogMethods.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingServiceLogMethods.cs index e623663d095..bdc63a7fdce 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingServiceLogMethods.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingServiceLogMethods.cs @@ -809,5 +809,32 @@ public void LogTaskFinished(BuildEventContext taskBuildEventContext, string task } #endregion + + #region Log telemetry + + /// + /// Logs a telemetry event. + /// + /// Event context information which describes who is logging the event + /// The event name. + /// The list of properties assocated with the event. + public void LogTelemetry(BuildEventContext buildEventContext, string eventName, IDictionary properties) + { + lock (_lockObject) + { + ErrorUtilities.VerifyThrow(eventName != null, "eventName is null"); + + TelemetryEventArgs telemetryEvent = new TelemetryEventArgs + { + BuildEventContext = buildEventContext, + EventName = eventName, + Properties = properties == null ? new Dictionary() : new Dictionary(properties) + }; + + ProcessLoggingEvent(telemetryEvent); + } + } + + #endregion } } diff --git a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs index 9cecf12cdfc..3a42166131f 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/RequestBuilder/TaskHost.cs @@ -37,7 +37,7 @@ internal class TaskHost : #if FEATURE_APPDOMAIN MarshalByRefObject, #endif - IBuildEngine4 + IBuildEngine5 { /// /// True if the "secret" environment variable MSBUILDNOINPROCNODE is set. @@ -615,6 +615,42 @@ public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime life #endregion + #region BuildEngine5 Members + + /// + /// Logs a telemetry event for the current task. + /// + /// The event name. + /// The list of properties associated with the event. + public void LogTelemetry(string eventName, IDictionary properties) + { + lock (_callbackMonitor) + { + ErrorUtilities.VerifyThrowArgumentNull(eventName, "eventName"); + + if (!_activeProxy) + { + // The task has been logging on another thread, typically + // because of logging a spawned process's output, and has + // not terminated this logging before it returned. This is common + // enough that we don't want to crash and break the entire build. But + // we don't have any good way to log it any more, as not only has this task + // finished, the whole build might have finished! The task author will + // just have to figure out that their task has a bug by themselves. + if (s_breakOnLogAfterTaskReturns) + { + Trace.Fail(String.Format(CultureInfo.CurrentUICulture, "Task at {0}, after already returning, attempted to log telemetry event '{1}'", _taskLocation.ToString(), eventName)); + } + + return; + } + + _taskLoggingContext.LoggingService.LogTelemetry(_taskLoggingContext.BuildEventContext, eventName, properties); + } + } + + #endregion + /// /// Called by the internal MSBuild task. /// Does not take the lock because it is called by another request builder thread. diff --git a/src/XMakeBuildEngine/Definition/ProjectCollection.cs b/src/XMakeBuildEngine/Definition/ProjectCollection.cs index fc45a894b1e..330fa65588c 100644 --- a/src/XMakeBuildEngine/Definition/ProjectCollection.cs +++ b/src/XMakeBuildEngine/Definition/ProjectCollection.cs @@ -1830,6 +1830,11 @@ internal class ReusableLogger : INodeLogger, IEventSource /// private BuildWarningEventHandler _buildWarningEventHandler; + /// + /// The telemetry event handler. + /// + private TelemetryEventHandler _telemetryEventHandler; + /// /// Constructor. /// @@ -1911,6 +1916,11 @@ public ReusableLogger(ILogger originalLogger) /// public event AnyEventHandler AnyEventRaised; + /// + /// The telemetry sent event. + /// + public event TelemetryEventHandler TelemetryLogged; + #endregion #region ILogger Members @@ -2027,6 +2037,7 @@ private void RegisterForEvents(IEventSource eventSource) _taskFinishedEventHandler = new TaskFinishedEventHandler(TaskFinishedHandler); _taskStartedEventHandler = new TaskStartedEventHandler(TaskStartedHandler); _buildWarningEventHandler = new BuildWarningEventHandler(WarningRaisedHandler); + _telemetryEventHandler = new TelemetryEventHandler(TelemetryLoggedHandler); // Register for the events. eventSource.AnyEventRaised += _anyEventHandler; @@ -2043,6 +2054,7 @@ private void RegisterForEvents(IEventSource eventSource) eventSource.TaskFinished += _taskFinishedEventHandler; eventSource.TaskStarted += _taskStartedEventHandler; eventSource.WarningRaised += _buildWarningEventHandler; + eventSource.TelemetryLogged += _telemetryEventHandler; } /// @@ -2065,6 +2077,7 @@ private void UnregisterForEvents(IEventSource eventSource) eventSource.TaskFinished -= _taskFinishedEventHandler; eventSource.TaskStarted -= _taskStartedEventHandler; eventSource.WarningRaised -= _buildWarningEventHandler; + eventSource.TelemetryLogged -= _telemetryEventHandler; // Null out the handlers. _anyEventHandler = null; @@ -2081,6 +2094,7 @@ private void UnregisterForEvents(IEventSource eventSource) _taskFinishedEventHandler = null; _taskStartedEventHandler = null; _buildWarningEventHandler = null; + _telemetryEventHandler = null; } /// @@ -2236,6 +2250,17 @@ private void AnyEventRaisedHandler(object sender, BuildEventArgs e) AnyEventRaised(sender, e); } } + + /// + /// Handler for telemetry events. + /// + private void TelemetryLoggedHandler(object sender, TelemetryEventArgs e) + { + if (TelemetryLogged != null) + { + TelemetryLogged(sender, e); + } + } } /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs index 6d0369b1dd7..b2cd1734636 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs @@ -18,6 +18,7 @@ using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Xml; using MockHost = Microsoft.Build.UnitTests.BackEnd.MockHost; @@ -1116,6 +1117,71 @@ public void TargetFinishedNullTargetName() #endregion + #region LogTelemetry + + /// + /// Verifies an InternalErrorException is thrown when a null event name is passed in + /// + [Fact] + public void LogTelemetryNullEventName() + { + InternalErrorException exception = Assert.Throws(() => + { + ProcessBuildEventHelper service = (ProcessBuildEventHelper)ProcessBuildEventHelper.CreateLoggingService(LoggerMode.Synchronous, 1); + service.LogTelemetry( + buildEventContext: null, + eventName: null, + properties: new Dictionary());; + }); + + Assert.True(exception.Message.Contains("eventName is null")); + } + + [Fact] + public void LogTelemetryTest() + { + IDictionary eventProperties = new Dictionary + { + {"Property1", "Value1"}, + {"Property2", "347EA055D5BD405F9726D7429BB30244"}, + {"Property3", @"C:\asdf\asdf\asdf"}, + }; + + TestLogTelemetry(buildEventContext: null, eventName: "no context and no properties", properties: null); + TestLogTelemetry(buildEventContext: null, eventName: "no context but with properties", properties: eventProperties); + TestLogTelemetry(buildEventContext: s_buildEventContext, eventName: "event context but no properties", properties: null); + TestLogTelemetry(buildEventContext: s_buildEventContext, eventName: "event context and properties", properties: eventProperties); + } + + private void TestLogTelemetry(BuildEventContext buildEventContext, string eventName, IDictionary properties) + { + ProcessBuildEventHelper service = (ProcessBuildEventHelper)ProcessBuildEventHelper.CreateLoggingService(LoggerMode.Synchronous, 1); + + service.LogTelemetry(buildEventContext, eventName, properties); + + TelemetryEventArgs expectedEventArgs = new TelemetryEventArgs + { + EventName = eventName, + BuildEventContext = buildEventContext, + Properties = properties == null ? new Dictionary() : new Dictionary(properties), + }; + + + TelemetryEventArgs actualEventArgs = (TelemetryEventArgs)service.ProcessedBuildEvent; + + Assert.Equal(expectedEventArgs.EventName, actualEventArgs.EventName); + Assert.Equal(expectedEventArgs.Properties.OrderBy(kvp => kvp.Key, StringComparer.Ordinal), actualEventArgs.Properties.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase)); + Assert.Equal(expectedEventArgs.BuildEventContext, actualEventArgs.BuildEventContext); + + if (properties != null) + { + // Ensure the properties were cloned into a new dictionary + Assert.False(Object.ReferenceEquals(actualEventArgs.Properties, properties)); + } + } + + #endregion + #region Private methods /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs index f3a9773ad0f..7ec91aa0fa6 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs @@ -465,6 +465,16 @@ public void LogTaskFinished(BuildEventContext taskBuildEventContext, string task { } + /// + /// Logs a telemetry event. + /// + /// The task's build event context + /// The event name. + /// The list of properties associated with the event. + public void LogTelemetry(BuildEventContext buildEventContext, string eventName, IDictionary properties) + { + } + #endregion } } diff --git a/src/XMakeCommandLine/Microsoft.Build.CommonTypes.xsd b/src/XMakeCommandLine/Microsoft.Build.CommonTypes.xsd index a8fb6c5662e..20ac01fdfeb 100644 --- a/src/XMakeCommandLine/Microsoft.Build.CommonTypes.xsd +++ b/src/XMakeCommandLine/Microsoft.Build.CommonTypes.xsd @@ -2412,6 +2412,16 @@ elementFormDefault="qualified"> + + + + + + + + + + diff --git a/src/XMakeCommandLine/OutOfProcTaskHostNode.cs b/src/XMakeCommandLine/OutOfProcTaskHostNode.cs index c5c238e11c2..d303c577a10 100644 --- a/src/XMakeCommandLine/OutOfProcTaskHostNode.cs +++ b/src/XMakeCommandLine/OutOfProcTaskHostNode.cs @@ -40,7 +40,7 @@ internal class OutOfProcTaskHostNode : #if CLR2COMPATIBILITY IBuildEngine3 #else - IBuildEngine4 + IBuildEngine5 #endif { /// @@ -442,6 +442,25 @@ public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime life } #endregion + + #region IBuildEngine5 Implementation + + /// + /// Logs a telemetry event. + /// + /// The event name. + /// The list of properties associated with the event. + public void LogTelemetry(string eventName, IDictionary properties) + { + SendBuildEvent(new TelemetryEventArgs + { + EventName = eventName, + Properties = properties == null ? new Dictionary() : new Dictionary(properties), + }); + } + + #endregion + #endif #region INodePacketFactory Members diff --git a/src/XMakeTasks/Microsoft.Build.Tasks.csproj b/src/XMakeTasks/Microsoft.Build.Tasks.csproj index 94ac71d5f62..84b06e73a02 100644 --- a/src/XMakeTasks/Microsoft.Build.Tasks.csproj +++ b/src/XMakeTasks/Microsoft.Build.Tasks.csproj @@ -1,4 +1,4 @@ - + PreserveNewest @@ -981,4 +981,4 @@ - + \ No newline at end of file diff --git a/src/XMakeTasks/Microsoft.Common.tasks b/src/XMakeTasks/Microsoft.Common.tasks index 984156c5774..95abae2481d 100644 --- a/src/XMakeTasks/Microsoft.Common.tasks +++ b/src/XMakeTasks/Microsoft.Common.tasks @@ -152,6 +152,7 @@ + diff --git a/src/XMakeTasks/Resources/Strings.resx b/src/XMakeTasks/Resources/Strings.resx index 243279294d5..0daa5f8c5c1 100644 --- a/src/XMakeTasks/Resources/Strings.resx +++ b/src/XMakeTasks/Resources/Strings.resx @@ -2606,7 +2606,16 @@ MSB3891: Both "{0}" and "{1}" were specified in the project file. Please choose one or the other. - + + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + - - + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.CSharp.DesignTime.targets + + diff --git a/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets b/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets index bf0771d3f32..84ddc431cea 100644 --- a/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets @@ -319,6 +319,13 @@ Copyright (C) Microsoft Corporation. All rights reserved. + + + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.CSharp.DesignTime.targets + + @@ -361,12 +368,6 @@ using System.Reflection%3b <_ExplicitReference Include="$(FrameworkPathOverride)\mscorlib.dll" /> - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.CSharp.DesignTime.targets - - - diff --git a/src/XMakeTasks/Microsoft.VisualBasic.CrossTargeting.targets b/src/XMakeTasks/Microsoft.VisualBasic.CrossTargeting.targets index 97a9952ae78..e0c0b18d373 100644 --- a/src/XMakeTasks/Microsoft.VisualBasic.CrossTargeting.targets +++ b/src/XMakeTasks/Microsoft.VisualBasic.CrossTargeting.targets @@ -11,13 +11,14 @@ Copyright (C) Microsoft Corporation. All rights reserved. --> - - + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.VisualBasic.DesignTime.targets + + diff --git a/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets b/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets index 59eefe574a8..2119f41506f 100644 --- a/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets @@ -320,6 +320,13 @@ Copyright (C) Microsoft Corporation. All rights reserved. + + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.VisualBasic.DesignTime.targets + + + @@ -364,12 +371,6 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_ExplicitReference Include="$(FrameworkPathOverride)\System.dll" /> - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.VisualBasic.DesignTime.targets - - - From 1891875e910e45434999fcc3e7746ac47e11ea2e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 26 Oct 2016 18:25:23 -0700 Subject: [PATCH 026/223] ToolLocationHelper.GetSDKContentFolderPath() in ref assembly (#1263) --- .../Microsoft.Build.Utilities.Core.cs | 1 + .../Microsoft.Build.Utilities.Core.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index 0cac78593ed..25675e7c6cb 100644 --- a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -488,6 +488,7 @@ public static void ClearSDKStaticCache() { } public static System.Collections.Generic.IEnumerable GetPlatformsForSDK(string sdkIdentifier, System.Version sdkVersion) { throw null; } public static System.Collections.Generic.IEnumerable GetPlatformsForSDK(string sdkIdentifier, System.Version sdkVersion, string[] diskRoots, string registryRoot) { throw null; } public static string GetProgramFilesReferenceAssemblyRoot() { throw null; } + public static string GetSDKContentFolderPath(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion, string folderName, string diskRoot=null) { throw null; } public static System.Collections.Generic.IList GetSDKDesignTimeFolders(string sdkRoot) { throw null; } public static System.Collections.Generic.IList GetSDKDesignTimeFolders(string sdkRoot, string targetConfiguration, string targetArchitecture) { throw null; } public static System.Collections.Generic.IList GetSDKRedistFolders(string sdkRoot) { throw null; } diff --git a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index c36e608a5c4..3a97ad00019 100644 --- a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -328,6 +328,7 @@ public static void ClearSDKStaticCache() { } public static System.Collections.Generic.IEnumerable GetPlatformsForSDK(string sdkIdentifier, System.Version sdkVersion) { throw null; } public static System.Collections.Generic.IEnumerable GetPlatformsForSDK(string sdkIdentifier, System.Version sdkVersion, string[] diskRoots, string registryRoot) { throw null; } public static string GetProgramFilesReferenceAssemblyRoot() { throw null; } + public static string GetSDKContentFolderPath(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion, string folderName, string diskRoot=null) { throw null; } public static System.Collections.Generic.IList GetSDKDesignTimeFolders(string sdkRoot) { throw null; } public static System.Collections.Generic.IList GetSDKDesignTimeFolders(string sdkRoot, string targetConfiguration, string targetArchitecture) { throw null; } public static System.Collections.Generic.IList GetSDKRedistFolders(string sdkRoot) { throw null; } From ea10cf4ebdf4f5435c88ad4b7052aae350b53816 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 26 Oct 2016 20:27:44 -0500 Subject: [PATCH 027/223] CPS and Roslyn project system GUIDs (#1252) ... are known to be MSBuild format, so treat them as such. Fixes #1237. --- src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs b/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs index 174507e51b4..57590459f12 100644 --- a/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs +++ b/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs @@ -70,6 +70,9 @@ public sealed class SolutionFile private const string vbProjectGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; private const string csProjectGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; + private const string cpsProjectGuid = "{13B669BE-BB05-4DDF-9536-439F39A36129}"; + private const string cpsCsProjectGuid = "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"; + private const string cpsVbProjectGuid = "{778DAE3C-4631-46EA-AA77-85C1314464D9}"; private const string vjProjectGuid = "{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}"; private const string vcProjectGuid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; private const string fsProjectGuid = "{F2A71F9B-5D33-465A-A702-920D77279786}"; @@ -1261,6 +1264,9 @@ ProjectInSolution proj // Figure out what type of project this is. if ((String.Compare(projectTypeGuid, vbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, csProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsCsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsVbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, fsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, dbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, vjProjectGuid, StringComparison.OrdinalIgnoreCase) == 0)) From 53ee3bf2cb7ef63b30c794af287338f0e879beda Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Wed, 26 Oct 2016 19:20:00 -0700 Subject: [PATCH 028/223] Automated commit of revision number value 00070. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index cbe54761421..3b510075fd6 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00069 + 00070 \ No newline at end of file From afa5981e61b51b9caecedf051586afc267885681 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Wed, 26 Oct 2016 19:27:05 -0700 Subject: [PATCH 029/223] Automated commit of revision number value 00071. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 3b510075fd6..c57fecaa694 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00070 + 00071 \ No newline at end of file From 451b53816ed45d01fc2c96e779977083e234fdfb Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 26 Oct 2016 21:30:54 -0500 Subject: [PATCH 030/223] CPS and Roslyn project system GUIDs (#1266) ... are known to be MSBuild format, so treat them as such. Fixes #1237. --- src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs b/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs index 48bf37ddc2b..f15853b1eea 100644 --- a/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs +++ b/src/XMakeBuildEngine/Construction/Solution/SolutionFile.cs @@ -70,6 +70,9 @@ public sealed class SolutionFile private const string vbProjectGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; private const string csProjectGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; + private const string cpsProjectGuid = "{13B669BE-BB05-4DDF-9536-439F39A36129}"; + private const string cpsCsProjectGuid = "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"; + private const string cpsVbProjectGuid = "{778DAE3C-4631-46EA-AA77-85C1314464D9}"; private const string vjProjectGuid = "{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}"; private const string vcProjectGuid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; private const string fsProjectGuid = "{F2A71F9B-5D33-465A-A702-920D77279786}"; @@ -1261,6 +1264,9 @@ ProjectInSolution proj // Figure out what type of project this is. if ((String.Compare(projectTypeGuid, vbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, csProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsCsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || + (String.Compare(projectTypeGuid, cpsVbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, fsProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, dbProjectGuid, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(projectTypeGuid, vjProjectGuid, StringComparison.OrdinalIgnoreCase) == 0)) From 2964bfe9e8494f909740f29d9f3509ef962bb56d Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Thu, 27 Oct 2016 10:27:23 -0700 Subject: [PATCH 031/223] The first child of a container computes whitespace based on parent indentation (#1264) fixes #1242 --- .../Construction/ProjectElementContainer.cs | 54 ++-- .../WhiteSpacePreservation_Tests.cs | 290 ++++++++++++++++++ ...Microsoft.Build.Engine.OM.UnitTests.csproj | 1 + 3 files changed, 321 insertions(+), 24 deletions(-) create mode 100644 src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index 00256d659f9..6a63ab89084 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -521,38 +521,44 @@ internal void AddToXml(ProjectElement child) if (XmlDocument.PreserveWhitespace) { - // Try to match the surrounding formatting and add one indentation level + // If the empty parent has whitespace in it, delete it if (XmlElement.FirstChild.NodeType == XmlNodeType.Whitespace) { - // This container had a whitespace node, which should generally be a newline and the indent - // before the closing tag. So we add the default indentation to it so the child will now be indented - // further, and then create a new whitespace node after the child so the closing tag will be on - // a new line with the same indentation. - // If the whitespace we end up copying isn't actually (newline + indentation) like we expect, then it - // should still be OK to copy it, as we'll still be trying to match the surrounding formatting. - string whitespace = XmlElement.FirstChild.Value; - XmlElement.FirstChild.Value = whitespace + DEFAULT_INDENT; - var newWhitespaceNode = XmlDocument.CreateWhitespace(whitespace); - XmlElement.InsertAfter(newWhitespaceNode, child.XmlElement); - } - else if (XmlElement.PreviousSibling != null && - XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace) - { - // This container didn't have any whitespace in it. This probably means it didn't have separate open - // and close tags. So add a whitespace node before the new child with additional indentation over the - // container's indentation, and add a whitespace node with the same level of indentation as the container - // after the new child so the closing tag will be indented properly. - string parentWhitespace = XmlElement.PreviousSibling.Value; - var indentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace + DEFAULT_INDENT); - XmlElement.InsertBefore(indentedWhitespaceNode, child.XmlElement); - var unindentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace); - XmlElement.InsertAfter(unindentedWhitespaceNode, child.XmlElement); + XmlElement.RemoveChild(XmlElement.FirstChild); } + + var parentIndentation = GetElementIndentation(XmlElement); + + var leadingWhitespaceNode = XmlDocument.CreateWhitespace("\n" + parentIndentation + DEFAULT_INDENT); + var trailingWhiteSpaceNode = XmlDocument.CreateWhitespace("\n" + parentIndentation); + + XmlElement.InsertBefore(leadingWhitespaceNode, child.XmlElement); + XmlElement.InsertAfter(trailingWhiteSpaceNode, child.XmlElement); } } } } + private string GetElementIndentation(XmlElementWithLocation xmlElement) + { + if (xmlElement.PreviousSibling?.NodeType != XmlNodeType.Whitespace) + { + return string.Empty; + } + + var leadingWhiteSpace = xmlElement.PreviousSibling.Value; + + var lastIndexOfNewLine = leadingWhiteSpace.LastIndexOf("\n", StringComparison.Ordinal); + + if (lastIndexOfNewLine == -1) + { + return string.Empty; + } + + // the last newline is not included in the indentation, only what comes after it + return leadingWhiteSpace.Substring(lastIndexOfNewLine + 1); + } + internal void RemoveFromXml(ProjectElement child) { if (child.ExpressedAsAttribute) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs new file mode 100644 index 00000000000..480010dba0f --- /dev/null +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs @@ -0,0 +1,290 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +//----------------------------------------------------------------------- +// +// Test white space preservation. +//----------------------------------------------------------------------- + +using System; +using System.IO; +using System.Xml; +using Microsoft.Build.Construction; + +using Xunit; +using System.Linq; +using Microsoft.Build.Evaluation; + + +namespace Microsoft.Build.UnitTests.OM.Construction +{ + public class WhitespacePreservation_Tests + { + [Theory] + [InlineData( +@" +", + +@" + +")] + + [InlineData( +@" + + +", + +@" + +")] + public void AddEmptyParent(string projectContents, string updatedProject) + { + AssertWhiteSpacePreservation(projectContents, updatedProject, (pe, p) => + { + var itemGroup = pe.AddItemGroup(); + + Assert.True(p.IsDirty); + }); + } + + [Theory] + [InlineData( +@" + + + + + +", + +@" + + + + + + + + + +")] + [InlineData( +@" + + + + + + + + + +", + +@" + + + + + + + + + + + + + + +")] + public void AddParentAndChild(string projectContents, string updatedProject) + { + AssertWhiteSpacePreservation(projectContents, updatedProject, (pe, p) => + { + var itemGroup = pe.AddItemGroup(); + + itemGroup.AddItem("i2", "b"); + + Assert.True(p.IsDirty); + }); + } + + [Theory] + + // no new lines are added + [InlineData( +@" + + + + + +", + +@" + + + + + + +")] + + // new lines between parents are preserved + [InlineData( +@" + + + + + + + + + + +", + +@" + + + + + + + + + + + +")] + + // parent has no indentation but has leading whitespace. Indentation is the whitespace after the last new line in the parent's entire leading whitespace + [InlineData( +@" + + + + + + +", + +@" + + + + + + + +")] + + // parent has no leading whitespace + [InlineData( +@" + + + + + + +", + +@" + + + + + + + +")] + + // empty parent has no whitespace in it; append new line and the parent's indentation + [InlineData( +@" + + + + + + + +", + +@" + + + + + + + + + +")] + + // the initial whitespace in the empty parent gets replaced with newline + parent_indentation + [InlineData( +@" + + + + + + + + + + + + +", + +@" + + + + + + + + + +")] + public void AddFirstChildInExistingParent(string projectContents, string updatedProject) + { + AssertWhiteSpacePreservation(projectContents, updatedProject, + (pe, p) => { pe.ItemGroups.ElementAt(1).AddItem("i2", "b"); }); + } + + private void AssertWhiteSpacePreservation(string projectContents, string updatedProject, + Action act) + { + var projectElement = + ProjectRootElement.Create( + XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(projectContents))), + ProjectCollection.GlobalProjectCollection, + true); + + var project = new Project(projectElement); + + act(projectElement, project); + + var writer = new StringWriter(); + project.Save(writer); + + var expected = @"" + + ObjectModelHelpers.CleanupFileContents(updatedProject); + var actual = writer.ToString(); + + VerifyAssertLineByLine(expected, actual); + } + + private void VerifyAssertLineByLine(string expected, string actual) + { + Helpers.VerifyAssertLineByLine(expected, actual, false); + } + } +} diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj index 1f57f4ff9d4..78a5dae8f39 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj @@ -85,6 +85,7 @@ + From 77f17241dd1af61b0a2d2ad189069edd861057cf Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 27 Oct 2016 11:23:21 -0700 Subject: [PATCH 032/223] Add stream buffering for named pipe reads (#1227) --- src/Shared/BufferedReadStream.cs | 153 ++++++++++++++++++ src/Shared/NodeEndpointOutOfProcBase.cs | 59 ++++--- .../NodeProviderOutOfProcBase.cs | 15 +- src/XMakeBuildEngine/Microsoft.Build.csproj | 1 + src/XMakeCommandLine/MSBuild.csproj | 1 + .../MSBuildTaskHost/MSBuildTaskHost.csproj | 1 + 6 files changed, 198 insertions(+), 32 deletions(-) create mode 100644 src/Shared/BufferedReadStream.cs diff --git a/src/Shared/BufferedReadStream.cs b/src/Shared/BufferedReadStream.cs new file mode 100644 index 00000000000..8bb8cdd6872 --- /dev/null +++ b/src/Shared/BufferedReadStream.cs @@ -0,0 +1,153 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +//----------------------------------------------------------------------- +// +//----------------------------------------------------------------------- + +using System; +using System.IO; + +namespace Microsoft.Build.BackEnd +{ + internal class BufferedReadStream : Stream + { + const int BUFFER_SIZE = 1024; + + Stream _innerStream; + byte[] _buffer; + + // The number of bytes in the buffer that have been read from the underlying stream but not read by consumers of this stream + int _currentlyBufferedByteCount; + + int _currentIndexInBuffer; + + public BufferedReadStream(Stream innerStream) + { + _innerStream = innerStream; + _buffer = new byte[BUFFER_SIZE]; + + _currentlyBufferedByteCount = 0; + } + + public override bool CanRead { get { return _innerStream.CanRead; } } + + public override bool CanSeek { get { return false; } } + + public override bool CanWrite { get { return _innerStream.CanWrite; } } + + public override long Length { get { return _innerStream.Length; } } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override void Flush() + { + _innerStream.Flush(); + } + + public override int ReadByte() + { + if (_currentlyBufferedByteCount > 0) + { + int ret = _buffer[_currentIndexInBuffer]; + _currentIndexInBuffer++; + _currentlyBufferedByteCount--; + return ret; + } + else + { + // Let the base class handle it, which will end up calling the Read() method + return base.ReadByte(); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (count > BUFFER_SIZE) + { + // Trying to read more data than the buffer can hold + int alreadyCopied = 0; + if (_currentlyBufferedByteCount > 0) + { + Array.Copy(_buffer, _currentIndexInBuffer, buffer, offset, _currentlyBufferedByteCount); + alreadyCopied = _currentlyBufferedByteCount; + _currentIndexInBuffer = 0; + _currentlyBufferedByteCount = 0; + } + int innerReadCount = _innerStream.Read(buffer, offset + alreadyCopied, count - alreadyCopied); + return innerReadCount + alreadyCopied; + } + else if (count <= _currentlyBufferedByteCount) + { + // Enough data buffered to satisfy read request + Array.Copy(_buffer, _currentIndexInBuffer, buffer, offset, count); + _currentIndexInBuffer += count; + _currentlyBufferedByteCount -= count; + return count; + } + else + { + // Need to read more data + int alreadyCopied = 0; + if (_currentlyBufferedByteCount > 0) + { + Array.Copy(_buffer, _currentIndexInBuffer, buffer, offset, _currentlyBufferedByteCount); + alreadyCopied = _currentlyBufferedByteCount; + _currentIndexInBuffer = 0; + _currentlyBufferedByteCount = 0; + } + + int innerReadCount = _innerStream.Read(_buffer, 0, BUFFER_SIZE); + _currentIndexInBuffer = 0; + _currentlyBufferedByteCount = innerReadCount; + + int remainingCopyCount; + + if (alreadyCopied + innerReadCount >= count) + { + remainingCopyCount = count - alreadyCopied; + } + else + { + remainingCopyCount = innerReadCount; + } + + Array.Copy(_buffer, 0, buffer, offset + alreadyCopied, remainingCopyCount); + _currentIndexInBuffer += remainingCopyCount; + _currentlyBufferedByteCount -= remainingCopyCount; + + return alreadyCopied + remainingCopyCount; + } + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + _innerStream.Write(buffer, offset, count); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _innerStream.Dispose(); + } + + base.Dispose(disposing); + } + + + } +} diff --git a/src/Shared/NodeEndpointOutOfProcBase.cs b/src/Shared/NodeEndpointOutOfProcBase.cs index ad61c6ddf80..54529e2a714 100644 --- a/src/Shared/NodeEndpointOutOfProcBase.cs +++ b/src/Shared/NodeEndpointOutOfProcBase.cs @@ -507,6 +507,36 @@ private void PacketPumpProc() localWritePipe.WriteLongForHandshake(GetClientHandshake()); ChangeLinkStatus(LinkStatus.Active); + RunReadLoop( + new BufferedReadStream(localReadPipe), + localWritePipe, + localPacketQueue, localPacketAvailable, localTerminatePacketPump); + + CommunicationsUtilities.Trace("Ending read loop"); + + try + { +#if FEATURE_NAMED_PIPES_FULL_DUPLEX + if (localPipeServer.IsConnected) + { + localPipeServer.WaitForPipeDrain(); + localPipeServer.Disconnect(); + } +#else + localReadPipe.Dispose(); + localWritePipe.WaitForPipeDrain(); + localWritePipe.Dispose(); +#endif + } + catch (Exception) + { + // We don't really care if Disconnect somehow fails, but it gives us a chance to do the right thing. + } + } + + private void RunReadLoop(Stream localReadPipe, Stream localWritePipe, + Queue localPacketQueue, AutoResetEvent localPacketAvailable, AutoResetEvent localTerminatePacketPump) + { // Ordering of the wait handles is important. The first signalled wait handle in the array // will be returned by WaitAny if multiple wait handles are signalled. We prefer to have the // terminate event triggered so that we cannot get into a situation where packets are being @@ -514,7 +544,7 @@ private void PacketPumpProc() CommunicationsUtilities.Trace("Entering read loop."); byte[] headerByte = new byte[5]; #if FEATURE_APM - IAsyncResult result = localPipeServer.BeginRead(headerByte, 0, headerByte.Length, null, null); + IAsyncResult result = localReadPipe.BeginRead(headerByte, 0, headerByte.Length, null, null); #else Task readTask = CommunicationsUtilities.ReadAsync(localReadPipe, headerByte, headerByte.Length); #endif @@ -541,7 +571,7 @@ private void PacketPumpProc() try { #if FEATURE_APM - bytesRead = localPipeServer.EndRead(result); + bytesRead = localReadPipe.EndRead(result); #else bytesRead = readTask.Result; #endif @@ -591,7 +621,7 @@ private void PacketPumpProc() } #if FEATURE_APM - result = localPipeServer.BeginRead(headerByte, 0, headerByte.Length, null, null); + result = localReadPipe.BeginRead(headerByte, 0, headerByte.Length, null, null); #else readTask = CommunicationsUtilities.ReadAsync(localReadPipe, headerByte, headerByte.Length); #endif @@ -630,7 +660,7 @@ private void PacketPumpProc() packetStream.Write(BitConverter.GetBytes((int)packetStream.Length - 5), 0, 4); #if FEATURE_MEMORYSTREAM_GETBUFFER - localPipeServer.Write(packetStream.GetBuffer(), 0, (int)packetStream.Length); + localWritePipe.Write(packetStream.GetBuffer(), 0, (int)packetStream.Length); #else ArraySegment packetStreamBuffer; if (packetStream.TryGetBuffer(out packetStreamBuffer)) @@ -671,27 +701,6 @@ private void PacketPumpProc() } } while (!exitLoop); - - CommunicationsUtilities.Trace("Ending read loop"); - - try - { -#if FEATURE_NAMED_PIPES_FULL_DUPLEX - if (localPipeServer.IsConnected) - { - localPipeServer.WaitForPipeDrain(); - localPipeServer.Disconnect(); - } -#else - localReadPipe.Dispose(); - localWritePipe.WaitForPipeDrain(); - localWritePipe.Dispose(); -#endif - } - catch (Exception) - { - // We don't really care if Disconnect somehow fails, but it gives us a chance to do the right thing. - } } #endregion diff --git a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs index bb1426b39d6..e3827974237 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs @@ -136,7 +136,8 @@ protected void ShutdownAllNodes(long hostHandshake, long clientHandshake, NodeCo // For all processes in the list, send signal to terminate if able to connect foreach (Process nodeProcess in nodeProcesses) { - NamedPipeClientStream nodeStream = TryConnectToProcess(nodeProcess.Id, 30/*verified to miss nodes if smaller*/, hostHandshake, clientHandshake); + Stream nodeStream = TryConnectToProcess(nodeProcess.Id, 30/*verified to miss nodes if smaller*/, hostHandshake, clientHandshake); + if (null != nodeStream) { // If we're able to connect to such a process, send a packet requesting its termination @@ -219,7 +220,7 @@ protected NodeContext GetNode(string msbuildLocation, string commandLineArgs, in _processesToIgnore.Add(nodeLookupKey); // Attempt to connect to each process in turn. - NamedPipeClientStream nodeStream = TryConnectToProcess(nodeProcess.Id, 0 /* poll, don't wait for connections */, hostHandshake, clientHandshake); + Stream nodeStream = TryConnectToProcess(nodeProcess.Id, 0 /* poll, don't wait for connections */, hostHandshake, clientHandshake); if (nodeStream != null) { // Connection successful, use this node. @@ -276,7 +277,7 @@ protected NodeContext GetNode(string msbuildLocation, string commandLineArgs, in // to the debugger process. Instead, use MSBUILDDEBUGONSTART=1 // Now try to connect to it. - NamedPipeClientStream nodeStream = TryConnectToProcess(msbuildProcessId, TimeoutForNewNodeCreation, hostHandshake, clientHandshake); + Stream nodeStream = TryConnectToProcess(msbuildProcessId, TimeoutForNewNodeCreation, hostHandshake, clientHandshake); if (nodeStream != null) { // Connection successful, use this node. @@ -335,7 +336,7 @@ private void ValidateRemotePipeSecurityOnWindows(NamedPipeClientStream nodeStrea /// /// Attempts to connect to the specified process. /// - private NamedPipeClientStream TryConnectToProcess(int nodeProcessId, int timeout, long hostHandshake, long clientHandshake) + private Stream TryConnectToProcess(int nodeProcessId, int timeout, long hostHandshake, long clientHandshake) { // Try and connect to the process. string pipeName = "MSBuild" + nodeProcessId; @@ -572,8 +573,8 @@ internal class NodeContext private static bool s_trace = String.Equals(Environment.GetEnvironmentVariable("MSBUILDDEBUGCOMM"), "1", StringComparison.Ordinal); // The pipe(s) used to communicate with the node. - private PipeStream _clientToServerStream; - private PipeStream _serverToClientStream; + private Stream _clientToServerStream; + private Stream _serverToClientStream; /// /// The factory used to create packets from data read off the pipe. @@ -620,7 +621,7 @@ internal class NodeContext /// public NodeContext(int nodeId, int processId, #if FEATURE_NAMED_PIPES_FULL_DUPLEX - NamedPipeClientStream nodePipe, + Stream nodePipe, #else AnonymousPipeServerStream clientToServerStream, AnonymousPipeServerStream serverToClientStream, diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index c15bbbb97f7..c42f2e705b0 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -137,6 +137,7 @@ True + diff --git a/src/XMakeCommandLine/MSBuild.csproj b/src/XMakeCommandLine/MSBuild.csproj index ece7a07779e..a597bf2538e 100644 --- a/src/XMakeCommandLine/MSBuild.csproj +++ b/src/XMakeCommandLine/MSBuild.csproj @@ -99,6 +99,7 @@ true + diff --git a/src/XMakeCommandLine/MSBuildTaskHost/MSBuildTaskHost.csproj b/src/XMakeCommandLine/MSBuildTaskHost/MSBuildTaskHost.csproj index b84d16897d4..82c873badf4 100644 --- a/src/XMakeCommandLine/MSBuildTaskHost/MSBuildTaskHost.csproj +++ b/src/XMakeCommandLine/MSBuildTaskHost/MSBuildTaskHost.csproj @@ -57,6 +57,7 @@ ITaskItem2.cs + CopyOnWriteDictionary.cs From 5515766ccafaf9d8debd9e0e4afd99bf5f112780 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 27 Oct 2016 11:31:36 -0700 Subject: [PATCH 033/223] Introduce IEventSource2 to not break usages of IEventSource (#1261) We can still improve on this by having an ILogger2 and update Logger but this will keep the telemetry stuff in without breaking people who implement IEventSource. --- src/Framework/IEventSource.cs | 10 -------- src/Framework/IEventSource2.cs | 23 +++++++++++++++++++ .../Microsoft.Build.Framework.csproj | 1 + src/OrcasEngine/Engine/EventSource.cs | 6 ----- src/Utilities/MuxLogger.cs | 16 ++++++++++--- src/Utilities/Task.cs | 11 +++++++++ .../Logging/CentralForwardingLogger.cs | 8 +++++-- .../Components/Logging/EventSourceSink.cs | 2 +- .../Definition/ProjectCollection.cs | 16 ++++++++++--- 9 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 src/Framework/IEventSource2.cs diff --git a/src/Framework/IEventSource.cs b/src/Framework/IEventSource.cs index 0f18ed337c9..4a5fe15d043 100644 --- a/src/Framework/IEventSource.cs +++ b/src/Framework/IEventSource.cs @@ -75,11 +75,6 @@ namespace Microsoft.Build.Framework /// public delegate void AnyEventHandler(object sender, BuildEventArgs e); - /// - /// Type of handler for TelemetryLogged events - /// - public delegate void TelemetryEventHandler(object sender, TelemetryEventArgs e); - /// /// This interface defines the events raised by the build engine. /// Loggers use this interface to subscribe to the events they @@ -156,10 +151,5 @@ public interface IEventSource /// this event is raised to log any build event. These events do not include telemetry. To receive telemetry, you must attach to the event. /// event AnyEventHandler AnyEventRaised; - - /// - /// this event is raised to when telemetry is logged. - /// - event TelemetryEventHandler TelemetryLogged; } } diff --git a/src/Framework/IEventSource2.cs b/src/Framework/IEventSource2.cs new file mode 100644 index 00000000000..9c289611c0c --- /dev/null +++ b/src/Framework/IEventSource2.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Build.Framework +{ + /// + /// Type of handler for TelemetryLogged events + /// + public delegate void TelemetryEventHandler(object sender, TelemetryEventArgs e); + + /// + /// This interface defines the events raised by the build engine. + /// Loggers use this interface to subscribe to the events they + /// are interested in receiving. + /// + public interface IEventSource2 : IEventSource + { + /// + /// this event is raised to when telemetry is logged. + /// + event TelemetryEventHandler TelemetryLogged; + } +} diff --git a/src/Framework/Microsoft.Build.Framework.csproj b/src/Framework/Microsoft.Build.Framework.csproj index b731d51a2cb..b28ee6a8988 100644 --- a/src/Framework/Microsoft.Build.Framework.csproj +++ b/src/Framework/Microsoft.Build.Framework.csproj @@ -61,6 +61,7 @@ + diff --git a/src/OrcasEngine/Engine/EventSource.cs b/src/OrcasEngine/Engine/EventSource.cs index 483c0810f9d..99454be7fa2 100644 --- a/src/OrcasEngine/Engine/EventSource.cs +++ b/src/OrcasEngine/Engine/EventSource.cs @@ -644,11 +644,5 @@ internal void RaiseStronglyTypedEvent(BuildEventArgs e) /// /// t-jeffv, sumedhk public event AnyEventHandler AnyEventRaised; - - /// - /// This event is not used in OrcasEngine - /// - [Obsolete("This event is not available for the older engine.")] - public event TelemetryEventHandler TelemetryLogged; } } diff --git a/src/Utilities/MuxLogger.cs b/src/Utilities/MuxLogger.cs index a2a0448bd22..031b3d05d7d 100644 --- a/src/Utilities/MuxLogger.cs +++ b/src/Utilities/MuxLogger.cs @@ -325,7 +325,7 @@ private class SubmissionRecord : #if FEATURE_APPDOMAIN MarshalByRefObject, #endif - IEventSource + IEventSource2 { #region Fields /// @@ -1319,7 +1319,12 @@ private void InitializeInternalEventSource() _eventSourceForBuild.TaskFinished += _taskFinishedEventHandler; _eventSourceForBuild.TaskStarted += _taskStartedEventHandler; _eventSourceForBuild.WarningRaised += _buildWarningEventHandler; - _eventSourceForBuild.TelemetryLogged += _telemetryEventHandler; + + IEventSource2 eventSource2 = _eventSourceForBuild as IEventSource2; + if (eventSource2 != null) + { + eventSource2.TelemetryLogged += _telemetryEventHandler; + } } /// @@ -1341,7 +1346,12 @@ private void UnregisterAllEventHandlers() _eventSourceForBuild.TaskFinished -= _taskFinishedEventHandler; _eventSourceForBuild.TaskStarted -= _taskStartedEventHandler; _eventSourceForBuild.WarningRaised -= _buildWarningEventHandler; - _eventSourceForBuild.TelemetryLogged -= _telemetryEventHandler; + + IEventSource2 eventSource2 = _eventSourceForBuild as IEventSource2; + if (eventSource2 != null) + { + eventSource2.TelemetryLogged -= _telemetryEventHandler; + } MessageRaised = null; ErrorRaised = null; diff --git a/src/Utilities/Task.cs b/src/Utilities/Task.cs index 7fc51f27b53..daf0c4393f5 100644 --- a/src/Utilities/Task.cs +++ b/src/Utilities/Task.cs @@ -110,6 +110,17 @@ public IBuildEngine4 BuildEngine4 } } + /// + /// Retrieves the IBuildEngine5 version of the build engine interface provided by the host. + /// + public IBuildEngine5 BuildEngine5 + { + get + { + return (IBuildEngine5)_buildEngine; + } + } + /// /// The build engine sets this property if the host IDE has associated a host object with this particular task. /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs index 27d860553d4..edaad8aa088 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/CentralForwardingLogger.cs @@ -87,8 +87,12 @@ public void Initialize(IEventSource eventSource) ErrorUtilities.VerifyThrow(eventSource != null, "eventSource is null"); eventSource.AnyEventRaised += new AnyEventHandler(EventSource_AnyEventRaised); - // Telemetry events aren't part of "all" so they need to be forwarded separately - eventSource.TelemetryLogged += EventSource_AnyEventRaised; + IEventSource2 eventSource2 = eventSource as IEventSource2; + if (eventSource2 != null) + { + // Telemetry events aren't part of "all" so they need to be forwarded separately + eventSource2.TelemetryLogged += EventSource_AnyEventRaised; + } } /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs index 203cb423214..7b11f16d6d1 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs @@ -19,7 +19,7 @@ internal sealed class EventSourceSink : #if FEATURE_APPDOMAIN MarshalByRefObject, #endif - IEventSource, IBuildEventSink + IEventSource2, IBuildEventSink { #region Events diff --git a/src/XMakeBuildEngine/Definition/ProjectCollection.cs b/src/XMakeBuildEngine/Definition/ProjectCollection.cs index 273ce4d9176..01388988da3 100644 --- a/src/XMakeBuildEngine/Definition/ProjectCollection.cs +++ b/src/XMakeBuildEngine/Definition/ProjectCollection.cs @@ -1743,7 +1743,7 @@ public ProjectRootElement ProjectRootElement /// The ReusableLogger wraps a logger and allows it to be used for both design-time and build-time. It internally swaps /// between the design-time and build-time event sources in response to Initialize and Shutdown events. /// - internal class ReusableLogger : INodeLogger, IEventSource + internal class ReusableLogger : INodeLogger, IEventSource2 { /// /// The logger we are wrapping. @@ -2054,7 +2054,12 @@ private void RegisterForEvents(IEventSource eventSource) eventSource.TaskFinished += _taskFinishedEventHandler; eventSource.TaskStarted += _taskStartedEventHandler; eventSource.WarningRaised += _buildWarningEventHandler; - eventSource.TelemetryLogged += _telemetryEventHandler; + + IEventSource2 eventSource2 = eventSource as IEventSource2; + if (eventSource2 != null) + { + eventSource2.TelemetryLogged += _telemetryEventHandler; + } } /// @@ -2077,7 +2082,12 @@ private void UnregisterForEvents(IEventSource eventSource) eventSource.TaskFinished -= _taskFinishedEventHandler; eventSource.TaskStarted -= _taskStartedEventHandler; eventSource.WarningRaised -= _buildWarningEventHandler; - eventSource.TelemetryLogged -= _telemetryEventHandler; + + IEventSource2 eventSource2 = eventSource as IEventSource2; + if (eventSource2 != null) + { + eventSource2.TelemetryLogged -= _telemetryEventHandler; + } // Null out the handlers. _anyEventHandler = null; From e834f1907fe05a471930b130101c815f7b3da70e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 27 Oct 2016 11:41:13 -0700 Subject: [PATCH 034/223] Add --target All to cibuild.cmd (#1268) * FIx missing echo * Add "All" option for --target --- cibuild.cmd | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cibuild.cmd b/cibuild.cmd index efc5921ac72..2751b9ab9d0 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -1,5 +1,6 @@ @if not defined _echo echo off -setlocal +setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS +SET _originalScript=%~f0 :parseArguments if "%1"=="" goto doneParsingArguments @@ -34,6 +35,13 @@ if /i "%TARGET%"=="CoreCLR" ( set BUILD_CONFIGURATION=Debug-NetCore ) else if /i "%TARGET%"=="Desktop" ( set BUILD_CONFIGURATION=Debug +) else if /i "%TARGET%"=="All" ( + SET _originalArguments=%* + CALL "!_originalScript!" !_originalArguments:All=Desktop! + IF ERRORLEVEL 1 GOTO :error + CALL "!_originalScript!" !_originalArguments:All=CoreCLR! + IF ERRORLEVEL 1 GOTO :error + EXIT /B 0 ) else ( echo Unsupported target detected: %TARGET%. Aborting. goto :error @@ -146,10 +154,10 @@ exit /b 0 :usage echo Options echo --scope ^ Scope of the build ^(Compile / Test^) -echo --target ^ CoreCLR or Desktop ^(default: Desktop^) +echo --target ^ CoreCLR, Desktop, or All ^(default: Desktop^) echo --host ^ CoreCLR or Desktop ^(default: Desktop^) echo --build-only Only build using a downloaded copy of MSBuild but do not bootstrap - or build again with those binaries +echo or build again with those binaries echo --bootstrap-only Build and bootstrap MSBuild but do not build again with those binaries echo --localized-build Do a localized build echo --sync-xlf Synchronize xlf files from resx files From 9bcc0028f211b6198f8514ae4a7e7f823dba18ce Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 27 Oct 2016 14:25:32 -0700 Subject: [PATCH 035/223] Fix unhandled exception when killing processes on non-Windows (#1274) Also change ObjectModelHelpers.SleepCommand() to use a TimeSpan and different commands. Disable CancelledBuildInTaskHostWithDelay20 and CancelledBuildInTaskHostWithDelay40 for scenarios where there is no task host support Closes #1269 --- src/Shared/UnitTests/ObjectModelHelpers.cs | 29 +++--------- src/Utilities/ProcessExtensions.cs | 8 +++- .../UnitTests/BackEnd/BuildManager_Tests.cs | 46 ++++++++++--------- 3 files changed, 37 insertions(+), 46 deletions(-) diff --git a/src/Shared/UnitTests/ObjectModelHelpers.cs b/src/Shared/UnitTests/ObjectModelHelpers.cs index 150e965d7f0..1dba58015d9 100644 --- a/src/Shared/UnitTests/ObjectModelHelpers.cs +++ b/src/Shared/UnitTests/ObjectModelHelpers.cs @@ -1445,32 +1445,15 @@ internal static void ClearDirtyFlag(ProjectRootElement project) } /// - /// Command you can pass to Exec to sleep for rough number of milliseconds. - /// @for /l %i in (1,1,X) do "@dir %windir% > nul" - /// sleeps for X/100 seconds, roughly - /// This works around not having sleep.exe on the path. + /// Gets a command that can be used by an Exec task to sleep for the specified amount of time. /// - internal static string SleepCommandInMilliseconds(int milliseconds) + /// A representing the amount of time to sleep. + internal static string GetSleepCommand(TimeSpan timeSpan) { return - string.Format( - NativeMethodsShared.IsWindows - ? @"@for /l %25%25i in (1,1,{0}) do @dir %25windir%25 > nul" - : "for i in {{1..{0}}}; do ls /bin > /dev/null; done", - milliseconds / 10); - } - - /// - /// Command you can pass to Exec to sleep for rough number of seconds. - /// @for /l %i in (1,1,X) do "@dir %windir% > nul" - /// sleeps for X/100 seconds, roughly - /// This works around not having sleep.exe on the path. - /// - /// - /// - internal static string SleepCommand(int seconds) - { - return SleepCommandInMilliseconds(seconds * 1000); + NativeMethodsShared.IsWindows + ? $"@powershell -command "Start-Sleep -Milliseconds {(int)timeSpan.TotalMilliseconds}" >nul" + : $"sleep {timeSpan.TotalSeconds}"; } /// diff --git a/src/Utilities/ProcessExtensions.cs b/src/Utilities/ProcessExtensions.cs index 993c8f9c4cc..001ea18c8e9 100644 --- a/src/Utilities/ProcessExtensions.cs +++ b/src/Utilities/ProcessExtensions.cs @@ -99,16 +99,20 @@ private static int RunProcessAndWaitForExit(string fileName, string arguments, o var process = Process.Start(startInfo); stdout = null; - if (process.WaitForExit(30)) + if (process.WaitForExit((int) TimeSpan.FromSeconds(30).TotalMilliseconds)) { stdout = process.StandardOutput.ReadToEnd(); } else { process.Kill(); + + // Kill is asynchronous so we should still wait a little + // + process.WaitForExit((int) TimeSpan.FromSeconds(1).TotalMilliseconds); } - return process.ExitCode; + return process.HasExited ? process.ExitCode : -1; } } } diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index 8626cf86840..4da155c3236 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -1122,7 +1122,7 @@ public void EndBuildBlocks() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1229,7 +1229,7 @@ public void OverlappingBuildSubmissions() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1355,7 +1355,7 @@ public void EndWithUnexecutedSubmission() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1375,7 +1375,7 @@ public void CancelledBuildWithUnexecutedSubmission() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1397,7 +1397,7 @@ public void CancelledBuild() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1430,7 +1430,7 @@ public void CancelledBuildWithDelay20() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1451,6 +1451,7 @@ public void CancelledBuildWithDelay20() } } +#if FEATURE_TASKHOST /// /// A canceled build which waits for the task to get started before canceling. Because it is a 2.0 task, we should /// wait until the task finishes normally (cancellation not supported.) @@ -1464,7 +1465,7 @@ public void CancelledBuildInTaskHostWithDelay20() - + @@ -1487,6 +1488,7 @@ public void CancelledBuildInTaskHostWithDelay20() _logger.AssertLogDoesntContain("MSB4217"); } } +#endif /// /// A canceled build which waits for the task to get started before canceling. Because it is a 12.. task, we should @@ -1499,7 +1501,7 @@ public void CancelledBuildWithDelay40() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1519,6 +1521,7 @@ public void CancelledBuildWithDelay40() _logger.AssertLogDoesntContain("[fail]"); } +#if FEATURE_TASKHOST /// /// A canceled build which waits for the task to get started before canceling. Because it is a 12.0 task, we should /// cancel the task and exit out after a short period wherein we wait for the task to exit cleanly. @@ -1530,7 +1533,7 @@ public void CancelledBuildInTaskHostWithDelay40() - + @@ -1552,6 +1555,7 @@ public void CancelledBuildInTaskHostWithDelay40() // Task host should not have exited prematurely _logger.AssertLogDoesntContain("MSB4217"); } +#endif /// /// This test verifies that builds of the same project instance in sequence are permitted. @@ -1593,7 +1597,7 @@ public void OverlappingBuildsOfTheSameProjectDifferentTargetsAreAllowed() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -1634,7 +1638,7 @@ public void OverlappingBuildsOfTheSameProjectSameTargetsAreAllowed() string contents = ObjectModelHelpers.CleanupFileContents(@" - + @@ -2619,7 +2623,7 @@ public void Regress473114() - + "; @@ -2726,7 +2730,7 @@ public void VerifyMultipleRequestForSameProjectWithErrors_Simple() - + "; @@ -2850,7 +2854,7 @@ public void VerifyMultipleRequestForSameProjectWithErrors_OnErrorChain() - + "; @@ -2974,7 +2978,7 @@ public void VerifyMultipleRequestForSameProjectWithErrors_ErrorAndContinue() - + "; @@ -3085,7 +3089,7 @@ public void VerifyMultipleRequestForSameProjectWithErrors_AfterTargets() - + "; @@ -3229,7 +3233,7 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData() string projectContent = @" - + @@ -3307,12 +3311,12 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData_P2P() string projectContent1 = @" - + - + @@ -3411,12 +3415,12 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData_P2P_MP() string projectContent1 = @" - + - + From 892840d6ce6b9b40f8b95b1ebc1a694789d265c6 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Thu, 27 Oct 2016 15:37:29 -0700 Subject: [PATCH 036/223] Automated commit of revision number value 00072. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index c57fecaa694..1cbcd93c2ff 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00071 + 00072 \ No newline at end of file From 7548aa6738cab3571b3188ae4e39a66d2ed67e59 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Thu, 27 Oct 2016 16:08:33 -0700 Subject: [PATCH 037/223] Automated commit of revision number value 00073. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 1cbcd93c2ff..074020226f4 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00072 + 00073 \ No newline at end of file From 0ff91af8fc60332f7245dc94afe56a4d375f6374 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Thu, 27 Oct 2016 16:16:55 -0700 Subject: [PATCH 038/223] Automated commit of revision number value 00074. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 074020226f4..4e7c88a3304 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00073 + 00074 \ No newline at end of file From c1bf9d88107f5b0e08fe7d0714293b4f0f59627a Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 28 Oct 2016 08:08:35 -0700 Subject: [PATCH 039/223] Upgrade BuildTools to 1.0.27-prerelease-00927-05 (#1279) By updating, we can get our code indexed at https://source.dot.net/ --- BuildToolsVersion.txt | 2 +- dir.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BuildToolsVersion.txt b/BuildToolsVersion.txt index 3ad16023f57..9d068b1a98a 100644 --- a/BuildToolsVersion.txt +++ b/BuildToolsVersion.txt @@ -1 +1 @@ -1.0.26-prerelease-00826-05 \ No newline at end of file +1.0.27-prerelease-00927-05 \ No newline at end of file diff --git a/dir.props b/dir.props index b4c083c87c6..bf83cfd1de6 100644 --- a/dir.props +++ b/dir.props @@ -46,7 +46,7 @@ $(BinDir)Bootstrap\ - 1.0.26-prerelease-00826-05 + 1.0.27-prerelease-00927-05 2.0.0-beta3 2.1.0 0.2.0 From b6ff43b8a83081ddf472443979945a87ade57806 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 28 Oct 2016 13:47:40 -0500 Subject: [PATCH 040/223] Avoid x-targeting perf impact on vcxproj (#1278) Targeted mitigation for #1276. VC++ noticed a dramatic regression in solution-load performance related to the time cost of ResolveProjectReferences. That affects all projects, but we can safely assume that a .vcxproj is NOT using cross-targeting, while it's impossible to detect from the outside whether a .csproj is. This commit avoids the regression for C++ projects by just not calling the MSBuild task again for .vcxproj references. --- src/XMakeTasks/Microsoft.Common.CurrentVersion.targets | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets index e0dc14c5470..4fc4b585b5a 100644 --- a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets @@ -1504,14 +1504,19 @@ Copyright (C) Microsoft Corporation. All rights reserved. ====================================================================================== --> - + + + RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove);TargetFramework" + Condition="'%(_MSBuildProjectReferenceExistent.Extension)' != '.vcxproj'"> From fd25bc9c7deb56dbfe51621afb1021056f410241 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 28 Oct 2016 12:07:34 -0700 Subject: [PATCH 041/223] Remove _CheckForInvalidConfigurationAndPlatform InitialTarget (#1280) * Only have _CheckForInvalidConfigurationAndPlatform target run before any build related target This target is running before targets like Restore which don't need the check. This change removes _CheckForInvalidConfigurationAndPlatform from InitialTargets and instead injects it before any of the BuildDependsOn, RebuildDependsOn, or CleanDependsOn targets. This will work except when a user specifies a BeforeTargets of the first target in those lists. To get around that, the user must specify a DependsOn of _CheckForInvalidConfigurationAndPlatform if they want the check to run before their target. * Reword comment to hopefully make it more understandable * Add Build, Rebuild, and Clean to the list of targets --- .../Microsoft.Common.CurrentVersion.targets | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets index 4fc4b585b5a..658a0fc7be5 100644 --- a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets @@ -14,7 +14,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. *********************************************************************************************** --> - + @@ -715,12 +715,16 @@ Copyright (C) Microsoft Corporation. All rights reserved. ============================================================ _CheckForInvalidConfigurationAndPlatform - This target checks for errors in statically defined properties. It always - gets executed before any other target. + This target checks for errors in statically defined properties. By setting BeforeTargets, we try + to ensure that the target runs before any build related targets. + If your target requires this check and is running as a BeforeTargets of one of the first targets + of $(BuildDependsOn), $(RebuildDependsOn), or $(CleanDependsOn) you will need to set your DependsOn + to this target. ============================================================ --> + Name="_CheckForInvalidConfigurationAndPlatform" + BeforeTargets="$(BuildDependsOn);Build;$(RebuildDependsOn);Rebuild;$(CleanDependsOn);Clean"> <_InvalidConfigurationMessageText>The OutputPath property is not set for project '$(MSBuildProjectFile)'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='$(_OriginalConfiguration)' Platform='$(_OriginalPlatform)'. From 186780d69844e16c27efdaaeefd6179ee640fff1 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Fri, 28 Oct 2016 12:56:50 -0700 Subject: [PATCH 042/223] Automated commit of revision number value 00075. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 4e7c88a3304..6e3e1c365e2 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00074 + 00075 \ No newline at end of file From 769a0e7a582132ac1c94018d89d54f30af6485fd Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Fri, 28 Oct 2016 13:05:02 -0700 Subject: [PATCH 043/223] Automated commit of revision number value 00076. --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 6e3e1c365e2..ce1bcc895a2 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00075 + 00076 \ No newline at end of file From 902f7b789403a013756ff768dbf070bcc4639475 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 28 Oct 2016 13:22:29 -0700 Subject: [PATCH 044/223] Fix GitVersioning after recent BuildTools update (#1282) BuildTools now writes a file named "version.txt" which is unfortunate because GitVersioning also looks for a file named that. This change sets $(ObjDir) so the BuildTools version.txt will be out of the paths taht GitVersioning searches. --- dir.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dir.props b/dir.props index bf83cfd1de6..6eb08d2a860 100644 --- a/dir.props +++ b/dir.props @@ -385,6 +385,9 @@ $([System.IO.Path]::Combine($(BaseIntermediateOutputPath)$(MSBuildProjectName),$(Configuration)))$([System.IO.Path]::DirectorySeparatorChar) $([System.IO.Path]::Combine($(BaseIntermediateOutputPath)$(MSBuildProjectName),$(Platform),$(Configuration)))$([System.IO.Path]::DirectorySeparatorChar) + + $(IntermediateOutputPath) + $(TestWorkingDir)$([System.IO.Path]::Combine($(MSBuildProjectName),$(Configuration)))$([System.IO.Path]::DirectorySeparatorChar) $([System.IO.Path]::Combine($(TestWorkingDir)$(MSBuildProjectName),$(Platform),$(Configuration)))$([System.IO.Path]::DirectorySeparatorChar) From 4e405a802d587368581117daf3402491beea8de7 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 31 Oct 2016 15:54:04 -0500 Subject: [PATCH 045/223] Keep path in invalid project exceptions (#1287) When #1004 moved the standard XML reading approach to be stream-based rather than file-based, the exceptions thrown on malformed XML changed--System.Xml no longer knows the path, so it isn't included in the XmlException. That caused MSBuild to fail to report the location of the XML error in a nice way as it had done before. Almost every case where we constructed a BuildEventFileInfo object already had access to the full path, so I added a constructor that accepted that as an argument and overrides the possibly-empty path returned from XmlException.SourceUri. Added a unit test to verify that the information is indeed preserved in the exception. Fixes #1286. --- src/Shared/BuildEventFileInfo.cs | 10 ++++++ .../Construction/ProjectRootElement.cs | 2 +- src/XMakeBuildEngine/Definition/Toolset.cs | 2 +- .../InvalidProjectFileException_Tests.cs | 31 +++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Shared/BuildEventFileInfo.cs b/src/Shared/BuildEventFileInfo.cs index d31ea94965f..9cd505911ce 100644 --- a/src/Shared/BuildEventFileInfo.cs +++ b/src/Shared/BuildEventFileInfo.cs @@ -97,6 +97,16 @@ internal BuildEventFileInfo(XmlException e) _endColumn = 0; } + /// + /// Creates an instance of this class using the information in the given XmlException and file location. + /// + internal BuildEventFileInfo(string file, XmlException e) : this(e) + { + ErrorUtilities.VerifyThrowArgumentNull(file, nameof(file)); + + _file = file; + } + #endregion #region Properties diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index f7824220eeb..0fbff1dd707 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -2059,7 +2059,7 @@ private XmlDocumentWithLocation LoadDocument(string fullPath, bool preserveForma if (xmlException != null) { - fileInfo = new BuildEventFileInfo(xmlException); + fileInfo = new BuildEventFileInfo(fullPath, xmlException); } else { diff --git a/src/XMakeBuildEngine/Definition/Toolset.cs b/src/XMakeBuildEngine/Definition/Toolset.cs index 8a8ea0dd121..034631dcfb1 100644 --- a/src/XMakeBuildEngine/Definition/Toolset.cs +++ b/src/XMakeBuildEngine/Definition/Toolset.cs @@ -1046,7 +1046,7 @@ private void LoadAndRegisterFromTasksFile(string searchPath, string[] defaultTas catch (XmlException e) { // handle XML errors in the default tasks file - ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, new BuildEventFileInfo(e), taskFileError, e.Message); + ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, new BuildEventFileInfo(defaultTasksFile, e), taskFileError, e.Message); } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) { diff --git a/src/XMakeBuildEngine/UnitTests/InvalidProjectFileException_Tests.cs b/src/XMakeBuildEngine/UnitTests/InvalidProjectFileException_Tests.cs index f4a7cc8fbe2..9429a7c6204 100644 --- a/src/XMakeBuildEngine/UnitTests/InvalidProjectFileException_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/InvalidProjectFileException_Tests.cs @@ -82,5 +82,36 @@ public void ErrorCodeShouldAppearForCircularDependency() File.Delete(file); } } + + /// + /// Regression test for https://github.com/Microsoft/msbuild/issues/1286 + /// + [Fact] + public void LogErrorShouldHavePathAndLocation() + { + string file = Path.GetTempPath() + Guid.NewGuid().ToString("N"); + + try + { + File.WriteAllText(file, ObjectModelHelpers.CleanupFileContents(@" + + + ")); + + var _ = ObjectModelHelpers.BuildTempProjectFileExpectFailure(file); + + Assert.True(false, "Loading an invalid project should have thrown an InvalidProjectFileException."); + } + catch (InvalidProjectFileException e) + { + Assert.Equal(3, e.LineNumber); + Assert.Equal(38, e.ColumnNumber); + Assert.Equal(file, e.ProjectFile); // https://github.com/Microsoft/msbuild/issues/1286 + } + finally + { + File.Delete(file); + } + } } } From dc4af3c5e49792ea4d18fe9dc42d8f1a20e5682e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 1 Nov 2016 12:27:32 -0700 Subject: [PATCH 046/223] Fix some build warnings, update ref assemblies (#1292) --- .../Microsoft.Build.Utilities.Core.cs | 1 + .../Microsoft.Build.Utilities.Core.cs | 1 + src/Framework/IEventSource.cs | 2 +- src/Utilities/ToolLocationHelper.cs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index 25675e7c6cb..06548271726 100644 --- a/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/net46/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -339,6 +339,7 @@ protected Task(System.Resources.ResourceManager taskResources, string helpKeywor public Microsoft.Build.Framework.IBuildEngine2 BuildEngine2 { get { throw null; } } public Microsoft.Build.Framework.IBuildEngine3 BuildEngine3 { get { throw null; } } public Microsoft.Build.Framework.IBuildEngine4 BuildEngine4 { get { throw null; } } + public Microsoft.Build.Framework.IBuildEngine5 BuildEngine5 { get { throw null; } } protected string HelpKeywordPrefix { get { throw null; } set { } } public Microsoft.Build.Framework.ITaskHost HostObject { get { throw null; } set { } } public Microsoft.Build.Utilities.TaskLoggingHelper Log { get { throw null; } } diff --git a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs index 3a97ad00019..095bef58f24 100644 --- a/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs +++ b/ref/netstandard1.3/Microsoft.Build.Utilities.Core/Microsoft.Build.Utilities.Core.cs @@ -184,6 +184,7 @@ protected Task(System.Resources.ResourceManager taskResources, string helpKeywor public Microsoft.Build.Framework.IBuildEngine2 BuildEngine2 { get { throw null; } } public Microsoft.Build.Framework.IBuildEngine3 BuildEngine3 { get { throw null; } } public Microsoft.Build.Framework.IBuildEngine4 BuildEngine4 { get { throw null; } } + public Microsoft.Build.Framework.IBuildEngine5 BuildEngine5 { get { throw null; } } protected string HelpKeywordPrefix { get { throw null; } set { } } public Microsoft.Build.Framework.ITaskHost HostObject { get { throw null; } set { } } public Microsoft.Build.Utilities.TaskLoggingHelper Log { get { throw null; } } diff --git a/src/Framework/IEventSource.cs b/src/Framework/IEventSource.cs index 4a5fe15d043..9c9d7fa9ab5 100644 --- a/src/Framework/IEventSource.cs +++ b/src/Framework/IEventSource.cs @@ -148,7 +148,7 @@ public interface IEventSource event BuildStatusEventHandler StatusEventRaised; /// - /// this event is raised to log any build event. These events do not include telemetry. To receive telemetry, you must attach to the event. + /// this event is raised to log any build event. These events do not include telemetry. To receive telemetry, you must attach to the event. /// event AnyEventHandler AnyEventRaised; } diff --git a/src/Utilities/ToolLocationHelper.cs b/src/Utilities/ToolLocationHelper.cs index 227293b67c7..89c7c2cd601 100644 --- a/src/Utilities/ToolLocationHelper.cs +++ b/src/Utilities/ToolLocationHelper.cs @@ -1189,6 +1189,7 @@ private static bool TryGetPlatformManifest(TargetPlatformSDK matchingSdk, string /// The min version of the targeted platform /// The version of the targeted platform /// The content folder name under SDK path + /// An optional disk root to search. A value should only be passed from a unit test. /// The SDK content folder path public static string GetSDKContentFolderPath( string sdkIdentifier, From 8ba61153357a11380d459ff7712dd412da762cab Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 1 Nov 2016 12:27:45 -0700 Subject: [PATCH 047/223] Fix build number for NuGet packages in official builds (#1295) I made a typo of the environment variable 'BUILD_NUMBER' which should be 'BUILD_BUILDNUMBER' --- build/NuGetPackages/CreateNuGetPackages.proj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/NuGetPackages/CreateNuGetPackages.proj b/build/NuGetPackages/CreateNuGetPackages.proj index c3f62cf055f..aa83bb9444a 100644 --- a/build/NuGetPackages/CreateNuGetPackages.proj +++ b/build/NuGetPackages/CreateNuGetPackages.proj @@ -66,7 +66,7 @@ - + - 00 + 00 - $([System.Int32]::Parse($([System.Text.RegularExpressions.Regex]::Match($(BUILD_NUMBER), $(_BuildRevisionRegex)).Groups["Revision"].Value)).ToString('D2')) + $([System.Int32]::Parse($([System.Text.RegularExpressions.Regex]::Match($(BUILD_BUILDNUMBER), $(_BuildRevisionRegex)).Groups["Revision"].Value)).ToString('D2')) $(PrereleaseVersion)-$([System.Int32]::Parse($(BuildVersionNumberComponent)).ToString('D6'))-$(BuildRevision) From 9a9ca39c87417752cb1e9121447313e91c59566e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 1 Nov 2016 12:46:11 -0700 Subject: [PATCH 048/223] Copy the test category 'netcore-osx-failing' as 'netcore-linux-failing' --- src/Shared/UnitTests/FileUtilities_Tests.cs | 9 +++++++ .../UnitTests/ToolLocationHelper_Tests.cs | 6 +++++ src/Utilities/UnitTests/ToolTask_Tests.cs | 1 + .../UnitTests/BackEnd/BuildManager_Tests.cs | 24 +++++++++++++++++++ .../BuildRequestConfiguration_Tests.cs | 1 + .../UnitTests/BackEnd/IntrinsicTask_Tests.cs | 1 + .../BackEnd/LoggingServicesLogMethod_Tests.cs | 1 + .../UnitTests/BackEnd/TaskBuilder_Tests.cs | 1 + .../Construction/ElementLocation_Tests.cs | 4 ++++ .../Construction/SolutionFile_Tests.cs | 2 ++ .../SolutionProjectGenerator_Tests.cs | 9 +++++++ .../Definition/Project_Internal_Tests.cs | 2 ++ .../UnitTests/Evaluation/Evaluator_Tests.cs | 2 ++ .../UnitTests/Evaluation/Expander_Tests.cs | 12 ++++++++++ .../Evaluation/ProjectStringCache_Tests.cs | 3 +++ .../UnitTests/FileLogger_Tests.cs | 1 + .../Construction/ProjectRootElement_Tests.cs | 2 ++ .../Definition/ProjectItem_Tests.cs | 1 + .../Definition/ProjectProperty_Tests.cs | 2 ++ .../Instance/ProjectInstance_Tests.cs | 4 ++++ .../UnitTests/ConvertToAbsolutePath_Tests.cs | 2 ++ src/XMakeTasks/UnitTests/Copy_Tests.cs | 7 ++++++ src/XMakeTasks/UnitTests/Culture_Tests.cs | 1 + src/XMakeTasks/UnitTests/Exec_Tests.cs | 2 ++ src/XMakeTasks/UnitTests/FileStateTests.cs | 4 ++++ .../UnitTests/FindUnderPath_Tests.cs | 2 ++ .../UnitTests/GenerateResource_Tests.cs | 7 ++++-- src/XMakeTasks/UnitTests/Move_Tests.cs | 1 + .../ResolveCodeAnalysisRuleSet_Tests.cs | 5 ++++ 29 files changed, 117 insertions(+), 2 deletions(-) diff --git a/src/Shared/UnitTests/FileUtilities_Tests.cs b/src/Shared/UnitTests/FileUtilities_Tests.cs index 6471162fbbd..07ebfc7b56a 100644 --- a/src/Shared/UnitTests/FileUtilities_Tests.cs +++ b/src/Shared/UnitTests/FileUtilities_Tests.cs @@ -21,6 +21,7 @@ public class FileUtilities_Tests [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetItemSpecModifier() { TestGetItemSpecModifier(Directory.GetCurrentDirectory()); @@ -85,6 +86,7 @@ private static void TestGetItemSpecModifier(string currentDirectory) [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void MakeRelativeTests() { if (NativeMethodsShared.IsWindows) @@ -118,6 +120,7 @@ public void MakeRelativeTests() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetItemSpecModifierOnBadPath() { Assert.Throws(() => @@ -132,6 +135,7 @@ public void GetItemSpecModifierOnBadPath() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetItemSpecModifierOnBadPath2() { Assert.Throws(() => @@ -184,6 +188,7 @@ public void GetFileInfoNoThrowNonexistent() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void EndsWithSlash() { Assert.True(FileUtilities.EndsWithSlash(@"C:\foo\")); @@ -208,6 +213,7 @@ public void EndsWithSlash() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetDirectoryWithTrailingSlash() { Assert.Equal(NativeMethodsShared.IsWindows ? @"c:\" : "/", FileUtilities.GetDirectory(NativeMethodsShared.IsWindows ? @"c:\" : "/")); @@ -475,6 +481,7 @@ public void NormalizePathInvalid() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void FileOrDirectoryExistsNoThrow() { Assert.Equal(false, FileUtilities.FileOrDirectoryExistsNoThrow("||")); @@ -785,6 +792,7 @@ public void GenerateTempFileNameWithExtensionNoPeriod() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GenerateTempBatchFileWithBadExtension() { Assert.Throws(() => @@ -811,6 +819,7 @@ public void GenerateTempBatchFileWithEmptyExtension() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GenerateTempBatchFileWithBadDirectory() { Assert.Throws(() => diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index 3294fa77ba3..d46828a90f0 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -59,6 +59,7 @@ public void GetApiContractReferencesHandlesNullContracts() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetApiContractReferencesHandlesNonExistingLocation() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -226,6 +227,7 @@ public void GetVersionedSDKUnionMetadataLocation() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GatherExtensionSDKsInvalidVersionDirectory() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -250,6 +252,7 @@ public void GatherExtensionSDKsInvalidVersionDirectory() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GatherExtensionSDKsNoManifest() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -274,6 +277,7 @@ public void GatherExtensionSDKsNoManifest() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GatherExtensionSDKsEmptyManifest() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -299,6 +303,7 @@ public void GatherExtensionSDKsEmptyManifest() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GatherExtensionSDKsGarbageManifest() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -633,6 +638,7 @@ public void FindPathForEverettThatIsntProperlyInstalled() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ExerciseMiscToolLocationHelperMethods() { Assert.Equal(ToolLocationHelper.GetDotNetFrameworkVersionFolderPrefix(TargetDotNetFrameworkVersion.Version11), FrameworkLocationHelper.dotNetFrameworkVersionFolderPrefixV11); diff --git a/src/Utilities/UnitTests/ToolTask_Tests.cs b/src/Utilities/UnitTests/ToolTask_Tests.cs index af8bcc48d94..3c1bf7ee402 100644 --- a/src/Utilities/UnitTests/ToolTask_Tests.cs +++ b/src/Utilities/UnitTests/ToolTask_Tests.cs @@ -220,6 +220,7 @@ public void HandleExecutionErrorsWhenToolDoesntLogError() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void HandleExecutionErrorsWhenToolLogsError() { diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index 4da155c3236..dfdadd786c7 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -105,6 +105,7 @@ public void BuildParametersWithNullCollection() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SimpleBuild() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -352,6 +353,7 @@ public void RunOutOfProcBuild(Action buildParametersModifier) /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void InProcForwardPropertiesFromChild() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -404,6 +406,7 @@ public void InProcForwardPropertiesFromChild() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void InProcMsBuildForwardAllPropertiesFromChild() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -861,6 +864,7 @@ public void ForwardNoPropertiesLaunchChildNodeDefault() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SimpleBuildWithFailure() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -882,6 +886,7 @@ public void SimpleBuildWithFailure() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SimpleBuildWithFailureAndWarningOnlyLogCriticalEventsTrue() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -917,6 +922,7 @@ public void SimpleBuildWithFailureAndWarningOnlyLogCriticalEventsTrue() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SimpleBuildWithFailureAndWarningOnlyLogCriticalEventsFalse() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1117,6 +1123,7 @@ public void BuildDuringBuild() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void EndBuildBlocks() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1187,6 +1194,7 @@ public void EndBuildCalledWithinSubmissionCallback() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SequentialBuild() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1224,6 +1232,7 @@ public void SequentialBuild() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void OverlappingBuildSubmissions() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1267,6 +1276,7 @@ public void OverlappingBuildSubmissions() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void OverlappingIdenticalBuildSubmissions() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1302,6 +1312,7 @@ public void OverlappingIdenticalBuildSubmissions() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void OverlappingBuildSubmissions_OnlyOneSucceeds() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1562,6 +1573,7 @@ public void CancelledBuildInTaskHostWithDelay40() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SequentialBuildsOfTheSameProjectAllowed() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1592,6 +1604,7 @@ public void SequentialBuildsOfTheSameProjectAllowed() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void OverlappingBuildsOfTheSameProjectDifferentTargetsAreAllowed() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1633,6 +1646,7 @@ public void OverlappingBuildsOfTheSameProjectDifferentTargetsAreAllowed() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void OverlappingBuildsOfTheSameProjectSameTargetsAreAllowed() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1732,6 +1746,7 @@ public void ProjectInstanceStoredInCache() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ProjectInstanceRetrievedAfterBuildMatchesSourceProject() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1759,6 +1774,7 @@ public void ProjectInstanceRetrievedAfterBuildMatchesSourceProject() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ResetCacheClearsInstances() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1792,6 +1808,7 @@ public void ResetCacheClearsInstances() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DisablingCacheResetKeepsInstance() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -1832,6 +1849,7 @@ public void DisablingCacheResetKeepsInstance() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GhostProjectRootElementCache() { string contents1 = ObjectModelHelpers.CleanupFileContents(@" @@ -1987,6 +2005,7 @@ public void VerifyImportedProjectRootElementsInheritExplicitLoadFlag() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void Regress251333() { string contents = ObjectModelHelpers.CleanupFileContents(@" @@ -2221,6 +2240,7 @@ public void ProjectInstanceLimitedTransferToOOPNode() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void CacheLifetime() { @@ -2337,6 +2357,7 @@ public void FailedAfterTargetInP2PShouldCauseOverallBuildFailure() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void FailedAfterTargetInP2PShouldCauseOverallBuildFailure_MultipleEntrypoints() { string projA = null; @@ -2487,6 +2508,7 @@ public void FailedNestedAfterTargetInP2PShouldCauseOverallBuildFailure() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void NonOverlappingEntrypointTargetsShouldNotInfluenceEachOthersResults() { string projA = null; @@ -3139,6 +3161,7 @@ public void VerifyMultipleRequestForSameProjectWithErrors_AfterTargets() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void VerifyMultipleRequestForSameProjectWithErrors_DifferentEntrypoints() { string projA = null; @@ -3301,6 +3324,7 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void TestSimultaneousSubmissionsWithLegacyThreadingData_P2P() { string projectPath1 = null; diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs index 65829a7b0db..4221d7d50a7 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs @@ -363,6 +363,7 @@ public void TestCache() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void TestCache2() { diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/IntrinsicTask_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/IntrinsicTask_Tests.cs index 7cfe2e19c33..7561eb13db2 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/IntrinsicTask_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/IntrinsicTask_Tests.cs @@ -2921,6 +2921,7 @@ public void IncludeCheckOnMetadata2() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void IncludeCheckOnMetadata_3() { diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs index b2cd1734636..f08b25e6761 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs @@ -897,6 +897,7 @@ public void LogBuildStarted() [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/437")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void LogBuildStartedCriticalOnly() { diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs index 2ee029498ca..e39533ff52b 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs @@ -440,6 +440,7 @@ public void MSBuildLastTaskResult() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void TasksCanAddRecursiveDirBuiltInMetadata() { diff --git a/src/XMakeBuildEngine/UnitTests/Construction/ElementLocation_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/ElementLocation_Tests.cs index 6dcc3cc7962..ecea00d1588 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/ElementLocation_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/ElementLocation_Tests.cs @@ -289,6 +289,7 @@ public void SerializationTest_SmallElementLocation() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void LocationStringsMedleyReadOnlyLoad() { string content = ObjectModelHelpers.CleanupFileContents(@" @@ -355,6 +356,7 @@ public void SaveReadOnly1() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SaveReadOnly2() { var doc = new XmlDocumentWithLocation(loadAsReadOnly: true); @@ -379,6 +381,7 @@ public void SaveReadOnly2() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SaveReadOnly3() { var doc = new XmlDocumentWithLocation(loadAsReadOnly: true); @@ -404,6 +407,7 @@ public void SaveReadOnly3() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SaveReadOnly4() { var doc = new XmlDocumentWithLocation(loadAsReadOnly: true); diff --git a/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs index a7385215b1c..d2a09f6e740 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs @@ -46,6 +46,7 @@ public void BasicParseFirstProjectLine() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ParseFirstProjectLine_VC() { Assert.Throws(() => @@ -457,6 +458,7 @@ public void TestVSAndSolutionVersionParsing() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ParseNestedEtpProjectMultipleLevel() { string proj1Path = Path.Combine(Path.GetTempPath(), "someproj.etp"); diff --git a/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs index b5b38b08f66..00f1dd3f5b8 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs @@ -114,6 +114,7 @@ public void AddNewErrorWarningMessageElement() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void EmitToolsVersionAttributeToInMemoryProject9() { if (FrameworkLocationHelper.PathToDotNetFrameworkV35 == null) @@ -149,6 +150,7 @@ public void EmitToolsVersionAttributeToInMemoryProject9() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void EmitToolsVersionAttributeToInMemoryProject10() { if (FrameworkLocationHelper.PathToDotNetFrameworkV35 == null) @@ -958,6 +960,7 @@ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionNo [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void Regress751742_SkipNonexistentProjects() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -1376,6 +1379,7 @@ public void TestConfigurationPlatformDefaults2() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void TestVenusConfigurationDefaults() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -1406,6 +1410,7 @@ public void TestVenusConfigurationDefaults() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void VenusSolutionDefaultTargetFrameworkVersion() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -1445,6 +1450,7 @@ public void VenusSolutionDefaultTargetFrameworkVersion() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void TestTargetFrameworkPaths0() { if (FrameworkLocationHelper.PathToDotNetFrameworkSdkV20 != null) @@ -1470,6 +1476,7 @@ public void TestTargetFrameworkPaths0() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void TestTargetFrameworkPaths1() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -1496,6 +1503,7 @@ public void TestTargetFrameworkPaths1() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void TestTargetFrameworkPaths2() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -1691,6 +1699,7 @@ public void SolutionGeneratorCanEmitSolutions() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void TestSkipInvalidConfigurationsCase() { diff --git a/src/XMakeBuildEngine/UnitTests/Definition/Project_Internal_Tests.cs b/src/XMakeBuildEngine/UnitTests/Definition/Project_Internal_Tests.cs index ca5be7290fc..1b92fdd8acb 100644 --- a/src/XMakeBuildEngine/UnitTests/Definition/Project_Internal_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Definition/Project_Internal_Tests.cs @@ -108,6 +108,7 @@ public void ReloadProjectWithInvalidToolsVersionInFile() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ProjectToolsVersion20Present() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) @@ -150,6 +151,7 @@ public void ProjectToolsVersion20Present() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void MSBuildToolsVersionProperty() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs index bfbee86993a..b3659b17de9 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs @@ -134,6 +134,7 @@ public void VerifyExistsInMemoryProjects() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void VerifyConditionsInsideOutsideTargets() { @@ -2324,6 +2325,7 @@ public void LocalAppDataWithGlobalOverride() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ReservedProjectProperties() { diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs index d4207aeebc3..9d5218fbbb8 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs @@ -227,6 +227,7 @@ public void ExpandItemVectorFunctionsAnyHaveMetadataValue() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ExpandItemVectorFunctionsGetDirectoryNameOfMetadataValueDistinct() { ProjectInstance project = ProjectHelpers.CreateEmptyProjectInstance(); @@ -252,6 +253,7 @@ public void ExpandItemVectorFunctionsGetDirectoryNameOfMetadataValueDistinct() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ExpandItemVectorFunctionsItemSpecModifier() { @@ -312,6 +314,7 @@ public void ExpandItemVectorFunctionsInvalid2() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ExpandItemVectorFunctionsChained1() { @@ -328,6 +331,7 @@ public void ExpandItemVectorFunctionsChained1() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ExpandItemVectorFunctionsChained2() { @@ -355,6 +359,7 @@ public void ExpandItemVectorFunctionsChained3() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ExpandItemVectorFunctionsChainedProject1() { @@ -631,6 +636,7 @@ public void ExpandItemVectorFunctionsBuiltIn_InvalidCharsError() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void ExpandItemVectorFunctionsItemSpecModifier2() { @@ -669,6 +675,7 @@ public void ExpandItemVectorFunctionsItemSpecModifier2() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ExpandItemVectorFunctionsGetDirectoryNameOfMetadataValue() { ProjectInstance project = ProjectHelpers.CreateEmptyProjectInstance(); @@ -688,6 +695,7 @@ public void ExpandItemVectorFunctionsGetDirectoryNameOfMetadataValue() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ExpandItemVectorFunctionsMetadataValueMultiItem() { ProjectInstance project = ProjectHelpers.CreateEmptyProjectInstance(); @@ -2011,6 +2019,7 @@ public void PropertyFunctionArrayReturn() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void PropertyFunctionDictionaryReturn() { @@ -2234,6 +2243,7 @@ public void PropertyFunctionNoCollisionsOnType() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void PropertyFunctionStaticMethodMakeRelative() { PropertyDictionary pg = new PropertyDictionary(); @@ -2367,6 +2377,7 @@ public void PropertyStaticFunctionUsingNamespaceNotFound() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void PropertyFunctionStaticMethodQuoted1() { PropertyDictionary pg = new PropertyDictionary(); @@ -2843,6 +2854,7 @@ public void PropertyFunctionDoesTaskHostExist_NonexistentTaskHost() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void PropertyFunctionStaticMethodFileAttributes() { diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/ProjectStringCache_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/ProjectStringCache_Tests.cs index 99cd365e2b9..462968d9b20 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/ProjectStringCache_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/ProjectStringCache_Tests.cs @@ -26,6 +26,7 @@ public class ProjectStringCache_Tests /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ContentIsSameAcrossInstances() { string content = ObjectModelHelpers.CleanupFileContents(@" @@ -91,6 +92,7 @@ Item group content /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ContentCanBeModified() { string content = ObjectModelHelpers.CleanupFileContents(@" @@ -176,6 +178,7 @@ Item group content /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void RemovingFilesRemovesEntries() { string content = ObjectModelHelpers.CleanupFileContents(@" diff --git a/src/XMakeBuildEngine/UnitTests/FileLogger_Tests.cs b/src/XMakeBuildEngine/UnitTests/FileLogger_Tests.cs index c48b75907d4..40651d76a21 100644 --- a/src/XMakeBuildEngine/UnitTests/FileLogger_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/FileLogger_Tests.cs @@ -86,6 +86,7 @@ public void BasicNoExistingFile() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void InvalidFile() { diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs index fe55959d64b..8dbae355a7c 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs @@ -389,6 +389,7 @@ public void ValidXmlInvalidSyntaxOpenFromDiskTwice() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ValidXmlXmlTextReaderNotCache() { string content = @" @@ -677,6 +678,7 @@ public void EncodingGetterBasedOnXmlDeclaration() [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/301")] #endif [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void EncodingGetterBasedOnActualEncodingWhenXmlDeclarationIsAbsent() { string projectFullPath = FileUtilities.GetTemporaryFile(); diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs index b571d07285c..1b32700a958 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs @@ -1599,6 +1599,7 @@ public void Rename() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void RenameItemInProjectWithWildcards() { string projectDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectProperty_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectProperty_Tests.cs index 6b90269a676..a1e0715b185 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectProperty_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectProperty_Tests.cs @@ -151,6 +151,7 @@ public void InvalidSetValueBuiltInProperty() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void SetValueEnvironmentProperty() { Project project = new Project(); @@ -173,6 +174,7 @@ public void SetValueEnvironmentProperty() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void IsEnvironmentVariable() { Project project = new Project(); diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Instance/ProjectInstance_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Instance/ProjectInstance_Tests.cs index 920ac4e2d70..17650e170cd 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Instance/ProjectInstance_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Instance/ProjectInstance_Tests.cs @@ -841,6 +841,7 @@ public void ImmutableProjectInstance_CloneMutableFromImmutable() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ImmutableProjectInstance_CloneImmutableFromMutable() { var protoInstance = GetSampleProjectInstance(false /* mutable */); @@ -862,6 +863,7 @@ public void ImmutableProjectInstance_CloneImmutableFromMutable() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ImmutableProjectInstance_CloneImmutableFromImmutable() { var protoInstance = GetSampleProjectInstance(true /* immutable */); @@ -886,6 +888,7 @@ public void ImmutableProjectInstance_CloneImmutableFromImmutable() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ImmutableProjectInstance_CloneImmutableFromImmutable2() { var protoInstance = GetSampleProjectInstance(true /* immutable */); @@ -907,6 +910,7 @@ public void ImmutableProjectInstance_CloneImmutableFromImmutable2() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ImmutableProjectInstance_CloneMutableFromMutable() { var protoInstance = GetSampleProjectInstance(false /* mutable */); diff --git a/src/XMakeTasks/UnitTests/ConvertToAbsolutePath_Tests.cs b/src/XMakeTasks/UnitTests/ConvertToAbsolutePath_Tests.cs index 5373918a046..b44232caff9 100644 --- a/src/XMakeTasks/UnitTests/ConvertToAbsolutePath_Tests.cs +++ b/src/XMakeTasks/UnitTests/ConvertToAbsolutePath_Tests.cs @@ -18,6 +18,7 @@ sealed public class ConvertToAbsolutePath_Tests /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void RelativePath() { @@ -50,6 +51,7 @@ public void RelativePath() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void RelativePathWithEscaping() { diff --git a/src/XMakeTasks/UnitTests/Copy_Tests.cs b/src/XMakeTasks/UnitTests/Copy_Tests.cs index 341dffce86e..3c608f8c596 100644 --- a/src/XMakeTasks/UnitTests/Copy_Tests.cs +++ b/src/XMakeTasks/UnitTests/Copy_Tests.cs @@ -123,6 +123,7 @@ public void DontCopyOverSameFile() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DoNotNormallyCopyOverReadOnlyFile() { string source = FileUtilities.GetTemporaryFile(); @@ -181,6 +182,7 @@ public void DoNotNormallyCopyOverReadOnlyFile() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void CopyOverReadOnlyFileEnvironmentOverride() { string source = FileUtilities.GetTemporaryFile(); @@ -242,6 +244,7 @@ public void CopyOverReadOnlyFileEnvironmentOverride() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void AlwaysRetryCopyEnvironmentOverride() { string source = FileUtilities.GetTemporaryFile(); @@ -309,6 +312,7 @@ public void AlwaysRetryCopyEnvironmentOverride() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void CopyOverReadOnlyFileParameterIsSet() { string source = FileUtilities.GetTemporaryFile(); @@ -438,6 +442,7 @@ public void CopyOverReadOnlyFileParameterIsSetWithDestinationFolder() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DoCopyOverDifferentFile() { string sourceFile = FileUtilities.GetTemporaryFile(); @@ -673,6 +678,7 @@ public void DoNotRetryCopyWhenSourceIsFolder() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DoRetryWhenDestinationLocked() { string destinationFile = Path.GetTempFileName(); @@ -1107,6 +1113,7 @@ public void CopyFileOnItself2() [Fact] [Trait("Category", "mono-osx-failing")] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void CopyFileOnItselfAndFailACopy() { string temp = Path.GetTempPath(); diff --git a/src/XMakeTasks/UnitTests/Culture_Tests.cs b/src/XMakeTasks/UnitTests/Culture_Tests.cs index 03ef75c6331..0b63610503d 100644 --- a/src/XMakeTasks/UnitTests/Culture_Tests.cs +++ b/src/XMakeTasks/UnitTests/Culture_Tests.cs @@ -47,6 +47,7 @@ public void NonCultureFile() */ [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void BogusEmbeddedCulture() { Culture.ItemCultureInfo info = Culture.GetItemCultureInfo("MyResource.notalocale.resx", null); diff --git a/src/XMakeTasks/UnitTests/Exec_Tests.cs b/src/XMakeTasks/UnitTests/Exec_Tests.cs index 0fcc7968f78..b74ff03da3f 100644 --- a/src/XMakeTasks/UnitTests/Exec_Tests.cs +++ b/src/XMakeTasks/UnitTests/Exec_Tests.cs @@ -119,6 +119,7 @@ public void WindowsNewLineCharactersInCommandOnUnix() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ExitCodeGetter() { Exec exec = PrepareExec("exit 120"); @@ -462,6 +463,7 @@ public void InvalidUncDirectorySet() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void InvalidWorkingDirectorySet() { Exec exec = PrepareExec("echo [%cd%]"); diff --git a/src/XMakeTasks/UnitTests/FileStateTests.cs b/src/XMakeTasks/UnitTests/FileStateTests.cs index 94ed6a1c2e5..cc504680d3d 100644 --- a/src/XMakeTasks/UnitTests/FileStateTests.cs +++ b/src/XMakeTasks/UnitTests/FileStateTests.cs @@ -51,6 +51,7 @@ public void BadChars() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void BadTooLongLastWriteTime() { @@ -343,6 +344,7 @@ public void LastWriteTimeUtcReset() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void LengthReset() { @@ -425,6 +427,7 @@ public void LengthOnDirectory() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DoesNotExistLastWriteTime() { string file = Guid.NewGuid().ToString("N"); @@ -434,6 +437,7 @@ public void DoesNotExistLastWriteTime() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void DoesNotExistLastWriteTimeUtc() { string file = Guid.NewGuid().ToString("N"); diff --git a/src/XMakeTasks/UnitTests/FindUnderPath_Tests.cs b/src/XMakeTasks/UnitTests/FindUnderPath_Tests.cs index 38d8cb12cbe..88b018d68d2 100644 --- a/src/XMakeTasks/UnitTests/FindUnderPath_Tests.cs +++ b/src/XMakeTasks/UnitTests/FindUnderPath_Tests.cs @@ -100,6 +100,7 @@ private static void RunTask(FindUnderPath t, out FileInfo testFile, out bool suc [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void VerifyFullPath() { @@ -122,6 +123,7 @@ public void VerifyFullPath() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] [Trait("Category", "mono-osx-failing")] public void VerifyFullPathNegative() { diff --git a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs index 2863416f689..117a1d7d4f8 100644 --- a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs @@ -271,6 +271,7 @@ public void BasicResources2Text() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void ForceOutOfDate() { string resxFile = Utilities.WriteTestResX(false, null, null); @@ -2481,7 +2482,8 @@ public void Regress25163_OutputResourcesContainsInvalidPathCharacters() public class References { [Fact] - [Trait("Category", "netcore-osx-failing")] // https://github.com/Microsoft/msbuild/issues/309 + [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] // https://github.com/Microsoft/msbuild/issues/309 public void DontLockP2PReferenceWhenResolvingSystemTypes() { // This WriteLine is a hack. On a slow machine, the Tasks unittest fails because remoting @@ -2659,7 +2661,8 @@ public class Class1 /// Assembly.LoadFrom instead. /// [Fact] - [Trait("Category", "netcore-osx-failing")] // https://github.com/Microsoft/msbuild/issues/309 + [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] // https://github.com/Microsoft/msbuild/issues/309 public void ReferencedAssemblySpecifiedUsingRelativePath() { // This WriteLine is a hack. On a slow machine, the Tasks unittest fails because remoting diff --git a/src/XMakeTasks/UnitTests/Move_Tests.cs b/src/XMakeTasks/UnitTests/Move_Tests.cs index d11752ca2ab..f2dbc7af4e0 100644 --- a/src/XMakeTasks/UnitTests/Move_Tests.cs +++ b/src/XMakeTasks/UnitTests/Move_Tests.cs @@ -462,6 +462,7 @@ public void OutputsOnlyIncludeSuccessfulMoves() /// [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void MoveLockedFile() { string file = null; diff --git a/src/XMakeTasks/UnitTests/ResolveCodeAnalysisRuleSet_Tests.cs b/src/XMakeTasks/UnitTests/ResolveCodeAnalysisRuleSet_Tests.cs index 9238ad10995..4eaf11ed3dc 100644 --- a/src/XMakeTasks/UnitTests/ResolveCodeAnalysisRuleSet_Tests.cs +++ b/src/XMakeTasks/UnitTests/ResolveCodeAnalysisRuleSet_Tests.cs @@ -139,6 +139,7 @@ public void GetResolvedRuleSetPath_SimpleNameAndProjectDirectory_Existent() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetResolvedRuleSetPath_SimpleNameAndProjectDirectory_NonExistent() { MockEngine mockEngine = new MockEngine(); @@ -189,6 +190,7 @@ public void GetResolvedRuleSetPath_SimpleNameAndDirectories_Existent() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetResolvedRuleSetPath_SimpleNameAndDirectories_NonExistent() { MockEngine mockEngine = new MockEngine(); @@ -211,6 +213,7 @@ public void GetResolvedRuleSetPath_SimpleNameAndDirectories_NonExistent() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetResolvedRuleSetPath_RelativePath_WithProject_NonExistent() { MockEngine mockEngine = new MockEngine(); @@ -234,6 +237,7 @@ public void GetResolvedRuleSetPath_RelativePath_WithProject_NonExistent() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetResolvedRuleSetPath_RelativePath_WithProject_Existent() { MockEngine mockEngine = new MockEngine(); @@ -264,6 +268,7 @@ public void GetResolvedRuleSetPath_RelativePath_WithProject_Existent() [Fact] [Trait("Category", "netcore-osx-failing")] + [Trait("Category", "netcore-linux-failing")] public void GetResolvedRuleSetPath_RelativePath_NoProject() { MockEngine mockEngine = new MockEngine(); From cc774ddd37aa3f87f3c80d4858506868993be21c Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 1 Nov 2016 12:54:22 -0700 Subject: [PATCH 049/223] Add netcore-linux-failing test category when testing on linux --- dir.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/dir.targets b/dir.targets index 5041f823b7f..b7417013f97 100644 --- a/dir.targets +++ b/dir.targets @@ -35,6 +35,7 @@ $(XunitOptions) -notrait category=nonwindowstests $(XunitOptions) -notrait category=nonlinuxtests + -notrait category=nonlinuxtests -notrait category=netcore-linux-failing $(XunitOptions) -notrait category=nonosxtests -notrait category=nonosxtests -notrait category=netcore-osx-failing $(XunitOptions) -notrait category=nonfreebsdtests From 3c1d5ad0a08b0d71f9834f5e731664aa09f60fa0 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 1 Nov 2016 13:15:18 -0700 Subject: [PATCH 050/223] Disable tests in BuildEnvironmentHelper_Tests that detect stuff related to Visual Studio for non-Windows. Disable tests that fail --- .../UnitTests/BuildEnvironmentHelper_Tests.cs | 14 ++++++++++++++ src/XMakeTasks/UnitTests/GenerateResource_Tests.cs | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs index a8773b0ef00..829c8bfc209 100644 --- a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs @@ -88,6 +88,8 @@ public void FindBuildEnvironmentFromRunningProcess() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void FindBuildEnvironmentFromVisualStudioRoot() { using (var env = new EmptyBuildEnviroment()) @@ -104,6 +106,8 @@ public void FindBuildEnvironmentFromVisualStudioRoot() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByEnvironment() { using (var env = new EmptyBuildEnviroment()) @@ -117,6 +121,8 @@ public void BuildEnvironmentDetectsVisualStudioByEnvironment() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByMSBuildProcess() { using (var env = new EmptyBuildEnviroment()) @@ -129,6 +135,8 @@ public void BuildEnvironmentDetectsVisualStudioByMSBuildProcess() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByMSBuildProcessAmd64() { using (var env = new EmptyBuildEnviroment()) @@ -141,6 +149,8 @@ public void BuildEnvironmentDetectsVisualStudioByMSBuildProcessAmd64() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioFromSetupInstance() { using (var env = new EmptyBuildEnviroment()) @@ -189,6 +199,8 @@ public void BuildEnvironmentDetectsRunningTests() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByProcessName() { using (var env = new EmptyBuildEnviroment()) @@ -201,6 +213,8 @@ public void BuildEnvironmentDetectsVisualStudioByProcessName() } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByBlendProcess() { using (var env = new EmptyBuildEnviroment()) diff --git a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs index 117a1d7d4f8..6cbed4ab742 100644 --- a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs @@ -156,6 +156,7 @@ public void BasicText2Resources() /// /// System dll is not locked because it forces a new app domain [Fact] + [Trait("Category", "netcore-linux-failing")] public void ResX2ResourcesWithReferences() { string systemDll = Utilities.GetPathToCopiedSystemDLL(); @@ -388,6 +389,7 @@ public void ForceOutOfDateLinked() /// Force partially out-of-date: should build only the out of date inputs /// [Fact] + [Trait("Category", "netcore-linux-failing")] public void ForceSomeOutOfDate() { string resxFile = null; @@ -577,6 +579,7 @@ public void NothingOutOfDate() /// /// System dll is not locked because it forces a new app domain [Fact] + [Trait("Category", "netcore-linux-failing")] public void NothingOutOfDateExceptReference() { string resxFile = null; From 2d4c2ea60876f8b43e91834781d079824d2706cc Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 2 Nov 2016 08:42:27 -0700 Subject: [PATCH 051/223] Allow bootstrapping of desktop and CoreCLR This sets the bootstrap destination as "Bootstrap-NetCore" for CoreCLR and improves the logic to delete the folder prior to bootstrapping. I build both all of the time but the CoreCLR bootstrapping wipes out the desktop one so I can't use them both! Update cibuild scripts Append -HOST to log file names so you can build both CoreCLR and Desktop without losing logs --- cibuild.cmd | 8 ++++---- cibuild.sh | 12 ++++++------ dir.props | 17 +++++++++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/cibuild.cmd b/cibuild.cmd index 2751b9ab9d0..350568f4ad2 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -85,7 +85,7 @@ call %~dp0init-tools.cmd echo. echo ** Rebuilding MSBuild with downloaded binaries -set MSBUILDLOGPATH=%~dp0msbuild_bootstrap_build.log +set MSBUILDLOGPATH=%~dp0msbuild_bootstrap_build-%HOST%.log call "%~dp0build.cmd" /t:Rebuild /p:Configuration=%BUILD_CONFIGURATION% /p:"SkipBuildPackages=true" %LOCALIZED_BUILD_ARGUMENT% %SYNC_XLF_ARGUMENT% if %ERRORLEVEL% NEQ 0 ( @@ -103,7 +103,7 @@ echo ** Moving bootstrapped MSBuild to the bootstrap folder :: Kill Roslyn, which may have handles open to files we want taskkill /F /IM vbcscompiler.exe -set MSBUILDLOGPATH=%~dp0msbuild_move_bootstrap.log +set MSBUILDLOGPATH=%~dp0msbuild_move_bootstrap-%HOST%.log set MSBUILD_ARGS=/verbosity:minimal BootStrapMSbuild.proj /p:Configuration=%BUILD_CONFIGURATION% call "%~dp0build.cmd" @@ -117,7 +117,7 @@ if "%BOOTSTRAP_ONLY%"=="true" goto :success set MSBUILD_ARGS= :: Rebuild with bootstrapped msbuild -set MSBUILDLOGPATH=%~dp0msbuild_local_build.log +set MSBUILDLOGPATH=%~dp0msbuild_local_build-%HOST%.log :: Only CoreCLR requires an override--it should use the host :: downloaded as part of its NuGet package references, rather @@ -127,7 +127,7 @@ if /i "%TARGET%"=="CoreCLR" ( ) if /i "%TARGET%"=="CoreCLR" ( - set MSBUILD_CUSTOM_PATH="%~dp0bin\Bootstrap\MSBuild.dll" + set MSBUILD_CUSTOM_PATH="%~dp0bin\Bootstrap-NetCore\MSBuild.dll" ) else ( set MSBUILD_CUSTOM_PATH="%~dp0bin\Bootstrap\15.0\Bin\MSBuild.exe" ) diff --git a/cibuild.sh b/cibuild.sh index bc66ddb4fea..dc63dd57cde 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -135,14 +135,10 @@ MSBUILD_DOWNLOAD_URL="https://github.com/Microsoft/msbuild/releases/download/mon MSBUILD_ZIP="$PACKAGES_DIR/msbuild.zip" HOME_DEFAULT="$WORKSPACE/msbuild-CI-home" -BOOTSTRAP_BUILD_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_bootstrap_build.log" -LOCAL_BUILD_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_local_build.log" -MOVE_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_move_bootstrap.log" - PROJECT_FILE_ARG='"'"$THIS_SCRIPT_PATH/build.proj"'"' BOOTSTRAP_FILE_ARG='"'"$THIS_SCRIPT_PATH/BootStrapMSBuild.proj"'"' -BOOTSTRAPPED_RUNTIME_HOST='"'"$THIS_SCRIPT_PATH/bin/Bootstrap/dotnet"'"' -MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap/MSBuild.dll"'"' +BOOTSTRAPPED_RUNTIME_HOST='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/dotnet"'"' +MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/MSBuild.dll"'"' # Default msbuild arguments TARGET_ARG="Build" @@ -270,6 +266,10 @@ case $host in ;; esac +BOOTSTRAP_BUILD_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_bootstrap_build-$host.log" +LOCAL_BUILD_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_local_build-$host.log" +MOVE_LOG_PATH="$THIS_SCRIPT_PATH"/"msbuild_move_bootstrap-$host.log" + BUILD_MSBUILD_ARGS="$PROJECT_FILE_ARG /p:OS=$OS_ARG /p:Configuration=$CONFIGURATION /p:OverrideToolHost=$RUNTIME_HOST /verbosity:minimal $EXTRA_ARGS" setHome diff --git a/dir.props b/dir.props index 6eb08d2a860..ee345a0bce3 100644 --- a/dir.props +++ b/dir.props @@ -43,7 +43,6 @@ $(ProjectDir)bin\ $(BinDir)tests\ - $(BinDir)Bootstrap\ 1.0.27-prerelease-00927-05 @@ -98,11 +97,6 @@ $(DnuCoreRestoreCommand) --packages $(PackagesDir) - - - $(BootstrapDestination) - - $(ToolPackagesDir) @@ -205,6 +199,15 @@ AnyCPU + + + $(BinDir)Bootstrap$([System.IO.Path]::DirectorySeparatorChar) + $(BinDir)Bootstrap-NetCore$([System.IO.Path]::DirectorySeparatorChar) + + + $(BootstrapDestination) + + @@ -399,8 +402,6 @@ $([System.IO.Path]::Combine($(BaseOutputPath), $(Configuration), $(DeploymentDirName)))$([System.IO.Path]::DirectorySeparatorChar) $([System.IO.Path]::Combine($(BaseOutputPath), $(Configuration), $(TestDeploymentDirName)))$([System.IO.Path]::DirectorySeparatorChar) - $(BinDir)Bootstrap$([System.IO.Path]::DirectorySeparatorChar) - $([System.IO.Path]::Combine($(ProjectDir), "build", "bin", $(RelativeOutputPathWithConfig), "Output"))$([System.IO.Path]::DirectorySeparatorChar) From 1a7b43a3366e5480a9f81ede32373134f640a93f Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 2 Nov 2016 13:15:47 -0700 Subject: [PATCH 052/223] Consolidate bootstrap projects Move BootStrapMSBuild.proj to the targets folder Move the logic from BootStrapAppLocalMSBuild.proj and BootStrapFullFramework.proj into BootStrapMSBuild.proj as different targets Update scripts --- BootStrapMSBuild.proj | 19 ---- RebuildWithLocalMSBuild.cmd | 4 +- cibuild.cmd | 2 +- cibuild.sh | 2 +- targets/BootStrapAppLocalMSBuild.proj | 27 ------ targets/BootStrapFullFrameworkMSBuild.proj | 59 ------------ targets/BootStrapMSBuild.proj | 107 +++++++++++++++++++++ 7 files changed, 111 insertions(+), 109 deletions(-) delete mode 100644 BootStrapMSBuild.proj delete mode 100644 targets/BootStrapAppLocalMSBuild.proj delete mode 100644 targets/BootStrapFullFrameworkMSBuild.proj create mode 100644 targets/BootStrapMSBuild.proj diff --git a/BootStrapMSBuild.proj b/BootStrapMSBuild.proj deleted file mode 100644 index 60cf649b3f8..00000000000 --- a/BootStrapMSBuild.proj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - diff --git a/RebuildWithLocalMSBuild.cmd b/RebuildWithLocalMSBuild.cmd index a8482ee36cf..42ffa730ecf 100644 --- a/RebuildWithLocalMSBuild.cmd +++ b/RebuildWithLocalMSBuild.cmd @@ -32,7 +32,7 @@ if %ERRORLEVEL% NEQ 0 ( taskkill /F /IM vbcscompiler.exe set MSBUILDLOGPATH=%~dp0msbuild_move_bootstrap.log -set MSBUILD_ARGS=/verbosity:minimal BootStrapMSbuild.proj /p:Configuration=Debug-NetCore +set MSBUILD_ARGS=/verbosity:minimal targets\BootStrapMSbuild.proj /p:Configuration=Debug-NetCore echo. echo ** Moving bootstrapped MSBuild to the bootstrap folder @@ -41,7 +41,7 @@ call "%~dp0build.cmd" set MSBUILD_ARGS= if %ERRORLEVEL% NEQ 0 ( - echo. + echo. echo build.cmd with bootstrapped MSBuild failed with errorlevel %ERRORLEVEL% 1>&2 goto :error ) diff --git a/cibuild.cmd b/cibuild.cmd index 350568f4ad2..6cac51d6fb4 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -104,7 +104,7 @@ echo ** Moving bootstrapped MSBuild to the bootstrap folder taskkill /F /IM vbcscompiler.exe set MSBUILDLOGPATH=%~dp0msbuild_move_bootstrap-%HOST%.log -set MSBUILD_ARGS=/verbosity:minimal BootStrapMSbuild.proj /p:Configuration=%BUILD_CONFIGURATION% +set MSBUILD_ARGS=/verbosity:minimal targets\BootStrapMSbuild.proj /p:Configuration=%BUILD_CONFIGURATION% call "%~dp0build.cmd" if %ERRORLEVEL% NEQ 0 ( diff --git a/cibuild.sh b/cibuild.sh index dc63dd57cde..8d013325211 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -136,7 +136,7 @@ MSBUILD_ZIP="$PACKAGES_DIR/msbuild.zip" HOME_DEFAULT="$WORKSPACE/msbuild-CI-home" PROJECT_FILE_ARG='"'"$THIS_SCRIPT_PATH/build.proj"'"' -BOOTSTRAP_FILE_ARG='"'"$THIS_SCRIPT_PATH/BootStrapMSBuild.proj"'"' +BOOTSTRAP_FILE_ARG='"'"$THIS_SCRIPT_PATH/targets/BootStrapMSBuild.proj"'"' BOOTSTRAPPED_RUNTIME_HOST='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/dotnet"'"' MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/MSBuild.dll"'"' diff --git a/targets/BootStrapAppLocalMSBuild.proj b/targets/BootStrapAppLocalMSBuild.proj deleted file mode 100644 index b14dbaa6eff..00000000000 --- a/targets/BootStrapAppLocalMSBuild.proj +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/targets/BootStrapFullFrameworkMSBuild.proj b/targets/BootStrapFullFrameworkMSBuild.proj deleted file mode 100644 index f49676976ab..00000000000 --- a/targets/BootStrapFullFrameworkMSBuild.proj +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/targets/BootStrapMSBuild.proj b/targets/BootStrapMSBuild.proj new file mode 100644 index 00000000000..ed732c6fe2b --- /dev/null +++ b/targets/BootStrapMSBuild.proj @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 53623bf62f149c7eb328a8b3123b98ba41402f05 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 4 Nov 2016 10:42:00 -0700 Subject: [PATCH 053/223] Propert versions for the legacy projects (#1311) * Add static assembly version to legacy projects * Rename Desktop to Full * Switch ProjectCollection.Version to using the assembly file version and not the product version This is because, on FF, the ProductBuildPart seems to be returning the bit from the assembly file version and not the assembly version, which lead to ProjectCollection reporting a mix between the assembly version and the assembly file version. As a consequence, for NetCore MSBuild, which does not use git versioning, we have to also add a static assembly file verison in assemblyinfo.cs. Otherwise the compiler default is set which is 0.0.0.0 --- cibuild.cmd | 29 ++++++++++++------- src/Framework/AssemblyInfo.cs | 1 + src/OrcasEngine/AssemblyInfo.cs | 5 ++++ src/Utilities/AssemblyInfo.cs | 1 + src/XMakeBuildEngine/AssemblyInfo.cs | 1 + .../Definition/ProjectCollection.cs | 2 +- .../Definition/ProjectCollection_Tests.cs | 3 +- src/XMakeCommandLine/AssemblyInfo.cs | 1 + .../MSBuildTaskHost/AssemblyInfo.cs | 1 + src/XMakeConversion/AssemblyInfo.cs | 5 ++++ src/XMakeTasks/AssemblyInfo.cs | 1 + src/dir.targets | 4 +-- 12 files changed, 39 insertions(+), 15 deletions(-) diff --git a/cibuild.cmd b/cibuild.cmd index 6cac51d6fb4..5e8ba3862ad 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -27,24 +27,25 @@ if /i "%SCOPE%"=="Build" set TARGET_ARG=Build :: Default to full-framework build if not defined TARGET ( - set TARGET=Desktop + set TARGET=Full ) set BUILD_CONFIGURATION= if /i "%TARGET%"=="CoreCLR" ( set BUILD_CONFIGURATION=Debug-NetCore -) else if /i "%TARGET%"=="Desktop" ( +) else if /i "%TARGET%"=="Full" ( set BUILD_CONFIGURATION=Debug ) else if /i "%TARGET%"=="All" ( SET _originalArguments=%* - CALL "!_originalScript!" !_originalArguments:All=Desktop! + CALL "!_originalScript!" !_originalArguments:All=Full! IF ERRORLEVEL 1 GOTO :error CALL "!_originalScript!" !_originalArguments:All=CoreCLR! IF ERRORLEVEL 1 GOTO :error EXIT /B 0 ) else ( - echo Unsupported target detected: %TARGET%. Aborting. - goto :error + echo Unsupported target detected: %TARGET%. Configuring as if for Full. + set TARGET=Full + set BUILD_CONFIGURATION=Debug ) :: Assign runtime host @@ -54,7 +55,7 @@ if not defined HOST ( if /i "%TARGET%"=="CoreCLR" ( set HOST=CoreCLR ) else ( - set HOST=Desktop + set HOST=Full ) ) @@ -62,7 +63,7 @@ set RUNTIME_HOST= if /i "%HOST%"=="CoreCLR" ( set RUNTIME_HOST=%~dp0Tools\DotNetCLI\Dotnet.exe set MSBUILD_CUSTOM_PATH=%~dp0Tools\MSBuild.exe -) else if /i "%HOST%"=="Desktop" ( +) else if /i "%HOST%"=="Full" ( set RUNTIME_HOST= ) else ( echo Unsupported host detected: %HOST%. Aborting. @@ -79,6 +80,12 @@ if "%SYNC_XLF%"=="true" ( set SYNC_XLF_ARGUMENT="/p:SyncXlf=true" ) +:: Full Framework MSBuild does not have the new built-in property MSBuildRuntimeType +set RUNTIMETYPE_ARGUMENT= +if "%TARGET%"=="Full" ( + set RUNTIMETYPE_ARGUMENT="/p:MSBuildRuntimeType=Full" +) + :: Restore build tools call %~dp0init-tools.cmd @@ -86,7 +93,7 @@ echo. echo ** Rebuilding MSBuild with downloaded binaries set MSBUILDLOGPATH=%~dp0msbuild_bootstrap_build-%HOST%.log -call "%~dp0build.cmd" /t:Rebuild /p:Configuration=%BUILD_CONFIGURATION% /p:"SkipBuildPackages=true" %LOCALIZED_BUILD_ARGUMENT% %SYNC_XLF_ARGUMENT% +call "%~dp0build.cmd" /t:Rebuild /p:Configuration=%BUILD_CONFIGURATION% /p:"SkipBuildPackages=true" %LOCALIZED_BUILD_ARGUMENT% %SYNC_XLF_ARGUMENT% %RUNTIMETYPE_ARGUMENT% if %ERRORLEVEL% NEQ 0 ( echo. @@ -104,7 +111,7 @@ echo ** Moving bootstrapped MSBuild to the bootstrap folder taskkill /F /IM vbcscompiler.exe set MSBUILDLOGPATH=%~dp0msbuild_move_bootstrap-%HOST%.log -set MSBUILD_ARGS=/verbosity:minimal targets\BootStrapMSbuild.proj /p:Configuration=%BUILD_CONFIGURATION% +set MSBUILD_ARGS=/verbosity:minimal targets\BootStrapMSbuild.proj /p:Configuration=%BUILD_CONFIGURATION% %RUNTIMETYPE_ARGUMENT% call "%~dp0build.cmd" if %ERRORLEVEL% NEQ 0 ( @@ -154,8 +161,8 @@ exit /b 0 :usage echo Options echo --scope ^ Scope of the build ^(Compile / Test^) -echo --target ^ CoreCLR, Desktop, or All ^(default: Desktop^) -echo --host ^ CoreCLR or Desktop ^(default: Desktop^) +echo --target ^ CoreCLR, Full, or All ^(default: Full^) +echo --host ^ CoreCLR or Full ^(default: Full^) echo --build-only Only build using a downloaded copy of MSBuild but do not bootstrap echo or build again with those binaries echo --bootstrap-only Build and bootstrap MSBuild but do not build again with those binaries diff --git a/src/Framework/AssemblyInfo.cs b/src/Framework/AssemblyInfo.cs index 76ff425d300..9578974d7d8 100644 --- a/src/Framework/AssemblyInfo.cs +++ b/src/Framework/AssemblyInfo.cs @@ -43,6 +43,7 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion("15.1.0.0")] +[assembly: AssemblyFileVersion("15.1.0.0")] #endif [assembly: InternalsVisibleTo("Microsoft.Build.Framework.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] [assembly: InternalsVisibleTo("Microsoft.Build.Tasks.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] diff --git a/src/OrcasEngine/AssemblyInfo.cs b/src/OrcasEngine/AssemblyInfo.cs index 4981f129d71..b6594e06c05 100644 --- a/src/OrcasEngine/AssemblyInfo.cs +++ b/src/OrcasEngine/AssemblyInfo.cs @@ -26,6 +26,11 @@ [assembly: AssemblyProduct("Microsoft® Build Tools®")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] +#if STATIC_VERSION_NUMBER +[assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +#endif + #if (LOCALIZED_BUILD) // Needed for the "hub-and-spoke model to locate and retrieve localized resources": https://msdn.microsoft.com/en-us/library/21a15yht(v=vs.110).aspx // We want "en" to require a satellite assembly for debug builds in order to flush out localization diff --git a/src/Utilities/AssemblyInfo.cs b/src/Utilities/AssemblyInfo.cs index 7c2299d2216..b2564a5e3e2 100644 --- a/src/Utilities/AssemblyInfo.cs +++ b/src/Utilities/AssemblyInfo.cs @@ -18,6 +18,7 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] #endif [assembly: InternalsVisibleTo("Microsoft.Build.Utilities.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] [assembly: InternalsVisibleTo("Microsoft.Build.Utilities.Whidbey.Unittest, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] diff --git a/src/XMakeBuildEngine/AssemblyInfo.cs b/src/XMakeBuildEngine/AssemblyInfo.cs index a5db3ae6e78..60da61f054d 100644 --- a/src/XMakeBuildEngine/AssemblyInfo.cs +++ b/src/XMakeBuildEngine/AssemblyInfo.cs @@ -23,6 +23,7 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] #endif [assembly: InternalsVisibleTo("Microsoft.Build.Engine.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] [assembly: InternalsVisibleTo("Microsoft.Build.Conversion.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] diff --git a/src/XMakeBuildEngine/Definition/ProjectCollection.cs b/src/XMakeBuildEngine/Definition/ProjectCollection.cs index 01388988da3..1f19b57e258 100644 --- a/src/XMakeBuildEngine/Definition/ProjectCollection.cs +++ b/src/XMakeBuildEngine/Definition/ProjectCollection.cs @@ -403,7 +403,7 @@ public static Version Version // work when Microsoft.Build.dll has been shadow-copied, for example // in scenarios where NUnit is loading Microsoft.Build. var versionInfo = FileVersionInfo.GetVersionInfo(FileUtilities.ExecutingAssemblyPath); - s_engineVersion = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart); + s_engineVersion = new Version(versionInfo.FileMajorPart, versionInfo.FileMinorPart, versionInfo.FileBuildPart, versionInfo.FilePrivatePart); } return s_engineVersion; diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectCollection_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectCollection_Tests.cs index e456ad690d7..75b5be12f9f 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectCollection_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectCollection_Tests.cs @@ -1438,7 +1438,8 @@ public void ProjectCollectionVersionIsCorrect() { Version expectedVersion = new Version(MSBuildConstants.CurrentAssemblyVersion); - Assert.Equal(expectedVersion, ProjectCollection.Version); + Assert.Equal(expectedVersion.Major, ProjectCollection.Version.Major); + Assert.Equal(expectedVersion.Minor, ProjectCollection.Version.Minor); } /// diff --git a/src/XMakeCommandLine/AssemblyInfo.cs b/src/XMakeCommandLine/AssemblyInfo.cs index 783a3bbca41..7700f12e544 100644 --- a/src/XMakeCommandLine/AssemblyInfo.cs +++ b/src/XMakeCommandLine/AssemblyInfo.cs @@ -9,6 +9,7 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] #endif [assembly: InternalsVisibleTo("Microsoft.Build.CommandLine.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] [assembly: InternalsVisibleTo("Microsoft.Build.Utilities.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] diff --git a/src/XMakeCommandLine/MSBuildTaskHost/AssemblyInfo.cs b/src/XMakeCommandLine/MSBuildTaskHost/AssemblyInfo.cs index 8db93fe3c0a..d443e6b7419 100644 --- a/src/XMakeCommandLine/MSBuildTaskHost/AssemblyInfo.cs +++ b/src/XMakeCommandLine/MSBuildTaskHost/AssemblyInfo.cs @@ -5,4 +5,5 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] #endif diff --git a/src/XMakeConversion/AssemblyInfo.cs b/src/XMakeConversion/AssemblyInfo.cs index 4bab6f326be..1c3529c3085 100644 --- a/src/XMakeConversion/AssemblyInfo.cs +++ b/src/XMakeConversion/AssemblyInfo.cs @@ -31,6 +31,11 @@ [assembly: AssemblyProduct("Microsoft® Build Tools®")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] +#if STATIC_VERSION_NUMBER +[assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +#endif + #if (LOCALIZED_BUILD) // Needed for the "hub-and-spoke model to locate and retrieve localized resources": https://msdn.microsoft.com/en-us/library/21a15yht(v=vs.110).aspx // We want "en" to require a satellite assembly for debug builds in order to flush out localization diff --git a/src/XMakeTasks/AssemblyInfo.cs b/src/XMakeTasks/AssemblyInfo.cs index e8c2c639225..e185fbcf082 100644 --- a/src/XMakeTasks/AssemblyInfo.cs +++ b/src/XMakeTasks/AssemblyInfo.cs @@ -15,6 +15,7 @@ #if STATIC_VERSION_NUMBER [assembly: AssemblyVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] +[assembly: AssemblyFileVersion(Microsoft.Build.Shared.MSBuildConstants.CurrentAssemblyVersion)] #endif [assembly: InternalsVisibleTo("Microsoft.Build.Tasks.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] [assembly: InternalsVisibleTo("Microsoft.Build.Tasks.Whidbey.Unittest, PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4")] diff --git a/src/dir.targets b/src/dir.targets index 3f807dc88db..4c886be2710 100644 --- a/src/dir.targets +++ b/src/dir.targets @@ -77,8 +77,8 @@ - + Condition="'$(MSBuildRuntimeType)' == 'Full'" /> + $(DefineConstants);STATIC_VERSION_NUMBER From 0cd5b42d11e8d05ed9ca7f5843606d9358d21c03 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 4 Nov 2016 14:58:19 -0700 Subject: [PATCH 054/223] Neutral xlf (#1288) Addresses #1259 * Generate neutral xlf file * Initial commit of neutral xlf files --- .../LocalizationTasks/ConvertToNeutralXlf.cs | 93 + .../EmitLocalizedResources.cs | 25 +- build/LocalizationTasks/LocalizationUtils.cs | 44 + .../Microsoft.Build.LocalizationTasks.csproj | 20 +- .../Microsoft.Build.Framework.csproj | 1 + src/OrcasEngine/Resources/xlf/Strings.xlf | 1820 +++++++++++++ src/Shared/Resources/xlf/Strings.shared.xlf | 227 ++ src/UpdateLocalizedResources.targets | 11 +- src/Utilities/Resources/xlf/Strings.xlf | 224 ++ .../Resources/xlf/Strings.xlf | 1582 +++++++++++ .../Resources/xlf/Strings.xlf | 887 ++++++ src/XMakeConversion/Resources/xlf/Strings.xlf | 122 + .../xlf/Strings.ManifestUtilities.xlf | 75 + src/XMakeTasks/Resources/xlf/Strings.xlf | 2396 +++++++++++++++++ src/dir.targets | 3 +- 15 files changed, 7494 insertions(+), 36 deletions(-) create mode 100644 build/LocalizationTasks/ConvertToNeutralXlf.cs create mode 100644 build/LocalizationTasks/LocalizationUtils.cs create mode 100644 src/OrcasEngine/Resources/xlf/Strings.xlf create mode 100644 src/Shared/Resources/xlf/Strings.shared.xlf create mode 100644 src/Utilities/Resources/xlf/Strings.xlf create mode 100644 src/XMakeBuildEngine/Resources/xlf/Strings.xlf create mode 100644 src/XMakeCommandLine/Resources/xlf/Strings.xlf create mode 100644 src/XMakeConversion/Resources/xlf/Strings.xlf create mode 100644 src/XMakeTasks/ManifestUtil/Resources/xlf/Strings.ManifestUtilities.xlf create mode 100644 src/XMakeTasks/Resources/xlf/Strings.xlf diff --git a/build/LocalizationTasks/ConvertToNeutralXlf.cs b/build/LocalizationTasks/ConvertToNeutralXlf.cs new file mode 100644 index 00000000000..4c3f5be3a09 --- /dev/null +++ b/build/LocalizationTasks/ConvertToNeutralXlf.cs @@ -0,0 +1,93 @@ +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Microsoft.Build.LocalizationTasks +{ + public class ConvertToNeutralXlf : Task + { + /// + /// Path to the neutral resx files to generate a corresponding neutral xlf from. + /// + [Required] + public ITaskItem[] NeutralResources { get; set; } + + public override bool Execute() + { + if (NeutralResources.Length == 0) + { + Log.LogError($"Task was called with empty {nameof(NeutralResources)}"); + } + + foreach (var neutralResource in NeutralResources) + { + var localizedXlf = LocalizationUtils.LocalizedXlfFiles(neutralResource).FirstOrDefault(); + + if (localizedXlf == null) + { + Log.LogError($"{neutralResource} has no corresponding xlf files"); + } + + var outputFilename = ComputeNeutralXlfName(neutralResource); + + MakeNeutral(localizedXlf, outputFilename); + } + + return !Log.HasLoggedErrors; + } + + private string ComputeNeutralXlfName(ITaskItem neutralResouce) + { + var filename = neutralResouce.GetMetadata("Filename"); + var xlfRootPath = LocalizationUtils.ComputeXlfRootPath(neutralResouce); + + return Path.Combine(xlfRootPath, filename + ".xlf"); + } + + private static void MakeNeutral(string inputfilename, string outputfilename) + { + //need to load xml file + var doc = XDocument.Load(inputfilename); + + //step 1: remove target-language attribute + //< file datatype = "xml" source - language = "en" target - language = "cs" original = "../Strings.shared.resx" > + var fileNodes = from node in doc.Descendants() + where node.Name.LocalName != null && node.Name.LocalName == "file" + select node; + fileNodes.ToList().ForEach(x => + { + if (x.HasAttributes) + { + foreach (var attrib in x.Attributes()) + { + if (attrib.Name == "target-language") + attrib.Remove(); + } + } + }); + + //step 2: remove all tags with "target" + // < target state = "new" > MSBuild is expecting a valid "{0}" object. + var targetNodes = from node in doc.Descendants() + where node.Name.LocalName != null && node.Name.LocalName == "target" + select node; + targetNodes.ToList().ForEach(x => x.Remove()); + + //save + var fi = new FileInfo(outputfilename); + + if (fi.Exists) + { + fi.Delete(); + } + if (fi.Directory.Exists == false) + { + fi.Directory.Create(); + } + + doc.Save(fi.FullName); + } + } +} \ No newline at end of file diff --git a/build/LocalizationTasks/EmitLocalizedResources.cs b/build/LocalizationTasks/EmitLocalizedResources.cs index 8e0787cfe8b..900e38452fb 100644 --- a/build/LocalizationTasks/EmitLocalizedResources.cs +++ b/build/LocalizationTasks/EmitLocalizedResources.cs @@ -31,13 +31,6 @@ public class EmitLocalizedResources : Task [Required] public string LocalizedResxRoot { get; set; } - /// - /// Path to the root directory that contains the xlf files for a neutral resource - /// Assumes all neutral resource have the same relative path to their xlf - /// - [Required] - public string RelativePathToXlfRoot { get; set; } - [Output] public ITaskItem[] ResolvedXlfResources { get; set; } @@ -78,8 +71,7 @@ private ITaskItem ComputeLocalizedResource(ITaskItem xlf) private IEnumerable ComputeXlfResourceItems(ITaskItem neutralResource) { - var neutralResxRootDirectory = Path.GetDirectoryName(neutralResource.GetMetadata("FullPath")); - var xlfRootPath = Path.Combine(neutralResxRootDirectory, RelativePathToXlfRoot); + string xlfRootPath = LocalizationUtils.ComputeXlfRootPath(neutralResource); if (!Directory.Exists(xlfRootPath)) { @@ -87,20 +79,9 @@ private IEnumerable ComputeXlfResourceItems(ITaskItem neutralResource $"Could not find expected xlf root {xlfRootPath} next to its neutral resource {neutralResource.ItemSpec}"); } - var resx = neutralResource.ItemSpec; - return - (Directory.EnumerateFiles(xlfRootPath) - .Where(f => IsValidXlf(f, resx)) - .Select((f => CreateXLFTaskItemForNeutralResx(f, resx)))); - } - - private bool IsValidXlf(string xlfPath, string resx) - { - var resxFileName = Path.GetFileNameWithoutExtension(resx); - var xlfFileName = Path.GetFileName(xlfPath); - - return Regex.IsMatch(xlfFileName, $"^{resxFileName}\\.[a-zA-Z\\-]+\\.xlf$"); + LocalizationUtils.LocalizedXlfFiles(neutralResource) + .Select(f => CreateXLFTaskItemForNeutralResx(f, neutralResource.ItemSpec)); } private ITaskItem CreateXLFTaskItemForNeutralResx(string xlfPath, string neutralResx) diff --git a/build/LocalizationTasks/LocalizationUtils.cs b/build/LocalizationTasks/LocalizationUtils.cs new file mode 100644 index 00000000000..60768d60df8 --- /dev/null +++ b/build/LocalizationTasks/LocalizationUtils.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Microsoft.Build.LocalizationTasks +{ + public static class LocalizationUtils + { + /// + /// Path to the root directory that contains the xlf files for a neutral resource + /// Assumes all neutral resource have the same relative path to their xlf + /// + public static string RelativePathToXlfRoot = "xlf"; + + public static string ComputeXlfRootPath(ITaskItem neutralResource) + { + var neutralResxRootDirectory = Path.GetDirectoryName(neutralResource.GetMetadata("FullPath")); + return Path.Combine(neutralResxRootDirectory, RelativePathToXlfRoot); + } + + public static bool IsValidLocalizedXlfName(string xlfPath, string neutralResx) + { + var resxFileName = Path.GetFileNameWithoutExtension(neutralResx); + var xlfFileName = Path.GetFileName(xlfPath); + + return Regex.IsMatch(xlfFileName, $"^{resxFileName}\\.[a-zA-Z\\-]+\\.xlf$"); + } + + public static IEnumerable LocalizedXlfFiles(string xlfRootPath, string neutralResx) + { + return Directory.EnumerateFiles(xlfRootPath) + .Where(f => IsValidLocalizedXlfName(f, neutralResx)); + } + + public static IEnumerable LocalizedXlfFiles(ITaskItem neutralResouce) + { + return LocalizedXlfFiles(ComputeXlfRootPath(neutralResouce), neutralResouce.ItemSpec); + } + } +} \ No newline at end of file diff --git a/build/LocalizationTasks/Microsoft.Build.LocalizationTasks.csproj b/build/LocalizationTasks/Microsoft.Build.LocalizationTasks.csproj index c5f42d134f4..7b9b65aa277 100644 --- a/build/LocalizationTasks/Microsoft.Build.LocalizationTasks.csproj +++ b/build/LocalizationTasks/Microsoft.Build.LocalizationTasks.csproj @@ -1,28 +1,26 @@ - + - Debug AnyCPU Library Microsoft.Build.LocalizationTasks Microsoft.Build.LocalizationTasks + {06347A6C-32A4-4218-A930-0A22699C726C} - - + - - - + + - + + + - - - + \ No newline at end of file diff --git a/src/Framework/Microsoft.Build.Framework.csproj b/src/Framework/Microsoft.Build.Framework.csproj index cbade8c9ea4..d389927a807 100644 --- a/src/Framework/Microsoft.Build.Framework.csproj +++ b/src/Framework/Microsoft.Build.Framework.csproj @@ -7,6 +7,7 @@ Properties Microsoft.Build.Framework Microsoft.Build.Framework + true diff --git a/src/OrcasEngine/Resources/xlf/Strings.xlf b/src/OrcasEngine/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..fe475fe6802 --- /dev/null +++ b/src/OrcasEngine/Resources/xlf/Strings.xlf @@ -0,0 +1,1820 @@ + + + +
+ + 4013 + 1176.8 + 1176.8 + 0 + 0 + + + 0 + 981 + 2334 + 0 + 0 + 698 + 0 + +
+ + + + MSB4001: The "{0}" task has more than one parameter called "{1}". + {StrBegin="MSB4001: "}UE: This message is shown when a task has more than one .NET property with the same name -- it's unclear which of + those properties the task wants to use as a parameter in project files. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4081: The value "{0}" of the "ItemName" attribute in element <Output> contains an "@" character. If you intended to use an item name then remove the @( ) around the item name. + {StrBegin="MSB4081: "}UE: This message is shown when an output tag has an itemname that contains an @. They probably typed @(foo) instead of foo in the ItemName.LOCALIZATION: Output and ItemName should not be localized. + + fuzzyMatch="15" wordcount="30" adjWordcount="25.5" curWordcount="25.5" + + + MSB4002: There was a failure retrieving the attributes for parameters in the "{0}" task. {1} + {StrBegin="MSB4002: "}UE: This message is shown when the .NET attributes that a task's .NET properties are decorated with, cannot be + retrieved -- this is typically because the .NET classes that define the .NET attributes cannot be loaded because the assembly + they are defined in cannot be found, or the classes themselves cannot be found. + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + MSB4003: "{0}" is a reserved attribute of the <{1}> element, and must be spelled with the correct casing. This attribute cannot be used as a parameter to the "{2}" task. + {StrBegin="MSB4003: "}UE: Tasks are not allowed to use incorrect case for reserved attributes on the task nodes e.g. "continueonerror" + instead of the "ContinueOnError". + + fuzzyMatch="15" wordcount="31" adjWordcount="26.35" curWordcount="26.35" + + + The "REQUESTBATCHSIZE" must be a number greater than 1. "{0}" is an invalid value. The value 10 will be used instead. + The name "REQUESTBATCHSIZE" is an environment variable + + fuzzyMatch="100" wordcount="21" adjWordcount="5.25" curWordcount="5.25" tmLabel="N''" + + + Build completed in {0}. + + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + Build FAILED. + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Build succeeded. + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Build started. + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Build started {0}. + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Building target "{0}" completely. + {0} is the name of the target. + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + No input files were specified. + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Input file "{0}" is newer than output file "{1}". + {0} and {1} are filenames on disk. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + Output file "{0}" does not exist. + {0} is a filename on disk. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Input file "{0}" does not exist. + {0} is a filename on disk. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Building target "{0}" partially, because some output files are out of date with respect to their input files. + {0} is the name of the target. + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + [{0}: Input={1}, Output={2}] Input file is newer than output file. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + [{0}: Input={1}, Output={2}] Output file does not exist. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + [{0}: Input={1}, Output={2}] Input file does not exist. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + The attribute "{0}" is a known MSBuild attribute, and cannot be accessed using this method. + + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + Properties in persisted property groups cannot be accessed by name. + + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4023: Cannot evaluate the item metadata "%({0})". {1} + {StrBegin="MSB4023: "}UE: This message is shown when the value of an item metadata cannot be computed for some reason e.g. trying to apply + %(RootDir) to an item-spec that's not a valid path, would result in this error. + LOCALIZATION: "{1}" is a localized message explaining the problem. + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Cannot execute a task not associated with a project object. + + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + The cache entry has already been set to a different value and cannot be modified. + + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + The "{0}" property comes from an environment variable, and cannot be modified. + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + The "{0}" property is a global property, and cannot be modified through an evaluated property group. Use "{1}" instead. + + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + Modifying the XML of an imported project file is not allowed. Open that project file directly. + + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + MSB4117: The "{0}" item name is reserved, and cannot be used. + {StrBegin="MSB4117: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild items e.g. @(Choose) + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4118: The "{0}" item metadata name is reserved, and cannot be used. + {StrBegin="MSB4118: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild items e.g. @(Choose) + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4004: The "{0}" property is reserved, and cannot be modified. + {StrBegin="MSB4004: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild properties e.g. $(MSBuildProjectFile) + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4094: "{0}" is an invalid value for the "{1}" parameter of the "{3}" task. Multiple items cannot be passed into a parameter of type "{2}". + {StrBegin="MSB4094: "} + UE: This error is shown when a project tries to pass multiple items into a task parameter of type ITaskItem (singular). + + + fuzzyMatch="101" wordcount="25" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4115: The "{0}" function only accepts a scalar value, but its argument "{1}" evaluates to "{2}" which is not a scalar value. + {StrBegin="MSB4115: "} + UE: This error is shown when a project tries to pass multiple items into a function in a conditional expression, that can only accept a scalar value (such as the "exists()" function). + + + fuzzyMatch="100" wordcount="22" adjWordcount="5.5" curWordcount="5.5" tmLabel="N''" + + + The task is currently associated with a project object, and should not be added to a different one. + + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + MSB4095: The item metadata %({0}) is being referenced without an item name. Specify the item name by using %(itemname.{0}). + {StrBegin="MSB4095: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + The task is not associated with the specified target element collection, and should not be removed from it. + + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + MSB4005: The current working directory could not be restored to {0}. {1} + {StrBegin="MSB4005: "}UE: This message is shown when the current working directory cannot be reset after a build. "{1}" contains a message explaining why. + LOCALIZATION: "{1}" is a message from an CLR/FX exception and is already localized. + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Cannot set a condition on an object not represented by an XML element in the project file. + + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + Cannot set ContinueOnError on an object not represented by an XML element in the project file. + + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + MSB4134: DefaultToolsVersion cannot be set after a project has been loaded into the Engine. + {StrBegin="MSB4134: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + Assigning the "{0}" attribute on an item that has been evaluated is not allowed. This operation is only allowed on the original persisted item that came directly from the project file. + + + fuzzyMatch="101" wordcount="31" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Assigning the "{0}" attribute of a virtual item is not allowed. + + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + A property cannot be set while building. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + A property cannot be set to null. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Cannot get or set parameters on a task not associated with a project object. + + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4162: <{0}> is not valid. Child elements are not allowed below a item remove element. + {StrBegin="MSB4162: "} + + fuzzyMatch="15" wordcount="16" adjWordcount="13.6" curWordcount="13.6" + + + MSB4166: Child node "{0}" exited prematurely. Shutting down. + {StrBegin="MSB4166: "} + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4085: A <Choose> must contain at least one <When>. + {StrBegin="MSB4085: "} + + fuzzyMatch="15" wordcount="11" adjWordcount="9.35" curWordcount="9.35" + + + MSB4114: <Choose> elements cannot be nested more than {0} levels deep. + {StrBegin="MSB4114: "}UE: This message appears if the project file contains unreasonably nested Choose elements. + LOCALIZATION: Do not localize "Choose" as it is an XML element name. + + fuzzyMatch="15" wordcount="12" adjWordcount="10.2" curWordcount="10.2" + + + MSB4006: There is a circular dependency in the target dependency graph involving target "{0}". + {StrBegin="MSB4006: "}UE: This message is shown when the build engine detects a target referenced in a circular manner -- a project cannot + request a target to build itself (perhaps via a chain of other targets). + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4086: A numeric comparison was attempted on "{1}" that evaluates to "{2}" instead of a number, in condition "{0}". + {StrBegin="MSB4086: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB4007: The clause "{0}", specified in the "{1}" attribute is invalid. + {StrBegin="MSB4007: "}UE: This message is shown when the Condition on an element is invalid in some way -- e.g. syntax error, unrecognized operator. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4130: The condition "{0}" may have been evaluated incorrectly in an earlier version of MSBuild. Please verify that the order of the AND and OR clauses is written as intended. To avoid this warning, add parentheses to make the evaluation order explicit. + {StrBegin="MSB4130: "} + + fuzzyMatch="101" wordcount="42" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4087: Specified condition "{0}" does not evaluate to a boolean. + {StrBegin="MSB4087: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4113: Specified condition "{0}" evaluates to "{1}" instead of a boolean. + {StrBegin="MSB4113: "} + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + {0}, line {1} + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + MSB4136: Error reading the toolset information from the configuration file "{0}". {1} + {StrBegin="MSB4136: "} + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4008: A conflicting assembly for the task assembly "{0}" has been found at "{1}". + {StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly. + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4142: MSBuildToolsPath is not the same as MSBuildBinPath for the ToolsVersion "{0}" defined at "{1}". If both are present they must have the same value. + {StrBegin="MSB4142: "} + + fuzzyMatch="101" wordcount="25" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4097: The element <{0}> beneath element <{1}> may not have a custom XML namespace. + {StrBegin="MSB4097: "} + + fuzzyMatch="15" wordcount="16" adjWordcount="13.6" curWordcount="13.6" + + + MSB4009: The default tasks file could not be successfully loaded. {0} + {StrBegin="MSB4009: "}UE: This message is shown when one of the default tasks file (*.tasks) located alongside the MSBuild binaries cannot + be opened/parsed. "{0}" contains a message explaining why. The filename itself is not part of the message but is provided + separately to loggers. + LOCALIZATION: "{0}" is a message from some FX method and is already localized. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4010: The "{0}" files could not be successfully loaded from their expected location "{1}". Default tasks will not be available. {2} + {StrBegin="MSB4010: "}UE: This message is shown when the default tasks files that are located alongside the MSBuild binaries cannot be + found, either because they don't exist, or because of lack of permissions. "{2}" contains a message explaining why. + LOCALIZATION: "{2}" is a message from some FX method and is already localized. + + fuzzyMatch="100" wordcount="21" adjWordcount="5.25" curWordcount="5.25" tmLabel="N''" + + + MSB4140: Default tools version is specified in neither the registry nor the configuration file. + {StrBegin="MSB4140: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4133: A default tools version "{0}" was specified, but its definition could not be found. + {StrBegin="MSB4133: "} + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + MSB4080: The value "{0}" of the "PropertyName" attribute in element <Output> contains a "$" character. If you intended to use a property name then remove the $( ) around the property name. + {StrBegin="MSB4080: "}UE: This message is shown when an output tag has an property name that contains an $. They probably typed $(foo) instead of foo in the PropertyName. LOCALIZATION: Output and PropertyName should not be localized. + + fuzzyMatch="15" wordcount="32" adjWordcount="27.2" curWordcount="27.2" + + + MSB4011: There is a circular reference involving the import of file "{0}". This file may have been imported more than once, or you may have attempted to import the main project file. All except the first instance of this file will be ignored. + {StrBegin="MSB4011: "} + + fuzzyMatch="101" wordcount="43" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4079: The <ProjectExtensions> element occurs more than once. + {StrBegin="MSB4079: "} + + fuzzyMatch="15" wordcount="9" adjWordcount="7.65" curWordcount="7.65" + + + MSB4012: The expression "{0}" cannot be used in this context. Item lists cannot be concatenated with other strings where an item list is expected. Use a semicolon to separate multiple item lists. + {StrBegin="MSB4012: "}UE: This message is shown when the user does not properly specify an item list when an item list is expected + e.g. "badprefix@(foo)badsuffix" instead of "prefix; @(foo); suffix" + + fuzzyMatch="101" wordcount="32" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Need to specify the project file name. + UE: This message is shown when the user calls into the engine to build a project without specifying a filename. + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + end of input + This is the name of the "EndOfInput" token. It is displayed in quotes as the + unexpected char or token when the end of a conditional was unexpectedly reached. + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + The previous error was converted to a warning because the task was called with ContinueOnError=true. + + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + {0} Error(s) + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4159: Error creating the toolset "{0}". {1} + {StrBegin="MSB4159: "} + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4146: Cannot evaluate the property expression "{0}" found at "{1}". {2} + {StrBegin="MSB4146: "} + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + The <{0}> tag is no longer supported as a child of the <Project> element. Place this tag within a target, and add the name of the target to the "InitialTargets" attribute of the <Project> element. + + + fuzzyMatch="15" wordcount="38" adjWordcount="32.3" curWordcount="32.3" + + + MSB4100: Expected "{0}" to evaluate to a boolean instead of "{1}", in condition "{2}". + {StrBegin="MSB4100: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4028: The "{0}" task's outputs could not be retrieved from the "{1}" parameter. {2} + {StrBegin="MSB4028: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4014: The build was aborted because of an internal failure. + {StrBegin="MSB4014: "}UE: This message is shown when an unhandled exception terminates the build. The cause is most likely a programming + error in the build engine. + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4015: The build was aborted because the "{0}" logger failed unexpectedly during shutdown. + {StrBegin="MSB4015: "}UE: This message is used for a special exception that is thrown when a logger fails while shutting down (most likely + because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a special + exception to abort the build. + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4016: The build was aborted because the "{0}" logger failed unexpectedly during initialization. + {StrBegin="MSB4016: "}UE: This message is used for a special exception that is thrown when a logger fails while initializing itself (most + likely because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a + special exception to abort the build. + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4017: The build was aborted because of an unexpected logger failure. + {StrBegin="MSB4017: "}UE: This message is used for a special exception that is thrown when a logger fails while logging an event (most + likely because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a + special exception to abort the build. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4018: The "{0}" task failed unexpectedly. + {StrBegin="MSB4018: "}UE: This message is shown when a task terminates because of an unhandled exception. The cause is most likely a + programming error in the task; however, it is also possible that the unhandled exception originated in the engine, and was + surfaced through the task when the task called into the engine. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4165: Failed to receive a response from the child node "{0}" in the timeout period "{1}" ms. Shutting down. + {StrBegin="MSB4165: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB4088: Condition "{0}" is improperly constructed. + {StrBegin="MSB4088: "} + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4105: Found an unexpected character '{2}' at position {1} in condition "{0}". Did you intend to use "=="? + {StrBegin="MSB4105: "} + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + MSB4106: Expected an item list at position {1} in condition "{0}". Did you forget the closing parenthesis? + {StrBegin="MSB4106: "} + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + MSB4107: Expected an item list at position {1} in condition "{0}". Did you forget the opening parenthesis after the '@'? To use a literal '@', use '%40' instead. + {StrBegin="MSB4107: "} + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4108: Expected an item list at position {1} in condition "{0}". Did you forget to close a quote inside the item list expression? + {StrBegin="MSB4108: "} + + fuzzyMatch="100" wordcount="23" adjWordcount="5.75" curWordcount="5.75" tmLabel="N''" + + + MSB4109: Expected a property at position {1} in condition "{0}". Did you forget the closing parenthesis? + {StrBegin="MSB4109: "} + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + MSB4110: Expected a property at position {1} in condition "{0}". Did you forget the opening parenthesis after the '$'? To use a literal '$', use '%24' instead. + {StrBegin="MSB4110: "} + + fuzzyMatch="101" wordcount="27" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4101: Expected a closing quote after position {1} in condition "{0}". + {StrBegin="MSB4101: "} + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4019: The imported project "{0}" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. + {StrBegin="MSB4019: "}LOCALIZATION: <Import> should not be localized. + + fuzzyMatch="15" wordcount="26" adjWordcount="22.1" curWordcount="22.1" + + + MSB4089: Incorrect number of arguments to function in condition "{0}". Found {1} argument(s) when expecting {2}. + {StrBegin="MSB4089: "} + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + The "{0}" object specified does not belong to the correct "{1}" object. + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4020: The value "{0}" of the "{1}" attribute in element <{2}> is invalid. + {StrBegin="MSB4020: "}UE: This is a generic message that is displayed when we find a project element with an incorrect value for one of its + attributes e.g. <Import Project=""> -- the value of Project should not be an empty string. + + fuzzyMatch="15" wordcount="14" adjWordcount="11.9" curWordcount="11.9" + + + MSB4102: The value "{0}" of the "{1}" attribute in element <{2}> is invalid. {3} + {StrBegin="MSB4102: "}UE: This is a generic message that is displayed when we find a project element with an incorrect value for one of its + attributes. At the end of the message we show the exception text we got trying to use the value. + + fuzzyMatch="15" wordcount="15" adjWordcount="12.75" curWordcount="12.75" + + + MSB4021: The "ContinueOnError" attribute of the "{0}" task is not valid. {1} + {StrBegin="MSB4021: "}LOCALIZATION: "ContinueOnError" should not be localized. "{1}" is a message from another exception explaining the problem. + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4139: Invalid value for default ToolsVersion is specified in registry key "{0}". + {StrBegin="MSB4139: "} + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4022: The result "{0}" of evaluating the value "{1}" of the "{2}" attribute in element <{3}> is not valid. + {StrBegin="MSB4022: "}UE: This message is shown when the engine is checking the correctness of the value (after evaluating embedded + properties/items) assigned to an XML attribute of an XML element in the project file. + + fuzzyMatch="15" wordcount="20" adjWordcount="17" curWordcount="17" + + + "{0}" is not a valid event category. To raise a custom event, use the "{1}" category. + + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + "{0}" is not a valid importance level for events. + + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4104: Failed to write to log file "{0}". {1} + {StrBegin="MSB4104: "}UE: This is shown when the File Logger can't create or write to the file it was instructed to log to. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4024: The imported project file could not be loaded. {0} + {StrBegin="MSB4024: "}UE: This message is shown when an imported project file cannot be loaded because of incorrect XML. The project + filename is not part of the message because it is provided separately to loggers. + LOCALIZATION: {0} is a localized message from the CLR/FX explaining why the project is invalid. + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + Operation invalid for a persisted item group. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Operation invalid for a virtual item group. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4071: The value Importance="{0}" in the <Message> element is invalid. Valid values are: High, Normal and Low. + {StrBegin="MSB4071: "}UE: This message is shown when a user specifies a value for the importance attribute of Message which is not valid. + The importance enumeration is: High, Normal and Low. Specifying any other importance will result in this message being shown + LOCALIZATION: "Importance" should not be localized. + "Message" should not be localized. + High should not be localized. + Normal should not be localized. + Low should not be localized. + + fuzzyMatch="15" wordcount="18" adjWordcount="15.3" curWordcount="15.3" + + + MSB4025: The project file could not be loaded. {0} + {StrBegin="MSB4025: "}UE: This message is shown when the project file given to the engine cannot be loaded because the filename/path is + invalid, or due to lack of permissions, or incorrect XML. The project filename is not part of the message because it is + provided separately to loggers. + LOCALIZATION: {0} is a localized message from the CLR/FX explaining why the project is invalid. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4147: The property "{0}" at "{1}" is invalid. {2} + {StrBegin="MSB4147: "} + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + "{0}" is an invalid "ProjectFileEncoding" value. + LOCALIZATION: "ProjectFileEncoding" should not be localized. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4143: The expression "{0}" cannot be evaluated. {1} + {StrBegin="MSB4143: "} + UE: This message is shown when the user attempts to provide an expression like "$(Registry:HKEY_LOCAL_MACHINE\Software\Vendor\Tools@TaskLocation)" + LOCALIZATION: "{0}" is the expression that was bad. "{1}" is a message from an FX exception that describes why the expression is bad. + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4184: The expression "{0}" cannot be evaluated. {1} + {StrBegin="MSB4184: "} + Single quotes as the expression will typically have double quotes in it. + UE: This message is shown when the user attempts to provide an expression like "$(SomeProperty.ToLower())" + LOCALIZATION: "{0}" is the expression that was bad. "{1}" is a message from an FX exception that describes why the expression is bad. + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4185: The function "{0}" on type "{1}" has not been enabled for execution. + {StrBegin="MSB4185: "} + UE: This message is shown when the user attempts to provide an expression like "$([System.DateTime]::Now)", but the expression has not been enabled + LOCALIZATION: "{0}" is the static function name, "{1}" is the .NET Framework type name + + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4186: Invalid static method invocation syntax: "{0}". Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)) + {StrBegin="MSB4186: "} + UE: This message is shown when the user attempts to call a static method on a type, but has used the incorrect syntax + LOCALIZATION: "{0}" is the function expression which is in error + + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB4070: The schema "{0}" is not valid. {1} + {StrBegin="MSB4070: "}UE: This message is shown when the schema file provided for the validation of a project is itself not valid. + LOCALIZATION: "{0}" is the schema file path. "{1}" is a message from an FX exception that describes why the schema file is bad. + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4026: The "{0}={1}" parameter for the "{2}" task is invalid. + {StrBegin="MSB4026: "}UE: This message is displayed when a task has an invalid parameter that cannot be initialized. + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4027: The "{0}" task generated invalid items from the "{1}" output parameter. {2} + {StrBegin="MSB4027: "} + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4029: The "{0}" task has an invalid output specification. The "TaskParameter" attribute is required, and either the "ItemName" or "PropertyName" attribute must be specified (but not both). + {StrBegin="MSB4029: "}LOCALIZATION: "TaskParameter", "ItemName" and "PropertyName" should not be localized. + + fuzzyMatch="101" wordcount="27" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4030: "{0}" is an invalid value for the "{1}" parameter of the "{3}" task. The "{1}" parameter is of type "{2}". + {StrBegin="MSB4030: "}UE: This error is shown when a type mis-match occurs between the value assigned to task parameter in the project file + and the type of the .NET property that corresponds to the task parameter. For example, if an int task parameter called "Count" + is assigned the value "x", this error would be displayed: <MyTask Count="x" /> + + fuzzyMatch="100" wordcount="21" adjWordcount="5.25" curWordcount="5.25" tmLabel="N''" + + + MSB4137: Invalid value specified in the configuration file at "{0}". Property name or tools version name is an empty string. + {StrBegin="MSB4137: "} + + fuzzyMatch="100" wordcount="20" adjWordcount="5" curWordcount="5" tmLabel="N''" + + + MSB4103: "{0}" is not a valid logger verbosity level. + {StrBegin="MSB4103: "} + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4163: <ItemDefinitionGroup> is not allowed inside a target. + {StrBegin="MSB4163: "} + + fuzzyMatch="15" wordcount="9" adjWordcount="7.65" curWordcount="7.65" + + + The specified item does not belong to the current item group. + + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4096: The item "{0}" in item list "{1}" does not define a value for metadata "{2}". In order to use this metadata, either qualify it by specifying %({1}.{2}), or ensure that all items in this list define a value for this metadata. + {StrBegin="MSB4096: "} + + fuzzyMatch="101" wordcount="42" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4099: A reference to an item list at position {1} is not allowed in this condition "{0}". + {StrBegin="MSB4099: "} + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + MSB4033: "{0}" is a reserved item metadata, and cannot be redefined as a custom metadata on the item. + {StrBegin="MSB4033: "} + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + An InternalLoggerException can only be thrown by the MSBuild engine. The public constructors of this class cannot be used to create an instance of the exception. + UE: This message is shown when a user tries to instantiate a special exception called InternalLoggerException through the OM -- + only the engine is allowed to create and throw this exception. + LOCALIZATION: "InternalLoggerException" and "MSBuild" should not be localized. + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Initial Items: + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4083: Expected a Condition attribute on element "{0}". + {StrBegin="MSB4083: "} + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4164: The value "{0}" of metadata "{1}" contains an item list expression. Item list expressions are not allowed on default metadata values. + {StrBegin="MSB4164: "} + + fuzzyMatch="100" wordcount="22" adjWordcount="5.5" curWordcount="5.5" tmLabel="N''" + + + MSBuild is expecting a valid "{0}" object. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4035: The required attribute "{0}" is missing from element <{1}>. + {StrBegin="MSB4035: "}UE: This message is shown when a user leaves off a required attribute from a project element + e.g. <UsingTask AssemblyName="foo"> -- this is missing the "TaskName" attribute. + + fuzzyMatch="15" wordcount="11" adjWordcount="9.35" curWordcount="9.35" + + + MSB4036: The "{0}" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "{1}" directory. + {StrBegin="MSB4036: "}LOCALIZATION: <UsingTask> and "*.tasks" should not be localized. + + fuzzyMatch="15" wordcount="64" adjWordcount="54.4" curWordcount="54.4" + + + MSB4141: MSBuildToolsPath is not specified for the ToolsVersion "{0}" defined at "{1}", or the value specified evaluates to the empty string. + {StrBegin="MSB4141: "} + + fuzzyMatch="100" wordcount="21" adjWordcount="5.25" curWordcount="5.25" tmLabel="N''" + + + MSB4031: The "MSBuildVersion" attribute is deprecated. If the project is authored in the MSBuild 2003 format, please remove the attribute from the <Project> tag. If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. + {StrBegin="MSB4031: "}UE: This message is shown for projects that still contain the "MSBuildVersion" attribute in their <Project> + tag. We no longer need this attribute because the project's XML namespace (i.e. the "xmlns" attribute) gives us all the + version information we need. + LOCALIZATION: "MSBuild", "MSBuildVersion" and <Project> should not be localized. + + fuzzyMatch="15" wordcount="45" adjWordcount="38.25" curWordcount="38.25" + + + MSB4144: Multiple definitions were found for the toolset "{0}". + {StrBegin="MSB4144: "} + + fuzzyMatch="15" wordcount="9" adjWordcount="7.65" curWordcount="7.65" + + + MSB4145: Multiple definitions were found for the property "{0}". + {StrBegin="MSB4145: "} + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4082: Choose has more than one <Otherwise> element. + {StrBegin="MSB4082: "} + + fuzzyMatch="15" wordcount="9" adjWordcount="7.65" curWordcount="7.65" + + + This method is only valid for persisted <{0}> elements. + + + fuzzyMatch="15" wordcount="10" adjWordcount="8.5" curWordcount="8.5" + + + This method is only valid for virtual property groups, not <{0}> elements. + + + fuzzyMatch="15" wordcount="13" adjWordcount="11.05" curWordcount="11.05" + + + MSB4038: The element <{0}> must be last under element <{1}>. Found element <{2}> instead. + {StrBegin="MSB4038: "} + + fuzzyMatch="15" wordcount="17" adjWordcount="14.45" curWordcount="14.45" + + + MSB4138: Non-string data was specified at the registry location "{0}". + {StrBegin="MSB4138: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4039: No "{0}" element was found in the project file. + {StrBegin="MSB4039: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4040: There is no target in the project. + {StrBegin="MSB4040: "} + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Removing the "{0}" attribute of an item is not allowed. + + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + The object passed in is not part of the project. + + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + Overriding target "{0}" in project "{1}" with target "{2}" from project "{3}". + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4167: The parent process unexpectedly exited. Shutting down child node "{0}". + {StrBegin="MSB4167: "} + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + {0} ms {1} {2} calls + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + (* = timing was not recorded because of reentrancy) + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + This project object has been unloaded from the MSBuild engine and is no longer valid. + + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + The project file "{0}" was not found. + UE: This message is shown when the user calls into the OM to build a project that doesn't exist on disk. + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Done building project "{0}" -- FAILED. + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Done building project "{0}". + + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + MSB4041: The default XML namespace of the project must be the MSBuild XML namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="{0}" to the <Project> element. If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. + {StrBegin="MSB4041: "}UE: This is a Beta 1 message only. + LOCALIZATION: <Project>, "MSBuild" and "xmlns" should not be localized. + + fuzzyMatch="15" wordcount="52" adjWordcount="44.2" curWordcount="44.2" + + + Project Performance Summary: + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + MSB4042: Stopping because of syntax errors in project file. + {StrBegin="MSB4042: "} + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + Project "{0}" is building "{1}" ({2} target(s)): + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Project "{0}" is building "{1}" (default targets): + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Project "{0}" ({1} target(s)): + + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + Project "{0}" (default targets): + + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + Done Building Project "{0}" ({1} target(s)). + + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Done Building Project "{0}" (default targets). + + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Done Building Project "{0}" ({1} target(s)) -- FAILED. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Done Building Project "{0}" (default targets) -- FAILED. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4075: The project file must be opened in the Visual Studio IDE and converted to the latest version before it can be built by MSBuild. + {StrBegin="MSB4075: "} + + fuzzyMatch="101" wordcount="25" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4192: The project file "{0}" is in the ".vcproj" file format, which MSBuild no longer supports. Please convert the project by opening it in the Visual Studio IDE or running the conversion tool, or use MSBuild 3.5 or earlier to build it. + {StrBegin="MSB4192: "} LOC: ".vcproj" should not be localized + + fuzzyMatch="101" wordcount="42" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + The specified property does not belong to the current property group. + + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + Initial Properties: + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4148: The name of a property stored under the registry key "{0}" has zero length. + {StrBegin="MSB4148: "} + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + The property names in the indexer and the "{0}" object do not match. + + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4043: The item metadata reference "{0}" is invalid because it is qualified with an item name. Item metadata referenced in transforms do not need to be qualified, because the item name is automatically deduced from the items being transformed. Change "{0}" to "%({1})". + {StrBegin="MSB4043: "}UE: This message is shown when the user does something like this: @(foo->'%(foo.metadata)'). There is no need to specify + "foo.metadata", because "foo" is automatically deduced. In corollary, "bar.metadata" is not allowed either, where "bar" is a different + item list type. + + fuzzyMatch="101" wordcount="43" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4135: Error reading the toolset information from the registry location "{0}". {1} + {StrBegin="MSB4135: "} + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4044: The "{0}" task was not given a value for the required parameter "{1}". + {StrBegin="MSB4044: "}UE: This message is shown when a task parameter designated as "required" is not set in the project file. + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + Validating project using schema file "{0}". + LOCALIZATION: "{0}" is the location of the schema file. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4045: Project is not valid. {0} + {StrBegin="MSB4045: "}UE: This error is shown when the user asks his project to be validated against a schema (/val switch for + MSBuild.exe), and the project has errors. "{0}" contains a message explaining the problem. + LOCALIZATION: "{0}" is a message from the System.XML schema validator and is already localized. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4112: The targets in this project have been disabled by the host and therefore cannot be built at this time. This may have been done for security reasons. To enable the targets, the host must set Project.BuildEnabled to "true". + {StrBegin="MSB4112: "} + + fuzzyMatch="101" wordcount="39" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4093: The "{0}" parameter of the "{1}" task cannot be written to because it does not have a "set" accessor. + {StrBegin="MSB4093: "}UE: This error is shown when a project tries to assign a value to a task parameter that does not have a "set" + accessor on the corresponding .NET property on the task class. + + fuzzyMatch="100" wordcount="20" adjWordcount="5" curWordcount="5" tmLabel="N''" + + + A shallow clone of this object cannot be created. + + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + Skipping target "{0}" because it has no inputs. + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Though the target has declared its inputs, the input specification only references empty properties and/or empty item lists. + + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + Skipping target "{0}" because it has no outputs. + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Though the target has declared its outputs, the output specification only references empty properties and/or empty item lists. + + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + Skipping target "{0}" because all output files are up-to-date with respect to the input files. + + + fuzzyMatch="100" wordcount="15" adjWordcount="3.75" curWordcount="3.75" tmLabel="N''" + + + Input files: {0} + {0} is a semicolon-separated list of filenames. + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Output files: {0} + {0} is a semicolon-separated list of filenames. + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Building solution configuration "{0}". + UE: This is not an error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + Using solution cache file "{0}" for configuration "{1}" and tools version "{2}". + UE: This is not an error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Failed to read solution cache file "{0}". {1} Using solution file directly. + UE: This is not a true error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Failed to write solution cache file "{0}". {1} + UE: This is not a true error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Solution cache file was created for a "{0}" value of "{1}" but the current value is "{2}". Refreshing cache file. + UE: This is not an error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="20" adjWordcount="5" curWordcount="5" tmLabel="N''" + + + Solution cache file has an internal version number "{0}" but the current value is "{1}". Refreshing cache file. + UE: This is not an error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + Solution cache file is out of date. Refreshing cache file. {0} + UE: This is not an error, so doesn't need an error code. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB4160: A circular dependency involving project "{0}" has been detected. + {StrBegin="MSB4160: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4126: The specified solution configuration "{0}" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration. + {StrBegin="MSB4126: "}UE: The solution filename is provided separately to loggers. + + fuzzyMatch="101" wordcount="37" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4046: Error reading project file "{0}": {1} + {StrBegin="MSB4046: "} + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4125: The project file name "{0}" is invalid. {1} + {StrBegin="MSB4125: "}UE: The solution filename is provided separately to loggers. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4051: Project {0} is referencing a project with GUID {1}, but a project with this GUID was not found in the .SLN file. + {StrBegin="MSB4051: "}UE: The solution filename is provided separately to loggers. + + fuzzyMatch="100" wordcount="23" adjWordcount="5.75" curWordcount="5.75" tmLabel="N''" + + + MSB4078: The project file "{0}" is not supported by MSBuild and cannot be built. + {StrBegin="MSB4078: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4054: The solution file must be opened in the Visual Studio IDE and converted to the latest version before it can be built by MSBuild. + {StrBegin="MSB4054: "}UE: The solution filename is provided separately to loggers. + + fuzzyMatch="101" wordcount="25" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4121: The project configuration for project "{0}" was not specified in the solution file for the solution configuration "{1}". + {StrBegin="MSB4121: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + The project "{0}" is not selected for building in solution configuration "{1}". + + UE: This is not an error, so doesn't need an error code. + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4122: Scanning project dependencies for project "{0}" failed. {1} + {StrBegin="MSB4122: "} + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4149: The tools version "{0}" of the solution does not support building projects with a different tools version. + {StrBegin="MSB4149: "} + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + Web projects do not support the "Clean" target. Continuing with remaining projects ... + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do not localize "Clean". + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Web projects do not support the "Publish" target. Continuing with remaining projects ... + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do not localize "Publish". + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Skipping because the "$(AspNetConfiguration)" configuration is not supported for this web project. You can use the AspNetConfiguration property to override the configuration used for building web projects, by adding /p:AspNetConfiguration=<value> to the command line. Currently web projects only support Debug and Release configurations. + + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do NOT localize "AspNetConfiguration", "Debug", "Release". + + + fuzzyMatch="15" wordcount="44" adjWordcount="37.4" curWordcount="37.4" + + + MSB4076: VC projects do not support the "Publish" target. + {StrBegin="MSB4076: "}LOCALIZATION: Do not localize "Publish". + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4098: MSBuild is invoking VCBuild to build this project. Project-to-project references between VC++ projects (.VCPROJ) and C#/VB/VJ# projects (.CSPROJ, .VBPROJ, .VJSPROJ) are not supported by the command-line build systems when building stand-alone VC++ projects. Projects that contain such project-to-project references will fail to build. Please build the solution file containing this project instead. + {StrBegin="MSB4098: "} + + fuzzyMatch="101" wordcount="53" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4056: The MSBuild engine must be called on a single-threaded-apartment. Current threading model is "{0}". Proceeding, but some tasks may not function correctly. + {StrBegin="MSB4056: "} + + fuzzyMatch="100" wordcount="23" adjWordcount="5.75" curWordcount="5.75" tmLabel="N''" + + + Schema validation + UE: this fragment is used to describe errors that are caused by schema validation. For example, if a normal error is + displayed like this: "MSBUILD : error MSB0000: This is an error.", then an error from schema validation would look like this: + "MSBUILD : Schema validation error MSB0000: This is an error." + LOCALIZATION: This fragment needs to be localized. + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Target "{0}" skipped. Previously built unsuccessfully. + + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Target "{0}" skipped. Previously built successfully. + + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4116: The condition "{1}" on the "{0}" target has a reference to item metadata. References to item metadata are not allowed in target conditions unless they are part of an item transform. + {StrBegin="MSB4116: "} + + fuzzyMatch="101" wordcount="32" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4057: The target "{0}" does not exist in the project. + {StrBegin="MSB4057: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + Done building target "{0}" in project "{1}" -- FAILED. + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + Done building target "{0}" in project "{1}". + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + {0}: (TargetId:{1}) + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4058: The "{0}" target is missing its output specification. If a target declares inputs, it must also declare outputs. + {StrBegin="MSB4058: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB4168: The item "{0}" of type "{1}" does not define a value for the metadata in the expression "{2}". This expression is used in the target output for target "{3}". If a target declares outputs that are transforms, all items in the transform must have a value for the metadata in the transform. + {StrBegin="MSB4168: "} + + fuzzyMatch="101" wordcount="53" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Target Performance Summary: + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Target "{0}" skipped, due to false condition; ({1}) was evaluated as ({2}). + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Target "{0}" in project "{1}" + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Target {0}: + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Target "{0}" in file "{1}": + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Build continuing because "{0}" on the task "{1}" is set to "{2}". + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Target {0} from project "{1}": + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Target "{0}" in file "{1}" from project "{2}": + + + fuzzyMatch="100" wordcount="8" adjWordcount="2" curWordcount="2" tmLabel="N''" + + + MSB4060: The "{0}" task has been declared or used incorrectly, or failed during construction. Check the spelling of the task name and the assembly name. + {StrBegin="MSB4060: "} + + fuzzyMatch="101" wordcount="25" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4077: The "{0}" task has been marked with the attribute LoadInSeparateAppDomain, but does not derive from MarshalByRefObject. Check that the task derives from MarshalByRefObject or AppDomainIsolatedTask. + {StrBegin="MSB4077: "}LOCALIZATION: <LoadInSeparateAppDomain>, <MarshalByRefObject>, <AppDomainIsolatedTask> should not be localized. + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Done executing task "{0}" -- FAILED. + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Done executing task "{0}". + + + fuzzyMatch="100" wordcount="4" adjWordcount="1" curWordcount="1" tmLabel="N''" + + + {0} (TaskId:{1}) + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Using "{0}" task from assembly "{1}". + UE: This informational message helps users determine which assemblies their tasks were loaded from. + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + MSB4061: The "{0}" task could not be instantiated from the assembly "{1}". {2} + {StrBegin="MSB4061: "}LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4127: The "{0}" task could not be instantiated from the assembly "{1}". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. {2} + {StrBegin="MSB4127: "}UE: This message is a specialized version of the TaskInstantiationFailureError message and can probably reuse some of its docs. + LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. Also, Microsoft.Build.Framework should not be localized + + fuzzyMatch="101" wordcount="49" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4062: The "{0}" task could not be loaded from the assembly {1}. {2} Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available. + {StrBegin="MSB4062: "}UE: This message is shown when a task cannot be loaded from its assembly for various reasons e.g. corrupt assembly, + invalid task declaration, disk error, etc. "{2}" contains a message explaining what happened. + LOCALIZATION: "{2}" is a message from the CLR loader and is already localized. Also, <UsingTask> should not be localized. + + fuzzyMatch="15" wordcount="31" adjWordcount="26.35" curWordcount="26.35" + + + MSB4063: The "{0}" task could not be initialized with its input parameters. {1} + {StrBegin="MSB4063: "} + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + Task Performance Summary: + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Task "{0}" skipped, due to false condition; ({1}) was evaluated as ({2}). + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Task "{0}" + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Time Elapsed {0} + + + fuzzyMatch="100" wordcount="3" adjWordcount="0.75" curWordcount="0.75" tmLabel="N''" + + + Building with tools version "{0}". + + + fuzzyMatch="100" wordcount="5" adjWordcount="1.25" curWordcount="1.25" tmLabel="N''" + + + Project file contains ToolsVersion="{0}". This toolset is unknown or missing. You may be able to resolve this by installing the appropriate .NET Framework for this toolset. Treating the project as if it had ToolsVersion="4.0". + + + fuzzyMatch="101" wordcount="34" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + Deferred Messages + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + Some messages did not display because they were not associated with any ProjectStarted events. Use diagnostic verbosity to view these messages. + + + fuzzyMatch="100" wordcount="21" adjWordcount="5.25" curWordcount="5.25" tmLabel="N''" + + + MSB4090: Found an unexpected character '{2}' at position {1} in condition "{0}". + {StrBegin="MSB4090: "} + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4091: Found a call to an undefined function "{1}" in condition "{0}". + {StrBegin="MSB4091: "} + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + MSB4064: The "{0}" parameter is not supported by the "{1}" task. Verify the parameter exists on the task, and it is a settable public instance property. + {StrBegin="MSB4064: "} + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4131: The "{0}" parameter is not supported by the "{1}" task. Verify the parameter exists on the task, and it is a gettable public instance property. + {StrBegin="MSB4131: "} + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4092: An unexpected token "{1}" was found at character position {2} in condition "{0}". + {StrBegin="MSB4092: "} + + fuzzyMatch="100" wordcount="14" adjWordcount="3.5" curWordcount="3.5" tmLabel="N''" + + + MSB4065: The "{0}" parameter is not marked for output by the "{1}" task. + {StrBegin="MSB4065: "} + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4066: The attribute "{0}" in element <{1}> is unrecognized. + {StrBegin="MSB4066: "} + + fuzzyMatch="15" wordcount="10" adjWordcount="8.5" curWordcount="8.5" + + + MSB4067: The element <{0}> beneath element <{1}> is unrecognized. + {StrBegin="MSB4067: "} + + fuzzyMatch="15" wordcount="11" adjWordcount="9.35" curWordcount="9.35" + + + MSB4068: The element <{0}> is unrecognized, or not supported in this context. + {StrBegin="MSB4068: "} + + fuzzyMatch="15" wordcount="13" adjWordcount="11.05" curWordcount="11.05" + + + MSB4132: The tools version "{0}" is unrecognized. + {StrBegin="MSB4132: "} + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + MSB4069: The "{0}" type of the "{1}" parameter of the "{2}" task is not supported by MSBuild. + {StrBegin="MSB4069: "}LOCALIZATION: "MSBuild" should not be localized. + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + MSB4072: A <{0}> element must contain either the "{1}" attribute or the "{2}" attribute (but not both). + {StrBegin="MSB4072: "} + + fuzzyMatch="15" wordcount="18" adjWordcount="15.3" curWordcount="15.3" + + + {0} Warning(s) + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4084: A <When> element may not follow an <Otherwise> element in a <Choose>. + {StrBegin="MSB4084: "} + + fuzzyMatch="15" wordcount="16" adjWordcount="13.6" curWordcount="13.6" + + + Target Name: "{0}" Project Name: "{1}" + + + fuzzyMatch="100" wordcount="6" adjWordcount="1.5" curWordcount="1.5" tmLabel="N''" + + + Cycle trace: + + + fuzzyMatch="100" wordcount="2" adjWordcount="0.5" curWordcount="0.5" tmLabel="N''" + + + MSB4150: Must initialize the console logger using the initialize method before using ApplyParameter + {StrBegin="MSB4150: "} + + fuzzyMatch="100" wordcount="13" adjWordcount="3.25" curWordcount="3.25" tmLabel="N''" + + + MSB4151: An error occurred while building project "{0}", target "{1}". Please see innerException for detailed information. + {StrBegin="MSB4151: "} + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + MSB4152: An error occurred on the child node "{0}" and could not be passed to the parent node. {1} + {StrBegin="MSB4152: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB4153: A call is made on an inactive IBuildEngine interface corresponding to a task that already finished execution. + {StrBegin="MSB4153: "} + + fuzzyMatch="100" wordcount="18" adjWordcount="4.5" curWordcount="4.5" tmLabel="N''" + + + MSB4154: A forwarding logger is attempting to forward BuildFinished event + {StrBegin="MSB4154: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB4155: There was an error while communicating with a node. + {StrBegin="MSB4155: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + MSB1021: Cannot create an instance of the logger - {0}. + {StrBegin="MSB1021: "}The error code for this message is duplicated from MSBuild.exe. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB1020: The logger {0} was not found. Check the following: 1.) The logger name specified is the same as the name of the logger class. 2.) The logger class is "public" and implements the Microsoft.Build.Framework.ILogger interface. 3.) The path to the logger assembly is correct, or the logger can be loaded using only the assembly name provided. + {StrBegin="MSB1020: "}The error code for this message is duplicated from MSBuild.exe. + + fuzzyMatch="101" wordcount="57" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + MSB4156: A forwarding logger is attempting to forward BuildStarted event + {StrBegin="MSB4156: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + "{0}" ({1} target) ({2}) -> + + + fuzzyMatch="15" wordcount="5" adjWordcount="4.25" curWordcount="4.25" + + + "{0}" (default target) ({1}) -> + + + fuzzyMatch="15" wordcount="5" adjWordcount="4.25" curWordcount="4.25" + + + {0} {1,5} + + + fuzzyMatch="15" wordcount="2" adjWordcount="1.7" curWordcount="1.7" + + + Project "{0}" on node {1} ({2} target(s)). + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Project "{0}" on node {1} (default targets). + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Project "{0}" ({1}) is building "{2}" ({3}) on node {4} ({5} target(s)). + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + Project "{0}" ({1}) is building "{2}" ({3}) on node {4} (default targets). + + + fuzzyMatch="100" wordcount="12" adjWordcount="3" curWordcount="3" tmLabel="N''" + + + ({0} target) -> + + + fuzzyMatch="15" wordcount="3" adjWordcount="2.55" curWordcount="2.55" + + + MSB4157: The array of project files needs to contain at least one value. + {StrBegin="MSB4157: "} + + fuzzyMatch="15" wordcount="13" adjWordcount="11.05" curWordcount="11.05" + + + MSB4158: The project file name at element {0} is empty. + {StrBegin="MSB4158: "} + + fuzzyMatch="100" wordcount="10" adjWordcount="2.5" curWordcount="2.5" tmLabel="N''" + + + The property "{0}" with value "{1}" is being overridden by another batch. The property is now: "{2}" + + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + Please see inner exception for error information. + + + fuzzyMatch="100" wordcount="7" adjWordcount="1.75" curWordcount="1.75" tmLabel="N''" + + + Event type "{0}" was expected to be serializable. The event was not serializable and has been ignored. + + + fuzzyMatch="100" wordcount="17" adjWordcount="4.25" curWordcount="4.25" tmLabel="N''" + + + The log file path cannot be null or empty. + + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB4161: Project "{0}" was loaded and unloaded during the current build. Reloading a project during the build can result in errors or an inconsistent build state. Either avoid unloading project "{0}" or cache the evaluation results of target(s) "{1}" before unloading the project. + {StrBegin="MSB4161: "} + + fuzzyMatch="101" wordcount="43" adjWordcount="0" curWordcount="0" tmLabel="N''" + + + [default] + + + fuzzyMatch="100" wordcount="1" adjWordcount="0.25" curWordcount="0.25" tmLabel="N''" + + +
+
\ No newline at end of file diff --git a/src/Shared/Resources/xlf/Strings.shared.xlf b/src/Shared/Resources/xlf/Strings.shared.xlf new file mode 100644 index 00000000000..439a4a77efc --- /dev/null +++ b/src/Shared/Resources/xlf/Strings.shared.xlf @@ -0,0 +1,227 @@ + + + + + + + MSB4188: Build was canceled. + {StrBegin="MSB4188: "} Error when the build stops suddenly for some reason. For example, because a child node died. + + + MSB5022: The MSBuild task host does not support running tasks that perform IBuildEngine callbacks. If you wish to perform these operations, please run your task in the core MSBuild process instead. A task will automatically execute in the task host if the UsingTask has been attributed with a "Runtime" or "Architecture" value, or the task invocation has been attributed with an "MSBuildRuntime" or "MSBuildArchitecture" value, that does not match the current runtime or architecture of MSBuild. + {StrBegin="MSB5022: "} "Runtime", "Architecture", "MSBuildRuntime", and "MSBuildArchitecture" are all attributes in the project file, and thus should not be localized. + + + Build started. + + + + MSB4008: A conflicting assembly for the task assembly "{0}" has been found at "{1}". + {StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly. + + + Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored. + + + + {0} ({1},{2}) + A file location to be embedded in a string. + + + Making the following modifications to the environment received from the parent node before applying it to the task host: + Only ever used when MSBuild is run under a "secret" environment variable switch, MSBuildTaskHostUpdateEnvironmentAndLog=1 + + + Setting '{0}' to '{1}' rather than the parent environment's value, '{2}'. + Only ever used when MSBuild is run under a "secret" environment variable switch, MSBuildTaskHostUpdateEnvironmentAndLog=1 + + + MSB4025: The project file could not be loaded. {0} + {StrBegin="MSB4025: "}UE: This message is shown when the project file given to the engine cannot be loaded because the filename/path is + invalid, or due to lack of permissions, or incorrect XML. The project filename is not part of the message because it is + provided separately to loggers. + LOCALIZATION: {0} is a localized message from the CLR/FX explaining why the project is invalid. + + + MSB4103: "{0}" is not a valid logger verbosity level. + {StrBegin="MSB4103: "} + + + MSBuild is expecting a valid "{0}" object. + + + + MSB4132: The tools version "{0}" is unrecognized. Available tools versions are {1}. + {StrBegin="MSB4132: "}LOCALIZATION: {1} contains a comma separated list. + + + MSB5016: The name "{0}" contains an invalid character "{1}". + {StrBegin="MSB5016: "} + + + "{0}" is a reserved item metadata, and cannot be modified or deleted. + UE: Tasks and OM users are not allowed to remove or change the value of the built-in metadata on items e.g. the meta-data "FullPath", "RelativeDir", etc. are reserved. + + + The string "{0}" cannot be converted to a boolean (true/false) value. + + + + MSB5003: Failed to create a temporary file. Temporary files folder is full or its path is incorrect. {0} + {StrBegin="MSB5003: "} + + + MSB5018: Failed to delete the temporary file "{0}". {1} + {StrBegin="MSB5018: "} + + + The item metadata "%({0})" cannot be applied to the path "{1}". {2} + UE: This message is shown when the user tries to perform path manipulations using one of the built-in item metadata e.g. %(RootDir), on an item-spec that's not a valid path. LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. + + + MSB4077: The "{0}" task has been marked with the attribute LoadInSeparateAppDomain, but does not derive from MarshalByRefObject. Check that the task derives from MarshalByRefObject or AppDomainIsolatedTask. + {StrBegin="MSB4077: "}LOCALIZATION: <LoadInSeparateAppDomain>, <MarshalByRefObject>, <AppDomainIsolatedTask> should not be localized. + + + .NET Framework version "{0}" is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion. + + + + .NET Framework version "{0}" is not supported when explicitly targeting the Windows SDK, which is only supported on .NET 4.5 and later. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion that is Version45 or above. + + + + Visual Studio version "{0}" is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.VisualStudioVersion. + + + + When attempting to generate a reference assembly path from the path "{0}" and the framework moniker "{1}" there was an error. {2} + No Error code because this resource will be used in an exception. The error code is discarded if it is included + + + Could not find directory path: {0} + Directory must exist + + + You do not have access to: {0} + Directory must have access + + + Schema validation + + UE: this fragment is used to describe errors that are caused by schema validation. For example, if a normal error is + displayed like this: "MSBUILD : error MSB0000: This is an error.", then an error from schema validation would look like this: + "MSBUILD : Schema validation error MSB0000: This is an error." + LOCALIZATION: This fragment needs to be localized. + + + + MSB5002: The task executable has not completed within the specified limit of {0} milliseconds, terminating. + {StrBegin="MSB5002: "} + + + Parameter "{0}" cannot be null. + + + + Parameter "{0}" cannot have zero length. + + + + Parameters "{0}" and "{1}" must have the same number of elements. + + + + The resource string "{0}" for the "{1}" task cannot be found. Confirm that the resource name "{0}" is correctly spelled, and the resource exists in the task's assembly. + + + + The "{0}" task has not registered its resources. In order to use the "TaskLoggingHelper.FormatResourceString()" method this task needs to register its resources either during construction, or via the "TaskResources" property. + LOCALIZATION: "TaskLoggingHelper.FormatResourceString()" and "TaskResources" should not be localized. + + + MSB5004: The solution file has two projects named "{0}". + {StrBegin="MSB5004: "}UE: The solution filename is provided separately to loggers. + + + MSB5005: Error parsing project section for project "{0}". The project file name "{1}" contains invalid characters. + {StrBegin="MSB5005: "}UE: The solution filename is provided separately to loggers. + + + MSB5006: Error parsing project section for project "{0}". The project file name is empty. + {StrBegin="MSB5006: "}UE: The solution filename is provided separately to loggers. + + + MSB5007: Error parsing the project configuration section in solution file. The entry "{0}" is invalid. + {StrBegin="MSB5007: "}UE: The solution filename is provided separately to loggers. + + + MSB5008: Error parsing the solution configuration section in solution file. The entry "{0}" is invalid. + {StrBegin="MSB5008: "}UE: The solution filename is provided separately to loggers. + + + MSB5009: Error parsing the nested project section in solution file. + {StrBegin="MSB5009: "}UE: The solution filename is provided separately to loggers. + + + MSB5023: Error parsing the nested project section in solution file. A project with the GUID "{0}" is listed as being nested under project "{1}", but does not exist in the solution. + {StrBegin="MSB5023: "}UE: The solution filename is provided separately to loggers. + + + MSB5010: No file format header found. + {StrBegin="MSB5010: "}UE: The solution filename is provided separately to loggers. + + + MSB5011: Parent project GUID not found in "{0}" project dependency section. + {StrBegin="MSB5011: "}UE: The solution filename is provided separately to loggers. + + + MSB5012: Unexpected end-of-file reached inside "{0}" project section. + {StrBegin="MSB5012: "}UE: The solution filename is provided separately to loggers. + + + MSB5013: Error parsing a project section. + {StrBegin="MSB5013: "}UE: The solution filename is provided separately to loggers. + + + MSB5014: File format version is not recognized. MSBuild can only read solution files between versions {0}.0 and {1}.0, inclusive. + {StrBegin="MSB5014: "}UE: The solution filename is provided separately to loggers. + + + MSB5015: The properties could not be read from the WebsiteProperties section of the "{0}" project. + {StrBegin="MSB5015: "}UE: The solution filename is provided separately to loggers. + + + Unrecognized solution version "{0}", attempting to continue. + + + + Solution file + UE: this fragment is used to describe errors found while parsing solution files. For example, if a normal error is + displayed like this: "MSBUILD : error MSB0000: This is an error.", then an error from solution parsing would look like this: + "MSBUILD : Solution file error MSB0000: This is an error." + LOCALIZATION: This fragment needs to be localized. + + + MSB5019: The project file is malformed: "{0}". {1} + {StrBegin="MSB5019: "} + + + MSB5020: Could not load the project file: "{0}". {1} + {StrBegin="MSB5020: "} + + + MSB5021: "{0}" and its child processes are being terminated in order to cancel the build. + {StrBegin="MSB5021: "} + + + This collection is read-only. + + + + MSB5024: Could not determine a valid location to MSBuild. Try running this process from the Developer Command Prompt for Visual Studio. + {StrBegin="MSB5021: "} + + + + \ No newline at end of file diff --git a/src/UpdateLocalizedResources.targets b/src/UpdateLocalizedResources.targets index df2a5279755..e0061114f26 100644 --- a/src/UpdateLocalizedResources.targets +++ b/src/UpdateLocalizedResources.targets @@ -4,6 +4,14 @@ + + + + + + + LocalizedResxRoot="$(IntermediateOutputPath)"> diff --git a/src/Utilities/Resources/xlf/Strings.xlf b/src/Utilities/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..f585e9dc314 --- /dev/null +++ b/src/Utilities/Resources/xlf/Strings.xlf @@ -0,0 +1,224 @@ + + + + + + + MSB6001: Invalid command line switch for "{0}". {1} + {StrBegin="MSB6001: "}UE: This message is shown when a tool-based task (i.e. the task is a wrapper for an .exe) is given a parameter value that converts into an invalid command line switch for the tool. "{0}" is the name of the tool e.g. "csc.exe", and "{1}" is a message explaining the problem. LOCALIZATION: "{1}" is a localized message. + + + Illegal quote passed to the command line switch named "{0}". The value was [{1}]. + + + + Illegal quote in the command line value [{0}]. + + + + The command exited with code {0}. + + + + MSB6005: Task attempted to log before it was initialized. Message was: {0} + {StrBegin="MSB6005: "}UE: This occurs if the task attempts to log something in its own constructor. + + + MSB6010: Could not find platform manifest file at "{0}". + {StrBegin="MSB6010: "} + + + .NET Framework version "{0}" is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion. + + + + .NET Framework version "{0}" is not supported when explicitly targeting the Windows SDK, which is only supported on .NET 4.5 and later. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion that is Version45 or above. + + + + Visual Studio version "{0}" is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.VisualStudioVersion. + + + + MSB6002: The command-line for the "{0}" task is too long. Command-lines longer than 32000 characters are likely to fail. Try reducing the length of the command-line by breaking down the call to "{0}" into multiple calls with fewer parameters per call. + {StrBegin="MSB6002: "} + + + MSB6003: The specified task executable "{0}" could not be run. {1} + {StrBegin="MSB6003: "} + + + MSB6006: "{0}" exited with code {1}. + {StrBegin="MSB6006: "} + + + MSB6004: The specified task executable location "{0}" is invalid. + {StrBegin="MSB6004: "} + + + There was an error reading the redist list file "{0}". {1} + No Error code because this resource will be used in an exception. The error code is discarded if it is included + + + The Framework at path "{0}" tried to include the framework at path "{1}" as part of its reference assembly paths but there was an error. {2} + No Error code because this resource will be used in an exception. The error code is discarded if it is included + + + When attempting to generate a reference assembly path from the path "{0}" and the framework moniker "{1}" there was an error. {2} + No Error code because this resource will be used in an exception. The error code is discarded if it is included + + + MSB6007: The "{0}" value passed to the Environment property is not in the format "name=value", where the value part may be empty. + {StrBegin="MSB6007: "} + + + Environment Variables passed to tool: + + + + Tracking logs are not available, minimal rebuild will be disabled. + + + + Missing input files detected, minimal rebuild will be disabled. + + + + Missing output files detected, minimal rebuild will be disabled. + + + + Skipping task because it is up-to-date. + + + + Write Tracking log not available, minimal rebuild will be disabled. + + + + Write Tracking Logs: + + + + Using cached output dependency table built from: + + + + Tracking Logs: + + + + Using cached dependency table built from: + + + + Outputs for {0}: + + + + Inputs for {0}: + + + + Output details ({0} of them) were not logged for performance reasons. + + + + Input details ({0} of them) were not logged for performance reasons. + + + + Tracking log {0} is not available. + + + + {0} will be compiled as the tracking log is not available. + + + + {0} will be compiled as it was not found in the tracking log. + + + + {0} will be compiled as not all outputs are available. + + + + {0} will be compiled as dependency {1} was missing. + + + + {0} will be compiled as {1} was modified at {2}. + + + + {0} will be compiled. + + + + All outputs are up-to-date. + + + + File {0} was modified at {1} which is newer than {2} modified at {3}. + + + + {0} does not exist; source compilation required. + + + + {0} will be compiled as output {1} does not exist. + + + + Read Tracking Logs: + + + + Using cached input dependency table built from: + + + + No output for {0} was found in the tracking log; source compilation required. + + + + No dependencies for output {0} were found in the tracking log; source compilation required. + + + + Could not find {0} in the write tracking log. + + + + Could not find {0} in the read tracking log. + + + + The number of source files and corresponding outputs must match. + + + + Source compilation required: input {0} is newer than output {1}. + + + + MSB6008: Forcing a rebuild of all sources due to an error with the tracking logs. {0} + {StrBegin="MSB6008: "} + + + MSB6009: Forcing a rebuild of all source files due to the contents of "{0}" being invalid. + {StrBegin="MSB6009: "} + + + Build FAILED. + + + + Build succeeded. + + + + + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..bd6c5cf756a --- /dev/null +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.xlf @@ -0,0 +1,1582 @@ + + + + + + + MSB4001: The "{0}" task has more than one parameter called "{1}". + {StrBegin="MSB4001: "}UE: This message is shown when a task has more than one .NET property with the same name -- it's unclear which of + those properties the task wants to use as a parameter in project files. + + + MSB4002: There was a failure retrieving the attributes for parameters in the "{0}" task. {1} + {StrBegin="MSB4002: "}UE: This message is shown when the .NET attributes that a task's .NET properties are decorated with, cannot be + retrieved -- this is typically because the .NET classes that define the .NET attributes cannot be loaded because the assembly + they are defined in cannot be found, or the classes themselves cannot be found. + + + MSB4003: "{0}" is a reserved attribute of the <{1}> element, and must be spelled with the correct casing. This attribute cannot be used as a parameter to the "{2}" task. + {StrBegin="MSB4003: "}UE: Tasks are not allowed to use incorrect case for reserved attributes on the task nodes e.g. "continueonerror" + instead of the "ContinueOnError". + + + The operation cannot be completed because a build is already in progress. + + + + The operation cannot be completed because BeginBuild has not yet been called. + + + + The operation cannot be completed because EndBuild has already been called but existing submissions have not yet completed. + + + + The operation cannot be completed because the submission has already been executed. + + + + Cannot dispose the build manager because it is not idle. + + + + MSB4197: Build was canceled. {0} + {StrBegin="MSB4197: "} Error when the build stops suddenly for some reason. For example, because a child node died. + + + Build FAILED. + + + + Build succeeded. + + + + Build started {0}. + + + + Building target "{0}" completely. + {0} is the name of the target. + + + No input files were specified. + + + + Input file "{0}" is newer than output file "{1}". + {0} and {1} are filenames on disk. + + + Output file "{0}" does not exist. + {0} is a filename on disk. + + + Input file "{0}" does not exist. + {0} is a filename on disk. + + + Building target "{0}" partially, because some output files are out of date with respect to their input files. + {0} is the name of the target. + + + [{0}: Input={1}, Output={2}] Input file is newer than output file. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + + [{0}: Input={1}, Output={2}] Output file does not exist. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + + [{0}: Input={1}, Output={2}] Input file does not exist. + {0} is the name of an MSBuild item. {1} and {2} are filenames on disk. + + + The attribute "{0}" is a known MSBuild attribute, and cannot be accessed using this method. + + + + MSB4023: Cannot evaluate the item metadata "%({0})". {1} + {StrBegin="MSB4023: "}UE: This message is shown when the value of an item metadata cannot be computed for some reason e.g. trying to apply + %(RootDir) to an item-spec that's not a valid path, would result in this error. + LOCALIZATION: "{1}" is a localized message explaining the problem. + + + MSB4193: MSBuild.exe could not be launched as a child node as it could not be found at the location "{0}". If necessary, specify the correct location in the BuildParameters, or with the MSBUILD_EXE_PATH environment variable. + {StrBegin="MSB4193: "} + + + MSB4218: Failed to successfully launch or connect to a child MSBuild.exe process. Verify that the MSBuild.exe "{0}" launches successfully, and that it is loading the same microsoft.build.dll that the launching process loaded. If the location seems incorrect, try specifying the correct location in the BuildParameters object, or with the MSBUILD_EXE_PATH environment variable. + {StrBegin="MSB4218: "} + + + MSB4117: The "{0}" item name is reserved, and cannot be used. + {StrBegin="MSB4117: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild items e.g. @(Choose) + + + MSB4118: The "{0}" item metadata name is reserved, and cannot be used. + {StrBegin="MSB4118: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild item metadata names e.g. %(FullPath). Only MSBuild can set those. + + + MSB4004: The "{0}" property is reserved, and cannot be modified. + {StrBegin="MSB4004: "}UE: This message is shown when the user tries to redefine one of the reserved MSBuild properties e.g. $(MSBuildProjectFile) + + + MSB4094: "{0}" is an invalid value for the "{1}" parameter of the "{3}" task. Multiple items cannot be passed into a parameter of type "{2}". + {StrBegin="MSB4094: "} + UE: This error is shown when a project tries to pass multiple items into a task parameter of type ITaskItem (singular). + + + + MSB4115: The "{0}" function only accepts a scalar value, but its argument "{1}" evaluates to "{2}" which is not a scalar value. + {StrBegin="MSB4115: "} + UE: This error is shown when a project tries to pass multiple items into a function in a conditional expression, that can only accept a scalar value (such as the "exists()" function). + + + + MSB4095: The item metadata %({0}) is being referenced without an item name. Specify the item name by using %(itemname.{0}). + {StrBegin="MSB4095: "} + + + MSB4162: <{0}> is not valid. Child elements are not allowed below a item remove element. + {StrBegin="MSB4162: "} + + + MSB4166: Child node "{0}" exited prematurely. Shutting down. Diagnostic information may be found in files in the temporary files directory named MSBuild_*.failure.txt. + {StrBegin="MSB4166: "} + + + MSB4085: A <Choose> must contain at least one <When>. + {StrBegin="MSB4085: "} + + + MSB4114: <Choose> elements cannot be nested more than {0} levels deep. + {StrBegin="MSB4114: "}UE: This message appears if the project file contains unreasonably nested Choose elements. + LOCALIZATION: Do not localize "Choose" as it is an XML element name. + + + MSB4006: There is a circular dependency in the target dependency graph involving target "{0}". + {StrBegin="MSB4006: "}UE: This message is shown when the build engine detects a target referenced in a circular manner -- a project cannot + request a target to build itself (perhaps via a chain of other targets). + + + MSB4086: A numeric comparison was attempted on "{1}" that evaluates to "{2}" instead of a number, in condition "{0}". + {StrBegin="MSB4086: "} + + + MSB4130: The condition "{0}" may have been evaluated incorrectly in an earlier version of MSBuild. Please verify that the order of the AND and OR clauses is written as intended. To avoid this warning, add parentheses to make the evaluation order explicit. + {StrBegin="MSB4130: "} + + + MSB4087: Specified condition "{0}" does not evaluate to a boolean. + {StrBegin="MSB4087: "} + + + MSB4113: Specified condition "{0}" evaluates to "{1}" instead of a boolean. + {StrBegin="MSB4113: "} + + + MSB4136: Error reading the toolset information from the configuration file "{0}". {1} + {StrBegin="MSB4136: "} + + + MSB4142: MSBuildToolsPath is not the same as MSBuildBinPath for the ToolsVersion "{0}" defined at "{1}". If both are present they must have the same value. + {StrBegin="MSB4142: "} + + + MSB4097: The element <{0}> beneath element <{1}> may not have a custom XML namespace. + {StrBegin="MSB4097: "} + + + MSB4009: The default tasks file could not be successfully loaded. {0} + {StrBegin="MSB4009: "}UE: This message is shown when one of the default tasks file (*.tasks) located alongside the MSBuild binaries cannot + be opened/parsed. "{0}" contains a message explaining why. The filename itself is not part of the message but is provided + separately to loggers. + LOCALIZATION: "{0}" is a message from some FX method and is already localized. + + + MSB4010: The "{0}" files could not be successfully loaded from their expected location "{1}". Default tasks will not be available. {2} + {StrBegin="MSB4010: "}UE: This message is shown when the default tasks files that are located alongside the MSBuild binaries cannot be + found, either because they don't exist, or because of lack of permissions. "{2}" contains a message explaining why. + LOCALIZATION: "{2}" is a message from some FX method and is already localized. + + + Importing the file "{0}" into the file "{1}" results in a circular dependency. + + {0} is a file imported into the file "{1}" such that it results in a circular dependency. For e.g. if t1.targets imports + t2.targets and t2.targets tries to import t1.targets, then it results in a circular dependency. + + + + Search paths being used for {0} are {1} + + + + Trying to import {0} using extensions path {1} + + + + MSB4194: The override tasks file could not be successfully loaded. {0} + + {StrBegin="MSB4194: "}UE: This message is shown when one of the override tasks file (*.overridetasks) located alongside the MSBuild binaries cannot + be opened/parsed. "{0}" contains a message explaining why. The filename itself is not part of the message but is provided + separately to loggers. + LOCALIZATION: "{0}" is a message from some FX method and is already localized. + + + + The override tasks path "{0}" must not be a relative path and must exist on disk. Default tasks will not be overridden. + + UE: This message is shown when the override tasks path in the registry or passed to the toolset is not a full path. + + + + A problem occurred loading the override tasks path "{0}". {1} + + UE: This message is shown when the override tasks path in the registry or passed to the toolset is not a full path. + + + + MSB4196: The "{0}" files could not be successfully loaded from their expected location "{1}". Default tasks will not be overridden. {2} + + {StrBegin="MSB4196: "}UE: This message is shown when the override tasks files that are located alongside the MSBuild binaries cannot be + found, either because they don't exist, or because of lack of permissions. "{2}" contains a message explaining why. + LOCALIZATION: "{2}" is a message from some FX method and is already localized. + + + + MSB4195: There was an error gathering properties for tasks file evaluation. {0} + + {StrBegin="MSB4195: "}UE: This message is shown when the gathering of properties for the evaluation of override and defaults tasks has an exception. "{0"} will be the exception message + + + MSB4133: A default tools version "{0}" was specified, but its definition could not be found. + {StrBegin="MSB4133: "} + + + MSB4011: "{0}" cannot be imported again. It was already imported at "{1}". This is most likely a build authoring error. This subsequent import will be ignored. {2} + {StrBegin="MSB4011: "} + + + MSB4211: The property "{0}" is being set to a value for the first time, but it was already consumed at "{1}". + {StrBegin="MSB4211: "} + + + MSB4210: "{0}" is attempting to import itself, directly or indirectly. This is most likely a build authoring error. The import will be ignored. + {StrBegin="MSB4210: "} + + + MSB4079: The <ProjectExtensions> element occurs more than once. + {StrBegin="MSB4079: "} + + + MSB4012: The expression "{0}" cannot be used in this context. Item lists cannot be concatenated with other strings where an item list is expected. Use a semicolon to separate multiple item lists. + {StrBegin="MSB4012: "}UE: This message is shown when the user does not properly specify an item list when an item list is expected + e.g. "badprefix@(foo)badsuffix" instead of "prefix; @(foo); suffix" + + + end of input + This is the name of the "EndOfInput" token. It is displayed in quotes as the + unexpected char or token when the end of a conditional was unexpectedly reached. + + + The previous error was converted to a warning because the task was called with ContinueOnError=true. + + + + {0} Error(s) + + + + MSB4159: Error creating the toolset "{0}". {1} + {StrBegin="MSB4159: "} + + + MSB4146: Cannot evaluate the property expression "{0}" found at "{1}". {2} + {StrBegin="MSB4146: "} + + + The <{0}> tag is no longer supported as a child of the <Project> element. Place this tag within a target, and add the name of the target to the "InitialTargets" attribute of the <Project> element. + + + + Launching task "{0}" from assembly "{1}" in an external task host with a runtime of "{2}" and a process architecture of "{3}". + + + + MSB4100: Expected "{0}" to evaluate to a boolean instead of "{1}", in condition "{2}". + {StrBegin="MSB4100: "} + + + MSB4028: The "{0}" task's outputs could not be retrieved from the "{1}" parameter. {2} + {StrBegin="MSB4028: "} + + + MSB4014: The build stopped unexpectedly because of an internal failure. + {StrBegin="MSB4014: "}UE: This message is shown when an unhandled exception terminates the build. The cause is most likely a programming + error in the build engine. + + + MSB4015: The build stopped unexpectedly because the "{0}" logger failed unexpectedly during shutdown. + {StrBegin="MSB4015: "}UE: This message is used for a special exception that is thrown when a logger fails while shutting down (most likely + because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a special + exception to abort the build. + + + MSB4016: The build stopped unexpectedly because the "{0}" logger failed unexpectedly during initialization. + {StrBegin="MSB4016: "}UE: This message is used for a special exception that is thrown when a logger fails while initializing itself (most + likely because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a + special exception to abort the build. + + + MSB4017: The build stopped unexpectedly because of an unexpected logger failure. + {StrBegin="MSB4017: "}UE: This message is used for a special exception that is thrown when a logger fails while logging an event (most + likely because of a programming error in the logger). When a logger dies, we cannot proceed with the build, and we throw a + special exception to abort the build. + + + MSB4018: The "{0}" task failed unexpectedly. + {StrBegin="MSB4018: "}UE: This message is shown when a task terminates because of an unhandled exception. The cause is most likely a + programming error in the task; however, it is also possible that the unhandled exception originated in the engine, and was + surfaced through the task when the task called into the engine. + + + MSB4187: Failed to receive a response from the task thread in the timeout period "{0}" ms. Shutting down. + {StrBegin="MSB4187: "} + + + MSB4088: Condition "{0}" is improperly constructed. + {StrBegin="MSB4088: "} + + + MSB4105: Found an unexpected character '{2}' at position {1} in condition "{0}". Did you intend to use "=="? + {StrBegin="MSB4105: "} + + + MSB4106: Expected an item list at position {1} in condition "{0}". Did you forget the closing parenthesis? + {StrBegin="MSB4106: "} + + + MSB4107: Expected an item list at position {1} in condition "{0}". Did you forget the opening parenthesis after the '@'? To use a literal '@', use '%40' instead. + {StrBegin="MSB4107: "} + + + MSB4108: Expected an item list at position {1} in condition "{0}". Did you forget to close a quote inside the item list expression? + {StrBegin="MSB4108: "} + + + MSB4109: Expected a property at position {1} in condition "{0}". Did you forget the closing parenthesis? + {StrBegin="MSB4109: "} + + + MSB4110: Expected a property at position {1} in condition "{0}". Did you forget the opening parenthesis after the '$'? To use a literal '$', use '%24' instead. + {StrBegin="MSB4110: "} + + + MSB4101: Expected a closing quote after position {1} in condition "{0}". + {StrBegin="MSB4101: "} + + + MSB4019: The imported project "{0}" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. + {StrBegin="MSB4019: "}LOCALIZATION: <Import> should not be localized. + + + MSB4226: The imported project "{0}" was not found. Also, tried to find "{1}" in the fallback search path(s) for {2} - {3} . These search paths are defined in "{4}". Confirm that the path in the <Import> declaration is correct, and that the file exists on disk in one of the search paths. + {StrBegin="MSB4226: "}LOCALIZATION: <Import> should not be localized. + + + MSB4226: The imported project "{0}" was not found. Also, tried to find "{1}" in the fallback search path(s) for {2} - {3} . Confirm that the path in the <Import> declaration is correct, and that the file exists on disk in one of the search paths. + {StrBegin="MSB4226: "}LOCALIZATION: <Import> should not be localized. + + + MSB4089: Incorrect number of arguments to function in condition "{0}". Found {1} argument(s) when expecting {2}. + {StrBegin="MSB4089: "} + + + MSB4020: The value "{0}" of the "{1}" attribute in element <{2}> is invalid. + {StrBegin="MSB4020: "}UE: This is a generic message that is displayed when we find a project element with an incorrect value for one of its + attributes e.g. <Import Project=""> -- the value of Project should not be an empty string. + + + MSB4102: The value "{0}" of the "{1}" attribute in element <{2}> is invalid. {3} + {StrBegin="MSB4102: "}UE: This is a generic message that is displayed when we find a project element with an incorrect value for one of its + attributes. At the end of the message we show the exception text we got trying to use the value. + + + MSB4021: The "ContinueOnError" attribute of the "{0}" task is not valid. {1} + {StrBegin="MSB4021: "}LOCALIZATION: "ContinueOnError" should not be localized. "{1}" is a message from another exception explaining the problem. + + + MSB4022: The result "{0}" of evaluating the value "{1}" of the "{2}" attribute in element <{3}> is not valid. + {StrBegin="MSB4022: "}UE: This message is shown when the engine is checking the correctness of the value (after evaluating embedded + properties/items) assigned to an XML attribute of an XML element in the project file. + + + MSB4104: Failed to write to log file "{0}". {1} + {StrBegin="MSB4104: "}UE: This is shown when the File Logger can't create or write to the file it was instructed to log to. + + + MSB4024: The imported project file "{0}" could not be loaded. {1} + {StrBegin="MSB4024: "}UE: This message is shown when an imported project file cannot be loaded because of incorrect XML. The project + filename is not part of the message because it is provided separately to loggers. + LOCALIZATION: {0} is a localized message from the CLR/FX explaining why the project is invalid. + + + MSB4147: The property "{0}" at "{1}" is invalid. {2} + {StrBegin="MSB4147: "} + + + MSB4177: Invalid property. {0} + {StrBegin="MSB4177: "} + UE: {0} is a localized message indicating what the problem was. + + + MSB4143: The registry expression "{0}" cannot be evaluated. {1} + {StrBegin="MSB4143: "} + UE: This message is shown when the user attempts to provide an expression like "$(Registry:HKEY_LOCAL_MACHINE\Software\Vendor\Tools@TaskLocation)" + LOCALIZATION: "{0}" is the expression that was bad. "{1}" is a message from an FX exception that describes why the expression is bad. + + + + MSB4184: The expression "{0}" cannot be evaluated. {1} + {StrBegin="MSB4184: "} + Double quotes as the expression will typically have single quotes in it. + UE: This message is shown when the user attempts to provide an expression like "$(SomeProperty.ToLower())" or "@(Foo->Bar())" + LOCALIZATION: "{0}" is the expression that was bad. "{1}" is a message from an FX exception that describes why the expression is bad. + + + + The quotes were mismatched. + This is a potential suffix to "InvalidFunctionPropertyExpression" so it has no error code. + + + The parentheses were mismatched. + This is a potential suffix to "InvalidFunctionPropertyExpression" so it has no error code. + + + The square brackets were mismatched. + This is a potential suffix to "InvalidFunctionPropertyExpression" so it has no error code. + + + MSB4185: The function "{0}" on type "{1}" is not available for execution as an MSBuild property function. + + {StrBegin="MSB4185: "} + UE: This message is shown when the user attempts to provide an expression like "$([System.DateTime]::Now)", but the expression has not been enabled + LOCALIZATION: "{0}" is the static function name, "{1}" is the .NET Framework type name + + + + MSB4212: Invalid static method invocation syntax: "{0}". The type "{1}" is either not available for execution in an MSBuild property function or could not be found. + + {StrBegin="MSB4212: "} + UE: This message is shown when the user attempts to provide an expression like "$([System.DateTime]::Now)", but the expression has not been enabled + LOCALIZATION: "{0}" is the function expression which is in error. "{1}" is the .NET Framework type name + + + + MSB4186: Invalid static method invocation syntax: "{0}". {1} Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). + {StrBegin="MSB4186: "} + UE: This message is shown when the user attempts to call a static method on a type, but has used the incorrect syntax + LOCALIZATION: "{0}" is the function expression which is in error. "{1}" is a message from an FX exception that describes why the expression is bad. + + + + MSB4198: The expression "{0}" cannot be evaluated on item "{1}". {2} + + {StrBegin="MSB4198: "} + Double quotes as the expression will typically have single quotes in it. + UE: This message is shown when the user attempts to provide an expression like "@(SomeItem->DirectoryName())" + LOCALIZATION: "{0}" is the expression that was bad, "{1}" is the item or file that was being worked on. "{2}" is a message from an FX exception that describes why the expression is bad. + + + + MSB4199: Invalid transformation syntax "{0}". An item function was not found with that name and {1} parameters. + + {StrBegin="MSB4199: "} + UE: This message is shown when the user attempts to call a transformation on an item, but has used the incorrect syntax + LOCALIZATION: "{0}" is the function which is in error + + + + MSB4200: Unknown item transformation function "{0}". + + {StrBegin="MSB4200: "} + UE: This message is shown when the user attempts to provide an expression like @(Item->SomeTransform()), but SomeTransform is unknown + LOCALIZATION: "{0}" is the function name + + + + MSB4026: The "{0}={1}" parameter for the "{2}" task is invalid. + {StrBegin="MSB4026: "}UE: This message is displayed when a task has an invalid parameter that cannot be initialized. + + + MSB4027: The "{0}" task generated invalid items from the "{1}" output parameter. {2} + {StrBegin="MSB4027: "} + + + MSB4029: The "{0}" task has an invalid output specification. The "TaskParameter" attribute is required, and either the "ItemName" or "PropertyName" attribute must be specified (but not both). + {StrBegin="MSB4029: "}LOCALIZATION: "TaskParameter", "ItemName" and "PropertyName" should not be localized. + + + MSB4030: "{0}" is an invalid value for the "{1}" parameter of the "{3}" task. The "{1}" parameter is of type "{2}". + {StrBegin="MSB4030: "}UE: This error is shown when a type mis-match occurs between the value assigned to task parameter in the project file + and the type of the .NET property that corresponds to the task parameter. For example, if an int task parameter called "Count" + is assigned the value "x", this error would be displayed: <MyTask Count="x" /> + + + MSB4137: Invalid value specified in the configuration file at "{0}". Property name or tools version name is an empty string. + {StrBegin="MSB4137: "} + + + MSB4163: <ItemDefinitionGroup> is not allowed inside a target. + {StrBegin="MSB4163: "} + + + MSB4096: The item "{0}" in item list "{1}" does not define a value for metadata "{2}". In order to use this metadata, either qualify it by specifying %({1}.{2}), or ensure that all items in this list define a value for this metadata. + {StrBegin="MSB4096: "} + + + MSB4099: A reference to an item list at position {1} is not allowed in this condition "{0}". + {StrBegin="MSB4099: "} + + + MSB4191: The reference to custom metadata "{2}" at position {1} is not allowed in this condition "{0}". + {StrBegin="MSB4191: "} + + + MSB4190: The reference to the built-in metadata "{2}" at position {1} is not allowed in this condition "{0}". + {StrBegin="MSB4190: "} + + + MSB4033: "{0}" is a reserved item metadata, and cannot be redefined as a custom metadata on the item. + {StrBegin="MSB4033: "} + + + An InternalLoggerException can only be thrown by the MSBuild engine. The public constructors of this class cannot be used to create an instance of the exception. + UE: This message is shown when a user tries to instantiate a special exception called InternalLoggerException through the OM -- + only the engine is allowed to create and throw this exception. + LOCALIZATION: "InternalLoggerException" and "MSBuild" should not be localized. + + + Initial Items: + + + + Environment at start of build: + + + + MSB4164: The value "{0}" of metadata "{1}" contains an item list expression. Item list expressions are not allowed on default metadata values. + {StrBegin="MSB4164: "} + + + MSB4035: The required attribute "{0}" is empty or missing from the element <{1}>. + {StrBegin="MSB4035: "}UE: This message is shown when a user leaves off a required attribute from a project element + e.g. <UsingTask AssemblyName="foo"> -- this is missing the "TaskName" attribute. + + + MSB4036: The "{0}" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "{1}" directory. + {StrBegin="MSB4036: "}LOCALIZATION: <UsingTask> and "*.tasks" should not be localized. + + + MSB4141: MSBuildToolsPath is not specified for the ToolsVersion "{0}" defined at "{1}", or the value specified evaluates to the empty string. + {StrBegin="MSB4141: "} + + + MSB4222: ToolsVersion "{0}", defined at "{1}", contains sub-toolset "{2}" which sets MSBuildBinPath or MSBuildToolsPath. This is not supported in sub-toolsets. + + + + MSB4144: Multiple definitions were found for the toolset "{0}". + {StrBegin="MSB4144: "} + + + MSB4225: Toolset contains multiple definitions of searchPaths for the OS "{0}" at "{1}". + {StrBegin="MSB4225: "} + + + MSB4145: Multiple definitions were found for the property "{0}". + {StrBegin="MSB4145: "} + + + MSB4082: Choose has more than one <Otherwise> element. + {StrBegin="MSB4082: "} + + + MSB4038: The element <{0}> must be last under element <{1}>. Found element <{2}> instead. + {StrBegin="MSB4038: "} + + + MSB4138: Non-string data was specified at the registry location "{0}". + {StrBegin="MSB4138: "} + + + MSB4039: No "{0}" element was found in the project file. + {StrBegin="MSB4039: "} + + + MSB4040: There is no target in the project. + {StrBegin="MSB4040: "} + + + A null entry was found in the collection of loggers. + + + + MaxNodeCount may only be assigned a value greater than zero. + + + + Overriding target "{0}" in project "{1}" with target "{2}" from project "{3}". + + + + {0} ms {1} {2} calls + + + + (* = timing was not recorded because of reentrancy) + + + + The project file "{0}" was not found. + UE: This message is shown when the user calls into the OM to build a project that doesn't exist on disk. + + + Done building project "{0}" -- FAILED. + + + + Done building project "{0}". + + + + Done Building Project "{0}" ({1} target(s)). + + + + Done Building Project "{0}" (default targets). + + + + Done Building Project "{0}" ({1} target(s)) -- FAILED. + + + + Done Building Project "{0}" (default targets) -- FAILED. + + + + MSB4041: The default XML namespace of the project must be the MSBuild XML namespace or no namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="{0}" to the <Project> element. If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. + {StrBegin="MSB4041: "}UE: This is a Beta 1 message only. + LOCALIZATION: <Project>, "MSBuild" and "xmlns" should not be localized. + + + Project Performance Summary: + + + + Project "{0}" is building "{1}" ({2} target(s)): + + + + Project "{0}" is building "{1}" (default targets): + + + + Project "{0}" ({1} target(s)): + + + + Project "{0}" (default targets): + + + + Task name cannot be empty. + + + + MSB4075: The project file "{0}" must be opened in the Visual Studio IDE and converted to the latest version before it can be built by MSBuild. + {StrBegin="MSB4075: "} + + + MSB4192: The project file "{0}" is in the ".vcproj" file format, which MSBuild no longer supports. Please convert the project by opening it in the Visual Studio IDE or running the conversion tool, or use MSBuild 3.5 or earlier to build it. + {StrBegin="MSB4192: "} LOC: ".vcproj" should not be localized + + + Initial Properties: + + + + MSB4148: The name of a property stored under the registry key "{0}" has zero length. + {StrBegin="MSB4148: "} + + + MSB4043: The item metadata reference "{0}" is invalid because it is qualified with an item name. Item metadata referenced in transforms do not need to be qualified, because the item name is automatically deduced from the items being transformed. Change "{0}" to "%({1})". + {StrBegin="MSB4043: "}UE: This message is shown when the user does something like this: @(foo->'%(foo.metadata)'). There is no need to specify + "foo.metadata", because "foo" is automatically deduced. In corollary, "bar.metadata" is not allowed either, where "bar" is a different + item list type. + + + MSB4135: Error reading the toolset information from the registry location "{0}". {1} + {StrBegin="MSB4135: "} + + + MSB4044: The "{0}" task was not given a value for the required parameter "{1}". + {StrBegin="MSB4044: "}UE: This message is shown when a task parameter designated as "required" is not set in the project file. + + + MSB4112: The targets in this project have been disabled by the host and therefore cannot be built at this time. This may have been done for security reasons. To enable the targets, the host must set Project.BuildEnabled to "true". + {StrBegin="MSB4112: "} + + + MSB4093: The "{0}" parameter of the "{1}" task cannot be written to because it does not have a "set" accessor. + {StrBegin="MSB4093: "}UE: This error is shown when a project tries to assign a value to a task parameter that does not have a "set" + accessor on the corresponding .NET property on the task class. + + + Skipping target "{0}" because it has no inputs. + + + + Though the target has declared its inputs, the input specification only references empty properties and/or empty item lists. + + + + Skipping target "{0}" because it has no outputs. + + + + Though the target has declared its outputs, the output specification only references empty properties and/or empty item lists. + + + + Skipping target "{0}" because all output files are up-to-date with respect to the input files. + + + + Input files: {0} + {0} is a semicolon-separated list of filenames. + + + Output files: {0} + {0} is a semicolon-separated list of filenames. + + + {0}: Defaulting .NET Framework v{1} to the .NET Framework v4.0 version of aspnet_compiler.exe. To change the version of the tool used, please set the "ToolPath" parameter with the correct path to the tool. + + + + MSB4203: {0}: Invalid TargetFrameworkMoniker {1}. The AspNetCompiler task only supports targeting the .NET Framework. + {StrBegin="MSB4203: "} + + + MSB4205: The website project in this solution is targeting the v2.0 runtime, but it is not installed. + {StrBegin="MSB4205: "} + + + MSB4204: {0}: Invalid TargetFrameworkMoniker {1}. {2}. + {StrBegin="MSB4204: "} + + + Using the MSBuild v3.5 solution wrapper generator because the tools version was set to {0}. + + + + Using the MSBuild v3.5 solution wrapper generator with a tools version of {0} because the solution file format was version {1} and no tools version was supplied. + + + + Building solution configuration "{0}". + UE: This is not an error, so doesn't need an error code. + + + MSB4160: A circular dependency involving project "{0}" has been detected. + {StrBegin="MSB4160: "} + + + MSB4126: The specified solution configuration "{0}" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration. + {StrBegin="MSB4126: "}UE: The solution filename is provided separately to loggers. + + + MSB4046: Error reading project file "{0}": {1} + {StrBegin="MSB4046: "} + + + MSB4125: The project file name "{0}" is invalid. {1} + {StrBegin="MSB4125: "}UE: The solution filename is provided separately to loggers. + + + MSB4051: Project {0} is referencing a project with GUID {1}, but a project with this GUID was not found in the .SLN file. + {StrBegin="MSB4051: "}UE: The solution filename is provided separately to loggers. + + + MSB4078: The project file "{0}" is not supported by MSBuild and cannot be built. + {StrBegin="MSB4078: "} + + + MSB4054: The solution file must be opened in the Visual Studio IDE and converted to the latest version before it can be built by MSBuild. + {StrBegin="MSB4054: "}UE: The solution filename is provided separately to loggers. + + + MSB4121: The project configuration for project "{0}" was not specified in the solution file for the solution configuration "{1}". + {StrBegin="MSB4121: "} + + + The project "{0}" is not selected for building in solution configuration "{1}". + + UE: This is not an error, so doesn't need an error code. + + + + MSB4122: Scanning project dependencies for project "{0}" failed. {1} + {StrBegin="MSB4122: "} + + + MSB4149: The tools version "{0}" of the solution does not support building projects with a different tools version. + {StrBegin="MSB4149: "} + + + Web projects do not support the "Clean" target. Continuing with remaining projects ... + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do not localize "Clean". + + + Web projects do not support the "Publish" target. Continuing with remaining projects ... + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do not localize "Publish". + + + Skipping because the "$(AspNetConfiguration)" configuration is not supported for this web project. You can use the AspNetConfiguration property to override the configuration used for building web projects, by adding /p:AspNetConfiguration=<value> to the command line. Currently web projects only support Debug and Release configurations. + + UE: This is not an error, so doesn't need an error code. + LOCALIZATION: Do NOT localize "AspNetConfiguration", "Debug", "Release". + + + + Target "{0}" skipped. Previously built unsuccessfully. + + + + Target "{0}" skipped. Previously built successfully. + + + + MSB4116: The condition "{1}" on the "{0}" target has a reference to item metadata. References to item metadata are not allowed in target conditions unless they are part of an item transform. + {StrBegin="MSB4116: "} + + + MSB4057: The target "{0}" does not exist in the project. + {StrBegin="MSB4057: "} + + + The target "{0}" listed in a BeforeTargets attribute at "{1}" does not exist in the project, and will be ignored. + + + + The target "{0}" listed in an AfterTargets attribute at "{1}" does not exist in the project, and will be ignored. + + + + Done building target "{0}" in project "{1}" -- FAILED. + + + + Done building target "{0}" in project "{1}". + + + + {0}: (TargetId:{1}) + + + + Target output items: + + + + {0} + + + + MSB4058: The "{0}" target is missing its output specification. If a target declares inputs, it must also declare outputs. + {StrBegin="MSB4058: "} + + + Target Performance Summary: + + + + Target "{0}" skipped, due to false condition; ({1}) was evaluated as ({2}). + + + + Target "{0}" in file "{1}" from project "{2}": + + + + Target "{0}" in file "{1}" from project "{2}" (entry point): + + + + Target "{0}" in file "{1}" from project "{2}" (target "{3}" depends on it): + + + + Target "{0}" in file "{1}" from project "{2}" (designated to run before target "{3}"): + + + + Target "{0}" in file "{1}" from project "{2}" (designated to run after target "{3}"): + + + + Target "{0}" in project "{1}": + + + + Target "{0}" in project "{1}" (entry point): + + + + Target "{0}" in project "{1}" (target "{2}" depends on it): + + + + Target "{0}" in project "{1}" (designated to run before target "{2}"): + + + + Target "{0}" in project "{1}" (designated to run after target "{2}"): + + + + Target {0}: + + + + Target "{0}" in file "{1}": + + + + Target {0} from project "{1}": + + + + Target "{0}" in file "{1}" from project "{2}": + + + + Added Item(s): + + + + Removed Item(s): + + + + Set Property: {0}={1} + + + + Output Item(s): + + + + Output Property: {0}={1} + + + + Build continuing because "{0}" on the task "{1}" is set to "{2}". + + + + MSB4060: The "{0}" task has been declared or used incorrectly, or failed during construction. Check the spelling of the task name and the assembly name. + {StrBegin="MSB4060: "} + + + MSB4214: The "{0}" task has been defined, but cannot be used due to the fact that the identity defined in the UsingTask declaration (Runtime="{1}", Architecture="{2}") does not match the identity specified by the task invocation (MSBuildRuntime="{3}", MSBuildArchitecture="{4}"). + {StrBegin="MSB4214: "}LOCALIZATION: Runtime, Architecture, MSBuildRuntime, and MSBuildArchitecture should not be localized. + + + Done executing task "{0}" -- FAILED. + + + + Done executing task "{0}". + + + + {0} (TaskId:{1}) + + + + Using "{0}" task from assembly "{1}". + UE: This informational message helps users determine which assemblies their tasks were loaded from. + + + Using "{0}" task from the task factory "{1}". + UE: This informational message helps users determine which assemblies their tasks were loaded from. + + + Task "{0}" will be run in a single-threaded apartment thread. + UE: This informational message helps users determine if their tasks are run in the STA or MTA. + + + MSB4061: The "{0}" task could not be instantiated from "{1}". {2} + {StrBegin="MSB4061: "}LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. + + + MSB4127: The "{0}" task could not be instantiated from the assembly "{1}". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. {2} + {StrBegin="MSB4127: "}UE: This message is a specialized version of the TaskInstantiationFailureError message and can probably reuse some of its docs. + LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. Also, Microsoft.Build.Framework should not be localized + + + MSB4180: The "{0}" logger could not be instantiated from the assembly "{1}". Please verify the logger assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. {2} + + {StrBegin="MSB4180: "} + LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. Also, Microsoft.Build.Framework should not be localized + + + + MSB1021: Cannot create an instance of the logger. {0} + {StrBegin="MSB1021: "} + UE: This error is shown when a logger cannot be loaded and instantiated from its assembly. + LOCALIZATION: The prefix "MSBxxxx: " should not be localized. {0} contains a message explaining why the + logger could not be created -- this message comes from the CLR/FX and is localized. + + + MSB1020: The logger was not found. Check the following: 1.) The logger name specified is the same as the name of the logger class. 2.) The logger class is "public" and implements the Microsoft.Build.Framework.ILogger interface. 3.) The path to the logger assembly is correct, or the logger can be loaded using only the assembly name provided. + + {StrBegin="MSB1020: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies an logger that does not exist e.g. "msbuild /logger:FooLoggerClass,FooAssembly". The + logger class must exist in the given assembly. + LOCALIZATION: The prefix "MSBxxxx: " should not be localized. + + + + MSB4179: The task factory instance for the "{0}" task could not be instantiated from the task factory "{1}". {2} + {StrBegin="MSB4179: "} + LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. + + + MSB4176: The "{0}" task factory could not be instantiated from the assembly "{1}". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. {2} + {StrBegin="MSB4176: "}UE: This message is a specialized version of the TaskFactoryInstantiationFailureError message and can probably reuse some of its docs. + LOCALIZATION: "{2}" is a localized message from a CLR/FX exception. Also, Microsoft.Build.Framework should not be localized + + + MSB4219: The TaskFactory "{0}" does not implement ITaskFactory2. The attributes "{1}" and/or "{2}" on the UsingTask declaration for task "{3}" will be be ignored. + {StrBegin="MSB4219: "} + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSB4062: The "{0}" task could not be loaded from the assembly {1}. {2} Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. + {StrBegin="MSB4062: "}UE: This message is shown when a task cannot be loaded from its assembly for various reasons e.g. corrupt assembly, + invalid task declaration, disk error, etc. "{2}" contains a message explaining what happened. + LOCALIZATION: "{2}" is a message from the CLR loader and is already localized. Also, <UsingTask> should not be localized. + + + MSB4215: The "{0}" task could not be loaded. "{1}" is an invalid value for the task host parameter "{2}". Valid values are: "{3}", "{4}", "{5}", and "{6}"; not specifying a value is also valid. + {StrBegin="MSB4215: "} + + + "{0}" is an invalid value for the task host parameter "{1}". Valid values are: "{2}", "{3}", "{4}", and "{5}"; not specifying a value is also valid. + + + + MSB4216: Could not run the "{0}" task because MSBuild could not create or connect to a task host with runtime "{1}" and architecture "{2}". Please ensure that (1) the requested runtime and/or architecture are available on the machine, and (2) that the required executable "{3}" exists and can be run. + {StrBegin="MSB4216: "} + + + MSB4221: Could not run the "{0}" task because MSBuild could not create or connect to a task host with runtime "{1}" and architecture "{2}". Please ensure that (1) the requested runtime and/or architecture are available on the machine, and (2) that the required executable "{3}" exists and can be run. Error {4} {5}. + {StrBegin="MSB4221: "} + + + A task requested launch of the .NET 3.5 version of the MSBuild task host, but .NET 3.5 is not installed on this machine so the task host could not be launched. To fix this error, please either install .NET 3.5 or retarget your project. + + + + MSB4217: Task host node exited prematurely. Diagnostic information may be found in files in the temporary files directory named MSBuild_*.failure.txt. {0} + {StrBegin="MSB4217: "} + + + MSB4063: The "{0}" task could not be initialized with its input parameters. {1} + {StrBegin="MSB4063: "} + + + Task Parameter: + + + + Task Performance Summary: + + + + Task "{0}" skipped, due to false condition; ({1}) was evaluated as ({2}). + + + + Task "{0}" + + + + Time Elapsed {0} + + + + Building with tools version "{0}". + + + + Project file contains ToolsVersion="{0}". This toolset may be unknown or missing, in which case you may be able to resolve this by installing the appropriate version of MSBuild, or the build may have been forced to a particular ToolsVersion for policy reasons. Treating the project as if it had ToolsVersion="{1}". For more information, please see http://go.microsoft.com/fwlink/?LinkId=293424. + + + + Deferred Messages + + + + MSB4090: Found an unexpected character '{2}' at position {1} in condition "{0}". + {StrBegin="MSB4090: "} + + + MSB4091: Found a call to an undefined function "{1}" in condition "{0}". + {StrBegin="MSB4091: "} + + + MSB4064: The "{0}" parameter is not supported by the "{1}" task. Verify the parameter exists on the task, and it is a settable public instance property. + {StrBegin="MSB4064: "} + + + MSB4131: The "{0}" parameter is not supported by the "{1}" task. Verify the parameter exists on the task, and it is a gettable public instance property. + {StrBegin="MSB4131: "} + + + MSB4092: An unexpected token "{1}" was found at character position {2} in condition "{0}". + {StrBegin="MSB4092: "} + + + MSB4065: The "{0}" parameter is not marked for output by the "{1}" task. + {StrBegin="MSB4065: "} + + + MSB4066: The attribute "{0}" in element <{1}> is unrecognized. + {StrBegin="MSB4066: "} + + + MSB4067: The element <{0}> beneath element <{1}> is unrecognized. + {StrBegin="MSB4067: "} + + + MSB4173: The element <{0}> beneath element <{1}> is invalid because a child element with that name already exists + {StrBegin="MSB4173: "} + + + MSB4189: <{1}> is not a valid child of the <{0}> element. + {StrBegin="MSB4189: "} + + + MSB4068: The element <{0}> is unrecognized, or not supported in this context. + {StrBegin="MSB4068: "} + + + MSB4069: The "{0}" type of the "{1}" parameter of the "{2}" task is not supported by MSBuild. + {StrBegin="MSB4069: "}LOCALIZATION: "MSBuild" should not be localized. + + + MSB4072: A <{0}> element must contain either the "{1}" attribute or the "{2}" attribute (but not both). + {StrBegin="MSB4072: "} + + + {0} Warning(s) + + + + MSB4084: A <When> element may not follow an <Otherwise> element in a <Choose>. + {StrBegin="MSB4084: "} + + + MSB4150: Must initialize the console logger using the initialize method before using ApplyParameter + {StrBegin="MSB4150: "} + + + MSB4206: A non-null host object cannot be specified for a project which has an affinity set to out-of-process. + {StrBegin="MSB4206: "} + + + MSB4207: Only an in-process affinity may be specified for projects which have registered host objects. + {StrBegin="MSB4207: "} + + + MSB4209: The specified project instance conflicts with the affinity specified in the HostServices. + {StrBegin="MSB4209: "} + + + MSB4213: The specified request affinity {0} conflicts with a previous affinity {1} specified for this project. + {StrBegin="MSB4213: "} + + + MSB4223: A node of the required type {0} could not be created. + {StrBegin="MSB4223: "} + + + MSB4224: KeepMetadata and RemoveMetadata are mutually exclusive. + {StrBegin="MSB4224: "} + + + "{0}" ({1} target) ({2}) -> + + + + "{0}" (default target) ({1}) -> + + + + {0} {1,5} + + + + Project "{0}" on node {1} ({2} target(s)). + + + + Project "{0}" on node {1} (default targets). + + + + Project "{0}" ({1}) is building "{2}" ({3}) on node {4} ({5} target(s)). + + + + Project "{0}" ({1}) is building "{2}" ({3}) on node {4} (default targets). + + + + ({0} target) -> + + + + The property "{0}" with value "{1}" is being overridden by another batch. The property is now: "{2}" + + + + The log file path cannot be null or empty. + + + + [default] + + + + MSB4174: The task factory "{0}" could not be found in the assembly "{1}". + {StrBegin="MSB4174: "} + + + MSB4175: The task factory "{0}" could not be loaded from the assembly "{1}". {2} + {StrBegin="MSB4175: "} + + + MSB4201: The cancel operation was unable to complete because the currently executing task is not responding. + {StrBegin="MSB4201: "} + + + MSB4220: Waiting for the currently executing task "{0}" to cancel. + {StrBegin="MSB4220: "} + + + MSB4202: The request to build submission {0} cannot proceed because submission {1} is already using the main thread. + {StrBegin="MSB4202: "} + + + The request to build this submission cannot proceed because a project with the same configuration is already building. + + + + Initializing task factory "{0}" from assembly "{1}". + + + + Initializing task host factory for task "{0}" from assembly "{1}" + + + + The build plan could not be written. Check that the build process has permissions to write to {0}. + + + + The MSBuild cache file "{0}" is inaccessible. Ensure you have access to the directory and that this file is not deleted during the build. {1} + + LOCALIZATION: "{1}" is a localized message from a CLR/FX exception. + + + + The build plan could not be read. Check that the build process has permissions to read {0}. + + + + The build plan at {0} appears to be corrupt and cannot be used. + + + + +Detailed Build Summary +====================== + + + + + +============================== Build Hierarchy (IDs represent configurations) ===================================================== +Id : Exclusive Time Total Time Path (Targets) +----------------------------------------------------------------------------------------------------------------------------------- + + + + {0}{1,-3}{2}: {3:0.000}s {4:0.000}s {5} ({6}) + Fields 3 and 4 represent seconds, and the 's' following them should reflect the localized abbreviation for seconds. + + + +============================== Node Utilization (IDs represent configurations) ==================================================== +Timestamp: {0} Duration Cumulative +----------------------------------------------------------------------------------------------------------------------------------- + Spacing is important. Preserve the number of characters between the start of each word. + + + {0} {1:0.000}s {2:0.000}s {3} + Fields 1 and 2 represents seconds, and the 's' following it should reflect the localized abbreviation for seconds. + + + ----------------------------------------------------------------------------------------------------------------------------------- +Utilization: {0} Average Utilization: {1:###.0} + Spacing is important. Preserve the number of characters between the start of each word. + + + This collection cannot convert from the specified value to the backing value. + + + + The "{0}" property name is reserved. + UE: This message is shown when the user tries to redefine one of the reserved MSBuild properties e.g. $(MSBuildProjectFile) through the object model + + + The <{0}> element must have either the "{1}" attribute or the "{2}" attribute but not both. + + + + The "Remove" attribute is not permitted on an item outside of a <Target>. + + + + The "KeepMetadata" attribute is not permitted on an item outside of a <Target>. + + + + The "RemoveMetadata" attribute is not permitted on an item outside of a <Target>. + + + + The "KeepDuplicates" attribute is not permitted on an item outside of a <Target>. + + + + Elements of this type do not have a condition. + For example, it is not legal for a <ProjectExtensions> element to have a condition attribute. + + + The node already has a parent. Remove it from its parent before moving it. + + + + The node is not parented by this object so it cannot be removed from it. + + + + The reference node is not a child of this node. + + + + Cannot make a node or an ancestor of that node a child of itself. + + + + Cannot create a relationship between nodes that were created from different projects. + + + + The parent node is not itself parented. + + + + This parent is not a valid parent for the item. + + + + The name "{0}" contains an invalid character "{1}". + + + + An <Otherwise> element cannot be located before a <When> or <Otherwise> element. + + + + Project has not been given a path to save to. + + + + Project was not loaded with the ProjectLoadSettings.RecordDuplicateImports flag. + + + + Project or targets file "{0}" was loaded in read-only mode, and cannot be saved. + + + + The "{0}" object specified does not belong to the correct "{1}" object. + + + + The "{0}" name is reserved, and cannot be used. + + + + The "{0}" property is a global property, and cannot be modified. + + + + An equivalent project (a project with the same global properties and tools version) is already present in the project collection, with the path "{0}". To load an equivalent into this project collection, unload this project first. + + + + The project provided was not loaded in the collection. + + + + Cannot modify an evaluated object originating in an imported file "{0}". + + + + Cannot remove the metadata named "{0}" as it originates from an item definition, rather than being directly defined on this item. + + + + The project cannot be used as it is no longer loaded into a project collection. + + + + The operation is not allowed because currently this object is not parented. + + + + The project XML file "{0}" cannot be unloaded because at least one project "{1}" is still loaded which references that project XML. + + + + Instance object was created as immutable. + + + + All build submissions in a build must use project instances originating from the same project collection. + This occurs if a client tries to add two BuildSubmissions to a build, each involving a ProjectInstance originating in different ProjectCollection. This is not allowed. + + + Build started. + + + + {0} ({1},{2}) + A file location to be embedded in a string. + + + MSB3203: The output path "{0}" cannot be rebased. {1} + {StrBegin="MSB3203: "}UE: This message is shown when the user asks the "MSBuild" task to rebase the paths of its output items relative to the project from where the "MSBuild" task is called (as opposed to the project(s) on which the "MSBuild" task is called), and one of the output item paths is invalid. LOCALIZATION: "{1}" is a localized message from a CLR/FX exception explaining the problem. + + + MSB3202: The project file "{0}" was not found. + + {StrBegin="MSB3202: "}UE: This message is shown when the user passes a non-existent project file to the MSBuild task, in the "Projects" parameter. + and they have not specified the SkipNonexistentProjects parameter, or it is set to false. + + + + Skipping project "{0}" because it was not found. + UE: This message is shown when the user passes a non-existent project file to the MSBuild task, in the "Projects" parameter, and they have specified the SkipNonexistentProjects parameter. + + + MSB3204: The project file "{0}" is in the ".vcproj" file format, which MSBuild no longer supports. Please convert the project by opening it in the Visual Studio IDE or running the conversion tool, or use MSBuild 3.5 or earlier to build it. + {StrBegin="MSB3204: "} LOC: ".vcproj" should not be localized + + + MSB3205: SkipNonexistentProject can only accept values of "True", "False" and "Build". + {StrBegin="MSB3205: "} LOC: "SkipNonexistentProject", "True", "False" and "Build" should not be localized + + + The MSBuild task is skipping the remaining projects because the StopOnFirstFailure parameter was set to true. + LOCALIZATION: Do not localize the words "MSBuild" or "StopOnFirstFailure". + + + The MSBuild task is skipping the remaining targets because the StopOnFirstFailure parameter was set to true. + LOCALIZATION: Do not localize the words "MSBuild" or "StopOnFirstFailure". + + + Overriding the BuildingInParallel property by setting it to false. This is due to the system being run in single process mode with StopOnFirstFailure set to true. + LOCALIZATION: Do not localize the words "MSBuild", "BuildingInParallel", or "StopOnFirstFailure". + + + StopOnFirstFailure will have no effect when the following conditions are all present: 1) The system is running in multiple process mode 2) The BuildInParallel property is true. 3) The RunEachTargetSeparately property is false. + LOCALIZATION: Do not localize the words "RunEachTargetSeparately", "BuildingInParallel", or "StopOnFirstFailure". + + + MSB3100: Syntax for "{0}" parameter is not valid ({1}). Correct syntax is {0}="<name>=<value>". + {StrBegin="MSB3100: "}This error is shown if the user does any of the following: + Properties="foo" (missing property value) + Properties="=4" (missing property name) + The user must pass in an actual property name and value, as in Properties="Configuration=Debug". + + + Global Properties: + + + + Removing Properties: + + + + Overriding Global Properties for project "{0}" with: + + + + Additional Properties for project "{0}": + + + + Removing Properties for project "{0}": + + + + MSB4111: At most one of the include, remove, and update attributes may be specified for an item element. + + + + MSB4227: The attribute "{0}" on element <{1}> is invalid because an attribute with that name already exists + {StrBegin="MSB4227: "} + + + MSB4228: The name "{0}" is not valid for metadata expressed as an attribute (on element <{1}>) + {StrBegin="MSB4228: "} + + + The <{0}> element must have either the "{1}" attribute, the "{2}" attribute, or the "{3}" attribute, but not more than one. + + + + An item not parented under a Target must have a value for Include or Update or Remove. + LOCALIZATION: Please do not localize "Target", "Include", "Update", and "Remove". + + + The requested operation needs to split the item element at location {0} into individual elements but item element splitting is disabled with {1}. + + + + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..9953a0db8f8 --- /dev/null +++ b/src/XMakeCommandLine/Resources/xlf/Strings.xlf @@ -0,0 +1,887 @@ + + + + + + + MSBUILD : error MSB1011: Specify which project or solution file to use because this folder contains more than one project or solution file. + {StrBegin="MSBUILD : error MSB1011: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : Configuration error {0}: {1} + {SubString="Configuration"}UE: This prefixes any error from reading the toolset definitions in msbuild.exe.config or the registry. + There's no error code because one was included in the error message. + LOCALIZATION: The word "Configuration" should be localized, the words "MSBuild" and "error" should NOT be localized. + + + + MSBUILD : error MSB1027: The /noautoresponse switch cannot be specified in the MSBuild.rsp auto-response file, nor in any response file that is referenced by the auto-response file. + {StrBegin="MSBUILD : error MSB1027: "}LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:", "/noautoresponse" and "MSBuild.rsp" should not be localized. + + + Microsoft (R) Build Engine version {0} +Copyright (C) Microsoft Corporation. All rights reserved. + + LOCALIZATION: {0} contains the DLL version number + + + MSBUILD : error MSB1008: Only one project can be specified. + {StrBegin="MSBUILD : error MSB1008: "}UE: This happens if the user does something like "msbuild.exe myapp.proj myapp2.proj". This is not allowed. + MSBuild.exe will only build a single project. The help topic may link to an article about how to author an MSBuild project + that itself launches MSBuild on a number of other projects. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1025: An internal failure occurred while running MSBuild. + {StrBegin="MSBUILD : error MSB1025: "}UE: This message is shown when the application has to terminate either because of a bug in the code, or because some + FX/CLR method threw an unexpected exception. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. + + + Syntax: MSBuild.exe [options] [project file] + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + Description: Builds the specified targets in the project file. If + a project file is not specified, MSBuild searches the + current working directory for a file that has a file + extension that ends in "proj" and uses that file. + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + Switches: + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /help Display this usage message. (Short form: /? or /h) + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /nologo Do not display the startup banner and copyright message. + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /version Display version information only. (Short form: /ver) + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + @<file> Insert command-line settings from a text file. To specify + multiple response files, specify each response file + separately. + + Any response files named "msbuild.rsp" are automatically + consumed from the following locations: + (1) the directory of msbuild.exe + (2) the directory of the first project or solution built + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /noautoresponse Do not auto-include any MSBuild.rsp files. (Short form: + /noautorsp) + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /target:<targets> Build these targets in this project. Use a semicolon or a + comma to separate multiple targets, or specify each + target separately. (Short form: /t) + Example: + /target:Resources;Compile + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /property:<n>=<v> Set or override these project-level properties. <n> is + the property name, and <v> is the property value. Use a + semicolon or a comma to separate multiple properties, or + specify each property separately. (Short form: /p) + Example: + /property:WarningLevel=2;OutDir=bin\Debug\ + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /logger:<logger> Use this logger to log events from MSBuild. To specify + multiple loggers, specify each logger separately. + The <logger> syntax is: + [<logger class>,]<logger assembly>[;<logger parameters>] + The <logger class> syntax is: + [<partial or full namespace>.]<logger class name> + The <logger assembly> syntax is: + {<assembly name>[,<strong name>] | <assembly file>} + The <logger parameters> are optional, and are passed + to the logger exactly as you typed them. (Short form: /l) + Examples: + /logger:XMLLogger,MyLogger,Version=1.0.2,Culture=neutral + /logger:XMLLogger,C:\Loggers\MyLogger.dll;OutputAsHTML + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /verbosity:<level> Display this amount of information in the event log. + The available verbosity levels are: q[uiet], m[inimal], + n[ormal], d[etailed], and diag[nostic]. (Short form: /v) + Example: + /verbosity:quiet + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /consoleloggerparameters:<parameters> + Parameters to console logger. (Short form: /clp) + The available parameters are: + PerformanceSummary--Show time spent in tasks, targets + and projects. + Summary--Show error and warning summary at the end. + NoSummary--Don't show error and warning summary at the + end. + ErrorsOnly--Show only errors. + WarningsOnly--Show only warnings. + NoItemAndPropertyList--Don't show list of items and + properties at the start of each project build. + ShowCommandLine--Show TaskCommandLineEvent messages + ShowTimestamp--Display the Timestamp as a prefix to any + message. + ShowEventId--Show eventId for started events, finished + events, and messages + ForceNoAlign--Does not align the text to the size of + the console buffer + DisableConsoleColor--Use the default console colors + for all logging messages. + DisableMPLogging-- Disable the multiprocessor + logging style of output when running in + non-multiprocessor mode. + EnableMPLogging--Enable the multiprocessor logging + style even when running in non-multiprocessor + mode. This logging style is on by default. + ForceConsoleColor--Use ANSI console colors even if + console does not support it + Verbosity--overrides the /verbosity setting for this + logger. + Example: + /consoleloggerparameters:PerformanceSummary;NoSummary; + Verbosity=minimal + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /noconsolelogger Disable the default console logger and do not log events + to the console. (Short form: /noconlog) + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /validate Validate the project against the default schema. (Short + form: /val) + + /validate:<schema> Validate the project against the specified schema. (Short + form: /val) + Example: + /validate:MyExtendedBuildSchema.xsd + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /maxcpucount[:n] Specifies the maximum number of concurrent processes to + build with. If the switch is not used, the default + value used is 1. If the switch is used without a value + MSBuild will use up to the number of processors on the + computer. (Short form: /m[:n]) + + + LOCALIZATION: "maxcpucount" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + Examples: + + MSBuild MyApp.sln /t:Rebuild /p:Configuration=Release + MSBuild MyApp.csproj /t:Clean + /p:Configuration=Debug;TargetFrameworkVersion=v3.5 + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + For switch syntax, type "MSBuild /help" + UE: this message is shown when the user makes a syntax error on the command-line for a switch. + LOCALIZATION: "MSBuild /help" should not be localized. + + + /distributedlogger:<central logger>*<forwarding logger> + Use this logger to log events from MSBuild, attaching a + different logger instance to each node. To specify + multiple loggers, specify each logger separately. + (Short form /dl) + The <logger> syntax is: + [<logger class>,]<logger assembly>[;<logger parameters>] + The <logger class> syntax is: + [<partial or full namespace>.]<logger class name> + The <logger assembly> syntax is: + {<assembly name>[,<strong name>] | <assembly file>} + The <logger parameters> are optional, and are passed + to the logger exactly as you typed them. (Short form: /l) + Examples: + /dl:XMLLogger,MyLogger,Version=1.0.2,Culture=neutral + /dl:MyLogger,C:\My.dll*ForwardingLogger,C:\Logger.dll + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg chars. + + + + /ignoreprojectextensions:<extensions> + List of extensions to ignore when determining which + project file to build. Use a semicolon or a comma + to separate multiple extensions. + (Short form: /ignore) + Example: + /ignoreprojectextensions:.sln + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /toolsversion:<version> + The version of the MSBuild Toolset (tasks, targets, etc.) + to use during build. This version will override the + versions specified by individual projects. (Short form: + /tv) + Example: + /toolsversion:3.5 + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /fileLogger[n] Logs the build output to a file. By default + the file is in the current directory and named + "msbuild[n].log". Events from all nodes are combined into + a single log. The location of the file and other + parameters for the fileLogger can be specified through + the addition of the "/fileLoggerParameters[n]" switch. + "n" if present can be a digit from 1-9, allowing up to + 10 file loggers to be attached. (Short form: /fl[n]) + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /distributedFileLogger + Logs the build output to multiple log files, one log file + per MSBuild node. The initial location for these files is + the current directory. By default the files are called + "MSBuild<nodeid>.log". The location of the files and + other parameters for the fileLogger can be specified + with the addition of the "/fileLoggerParameters" switch. + + If a log file name is set through the fileLoggerParameters + switch the distributed logger will use the fileName as a + template and append the node id to this fileName to + create a log file for each node. + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /fileloggerparameters[n]:<parameters> + Provides any extra parameters for file loggers. + The presence of this switch implies the + corresponding /filelogger[n] switch. + "n" if present can be a digit from 1-9. + /fileloggerparameters is also used by any distributed + file logger, see description of /distributedFileLogger. + (Short form: /flp[n]) + The same parameters listed for the console logger are + available. Some additional available parameters are: + LogFile--path to the log file into which the + build log will be written. + Append--determines if the build log will be appended + to or overwrite the log file. Setting the + switch appends the build log to the log file; + Not setting the switch overwrites the + contents of an existing log file. + The default is not to append to the log file. + Encoding--specifies the encoding for the file, + for example, UTF-8, Unicode, or ASCII + Default verbosity is Detailed. + Examples: + /fileLoggerParameters:LogFile=MyLog.log;Append; + Verbosity=diagnostic;Encoding=UTF-8 + + /flp:Summary;Verbosity=minimal;LogFile=msbuild.sum + /flp1:warningsonly;logfile=msbuild.wrn + /flp2:errorsonly;logfile=msbuild.err + + + LOCALIZATION: The following should not be localized: + 1) "MSBuild", "MSBuild.exe" and "MSBuild.rsp" + 2) the string "proj" that describes the extension we look for + 3) all switch names and their short forms e.g. /property, or /p + 4) all verbosity levels and their short forms e.g. quiet, or q + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /nodeReuse:<parameters> + Enables or Disables the reuse of MSBuild nodes. + The parameters are: + True --Nodes will remain after the build completes + and will be reused by subsequent builds (default) + False--Nodes will not remain after the build completes + (Short form: /nr) + Example: + /nr:true + + + + + /preprocess[:file] + Creates a single, aggregated project file by + inlining all the files that would be imported during a + build, with their boundaries marked. This can be + useful for figuring out what files are being imported + and from where, and what they will contribute to + the build. By default the output is written to + the console window. If the path to an output file + is provided that will be used instead. + (Short form: /pp) + Example: + /pp:out.txt + + + + + /detailedsummary + Shows detailed information at the end of the build + about the configurations built and how they were + scheduled to nodes. + (Short form: /ds) + + + + + /debug + Causes a debugger prompt to appear immediately so that + Visual Studio can be attached for you to debug the + MSBuild XML and any tasks and loggers it uses. + + + + + MSBUILD : Configuration error MSB1043: The application could not start. {0} + + {StrBegin="MSBUILD : Configuration error MSB1043: "} + UE: This error is shown when the msbuild.exe.config file had invalid content. + LOCALIZATION: The prefix "MSBUILD : Configuration error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1019: Logger switch was not correctly formed. + {StrBegin="MSBUILD : error MSB1019: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user does any of the following: + msbuild.exe /logger:;"logger parameters" (missing logger class and assembly) + msbuild.exe /logger:loggerclass, (missing logger assembly) + msbuild.exe /logger:loggerclass,;"logger parameters" (missing logger assembly) + The correct way to specify a logger is to give both the logger class and logger assembly, or just the logger assembly (logger + parameters are optional). + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1030: Maximum CPU count is not valid. {0} + + {StrBegin="MSBUILD : error MSB1030: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies an invalid CPU value. For example, /m:foo instead of /m:2. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1032: Maximum CPU count is not valid. Value must be an integer greater than zero and no more than 1024. + {StrBegin="MSBUILD : error MSB1032: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies a CPU value that is zero or less. For example, /m:0 instead of /m:2. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1033: Node number is not valid. {0}. + + {StrBegin="MSBUILD : error MSB1033: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies a CPU value that is zero or less. For example, /nodemode:foo instead of /nodemode:2. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1034: Node number is not valid. Value must be an integer greater than zero. + {StrBegin="MSBUILD : error MSB1034: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies a CPU value that is zero or less. For example, /nodemode:0 instead of /nodemode:2. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1006: Property is not valid. + + {StrBegin="MSBUILD : error MSB1006: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown if the user does any of the following: + msbuild.exe /property:foo (missing property value) + msbuild.exe /property:=4 (missing property name) + The user must pass in an actual property name and value following the switch, as in "msbuild.exe /property:Configuration=Debug". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : MSB1046: The schema "{0}" is not valid. {1} + {StrBegin="MSBUILD : MSB1046: "}UE: This message is shown when the schema file provided for the validation of a project is itself not valid. + LOCALIZATION: "{0}" is the schema file path. "{1}" is a message from an FX exception that describes why the schema file is bad. + + + Switch: {0} + + UE: This is attached to error messages caused by an invalid switch. This message indicates what the invalid arg was. + For example, if an unknown switch is passed to MSBuild.exe, the error message will look like this: + MSBUILD : error MSB1001: Unknown switch. + Switch: /bogus + LOCALIZATION: {0} contains the invalid switch text. + + + + MSBUILD : error MSB1040: ToolsVersion is not valid. {0} + + {StrBegin="MSBUILD : error MSB1040: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies an unknown toolversion, eg /toolsversion:99 + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1018: Verbosity level is not valid. + + {StrBegin="MSBUILD : error MSB1018: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies an unknown verbosity level e.g. "msbuild /verbosity:foo". The only valid verbosities + (and their short forms) are: q[uiet], m[inimal], n[ormal], d[etailed], diag[nostic]. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1028: The logger failed unexpectedly. + {StrBegin="MSBUILD : error MSB1028: "} + UE: This error is shown when a logger specified with the /logger switch throws an exception while being + initialized. This message is followed by the exception text including the stack trace. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : Logger error {0}: {1} + UE: This prefixes the error message emitted by a logger, when a logger fails in a controlled way using a LoggerException. + For example, the logger is indicating that it could not create its output file. + There's no error code because one was supplied by the logger. + LOCALIZATION: The word "Logger" should be localized, the words "MSBuild" and "error" should NOT be localized. + + + + MSBUILD : Logger error MSB1029: {0} + {SubString="Logger", "{0}"}{StrBegin="MSBUILD : "} + UE: This prefixes the error message emitted by a logger, when a logger fails in a controlled way using a LoggerException. + For example, the logger is indicating that it could not create its output file. + This is like LoggerFailurePrefixNoErrorCode, but the logger didn't supply its own error code, so we have to provide one. + LOCALIZATION: The word "Logger" should be localized, the words "MSBuild" and "error" should NOT be localized. + + + + MSBUILD : error MSB1007: Specify a logger. + + {StrBegin="MSBUILD : error MSB1007: "}UE: This happens if the user does something like "msbuild.exe /logger". The user must pass in an actual logger class + following the switch, as in "msbuild.exe /logger:XMLLogger,MyLogger,Version=1.0.2,Culture=neutral". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1031: Specify the maximum number of CPUs. + + {StrBegin="MSBUILD : error MSB1031: "}UE: This happens if the user does something like "msbuild.exe /m". The user must pass in an actual number like /m:4. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file. + + {StrBegin="MSBUILD : error MSB1003: "}UE: The user must either specify a project or solution file to build, or there must be a project file in the current directory + with a file extension ending in "proj" (e.g., foo.csproj), or a solution file ending in "sln". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1005: Specify a property and its value. + + {StrBegin="MSBUILD : error MSB1005: "}UE: This happens if the user does something like "msbuild.exe /property". The user must pass in an actual property + name and value following the switch, as in "msbuild.exe /property:Configuration=Debug". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1012: Specify a response file. + + {StrBegin="MSBUILD : error MSB1012: "}UE: This error would occur if the user did something like "msbuild.exe @ foo.proj". The at-sign must be followed by a + response file. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1004: Specify the name of the target. + + {StrBegin="MSBUILD : error MSB1004: "}UE: This happens if the user does something like "msbuild.exe /target". The user must pass in an actual target name + following the switch, as in "msbuild.exe /target:blah". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1039: Specify the version of the toolset. + + {StrBegin="MSBUILD : error MSB1039: "} + UE: This happens if the user does something like "msbuild.exe /ToolsVersion". The user must pass in an actual toolsversion + name following the switch, as in "msbuild.exe /ToolsVersion:3.5". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1016: Specify the verbosity level. + + {StrBegin="MSBUILD : error MSB1016: "}UE: This happens if the user does something like "msbuild.exe /verbosity". The user must pass in a verbosity level + after the switch e.g. "msbuild.exe /verbosity:detailed". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1024: Only one schema can be specified for validation of the project. + + {StrBegin="MSBUILD : error MSB1024: "}UE: The user did something like msbuild /validate:foo.xsd /validate:bar.xsd. We only allow one schema to be specified. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + Some command line switches were read from the auto-response file "{0}". To disable this file, use the "/noautoresponse" switch. + + UE: This message appears in high verbosity modes when we used some + switches from the auto-response file msbuild.rsp: otherwise the user may be unaware + where the switches are coming from. + + + + MSBUILD : error MSB1009: Project file does not exist. + {StrBegin="MSBUILD : error MSB1009: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. + + + + MSBUILD : MSB1045: Stopping because of syntax errors in project file. + {StrBegin="MSBUILD : MSB1045: "} + + + MSBUILD : error MSB1023: Cannot read the response file. {0} + {StrBegin="MSBUILD : error MSB1023: "}UE: This error is shown when the response file cannot be read off disk. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. {0} contains a localized message explaining + why the response file could not be read -- this message comes from the CLR/FX. + + + MSBUILD : error MSB1013: The response file was specified twice. A response file can be specified only once. Any files named "msbuild.rsp" in the directory of MSBuild.exe or in the directory of the first project or solution built (which if no project or solution is specified is the current working directory) were automatically used as response files. + {StrBegin="MSBUILD : error MSB1013: "}UE: Response files are just text files that contain a bunch of command-line switches to be passed to MSBuild.exe. The + purpose is so you don't have to type the same switches over and over again ... you can just pass in the response file instead. + Response files can include the @ switch in order to further include other response files. In order to prevent a circular + reference here, we disallow the same response file from being included twice. This error message would be followed by the + exact @ switch that resulted in the duplicate response file. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1022: Response file does not exist. + {StrBegin="MSBUILD : error MSB1022: "}UE: This message would show if the user did something like "msbuild @bogus.rsp" where bogus.rsp doesn't exist. This + message does not need in-line parameters because the exception takes care of displaying the invalid arg. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + Validating project using schema file "{0}". + LOCALIZATION: "{0}" is the location of the schema file. + + + MSBUILD : MSB1044: Project is not valid. {0} + {StrBegin="MSBUILD : MSB1044: "}UE: This error is shown when the user asks his project to be validated against a schema (/val switch for + MSBuild.exe), and the project has errors. "{0}" contains a message explaining the problem. + LOCALIZATION: "{0}" is a message from the System.XML schema validator and is already localized. + + + MSBUILD : error MSB1026: Schema file does not exist. + {StrBegin="MSBUILD : error MSB1026: "}UE: This error is shown when the user specifies a schema file using the /validate:<schema> switch, and the file + does not exist on disk. This message does not need in-line parameters because the exception takes care of displaying the + invalid arg. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1026: Schema file '{0}' does not exist. + {StrBegin="MSBUILD : error MSB1026: "}UE: This error is printed if the default schema does not exist or in the extremely unlikely event + that an explicit schema file was passed and existed when the command line parameters were checked but was deleted from disk before this check was made. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1002: This switch does not take any parameters. + {StrBegin="MSBUILD : error MSB1002: "}UE: For example, if somebody types "msbuild.exe /nologo:1", they would get this error because the /nologo switch + should not be followed by any parameters ... it stands alone. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1001: Unknown switch. + {StrBegin="MSBUILD : error MSB1001: "}UE: This occurs when the user passes in an unrecognized switch on the MSBuild.exe command-line. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1015: MSBuild does not run on this version of the operating system. It is only supported on Windows 2000, Windows XP, and later versions. + {StrBegin="MSBUILD : error MSB1015: "}LOCALIZATION: The error prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + Forcing load of Microsoft.Build.Engine because MSBUILDOLDOM=1... + + + + MSBUILD : error MSB1035: Specify the project extensions to ignore. + {StrBegin="MSBUILD : error MSB1035: "} + UE: This happens if the user does something like "msbuild.exe /IgnoreProjectextensions". The user must pass in one or more + project extensions to ignore e.g. "msbuild.exe /IgnoreProjectExtensions:.sln". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1036: There is an invalid extension in the /ignoreprojectextensions list. Extensions must start with a period ".", have one or more characters after the period and not contain any invalid path characters or wildcards. + {StrBegin="MSBUILD : error MSB1036: "}LOCALIZATION: The error prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + MSBUILD : error MSB1037: Specify one or more parameters for the console logger if using the /consoleLoggerParameters switch + {StrBegin="MSBUILD : error MSB1037: "} + UE: This happens if the user does something like "msbuild.exe /consoleLoggerParameters:". The user must pass in one or more parameters + after the switch e.g. "msbuild.exe /consoleLoggerParameters:ErrorSummary". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1038: Specify one or more parameters for the file logger if using the /fileLoggerParameters switch + {StrBegin="MSBUILD : error MSB1038: "} + UE: This happens if the user does something like "msbuild.exe /fileLoggerParameters:". The user must pass in one or more parameters + after the switch e.g. "msbuild.exe /fileLoggerParameters:logfile=c:\temp\logfile". + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1041: Specify one or more parameters for node reuse if using the /nodereuse switch + {StrBegin="MSBUILD : error MSB1041: "} + UE: This happens if the user does something like "msbuild.exe /nodereuse:" without a true or false + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB1042: Node reuse value is not valid. {0}. + {StrBegin="MSBUILD : error MSB1042: "} + UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies a node reuse value that is not equivilant to Boolean.TrueString or Boolean.FalseString. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + Attempting to cancel the build... + + + + MSBUILD : error MSB1047: File to preprocess to is not valid. {0} + {StrBegin="MSBUILD : error MSB1047: "} + + + MSBUILD : error MSB1021: Cannot create an instance of the logger. {0} + {StrBegin="MSBUILD : error MSB1021: "} + UE: This error is shown when a logger cannot be loaded and instantiated from its assembly. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. {0} contains a message explaining why the + logger could not be created -- this message comes from the CLR/FX and is localized. + + + MSBUILD : error MSB1020: The logger was not found. Check the following: 1.) The logger name specified is the same as the name of the logger class. 2.) The logger class is "public" and implements the Microsoft.Build.Framework.ILogger interface. 3.) The path to the logger assembly is correct, or the logger can be loaded using only the assembly name provided. + + {StrBegin="MSBUILD : error MSB1020: "}UE: This message does not need in-line parameters because the exception takes care of displaying the invalid arg. + This error is shown when a user specifies an logger that does not exist e.g. "msbuild /logger:FooLoggerClass,FooAssembly". The + logger class must exist in the given assembly. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + + MSBUILD : error MSB4192: The project file "{0}" is in the ".vcproj" or ".dsp" file format, which MSBuild cannot build directly. Please convert the project by opening it in the Visual Studio IDE or running the conversion tool, or, for ".vcproj", use MSBuild to build the solution file containing the project instead. + {StrBegin="MSBUILD : error MSB4192: "} LOC: ".vcproj" and ".dsp" should not be localized + + + If MSBuild debugging does not work correctly, please verify that the "Just My Code" feature is enabled in Visual Studio, and that you have selected the managed debugger. + + + + MSBUILD : error MSB1048: Solution files cannot be debugged directly. Run MSBuild first with an environment variable MSBUILDEMITSOLUTION=1 to create a corresponding ".sln.metaproj" file. Then debug that. + {StrBegin="MSBUILD : error MSB1048: "} LOC: ".SLN" should not be localized + + + Build started. + + + + {0} ({1},{2}) + A file location to be embedded in a string. + + + + \ No newline at end of file diff --git a/src/XMakeConversion/Resources/xlf/Strings.xlf b/src/XMakeConversion/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..b0867aebae9 --- /dev/null +++ b/src/XMakeConversion/Resources/xlf/Strings.xlf @@ -0,0 +1,122 @@ + + + +
+ + 231 + 107.05 + 107.05 + 0 + 0 + + + 0 + 26 + 112 + 0 + 0 + 93 + 0 + +
+ + + + MSB2013: The project-to-project reference with GUID {0} could not be converted because a valid .SLN file containing all projects could not be found. + {StrBegin="MSB2013: "} + + fuzzyMatch="100" wordcount="23" adjWordcount="5.75" curWordcount="5.75" tmLabel="N''" + + + MSB2016: Found an empty .RESX file in the project ({0}). Removing it from the converted project. + {StrBegin="MSB2016: "} + + fuzzyMatch="100" wordcount="16" adjWordcount="4" curWordcount="4" tmLabel="N''" + + + MSB2015: Found an <Exclude> element in the original project file. This cannot be converted to Visual Studio .NET and is being ignored. + {StrBegin="MSB2015: "} + + fuzzyMatch="15" wordcount="23" adjWordcount="19.55" curWordcount="19.55" + + + MSB2001: Element <{0}> does not contain the required attribute "{1}". + {StrBegin="MSB2001: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="11" adjWordcount="9.35" curWordcount="9.35" + + + MSB2002: The file name of the new project must be specified. + {StrBegin="MSB2002: "}This error shouldn't be possible when converting through Visual Studio, but we have it just in case. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB2003: The file name of the old project must be specified. + {StrBegin="MSB2003: "}This error shouldn't be possible when converting through Visual Studio, but we have it just in case. + + fuzzyMatch="100" wordcount="11" adjWordcount="2.75" curWordcount="2.75" tmLabel="N''" + + + MSB2004: Element <{0}> cannot contain more than one language node. + {StrBegin="MSB2004: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. The {0} in this case is going to be "VisualStudioProject". + + fuzzyMatch="15" wordcount="11" adjWordcount="9.35" curWordcount="9.35" + + + MSB2005: Element <{0}> cannot contain attributes. + {StrBegin="MSB2005: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="7" adjWordcount="5.95" curWordcount="5.95" + + + MSB2006: The project file does not contain the root element <{0}>. + {StrBegin="MSB2006: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="12" adjWordcount="10.2" curWordcount="10.2" + + + MSB2007: Visual Studio cannot find the project file "{0}". + {StrBegin="MSB2007: "}This error shouldn't be possible when converting through Visual Studio, but we have it just in case. + + fuzzyMatch="100" wordcount="9" adjWordcount="2.25" curWordcount="2.25" tmLabel="N''" + + + MSB2014: The project-to-project reference with GUID {0} cannot be converted because it is not listed in the file '{1}'. + {StrBegin="MSB2014: "} + + fuzzyMatch="100" wordcount="19" adjWordcount="4.75" curWordcount="4.75" tmLabel="N''" + + + MSB2008: This Visual Studio project system cannot convert "{0}" projects. It can only be used to convert C#, VB, and VJ# client projects. + {StrBegin="MSB2008: "}It appears we've been asked to convert a project that either wasn't created by the Visual Studio managed client project system (C#, VB, J#), or that has been hand-modified or corrupted. You would get this error if this conversion utility was invoked on a VC++ project (.VCPROJ) for example. In this case, the {0} would be replaced with "Visual C++". + + fuzzyMatch="100" wordcount="23" adjWordcount="5.75" curWordcount="5.75" tmLabel="N''" + + + MSB2009: Attribute "{0}" of element <{1}> is not valid. + {StrBegin="MSB2009: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="10" adjWordcount="8.5" curWordcount="8.5" + + + MSB2010: Child element <{0}> of element <{1}> is not valid. + {StrBegin="MSB2010: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="12" adjWordcount="10.2" curWordcount="10.2" + + + MSB2011: Element <{0}> is not valid. + {StrBegin="MSB2011: "}It appears we've been asked to convert a project that either wasn't created by Visual Studio, or that has been hand-modified or corrupted. + + fuzzyMatch="15" wordcount="7" adjWordcount="5.95" curWordcount="5.95" + + + MSB2012: Project-to-project references to web projects are no longer supported and therefore cannot be converted. Please remove the reference to project {0} and add it again. + {StrBegin="MSB2012: "} + + fuzzyMatch="101" wordcount="26" adjWordcount="0" curWordcount="0" tmLabel="N''" + + +
+
\ No newline at end of file diff --git a/src/XMakeTasks/ManifestUtil/Resources/xlf/Strings.ManifestUtilities.xlf b/src/XMakeTasks/ManifestUtil/Resources/xlf/Strings.ManifestUtilities.xlf new file mode 100644 index 00000000000..5497bfad09f --- /dev/null +++ b/src/XMakeTasks/ManifestUtil/Resources/xlf/Strings.ManifestUtilities.xlf @@ -0,0 +1,75 @@ + + + + + + + Out of process servers are not supported + + + + Registry key '{0}' is missing value '{1}'. + + + + No registered classes were detected for this component. + + + + Components under system file protection should not be isolated. + + + + Could not load type library. + + + + Registry key '{0}' was not imported. + + + + Registry value '{0}' was not imported. + + + + The file to be signed {0} could not be found. + + + + Failed to sign {0}. {1} + + + + Warning while signing {0}. {1} + + + + SignTool.exe was not found at path {0}. + + + + Timestamp URL server name or address could not be resolved. + + + + Only certificates using RSA encryption are valid for signing ClickOnce manifests. + + + + + UAC Manifest Options + If you want to change the Windows User Account Control level replace the + requestedExecutionLevel node with one of the following. + + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> + <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> + + If you want to utilize File and Registry Virtualization for backward + compatibility then delete the requestedExecutionLevel node. + + + + + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.xlf b/src/XMakeTasks/Resources/xlf/Strings.xlf new file mode 100644 index 00000000000..d73917931fb --- /dev/null +++ b/src/XMakeTasks/Resources/xlf/Strings.xlf @@ -0,0 +1,2396 @@ + + + + + + + BindingRedirect is missing required field 'oldVersion'. + + + + BindingRedirect is missing required field 'newVersion'. + + + + Some attributes of the assemblyIdentity element are incorrect. + + + + There was a problem parsing the oldVersion attribute. {0} + + + + There was a problem parsing the newVersion attribute. {0} + + + + The platform mapping "{0}" in the platform mapping list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "foo=bar;foo2=bar2". + + + + Project reference "{0}" has not been resolved. + + UE and LOCALIZATION: + This is not an error - we pass unresolved references to UnresolvedProjectReferences for further + processing in the .targets file. + + + + Project reference "{0}" has been assigned the "{1}" configuration. + + + + MSB3461: The MetabasePath parameter cannot be combined with VirtualPath or PhysicalPath. + {StrBegin="MSB3461: "} + + + MSB3462: Either MetabasePath or VirtualPath must be specified. + {StrBegin="MSB3462: "} + + + MSB3463: The TargetPath parameter must be specified if the application is updatable. + {StrBegin="MSB3463: "} + + + MSB3464: The TargetPath parameter must be specified if the target directory needs to be overwritten. + {StrBegin="MSB3464: "} + + + MSB3001: Cannot extract culture information from file name "{0}". {1} + {StrBegin="MSB3001: "} + + + Culture of "{0}" was assigned to file "{1}". + + + + MSB3656: No input file has been passed to the task, exiting. + {StrBegin="MSB3656: "} + + + MSB3646: Cannot specify values for both KeyFile and KeyContainer. + {StrBegin="MSB3646: "} + + + MSB3647: DelaySign parameter is true, but no KeyFile or KeyContainer was specified. + {StrBegin="MSB3647: "} + + + MSB3649: The KeyFile path '{0}' is invalid. KeyFile must point to an existing file. + {StrBegin="MSB3649: "} + + + MSB3650: Neither SDKToolsPath '{0}' nor ToolPath '{1}' is a valid directory. One of these must be set. + {StrBegin="MSB3650: "} + + + MSB3651: The key container '{0}' does not contain a public/private key pair. + {StrBegin="MSB3651: "} + + + MSB3652: The key file '{0}' does not contain a public/private key pair. + {StrBegin="MSB3652: "} + + + MSB3653: AxTlbBaseTask is not an executable task. If deriving from it, please ensure the ToolName property was set. + {StrBegin="MSB3653: "} + + + MSB3654: Delay signing requires that at least a public key be specified. Please either supply a public key using the KeyFile or KeyContainer properties, or disable delay signing. + {StrBegin="MSB3654: "} + + + MSB3881: Fatal Error: more than {0} command line arguments. + {StrBegin="MSB3881: "} + + + MSB3882: Fatal Error: No response from server. + {StrBegin="MSB3882: "} + + + MSB3883: Unexpected exception: + {StrBegin="MSB3883: "} + + + MSB3884: Could not find rule set file "{0}". + {StrBegin="MSB3884: "} + + + Creating directory "{0}". + + + + MSB3024: Could not copy the file "{0}" to the destination file "{1}", because the destination is a folder instead of a file. To copy the source file into a folder, consider using the DestinationFolder parameter instead of DestinationFiles. + {StrBegin="MSB3024: "} + + + Did not copy from file "{0}" to file "{1}" because the "{2}" parameter was set to "{3}" in the project and the files' sizes and timestamps match. + + + + MSB3021: Unable to copy file "{0}" to "{1}". {2} + {StrBegin="MSB3021: "} + + + MSB3022: Both "{0}" and "{1}" were specified as input parameters in the project file. Please choose one or the other. + {StrBegin="MSB3022: "} + + + Copying file from "{0}" to "{1}". + LOCALIZATION: {0} and {1} are paths. + + + Creating hard link to copy "{0}" to "{1}". + LOCALIZATION: {0} and {1} are paths. + + + Could not use a link to copy "{0}" to "{1}". Copying the file instead. {2} + LOCALIZATION: {0} and {1} are paths. {2} is an optional localized message. + + + MSB3023: No destination specified for Copy. Please supply either "{0}" or "{1}". + {StrBegin="MSB3023: "} + + + Removing read-only attribute from "{0}". + + + + MSB3025: The source file "{0}" is actually a directory. The "Copy" task does not support copying directories. + {StrBegin="MSB3025: "} + + + MSB3026: Could not copy "{0}" to "{1}". Beginning retry {2} in {3}ms. {4} + {StrBegin="MSB3026: "} LOCALIZATION: {0} and {1} are paths. {2} and {3} are numbers. {4} is an optional localized message. + + + MSB3027: Could not copy "{0}" to "{1}". Exceeded retry count of {2}. Failed. + {StrBegin="MSB3027: "} LOCALIZATION: {0} and {1} are paths. {2} is a number. + + + MSB3028: {0} is an invalid retry count. Value must not be negative. + {StrBegin="MSB3028: "} LOCALIZATION: {0} is a number. + + + MSB3029: {0} is an invalid retry delay. Value must not be negative. + {StrBegin="MSB3029: "} LOCALIZATION: {0} is a number. + + + MSB3030: Could not copy the file "{0}" because it was not found. + {StrBegin="MSB3030: "} LOCALIZATION: {0} is a number. + + + MSB3031: Could not set additional metadata. "{0}" is a reserved metadata name and cannot be modified. + {StrBegin="MSB3031: "} UE: Tasks and OM users are not allowed to remove or change the value of the built-in meta-data on items e.g. the meta-data "FullPath", "RelativeDir", etc. are reserved. + + + Resource file '{0}' gets manifest resource name '{1}'. + + + + MSB3042: A namespace or class definition was found within a conditional compilation directive in the file "{0}". This may lead to an incorrect choice for the manifest resource name for resource "{1}". + {StrBegin="MSB3042: "} + + + Resource file '{0}' depends on '{1}'. + + + + Resource file '{0}' doesn't depend on any other file. + + + + MSB3041: Unable to create a manifest resource name for "{0}". {1} + {StrBegin="MSB3041: "} + + + Root namespace is empty. + + + + Root namespace is '{0}'. + + + + MSB3053: The assembly alias "{1}" on reference "{0}" contains illegal characters. + {StrBegin="MSB3053: "} + + + MSB3051: The parameter to the compiler is invalid. {0} + {StrBegin="MSB3051: "} + + + MSB3052: The parameter to the compiler is invalid, '{0}{1}' will be ignored. + {StrBegin="MSB3052: "} + + + Deleting file "{0}". + + + + MSB3061: Unable to delete file "{0}". {1} + {StrBegin="MSB3061: "} + + + File "{0}" doesn't exist. Skipping. + + + + MSB3071: All drive letters from A: through Z: are currently in use. Since the working directory "{0}" is a UNC path, the "Exec" task needs a free drive letter to map the UNC path to. Disconnect from one or more shared resources to free up drive letters, or specify a local working directory before attempting this command again. + {StrBegin="MSB3071: "}LOCALIZATION: "Exec", "A:", and "Z:" should not be localized. + + + MSB3073: The command "{0}" exited with code {1}. + {StrBegin="MSB3073: "} + + + MSB3075: The command "{0}" exited with code {1}. Please verify that you have sufficient rights to run this command. + {StrBegin="MSB3075: "} + + + The command "{0}" exited with code {1}. + + + + MSB3076: The regular expression "{0}" that was supplied is invalid. {1} + {StrBegin="MSB3076: "} + + + MSB3072: The "Exec" task needs a command to execute. + {StrBegin="MSB3072: "}LOCALIZATION: "Exec" should not be localized. + + + The working directory "{0}" does not exist. + No error code because an error will be prefixed. + + + Found "{0}". + + + + "{0}" is not a valid file name. {1} + + + + Comparison path is "{0}". + + + + MSB3541: {0} has invalid value "{1}". {2} + {StrBegin="MSB3541: "} + + + MSB3102: Could not delete state file "{0}". {1} + {StrBegin="MSB3102: "} + + + Could not locate the assembly "{0}". Check to make sure the assembly exists on disk. + + + + MSB3088: Could not read state file "{0}". {1} + {StrBegin="MSB3088: "} + + + Could not read state file "{0}". {1} + + + + MSB3081: A problem occurred while trying to set the "{0}" parameter for the IDE's in-process compiler. {1} + {StrBegin="MSB3081: "} + + + MSB3101: Could not write state file "{0}". {1} + {StrBegin="MSB3101: "} + + + MSB3105: The item "{0}" was specified more than once in the "{1}" parameter. Duplicate items are not supported by the "{1}" parameter. + {StrBegin="MSB3105: "} + + + MSB3083: The item "{0}" was specified more than once in the "{1}" parameter and both items had the same value "{2}" for the "{3}" metadata. Duplicate items are not supported by the "{1}" parameter unless they have different values for the "{3}" metadata. + {StrBegin="MSB3083: "} + + + MSB3108: Error executing the {0} task. {1} + {StrBegin="MSB3108: "} + + + Expected a file but got directory "{0}". + + + + Expected file "{0}" does not exist. + + + + MSB3082: Task failed because "{0}" was not found, or the .NET Framework {1} is not installed. Please install the .NET Framework {1}. + {StrBegin="MSB3082: "} + + + MSB3087: An incompatible host object was passed into the "{0}" task. The host object for this task must implement the "{1}" interface. + {StrBegin="MSB3087: "} + + + The format of this state file is not valid. + + + + Item "{0}" has attribute "{1}" with value "{2}" that could not be converted to "{3}". + + + + MSB3095: Invalid argument. {0} + {StrBegin="MSB3095: "} + + + MSB3097: File "{0}" is not a valid assembly. + {StrBegin="MSB3097: "} + + + MSB3098: "{1}" task received an invalid value for the "{0}" parameter. + {StrBegin="MSB3098: "} + + + MSB3099: Invalid assembly name "{0}". {1} + {StrBegin="MSB3099: "}UE: This message is shown when RegisterAssembly or UnregisterAssembly is passed an assembly with an invalid filename. "{0}" is the name of the file, and "{1}" is a message explaining the problem. LOCALIZATION: "{1}" is a localized message. + + + MSB3100: Syntax for "{0}" parameter is not valid ({1}). Correct syntax is {0}="<name>=<value>". + {StrBegin="MSB3100: "}This error is shown if the user does any of the following: + Properties="foo" (missing property value) + Properties="=4" (missing property name) + The user must pass in an actual property name and value, as in Properties="Configuration=Debug". + + + Global Properties: + + + + Removing Properties: + + + + Overriding Global Properties for project "{0}" with: + + + + Additional Properties for project "{0}": + + + + Removing Properties for project "{0}": + + + + MSB3103: Invalid Resx file. {0} + {StrBegin="MSB3103: "} + + + MSB3106: Assembly strong name "{0}" is either a path which could not be found or it is a full assembly name which is badly formed. If it is a full assembly name it may contain characters that need to be escaped with backslash(\). Those characters are Equals(=), Comma(,), Quote("), Apostrophe('), Backslash(\). + {StrBegin="MSB3106: "} + + + MSB3107: The specified project reference metadata for the reference "{0}" is missing or has an invalid value: {1} + {StrBegin="MSB3107: "} + + + The IDE's in-process compiler does not support the specified values for the "{0}" parameter. Therefore, this task will fallback to using the command-line compiler. + + + + MSB3091: Task failed because "{0}" was not found, or the correct Microsoft Windows SDK is not installed. The task is looking for "{0}" in the "bin" subdirectory beneath the location specified in the {1} value of the registry key {2}. You may be able to solve the problem by doing one of the following: 1) Install the Microsoft Windows SDK. 2) Install Visual Studio 2010. 3) Manually set the above registry key to the correct location. 4) Pass the correct location into the "ToolPath" parameter of the task. + {StrBegin="MSB3091: "} + + + MSB3084: Task attempted to find "{0}" in two locations. 1) Under the "{1}" processor specific directory which is generated based on SdkToolsPath 2) The x86 specific directory under "{2}" which is specified by the SDKToolsPath property. You may be able to solve the problem by doing one of the following: 1) Set the "SDKToolsPath" property to the location of the Microsoft Windows SDK. + {StrBegin="MSB3084: "} + + + Task attempted to find "{0}" using the SdkToolsPath value "{1}". Make sure the SdkToolsPath is set to the correct value and the tool exists in the correct processor specific location below it. + + + + MSB3086: Task could not find "{0}" using the SdkToolsPath "{1}" or the registry key "{2}". Make sure the SdkToolsPath is set and the tool exists in the correct processor specific location under the SdkToolsPath and that the Microsoft Windows SDK is installed + {StrBegin="MSB3086: "} + + + MSB3666: The SDK tool "{0}" could not be found. {1} + {StrBegin="MSB3666: "} The {1} will be the exception message + + + MSB3104: The referenced assembly "{0}" was not found. If this assembly is produced by another one of your projects, please make sure to build that project before building this one. + {StrBegin="MSB3104: "} + + + MSB3093: The command exited with code {0}. + {StrBegin="MSB3093: "} + + + MSB3094: "{2}" refers to {0} item(s), and "{3}" refers to {1} item(s). They must have the same number of items. + {StrBegin="MSB3094: "} + + + MSB3831: The application configuration file must have root configuration element. + {StrBegin="MSB3831: "} + + + MSB3832: The version number "{0}" is invalid. + {StrBegin="MSB3832: "} + + + MSB3833: The assembly name "{0}" contained in the suggested binding redirect is invalid. + {StrBegin="MSB3833: "} + + + No suggested binding redirects from ResolveAssemblyReferences. + + + + MSB3835: The "{0}" node is missing from the "{1}" node. Skipping. + {StrBegin="MSB3835: "} + + + MSB3836: The explicit binding redirect on "{0}" conflicts with an autogenerated binding redirect. Consider removing it from the application configuration file or disabling autogenerated binding redirects. The build will replace it with: "{1}". + {StrBegin="MSB3836: "} + + + Processing suggested binding redirect on "{0}" with MaxVersion "{1}". + + + + MSB3161: A circular dependency was detected between the following built packages: {0}. + {StrBegin="MSB3161: "} + + + MSB3142: An error occurred trying to copy '{0}' to '{1}': {2} + {StrBegin="MSB3142: "} + + + MSB3143: An error occurred trying to copy '{0}' for item '{1}': {2} + {StrBegin="MSB3143: "} + + + MSB3162: The '{0}' item selected requires '{1}'. Select the missing prerequisite in the Prerequisites Dialog Box or create a bootstrapper package for the missing prerequisite. + {StrBegin="MSB3162: "} + + + MSB3165: The value of the '{0}' attribute in '{1}' does not match that of file '{2}'. + {StrBegin="MSB3165: "} + + + MSB3168: Duplicate item '{0}' will be ignored. + {StrBegin="MSB3168: "} + + + MSB3169: An error occurred generating a bootstrapper: {0} + {StrBegin="MSB3169: "} + + + MSB3151: Item '{0}' already includes '{1}'. + {StrBegin="MSB3151: "} + + + MSB3163: Build input parameter 'ComponentsLocation={0}' is not valid. The value must be one of 'HomeSite', 'Relative', or 'Absolute'. Defaulting to 'HomeSite'. + {StrBegin="MSB3163: "} + + + MSB3144: Not enough data was provided to generate a bootstrapper. Please provide a value for at least one of the parameters: 'ApplicationFile' or 'BootstrapperItems'. + {StrBegin="MSB3144: "} + + + MSB3145: Build input parameter '{0}={1}' is not a web url or UNC share. + {StrBegin="MSB3145: "} + + + MSB3146: Item '{0}' is required by '{1}', but was not included. + {StrBegin="MSB3146: "} + + + MSB3696: One of the following items '{0}' is required by '{1}', but none were included. + {StrBegin="MSB3696: "} + + + MSB3147: Could not find required file '{0}' in '{1}'. + {StrBegin="MSB3147: "} + + + MSB3141: No 'PublicKey' or 'Hash' attribute specified for file '{0}' in item '{1}'. + {StrBegin="MSB3141: "} + + + MSB3170: Item '{0}' could not find any of dependent items '{1}'. + {StrBegin="MSB3170: "} + + + MSB3148: No output path specified in build settings. + {StrBegin="MSB3148: "} + + + MSB3149: No resources available for building a bootstrapper. + {StrBegin="MSB3149: "} + + + MSB3150: No string resources available for building a bootstrapper with culture '{0}'. + {StrBegin="MSB3150: "} + + + MSB3152: To enable 'Download prerequisites from the same location as my application' in the Prerequisites dialog box, you must download file '{0}' for item '{1}' to your local machine. For more information, see http://go.microsoft.com/fwlink/?LinkId=616018. + {StrBegin="MSB3152: "} + + + MSB3166: Could not find required file '{0}' for item '{1}'. + {StrBegin="MSB3166: "} + + + MSB3164: No 'HomeSite' attribute has been provided for '{0}', so the package will be published to the same location as the bootstrapper. + {StrBegin="MSB3164: "} + + + MSB3153: Xml validation did not pass for item '{0}' located at '{1}'. + {StrBegin="MSB3153: "} + + + MSB3154: Could not find string resources for item '{0}'. + {StrBegin="MSB3154: "} + + + MSB3155: Item '{0}' could not be located in '{1}'. + {StrBegin="MSB3155: "} + + + MSB3156: Xml validation did not pass for item '{0}' located at '{1}'. + {StrBegin="MSB3156: "} + + + MSB3157: Could not match culture '{0}' for item '{1}'. Using culture '{2}' instead. + {StrBegin="MSB3157: "} + + + MSB3158: Could not find resources for culture '{0}'. Using culture '{1}' instead. + {StrBegin="MSB3158: "} + + + MSB3159: Xml Validation error in file '{0}': {1} + {StrBegin="MSB3159: "} + + + MSB3160: Xml Validation warning in file '{0}': {1} + {StrBegin="MSB3160: "} + + + MSB3177: Reference '{0}' does not allow partially trusted callers. + {StrBegin="MSB3177: "} + + + MSB3178: Assembly '{0}' is incorrectly specified as a file. + {StrBegin="MSB3178: "} + + + MSB3179: Problem isolating COM reference '{0}': {1} + {StrBegin="MSB3179: "} + + + MSB3111: Use of app.config binding redirects requires full trust. + {StrBegin="MSB3111: "} + + + MSB3112: Two or more assemblies have the same identity '{0}'. + {StrBegin="MSB3112: "} + + + MSB3180: COM component '{1}' is defined in both '{3}' and '{4}', {0}="{2}". + {StrBegin="MSB3180: "} + + + MSB3181: Two or more files have the same target path '{0}'. + {StrBegin="MSB3181: "} + + + MSB3127: The default icon {0} could not be found in the current file references or is not part of the required download group. The default icon file name is case sensitive so the file name referenced in the application manifest must exactly match the icon's file name. + {StrBegin="MSB3127: "} + + + MSB3119: File association extensions must start with a period character (.). + {StrBegin="MSB3119: "} + + + MSB3120: File association extension '{0}' exceeds the maximum allowed length of {1}. + {StrBegin="MSB3120: "} + + + MSB3121: The file association element in the application manifest is missing one or more of the following required attributes: extension, description, progid, or default icon. + {StrBegin="MSB3121: "} + + + MSB3122: Use of file associations requires full trust. + {StrBegin="MSB3122: "} + + + MSB3123: The number of file associations exceeds the limit of {0}. + {StrBegin="MSB3123: "} + + + MSB3124: A file association has already been created for extension '{0}'. + {StrBegin="MSB3124: "} + + + MSB3125: The application is using file associations but has no EntryPoint build parameter. + {StrBegin="MSB3125: "} + + + MSB3126: The application is using file associations but is not marked for installation. File associations cannot be used for applications that are not installed such as applications hosted in a web browser. + {StrBegin="MSB3126: "} + + + MSB3171: Problem generating manifest. {0} + {StrBegin="MSB3171: "} + + + MSB3176: Specified minimum required version is greater than the current publish version. Please specify a version less than or equal to the current publish version. + {StrBegin="MSB3176: "} + + + MSB3117: Application is set to host in browser but the TargetFrameworkVersion is set to v2.0. + + + + MSB3116: Application is marked to host in browser but is also marked for online and offline use. Please change your application to online only. + + + + MSB3110: Assembly '{0}' has mismatched identity '{1}', expected file name: '{2}'. + {StrBegin="MSB3110: "} + + + MSB3115: File '{0}' is not a valid entry point. + {StrBegin="MSB3115: "} + + + MSB3184: Input manifest is invalid. + {StrBegin="MSB3184: "} + + + MSB3133: The ExcludePermissions property is deprecated. The permission set requested by the application has been set to the permissions defined in Internet or Local Intranet zone. To continue using a custom Permission Set, define your custom permission set in the Security Page of the Project Designer. + {StrBegin="MSB3133: "} + + + MSB3134: The permission set requested by the application exceeded the permissions allowed by the Internet or Intranet zones. Select Full Trust or to continue using partial trust, define your custom permission set in the Security Page of the Project Designer. + {StrBegin="MSB3134: "} + + + MSB3135: The PermissionSet for the target zone has not been defined for the following version of the .NET Framework: {0}. + {StrBegin="MSB3135: "} + + + MSB3175: Invalid value for '{0}' of item '{1}'. + {StrBegin="MSB3175: "} + + + MSB3174: Invalid value for '{0}'. + {StrBegin="MSB3174: "} + + + MSB3189: The update location for this application is a local path. + {StrBegin="MSB3189: "} + + + MSB3185: EntryPoint not specified for manifest. + {StrBegin="MSB3185: "} + + + MSB3186: Unable to infer an assembly identity for generated manifest from task input parameters. + {StrBegin="MSB3186: "} + + + MSB3187: Referenced assembly '{0}' targets a different processor than the application. + {StrBegin="MSB3187: "} + + + MSB3188: Assembly '{0}' must be strong signed in order to be marked as a prerequisite. + {StrBegin="MSB3188: "} + + + MSB3172: Unable to read manifest '{0}'. {1} + {StrBegin="MSB3172: "} + + + MSB3114: Could not find file '{0}' referenced by assembly '{1}'. + {StrBegin="MSB3114: "} + + + MSB3113: Could not find file '{0}'. + {StrBegin="MSB3113: "} + + + MSB3128: The ClickOnce manifests cannot be signed because they contain one or more references that are not hashed. + {StrBegin="MSB3128: "} + + + MSB3182: File name '{0}' exceeds {1} characters. + {StrBegin="MSB3182: "} + + + MSB3183: Reference '{0}' is an interop assembly requiring full trust. + {StrBegin="MSB3183: "} + + + MSB3173: Unable to write manifest '{0}'. {1} + {StrBegin="MSB3173: "} + + + MSB3190: ClickOnce does not support the request execution level '{0}'. + {StrBegin="MSB3190: "} + + + MSB3552: Resource file "{0}" cannot be found. + {StrBegin="MSB3552: "} + + + MSB3553: Resource file "{0}" has an invalid name. {1} + {StrBegin="MSB3553: "}Appears if the input file name is so invalid we can't change the file extension on it. + + + MSB3554: Cannot write to the output file "{0}". {1} + {StrBegin="MSB3554: "} + + + MSB3555: Output file "{0}" is possibly corrupt. + {StrBegin="MSB3555: "} + + + MSB3556: Only strings can be written to a .txt file, resource "{0}" is type {1}. + {StrBegin="MSB3556: "} + + + MSB3557: Error(s) generating strongly typed resources for file "{0}". + {StrBegin="MSB3557: "} + + + MSB3558: Unsupported file extension "{0}" on file "{1}". + {StrBegin="MSB3558: "} + + + MSB3559: The code DOM provider for the "{0}" language failed. {1} + {StrBegin="MSB3559: "} + + + MSB3560: Could not delete the possibly corrupt output file "{0}". {1} + {StrBegin="MSB3560: "} + + + MSB3562: The "[strings]" tag is no longer necessary in text resources; please remove it. + {StrBegin="MSB3562: "} + + + MSB3563: Unsupported square bracket keyword, "{0}". + {StrBegin="MSB3563: "} + + + MSB3564: Resource line without an equals sign, "{0}". + {StrBegin="MSB3564: "} + + + MSB3565: Resource line without a name. + {StrBegin="MSB3565: "} + + + MSB3566: Unsupported or invalid escape character in resource "{0}", char '{1}'. + {StrBegin="MSB3566: "} + + + MSB3567: Could not generate property on class "{0}". + {StrBegin="MSB3567: "} + + + Could not load type {0} which is used in the .RESX file. Ensure that the necessary references have been added to your project. + + + + MSB3568: Duplicate resource name "{0}" is not allowed, ignored. + {StrBegin="MSB3568: "} + + + MSB3569: Invalid hex value after '\u' in resource "{0}", value '{1}'. + {StrBegin="MSB3569: "} + + + MSB3570: Cannot write to the Strongly Typed Resource class file "{0}". {1} + {StrBegin="MSB3570: "} + + + MSB3572: StronglyTypedClassName, StronglyTypedNamespace, and/or StronglyTypedFileName parameters were passed in, but no StronglyTypedLanguage. If you want to create a strongly typed resource class, please specify a language. Otherwise remove all class, file name, and namespace parameters. + {StrBegin="MSB3572: "} + + + MSB3573: The language for a strongly typed resource class was specified, but more than one source file was passed in. Please pass in only one source file at a time if you want to generate strongly typed resource classes. + {StrBegin="MSB3573: "} + + + {0} + + + + Processing resource file "{0}" into "{1}". + + + + Extracting .ResW files from assembly "{0}" into "{1}". + + + + Skipping extracting .ResW files from assembly "{0}" because it declares non-supported framework "{1}". + + + + Processing {0} resources from file "{1}". + + + + Creating strongly typed resources class "{0}". + + + + No resources specified in "Sources". Skipping resource generation. + + LOCALIZATION: Please don't localize "Sources" this is an item meta-data name. + + + + No resources are out of date with respect to their source files. Skipping resource generation. + + + + Additional input "{0}" has been updated since the last build. Forcing regeneration of all resources. + + + + Creating a separate AppDomain because "NeverLockTypeAssemblies" evaluated to 'true'. + + + + Creating a separate AppDomain because while parsing "{0}" the serialized type "{1}" on line {2} could not be loaded. {3} + + + + Creating a separate AppDomain because of error parsing "{0}". {1} + + + + Creating a separate AppDomain because of error parsing "{0}" on line {1}. {2} + + + + Creating a separate AppDomain because of resource "{0}" representing a serialized type "{1}" in "{2}" on line {3}. + + + + Creating a separate AppDomain because of resource "{0}" of type "{1}" in "{2}" on line {3}. + + + + MSB3574: Did not recognize "{0}" as a managed assembly. + {StrBegin="MSB3574: "} + + + MSB3575: GenerateResource cannot write assemblies, only read from them. Cannot create assembly "{0}". + {StrBegin="MSB3575: "} + + + MSB3576: Creating the CultureInfo failed for assembly "{2}". Note the set of cultures supported is Operating System-dependent, and the Operating System has removed some cultures from time to time (ie, some Serbian cultures are split up in Windows 7). The culture may be a user-defined custom culture that we can't currently load on this machine. Exception info: {0}: {1} + {StrBegin="MSB3576: "} + + + MSB3577: Two output file names resolved to the same output path: "{0}" + {StrBegin="MSB3577: "} + + + MSB3578: This assembly contains neutral resources corresponding to the culture "{0}". These resources will not be considered neutral in the output format as we are unable to preserve this information. The resources will continue to correspond to "{0}" in the output format. + {StrBegin="MSB3578: "} + + + MSB3579: Couldn't find the linked resources file "{0}" listed in the assembly manifest. + {StrBegin="MSB3579: "} + + + MSB3580: The assembly in file "{0}" has an assembly culture, indicating it is a satellite assembly for culture "{1}". But satellite assembly simple names must end in ".resources", while this one's simple name is "{2}". This is either a main assembly with the culture incorrectly set, or a satellite assembly with an incorrect simple name. + {StrBegin="MSB3580: "} + + + MSB3811: The assembly "{0}" says it is a satellite assembly, but it contains code. Main assemblies shouldn't specify the assembly culture in their manifest, and satellites should not contain code. This is almost certainly an error in your build process. + {StrBegin="MSB3811: "} + + + MSB3812: This assembly claims to be a satellite assembly, but doesn't contain any properly named .resources files as manifest resources. The name of the files should end in {0}.resources. There is probably a build-related problem with this assembly. + {StrBegin="MSB3812: "} + + + MSB3813: Invalid or unrecognized UltimateResourceFallbackLocation value in the NeutralResourcesLanguageAttribute for assembly "{1}". Location: "{0}" + {StrBegin="MSB3813: "} + + + MSB3814: Main assembly "{1}" was built improperly. The manifest resource "{0}" ends in .en-US.resources, when it should end in .resources. Either rename it to something like foo.resources (and consider using the NeutralResourcesLanguageAttribute on the main assembly), or move it to a US English satellite assembly. + {StrBegin="MSB3814: "} + + + MSB3815: Satellite assembly "{2}" was built improperly. The manifest resource "{0}" will not be found by the ResourceManager. It must end in "{1}". + {StrBegin="MSB3815: "} + + + MSB3816: Loading assembly "{0}" failed. {1} + {StrBegin="MSB3816: "} + + + MSB3817: The assembly "{0}" does not have a NeutralResourcesLanguageAttribute on it. To be used in an app package, portable libraries must define a NeutralResourcesLanguageAttribute on their main assembly (ie, the one containing code, not a satellite assembly). + {StrBegin="MSB3817: "} + + + MSB3818: The GenerateResource task doesn't currently support simultaneously running as an external tool and extracting ResW files from assemblies. + {StrBegin="MSB3818: "} + + + MSB3819: Cannot find assembly "{0}", which may contain managed resources that need to be included in this app package. Please ensure that this assembly exists. + {StrBegin="MSB3819: "} + + + MSB3820: The path needed to store build-related temporary files is too long. Try your project in a shorter directory, or rename some of your resources. The full path was "{0}". + {StrBegin="MSB3820: "} + + + MSB3441: Cannot get assembly name for "{0}". {1} + {StrBegin="MSB3441: "} + + + Could not locate the expected version of the Microsoft Windows SDK. Looked for a location specified in the "{0}" value of the registry key "{1}". If your build process does not need the SDK then this can be ignored. Otherwise you can solve the problem by doing one of the following: 1) Install the Microsoft Windows SDK. 2) Install Visual Studio 2010. 3) Manually set the above registry key to the correct location. + + + + Found the Microsoft Windows SDK installed at "{0}". + + + + Creating directory "{0}". + + + + MSB3191: Unable to create directory "{0}". {1} + {StrBegin="MSB3191: "} + + + MSB3511: "{0}" is an invalid value for the "Importance" parameter. Valid values are: High, Normal and Low. + {StrBegin="MSB3511: "}UE: This message is shown when a user specifies a value for the importance attribute of Message which is not valid. + The importance enumeration is: High, Normal and Low. Specifying any other importance will result in this message being shown + LOCALIZATION: "Importance" should not be localized. + High should not be localized. + Normal should not be localized. + Low should not be localized. + + + Creating directory "{0}". + + + + MSB3676: Could not move the file "{0}" to the destination file "{1}", because the destination is a folder instead of a file. To move the source file into a folder, consider using the DestinationFolder parameter instead of DestinationFiles. + {StrBegin="MSB3676: "} + + + MSB3677: Unable to move file "{0}" to "{1}". {2} + {StrBegin="MSB3677: "} + + + MSB3678: Both "{0}" and "{1}" were specified as input parameters in the project file. Only one must be provided. + {StrBegin="MSB3678: "} + + + Moving file from "{0}" to "{1}". + + + + MSB3679: No destination specified for Move. Please supply either "{0}" or "{1}". + {StrBegin="MSB3679: "} + + + MSB3680: The source file "{0}" does not exist. + {StrBegin="MSB3680: "} + + + MSB3681: The source file "{0}" is a directory. The "Move" task does not support moving directories. + {StrBegin="MSB3681: "} + + + MSB3203: The output path "{0}" cannot be rebased. {1} + {StrBegin="MSB3203: "}UE: This message is shown when the user asks the "MSBuild" task to rebase the paths of its output items relative to the project from where the "MSBuild" task is called (as opposed to the project(s) on which the "MSBuild" task is called), and one of the output item paths is invalid. LOCALIZATION: "{1}" is a localized message from a CLR/FX exception explaining the problem. + + + MSB3202: The project file "{0}" was not found. + {StrBegin="MSB3202: "}UE: This message is shown when the user passes a non-existent project file to the MSBuild task, in the "Projects" parameter. + and they have not specified the SkipNonexistentProjects parameter, or it is set to false. + + + Skipping project "{0}" because it was not found. + UE: This message is shown when the user passes a non-existent project file to the MSBuild task, in the "Projects" parameter, and they have specified the SkipNonexistentProjects parameter. + + + MSB3204: The project file "{0}" is in the ".vcproj" file format, which MSBuild no longer supports. Please convert the project by opening it in the Visual Studio IDE or running the conversion tool, or use MSBuild 3.5 or earlier to build it. + {StrBegin="MSB3204: "} LOC: ".vcproj" should not be localized + + + MSB3205: SkipNonexistentProject can only accept values of "True", "False" and "Build". + {StrBegin="MSB3205: "} LOC: "SkipNonexistentProject", "True", "False" and "Build" should not be localized + + + The MSBuild task is skipping the remaining projects because the StopOnFirstFailure parameter was set to true. + LOCALIZATION: Do not localize the words "MSBuild" or "StopOnFirstFailure". + + + The MSBuild task is skipping the remaining targets because the StopOnFirstFailure parameter was set to true. + LOCALIZATION: Do not localize the words "MSBuild" or "StopOnFirstFailure". + + + Overriding the BuildingInParallel property by setting it to false. This is due to the system being run in single process mode with StopOnFirstFailure set to true. + LOCALIZATION: Do not localize the words "MSBuild", "BuildingInParallel", or "StopOnFirstFailure". + + + StopOnFirstFailure will have no effect when the following conditions are all present: 1) The system is running in multiple process mode 2) The BuildInParallel property is true. 3) The RunEachTargetSeparately property is false. + LOCALIZATION: Do not localize the words "RunEachTargetSeparately", "BuildingInParallel", or "StopOnFirstFailure". + + + MSB3501: Could not read lines from file "{0}". {1} + {StrBegin="MSB3501: "} + + + MSB3211: The assembly '{0}' is not registered for COM Interop. Please register it with regasm.exe /tlb. + {StrBegin="MSB3211: "} + + + MSB3212: The assembly "{0}" could not be converted to a type library. {1} + {StrBegin="MSB3212: "} + + + MSB3217: Cannot register assembly "{0}". {1} + {StrBegin="MSB3217: "} + + + MSB3213: Cannot register type library "{0}". {1} + {StrBegin="MSB3213: "} + + + MSB3214: "{0}" does not contain any types that can be registered for COM Interop. + {StrBegin="MSB3214: "} + + + MSB3215: Cannot register assembly "{0}" - file doesn't exist. + {StrBegin="MSB3215: "} + + + Registering assembly "{0}" for COM Interop. + + + + Exporting and registering type library "{0}". + + + + Type library "{0}" is up to date, skipping regeneration. + + + + MSB3216: Cannot register assembly "{0}" - access denied. Please make sure you're running the application as administrator. {1} + {StrBegin="MSB3216: "} + + + MSB3231: Unable to remove directory "{0}". {1} + {StrBegin="MSB3231: "} + + + Removing directory "{0}". + + + + Directory "{0}" doesn't exist. Skipping. + + + + No resources specified in "InputFiles". Skipping resource generation. + + + + MSB3451: Neither SDKToolsPath '{0}' nor ToolPath '{1}' is a valid directory. One of these must be set. + {StrBegin="MSB3451: "} + + + MSB3452: StronglyTypedClassName, StronglyTypedNamespace, and/or StronglyTypedFileName parameters were passed in, but no StronglyTypedLanguage. If you want to create a strongly typed resource class, please specify a language. Otherwise remove all class, file name, and namespace parameters. + {StrBegin="MSB3452: "} + + + MSB3453: The language for a strongly typed resource class was specified, but more than one source file was passed in. Please pass in only one source file at a time if you want to generate strongly typed resource classes. + {StrBegin="MSB3453: "} + + + MSB3454: Tracker.exe is required to correctly incrementally generate resources in some circumstances, such as when building on a 64-bit OS using 32-bit MSBuild. This build requires Tracker.exe, but it could not be found. The task is looking for Tracker.exe beneath the {0} value of the registry key {1}. To solve the problem, either: 1) Install the Microsoft Windows SDK v7.0A or later. 2) Install Microsoft Visual Studio 2010. 3) Manually set the above registry key to the correct location. Alternatively, you can turn off incremental resource generation by setting the "TrackFileAccess" property to "false". + {StrBegin="MSB3454: "} + + + MSB3455: ResGen.exe may not run because the command line is {0} characters long, which exceeds the maximum length of the command. To fix this problem, please either (1) remove unnecessary assembly references, or (2) make the paths to those references shorter. + {StrBegin="MSB3455: "} + + + AssemblyFoldersEx location: "{0}" + + + + Considered AssemblyFoldersEx locations. + + + + There was a conflict between "{0}" and "{1}". + + + + "{0}" was chosen because it had a higher version. + + + + "{0}" was chosen because it was primary and "{1}" was not. + + + + Consider app.config remapping of assembly "{0}" from Version "{1}" [{2}] to Version "{3}" [{4}] to solve conflict and get rid of warning. + + UE and LOCALIZATION: + {1} and {3} are version numbers like 1.0.0.0 + {2} and {4} are file names correspending to {1} and {3} respectively + {0} is an assembly name with no version number like 'D, Culture=neutral, PublicKeyToken=aaaaaaaaaaaaaaaa' + + + + Considered "{0}", + but its name "{1}" + didn't match the expected name "{2}". + + + + Considered "{0}", but it didn't exist. + + + + Considered treating "{0}" as a file name, but it didn't exist. + + + + Considered "{0}", which was not found in the GAC. + + + + Considered "{0}", which existed but didn't have a valid identity. This may not be an assembly. + + + + Considered "{0}", which existed but had a processor architecture "{1}" which does not match the targeted processor architecture "{2}". + + + + Dependency "{0}". + + + + {0} + + + + {0} + + + + {0} + + + + Found related file "{0}". + + + + Found satellite file "{0}". + + + + Found embedded scatter file "{0}". + + + + {0} + + + + Ignoring "{0}" because it has a non-empty subtype "{1}". + + + + Ignoring invalid Target Framework value "{0}". + + + + MSB3242: Conflict between mutually exclusive parameters. AutoUnify was 'true' and AppConfigFile was set. + {StrBegin="MSB3242: "} + + + MSB3243: No way to resolve conflict between "{0}" and "{1}". Choosing "{0}" arbitrarily. + {StrBegin="MSB3243: "} + + + MSB3244: Could not find dependent files. {0} + {StrBegin="MSB3244: "} + + + MSB3245: Could not resolve this reference. {0} If this reference is required by your code, you may get compilation errors. + {StrBegin="MSB3245: "} + + + MSB3246: Resolved file has a bad image, no metadata, or is otherwise inaccessible. {0} + {StrBegin="MSB3246: "} + + + MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file: {0} + {StrBegin="MSB3247: "} + + + MSB3248: Parameter "{0}" has invalid value "{1}". {2} + {StrBegin="MSB3248: "} + + + MSB3249: Application Configuration file "{0}" is invalid. {1} + {StrBegin="MSB3249: "} + + + MSB3250: The file "{0}" will be ignored because it cannot be read. This file was either passed in to InstalledAssemblyTables or was found by searching the {1} folder in the TargetFrameworkDirectories. {2} + {StrBegin="MSB3250: "} + + + MSB3251: Could not resolve assembly {0}. The target framework required by this assembly ({1}) is higher than the project target framework. If this reference is required by your code, you may get compilation errors. + + + + MSB3252: The currently targeted framework "{1}" does not include the referenced assembly "{0}". To fix this, either (1) change the targeted framework for this project or (2) remove the referenced assembly from the project. + {StrBegin="MSB3252: "} + + + MSB3253: The currently targeted framework "{2}" does not include "{1}" which the referenced assembly "{0}" depends on. This caused the referenced assembly to not resolve. To fix this, either (1) change the targeted framework for this project, or (2) remove the referenced assembly from the project. + {StrBegin="MSB3253: "} + + + MSB3254: The file "{0}" will be ignored because it cannot be read. This file was either passed in to InstalledAssemblySubsetTables or was found by searching the {1} folder in the TargetFrameworkDirectories. {2} + {StrBegin="MSB3254: "} + + + MSB3255: Could not find any Target Framework Subset files in the Target Framework Directories or at the locations specified in the InstalledAssemblySubsetTables. + {StrBegin="MSB3255: "} + + + MSB3256: No assemblies were read in from the redist lists. A TargetFramework profile exclusion list could not be generated. + {StrBegin="MSB3256: "} + + + MSB3257: The primary reference "{0}" could not be resolved because it has a higher version "{1}" than exists in the current target framework. The version found in the current target framework is "{2}". + {StrBegin="MSB3257: "} + + + MSB3258: The primary reference "{0}" could not be resolved because it has an indirect dependency on the .NET Framework assembly "{1}" which has a higher version "{2}" than the version "{3}" in the current target framework. + {StrBegin="MSB3258: "} + + + MSB3259: Invalid parameter combination. Can only set either subset or profile parameters. Cannot set one or more subset parameters ("TargetFrameworkSubsets", "InstalledAssemblySubsetTables") and one or more profile parameters ("ProfileName", "FullFrameworkFolders", "FullFrameworkAssemblyTables") at the same time. + {StrBegin="MSB3259: "} + + + MSB3260: Could not find any target framework profile redist files in the FullFrameworkFolders locations. + {StrBegin="MSB3260: "} + + + MSB3261: The FrameworkDirectory metadata must be set on all items passed to the FullFrameworkAssemblyTables parameter. The item "{0}" did not have the metadata set. + {StrBegin="MSB3261: "} + + + MSB3262: When targeting a profile the ProfileName parameter and one of FullFrameworkFolders or FullFrameworkAssemblyTables must be set. + {StrBegin="MSB3262: "} + + + MSB3263: The file "{0}" will be ignored because it cannot be read. This file was either passed in to FullFrameworkAssemblyTables or was found by searching the "{1}" folder in the FullFrameworkFolders. {2} + {StrBegin="MSB3263: "} + + + MSB3267: The primary reference "{0}", which is a framework assembly, could not be resolved in the currently targeted framework. "{1}". To resolve this problem, either remove the reference "{0}" or retarget your application to a framework version which contains "{0}". + {StrBegin="MSB3267: "} + + + MSB3268: The primary reference "{0}" could not be resolved because it has an indirect dependency on the framework assembly "{1}" which could not be resolved in the currently targeted framework. "{2}". To resolve this problem, either remove the reference "{0}" or retarget your application to a framework version which contains "{1}". + {StrBegin="MSB3268: "} + + + MSB3269: Could not determine if resolved references are part of the targeted framework because of an error. "{0}" + {StrBegin="MSB3269: "} + + + MSB3270: There was a mismatch between the processor architecture of the project being built "{0}" and the processor architecture of the reference "{1}", "{2}". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. + {StrBegin="MSB3270: "} + + + MSB3271: There was a mismatch between the processor architecture of the project being built "{0}" and the processor architecture, "{1}", of the implementation file "{2}" for "{3}". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and implementation file, or choose a winmd file with an implementation file that has a processor architecture which matches the targeted processor architecture of your project. + {StrBegin="MSB3271: "} + + + MSB3272: There was a problem reading the implementation file "{0}". "{1}" + {StrBegin="MSB3272: "} + + + Invalid PE header found. The implementation file will not used. + This message can be used as the {1} in MSB3272 + + + MSB3273: Unknown processor architecture. The implementation file "{0}" for "{1}" had an ImageFileMachine value of "0x{2}". If you wish to use this implementation file make sure the "ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch" property in your project is set to "Warning" or "None". + {StrBegin="MSB3273: "} + + + MSB3274: The primary reference "{0}" could not be resolved because it was built against the "{1}" framework. This is a higher version than the currently targeted framework "{2}". + {StrBegin="MSB3274: "} + + + MSB3275: The primary reference "{0}" could not be resolved because it has an indirect dependency on the assembly "{1}" which was built against the "{2}" framework. This is a higher version than the currently targeted framework "{3}". + {StrBegin="MSB3275: "} + + + MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. + {StrBegin="MSB3276: "} + + + MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. + {StrBegin="MSB3277: "} + + + {0} = '{1}' + + + + {0}: + + + + This reference is not "CopyLocal" because it conflicted with another reference with the same name and lost the conflict. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. + + + + The ImageRuntimeVersion for this reference is "{0}". + + LOCALIZATION: Please don't localize "ImageRuntimeVersion" this is an item meta-data name. + + + + This reference is a WinMDFile. + + LOCALIZATION: Please don't localize "WinMDFile" this is an item meta-data name. + + + + This reference is not "CopyLocal" because the CopyLocalDependenciesWhenParentReferenceInGac property is set to false and all the parent references for this reference are found in the GAC. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. "CopyLocalDependenciesWhenParentReferenceInGac" is a property name. + + + + This reference is not "CopyLocal" because its types will be embedded into the target assembly. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. + + + + This reference is not "CopyLocal" because it's in a Frameworks directory. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. + + + + This reference is not "CopyLocal" because at least one source item had "Private" set to "false" and no source items had "Private" set to "true". + + LOCALIZATION: Please don't localize "CopyLocal", "Private", "false", "true". + + + + This reference is not "CopyLocal" because it's a prerequisite file. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. + + + + This reference is not "CopyLocal" because it's registered in the GAC. + + LOCALIZATION: Please don't localize "CopyLocal" this is an item meta-data name. + + + + Primary reference "{0}". + + + + Required by "{0}". + + + + References which depend on "{0}" [{1}]. + This will look like references which depend on "A, Version=2.0.0.0 PublicKey=4a4fded9gisujf" [a.dll]. + + + Unresolved primary reference with an item include of "{0}". + This messages is for a reference which could not be resolved, however we have its item spec and will display that. {0} will be somethign like System or A, Version=xxx + + + Project file item includes which caused reference "{0}". + This will look like, Project file item includes which caused reference "a.dll". + + + Resolved file path is "{0}". + + + + Reference found at search path location "{0}". + + + + For SearchPath "{0}". + + + + Using this version instead of original version "{0}" in "{2}" because of a binding redirect entry in the file "{1}". + + + + Using this version instead of original version "{0}" in "{1}" because AutoUnify is 'true'. + + + + Due to a remapping entry in the currently targeted framework redist list, reference "{0}" was remapped to "{1}". + + + + Using this version instead of original version "{0}" in "{1}" because there is a more recent version of this framework file. + + + + Unified Dependency "{0}". + + + + Unified primary reference "{0}". + + + + Could not find satellite assemblies for reference "{0}". {1} + + + + A TargetFramework profile exclusion list will be generated. The exclusion list is a list of assemblies not in the profile. + + + + A TargetFramework profile exclusion list will not be generated. A full client name "{0}" was found in the TargetFrameworkSubsetNames list. + + + + No TargetFramework subset exclusion list will be generated. IgnoreDefaultInstalledAssemblySubsetTables is true and no additional profile files were passed in to InstalledAssemblySubsetTables. + + + + A TargetFramework profile exclusion list will be generated. + + + + No TargetFramework profile exclusion list will be generated. No TargetFrameworkSubsets were provided and no additional profile files were passed in to InstalledAssemblySubsetTables. + + + + TargetFramework Profile List Information: + + + + TargetFramework Profile List Paths: + + + + Redist List File Paths: + + + + Computed TargetFramework profile exclusion list assembly full names: + + + + Path: "{0}" + + + + The redist list file "{0}" has a null or empty Redist name in the FileList element. Make sure the Redist Name is not null or empty. + + + + COM Reference '{0}' is the interop assembly for ActiveX control '{1}' but was marked to be linked by the compiler with the /link flag. This COM reference will be treated as a reference and will not be linked. + + + + Adding a matching tlbimp reference for the aximp reference "{0}". + + + + Using cache file at "{0}". + + + + Creating new cache file at "{0}". + + + + MSB3281: The assembly "{0}" is not a valid assembly file. + {StrBegin="MSB3281: "} + + + MSB3282: Cannot access type library name for library "{0}". {1} + {StrBegin="MSB3282: "} + + + MSB3283: Cannot find wrapper assembly for type library "{0}". Verify that (1) the COM component is registered correctly and (2) your target platform is the same as the bitness of the COM component. For example, if the COM component is 32-bit, your target platform must not be 64-bit. + {StrBegin="MSB3283: "} + + + MSB3284: Cannot get the file path for type library "{0}" version {1}.{2}. {3} + {StrBegin="MSB3284: "} + + + MSB3285: Cannot get type library attributes for a dependent type library! + {StrBegin="MSB3285: "} + + + MSB3286: Cannot load type library "{0}" version {1}.{2}. {3} + {StrBegin="MSB3286: "} + + + MSB3287: Cannot load type library for reference "{0}". {1} + {StrBegin="MSB3287: "} + + + MSB3302: Cannot retrieve information about a dependent type. + {StrBegin="MSB3302: "} + + + MSB3300: Cannot specify values for both KeyFile and KeyContainer. + {StrBegin="MSB3300: "} + + + MSB3301: DelaySign parameter is true, but no KeyFile or KeyContainer was specified. + {StrBegin="MSB3301: "} + + + MSB3288: COM reference "{0}" conflicts with reference "{1}" - the project references different type libraries with the same type library names. Ignoring reference "{0}". + {StrBegin="MSB3288: "} + + + MSB3290: Failed to create the wrapper assembly for type library "{0}". {1} + {StrBegin="MSB3290: "} + + + MSB3291: Could not resolve dependent .NET assembly "{0}". Please make sure this assembly is included in the references section of the project file. + {StrBegin="MSB3291: "} + + + MSB3292: Failed to remap ADO reference version {0}.{1} to version 2.7 - "{2}". + {StrBegin="MSB3292: "} + + + MSB3303: Could not resolve COM reference "{0}" version {1}.{2}. {3} + {StrBegin="MSB3303: "} + + + MSB3293: Could not resolve dependent COM reference "{0}" version {1}.{2}. + {StrBegin="MSB3293: "} + + + MSB3294: Could not resolve dependent COM reference "{0}". + {StrBegin="MSB3294: "} + + + MSB3304: Could not determine the dependencies of the COM reference "{0}". {1} + {StrBegin="MSB3304: "} + + + MSB3305: Processing COM reference "{0}" from path "{1}". {2} + {StrBegin="MSB3305: "} + + + Processing COM reference "{0}" from path "{1}". {2} + + + + MSB3295: Failed to load an assembly. Please make sure you have disabled strong name verification for your public key if you want to generate delay signed wrappers. {0} + {StrBegin="MSB3295: "} + + + MSB3296: The specified COM reference meta-data for the reference "{1}" is missing or has an invalid value: "{0}". + {StrBegin="MSB3296: "} + + + MSB3297: No COM references have been passed into the task, exiting. + {StrBegin="MSB3297: "} + + + Remapping ADO reference version {0}.{1} to version 2.7. + + + + Resolved COM reference dependency "{0}" version {1}.{2}: "{3}" + + + + Resolved COM reference dependency "{0}": "{1}" + + + + Resolved COM reference for item "{0}": "{1}". + + + + Resolving COM reference for item "{0}" with a wrapper "{1}". + + + + Resolving COM reference dependency "{0}" version {1}.{2}. + + + + Determining dependencies of the COM reference "{0}". + + + + MSB3298: The key container '{0}' does not contain a public/private key pair. + {StrBegin="MSB3298: "} + + + MSB3299: The key file '{0}' does not contain a public/private key pair. + {StrBegin="MSB3299: "} + + + {0} {1}.{2} + + + + MSB3321: Importing key file "{0}" was canceled. + {StrBegin="MSB3321: "} + + + MSB3322: Unable to get MD5 checksum for the key file "{0}". {1} + {StrBegin="MSB3322: "} + + + Error importing key + + + + MSB3323: Unable to find manifest signing certificate in the certificate store. + {StrBegin="MSB3323: "} + + + MSB3324: Invalid key file name "{0}". {1} + {StrBegin="MSB3324: "} + + + MSB3325: Cannot import the following key file: {0}. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: {1} + {StrBegin="MSB3325: "} + + + MSB3326: Cannot import the following key file: {0}. The key file may be password protected. To correct this, try to import the certificate again or import the certificate manually into the current user’s personal certificate store. + {StrBegin="MSB3326: "} + + + MSB3327: Unable to find code signing certificate in the current user’s Windows certificate store. To correct this, either disable signing of the ClickOnce manifest or install the certificate into the certificate store. + {StrBegin="MSB3327: "} + + + MSB3331: Unable to apply publish properties for item "{0}". + {StrBegin="MSB3331: "} + + + Processing manifest file "{0}". + + + + Attempting to resolve reference "{0}" on path(s): + + + + MSB3341: Could not resolve reference "{0}". If this reference is required by your code, you may get compilation errors. + {StrBegin="MSB3341: "} + + + MSB3582: Could not resolve project reference "{0}". + {StrBegin="MSB3582: "} + + + Project reference "{0}" has not been resolved. + + UE and LOCALIZATION: + This is not an error - we pass unresolved references to UnresolvedProjectReferences for further + processing in the .targets file. + + + + Resolving project reference "{0}". + + + + Project reference "{0}" resolved as "{1}". + + + + MSB3471: Non-existent reference "{0}" passed to the SGen task. + {StrBegin="MSB3471: "} + + + MSB3472: We were unable to delete the existing serializer "{0}" before creating a new one: {1} + {StrBegin="MSB3472: "} + + + MSB3473: Path for "{0}" is invalid. {1} + {StrBegin="MSB3473: "} + + + MSB3481: The signing certificate could not be located. Ensure that it is in the current user's personal store. + {StrBegin="MSB3481: "} + + + MSB3482: An error occurred while signing: {0} + {StrBegin="MSB3482: "} + + + MSB3483: A warning occurred while signing: {0} + {StrBegin="MSB3483: "} + + + MSB3484: Signing target '{0}' could not be found. + {StrBegin="MSB3484: "} + + + MSB3487: The signing certificate does not include private key information. + {StrBegin="MSB3487: "} + + + MSB3351: Unable to create a strong name key pair from key container '{0}'. + {StrBegin="MSB3351: "} + + + MSB3352: The specified key file '{0}' could not be read. + {StrBegin="MSB3352: "} + + + MSB3353: Public key necessary for delay signing was not specified. + {StrBegin="MSB3353: "} + + + MSB3661: Invalid value '{0}' passed to the Transform property. + {StrBegin="MSB3661: "} + + + MSB3662: No input file has been passed to the task, exiting. + {StrBegin="MSB3662: "} + + + MSB3371: The file "{0}" cannot be created. {1} + {StrBegin="MSB3371: "} + + + MSB3372: The file "{0}" cannot be made writable. {1} + {StrBegin="MSB3372: "} + + + MSB3373: The attributes on file "{0}" cannot be restored to their original value. {1} + {StrBegin="MSB3373: "} + + + MSB3374: The last access/last write time on file "{0}" cannot be set. {1} + {StrBegin="MSB3374: "} + + + Creating "{0}" because "{1}" was specified. + + + + MSB3375: The file "{0}" does not exist. + {StrBegin="MSB3375: "} + + + MSB3376: The syntax of the Time parameter is incorrect. {0} + {StrBegin="MSB3376: "} + + + Touching "{0}". + + + + MSB3396: The "{0}" task needs either an assembly path or state file path. + {StrBegin="MSB3396: "} + + + MSB3395: Cannot unregister assembly "{0}". {1} + {StrBegin="MSB3395: "} + + + MSB3391: "{0}" does not contain any types that can be unregistered for COM Interop. + {StrBegin="MSB3391: "} + + + MSB3392: Cannot unregister assembly "{0}" - access denied. Please make sure you're running the application as administrator. {1} + {StrBegin="MSB3392: "} + + + MSB3393: Cannot unregister assembly "{0}" - file doesn't exist. + {StrBegin="MSB3393: "} + + + Unregistering assembly "{0}" for COM Interop. + + + + Unregistering type library "{0}". + + + + MSB3397: Cannot unregister type library "{0}" - cannot load file, check to make sure it's a valid type library. + {StrBegin="MSB3397: "} + + + Cannot unregister type library "{0}" - file doesn't exist. + + + + MSB3394: Type library "{0}" is not registered, cannot unregister. + {StrBegin="MSB3394: "} + + + MSB3401: "{1}" is an invalid value for the "{0}" parameter. The valid values are: {2} + {StrBegin="MSB3401: "} + + + MSB3402: There was an error creating the pdb file "{0}". {1} + {StrBegin="MSB3402: "} + + + "{1}" is an invalid value for the "{0}" parameter. + + + + MSB3491: Could not write lines to file "{0}". {1} + {StrBegin="MSB3491: "} + + + MSB3642: The Target Framework Moniker "{0}" is invalid. "{1}" + {StrBegin="MSB3642: "} + + + MSB3643: There was an error generating reference assembly paths based on the TargetFrameworkMoniker "{0}". {1} + {StrBegin="MSB3643: "} + + + MSB3644: The reference assemblies for framework "{0}" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend. + {StrBegin="MSB3644: "} + + + MSB3645: .NET Framework v3.5 Service Pack 1 was not found. In order to target "{0}", .NET Framework v3.5 Service Pack 1 or later must be installed. + {StrBegin="MSB3645: "} + + + MSB3762: No references were passed to the task. References to at least mscorlib and Windows.Foundation are required. + {StrBegin="MSB3762: "} + + + MSB3686: Unable to create Xaml task. Compilation failed. {0} + {StrBegin="MSB3686: "} + + + MSB3687: Unable to parse Xaml rule. {0} + {StrBegin="MSB3687: "} + + + MSB3688: Unable to create Xaml task. File not found: {0}. + {StrBegin="MSB3688: "} + + + MSB3689: Unable to execute Xaml task. If the CommandLineTemplate task parameter is not specified, then the ToolName attribute must be specified in the Rule or the ToolExe task parameter must be set. + {StrBegin="MSB3689: "} + + + MSB3690: Unable to create Xaml task. The Rule "{0}" was not found. + {StrBegin="MSB3690: "} + + + MSB3691: Unable to create Xaml task. The root object was not of type ProjectSchemaDefinitions. + {StrBegin="MSB3691: "} + + + MSB3692: Unable to create Xaml task. The <UsingTask> does not contain a <Task> definition. + {StrBegin="MSB3692: "} + + + MSB3693: Unable to execute Xaml task. The value "{1}" specified for task parameter "{0}" is not valid. + {StrBegin="MSB3693: "} + + + MSB3694: Unable to create Xaml task. The EnumValue "{1}" on EnumProperty "{0}" is missing the SwitchValue attribute. + {StrBegin="MSB3694: "} + + + MSB3721: The command "{0}" exited with code {1}. + {StrBegin="MSB3721: "} + + + MSB3722: The command "{0}" exited with code {1}. Please verify that you have sufficient rights to run this command. + {StrBegin="MSB3722: "} + + + MSB3723: The parameter "{0}" requires missing parameter "{1}" to be set. + {StrBegin="MSB3723: "} + + + MSB3701: Unable to load arguments for the XslTransformation task. {0} + {StrBegin="MSB3701: "} + + + MSB3702: Unable to process the XsltParameters argument for the XslTransformation task. {0} + {StrBegin="MSB3702: "} + + + MSB3703: Unable to execute transformation. {0} + {StrBegin="MSB3703: "} + + + Only one of XmlContent or XmlInputPaths arguments can be set. + + + + One of XmlContent or XmlInputPaths arguments must be set. + + + + Only one of XslContent, XslInputPath or XslCompiledDllPath arguments can be set. + + + + One of XslContent, XslInputPath and XslCompiledDllPath arguments must be set. + + + + MSB3704: Unable to load the specified Xslt. {0} + {StrBegin="MSB3704: "} + + + When specifying assembly "{0}", you must specify the type as well. + + + + The specified Xslt Parameter doesn't have attribute "{0}". + + + + The specified Xslt Parameter attribute is not a well-formed XML fragment. + + + + The usage of the document() method and embedded scripts is prohibited by default, due to risks of foreign code execution. If "{0}" is a trusted source that requires those constructs, please set the "UseTrustedSettings" parameter to "true" to allow their execution. + + + + MSB3731: Unable to process the Namespaces argument for the XmlPoke task. {0} + {StrBegin="MSB3731: "} + + + The specified Namespaces attribute doesn't have attribute "{0}". + + + + The specified Namespaces attribute is not a well-formed XML fragment. + + + + Replaced "{0}" with "{1}". + + + + Made {0} replacement(s). + + + + MSB3732: Unable to set XPath expression's Context. {0} + {StrBegin="MSB3732: "} + + + MSB3733: Input file "{0}" cannot be opened. {1} + {StrBegin="MSB3733: "} + + + MSB3734: XPath Query "{0}" cannot be loaded. {1} + {StrBegin="MSB3734: "} + + + MSB3735: Error while executing poke operation with the Value parameter "{0}". {1} + {StrBegin="MSB3735: "} + + + MSB3741: Unable to load arguments for the XmlPeek task. {0} + {StrBegin="MSB3741: "} + + + MSB3742: Unable to process the Namespaces argument for the XmlPeek task. {0} + {StrBegin="MSB3742: "} + + + MSB3743: Unable to set XPath expression's Context. {0} + {StrBegin="MSB3743: "} + + + Only one of XmlContent or XmlInputPath arguments can be set. + + + + One of XmlContent or XmlInputPath arguments must be set. + + + + The specified Namespaces attribute does not have attribute "{0}". + + + + The specified Namespaces attribute is not a well-formed XML fragment. + + + + Found "{0}". + + + + The specified XPath query did not capture any nodes. + + + + MSB3711: At least one of OutputFile or OutputDirectory must be provided. + {StrBegin="MSB3711: "} + + + MSB3712: Code for the language "{0}" could not be generated. {1} + {StrBegin="MSB3712: "} + + + MSB3713: The file "{0}" could not be created. {1} + {StrBegin="MSB3713: "} + + + MSB3714: The parameter "{0}" was supplied, but not all previously numbered parameters. + {StrBegin="MSB3714: "} + + + No output file was written because no code was specified to create. + + + + Emitted specified code into "{0}". + + + + Generated by the MSBuild WriteCodeFragment class. + + + + MSB3751: The <Code> element is missing for the "{0}" task. This element is required. + {StrBegin="MSB3751: "} <Code> should not be localized it is the name of an xml element + + + MSB3752: The "{0}" attribute has been set but is empty. If the "{0}" attribute is set it must not be empty. + {StrBegin="MSB3752: "} + + + MSB3753: The task could not be instantiated because it does not implement the ITask interface. Make sure the task implements the Microsoft.Build.Framework.ITask interface. + {StrBegin="MSB3753: "} + + + MSB3754: The reference assembly "{0}" is invalid. "{1}" + {StrBegin="MSB3754: "} + + + MSB3755: Could not find reference "{0}". If this reference is required by your code, you may get compilation errors." + {StrBegin="MSB3755: "} + + + MSB3756: The xml element "{0}" is not valid under the xml element "{1}". + {StrBegin="MSB3756: "} + + + MSB3757: Multiple Code xml elements have been found, this is not allowed. To fix this issue remove any additional Code xml elements from the task. + {StrBegin="MSB3757: "} + + + MSB3758: An error has occurred during compilation. {0} + {StrBegin="MSB3758: "} + + + The task name "{0}" could not be found. + + + + The source file for this compilation can be found at: "{0}" + + + + The reference assembly "{0}" is a metadata only assembly. + + + + Searching for SDK "{0}": + + + + Found at search location "{0}". + + + + There was a problem reading the SDK manifest file "{0}". {1} + + + + Reading SDK manifest file "{0}". + + + + Targeted configuration and architecture "{0}|{1}" + + + + Has a platform identity of "{0}". + + + + Could not find "FrameworkIdentity" attribute "{0}" in the SDK manifest. + + + + No FrameworkIdentity attributes were found in the SDK manifest, treating this SDK as a non-framework SDK. + + + + No "APPX" attributes indicating app package locations were found in the SDK manifest. If an app package is required at runtime the project may not run. + + + + Found "FrameworkIdentity" attribute "{0}" in the SDK manifest. + + + + Found "APPX" location attribute "{0}" in the SDK manifest. + + + + Updating the "{0}" architecture "APPX" location from "{1}" to "{2}". + + + + Cannot resolve "SDKReference" items because no installed SDK locations were passed into the property "InstalledSdks". + "SDKReference" and "InstalledSDKs" are property names on the task and should not be localized + + + MSB3773: The SDK "{0}" cannot be referenced alongside SDK(s) {1}, as they all belong to the same SDK product Family "{2}". Please consider removing references to other SDKs of the same product family. + {StrBegin="MSB3773: "} + + + MSB3774: Could not find SDK "{0}". + {StrBegin="MSB3774: "} + + + MSB3775: There was an error resolving the SDK "{0}". {1} + {StrBegin="MSB3775: "} "{0}" will be the root location which could not be searched. Ie (c:\program files\sdks\..) + + + MSB3776: The SDK Reference "{0}" is incorrectly formatted. It must be in the following format "<SDKName>, Version=<SDKVersion>. For example: "MySDK, Version=2.0" + {StrBegin="MSB3776: "} + + + MSB3777: "FrameworkIdentity" attributes were found in the SDK manifest file "{0}", however none of the attributes matched the targeted configuration and architecture "{1} | {2}" and no "FrameworkIdentity" attribute without configuration and architecture could be found. If this project is to be packaged, packaging will fail. + {StrBegin="MSB3777: "} + + + MSB3778: "APPX" attributes were found in the SDK manifest file "{0}" however none of the attributes matched the targeted configuration and architecture "{1} | {2}" and no "APPX" attribute without configuration and architecture could be found. If an app package is required then the project will fail at runtime. + {StrBegin="MSB3778: "} + + + MSB3779: The processor architecture of the project being built "{0}" is not supported by the referenced SDK "{1}". Please consider changing the targeted processor architecture of your project (in Visual Studio this can be done through the Configuration Manager) to one of the architectures supported by the SDK: "{2}". + {StrBegin="MSB3779: "} + + + MSB3780: The SDK "{0}" cannot be referenced alongside SDK(s) {1}, because only one version of the SDK can be referenced from a project. Please consider removing references to the other SDKs. + {StrBegin="MSB3780: "} + + + MSB3781: The SDK "{0}" depends on the following SDK(s) {1}, which have not been added to the project or were not found. Please ensure that you add these dependencies to your project or you may experience runtime issues. You can add dependencies to your project through the Reference Manager. + {StrBegin="MSB3781: "} + + + MSB3782: The "{0}" SDK does not support targeting a neutral architecture with "Prefer 32-Bit" enabled for the project. Please go to the project properties (Build tab for C# and Compile tab for VB) and disable the "Prefer 32-bit" option, or change your project to target a non-neutral architecture. + {StrBegin="MSB3782: "} Also, please localize "Prefer 32-Bit" in the same way that it is localized in wizard\vbdesigner\designer\proppages\buildproppage.resx + + + MSB3783: Project "{0}" depends upon SDK "{1} v{2}" which was released originally for apps targeting "{3} {4}". To verify whether "{1} v{2}" is compatible with "{5} {6}", contact the SDK author or see http://go.microsoft.com/fwlink/?LinkID=309181. + {StrBegin="MSB3783: "} + + + MSB3841: The SDK "{0}" depends on the SDK "{1}", which is not compatible with "{2} {3}". Please reference a version of SDK "{0}" which supports "{2} {3}". + {StrBegin="MSB3841: "} + + + MSB3842: Project "{0}" depends upon SDK "{1} v{2}" which supports apps targeting "{3} {4}". To verify whether "{1} v{2}" is compatible with "{5} {6}", contact the SDK author or see http://go.microsoft.com/fwlink/?LinkID=309181. + {StrBegin="MSB3842: "} + + + MSB3843: Project "{0}" targets platform "{3}", but references SDK "{1} v{2}" which targets platform "{4}". + {StrBegin="MSB3843: "} + + + MSB3844: Project "{0}" targets platform version "{3}", but references SDK "{1} v{2}" which requires platform version "{4}" or higher. + {StrBegin="MSB3844: "} + + + Installed SDKs: + + + + SDK "{0}" is installed at "{1}" + + + + Found "{0}" SDKs. + + + + Searching for SDKs targeting "{0}, {1}". + {0} will be the platform identifier, "Windows" and {1} will be a version number + + + MSB3784: "TargetPlatformVersion" and "TargetPlatformIdentifier" cannot be empty. + {StrBegin="MSB3784: "} TargetPlatformVersion and TargetPlatformIdentifier root are property names and should not be localized + + + MSB3785: No SDKs were found for TargetPlatform = {0} v{1}. SDKReference items will not be resolved. If your application requires these references there may be compilation errors. + {StrBegin="MSB3785: "} "SDKReference" refers to SDKReference items in the project file and should not be localized. + + + MSB3786: There was a problem retrieving the installed SDKs on the machine. {0} + {StrBegin="MSB3786: "} + + + Enumerating SDK Reference "{0}" from "{1}". + + + + Looking for references under "{0}". + + + + Looking for redist files under "{0}". + + + + Not enumerating SDK Reference "{0}" because the "ExpandReferences" metadata is not true on the reference. + + + + Adding reference "{0}". + + + + Adding file "{0}" from redist folder with target path "{1}". + + + + There was a conflict between two redist files going to the same target path "{0}" within the "{1}" SDK. Choosing "{2}" over "{3}" because it was resolved first. + + + + There was a conflict between two files from the redist folder files going to the same target path "{0}" between the "{1}" and "{2}" SDKs. Choosing "{3}" over "{4}" because it was resolved first. + + + + There was a conflict between two references with the same file name resolved within the "{0}" SDK. Choosing "{1}" over "{2}" because it was resolved first. + + + + There was a conflict between two references with the same file name between the "{0}" and "{1}" SDKs. Choosing "{2}" over "{3}" because it was resolved first. + + + + There was a problem reading the cache file "{0}". "{1}" + + + + There was a problem deleting the cache file "{0}". "{1}" + + + + There was a problem getting the time stamp of the current assembly "{0}". "{1}" + + + + There was a problem getting the assembly metadata for "{0}". "{1}" + + + + There was a problem writing the cache file "{0}". "{1}" + + + + The "OriginalItemSpec" metadata for the resolved SDK with path "{0}" was empty. The "OriginalItemSpec" metadata must be set." + + + + MSB3795: There was a problem in the GetSDKReferenceFiles task. {0} + {StrBegin="MSB3795: "} + + + MSB3796: There was a conflict between two files. {0} + {StrBegin="MSB3796: "} + + + MSB3797: The targeted configuration for the resolved sdk reference "{0}" was empty. Cannot find reference or redist files without a targeted configuration. + {StrBegin="MSB3797: "} + + + MSB3798: The targeted architecture for the resolved sdk reference "{0}" was empty. Cannot find reference or redist files without a targeted architecture. + {StrBegin="MSB3798: "} + + + MSB3851: This project targets "{0}, Version={1}", but it is attempting to reference "{2}" targeting "{3}", which is invalid. + {StrBegin="MSB3851: "} + + + MSB3861: Failed to log an error using resource string "{0}". {1} + {StrBegin="MSB3861: "} + + + MSB3871: Shared projects cannot be built on their own. Please either build a project that references this project, or build the entire solution. + {StrBegin="MSB3871: "} + + + Creating symbolic link to copy "{0}" to "{1}". + LOCALIZATION: {0} and {1} are paths. + + + The AssemblyFolder config file ('{0}') specified in Microsoft.Common.CurrentVersion.targets was invalid. The error was: {1} + + + + MSB3891: Both "{0}" and "{1}" were specified in the project file. Please choose one or the other. + + + + + \ No newline at end of file diff --git a/src/dir.targets b/src/dir.targets index 846fa9538a4..ef3a20b6f7d 100644 --- a/src/dir.targets +++ b/src/dir.targets @@ -9,7 +9,8 @@ - + + From 5e1eddb0e78b6351439bd89833d24b3e5dc0e3bb Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 7 Nov 2016 15:12:19 -0800 Subject: [PATCH 055/223] Fix tests that weren't working on Linux (#1318) * Fix tests that weren't working on Linux * Update comment to reflect a change in logic Closes #1297 --- .../UnitTests/GenerateResource_Tests.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs index 6cbed4ab742..126f022ac5d 100644 --- a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs @@ -156,7 +156,6 @@ public void BasicText2Resources() ///
/// System dll is not locked because it forces a new app domain [Fact] - [Trait("Category", "netcore-linux-failing")] public void ResX2ResourcesWithReferences() { string systemDll = Utilities.GetPathToCopiedSystemDLL(); @@ -389,7 +388,6 @@ public void ForceOutOfDateLinked() /// Force partially out-of-date: should build only the out of date inputs /// [Fact] - [Trait("Category", "netcore-linux-failing")] public void ForceSomeOutOfDate() { string resxFile = null; @@ -419,9 +417,10 @@ public void ForceSomeOutOfDate() DateTime time2 = File.GetLastWriteTime(t.OutputResources[1].ItemSpec); System.Threading.Thread.Sleep(200); - if (NativeMethodsShared.IsOSX) + if (!NativeMethodsShared.IsWindows) { - // Must be > 1 sec on HFS+ timestamp granularity + // Must be > 1 sec on some file systems for proper timestamp granularity + // TODO: Implement an interface for fetching deterministic timestamps rather than relying on the file System.Threading.Thread.Sleep(1000); } @@ -579,7 +578,6 @@ public void NothingOutOfDate() /// /// System dll is not locked because it forces a new app domain [Fact] - [Trait("Category", "netcore-linux-failing")] public void NothingOutOfDateExceptReference() { string resxFile = null; @@ -614,9 +612,10 @@ public void NothingOutOfDateExceptReference() t3.References = new ITaskItem[] { new TaskItem(systemDll) }; t3.StateFile = new TaskItem(t.StateFile); - if (NativeMethodsShared.IsOSX) + if (!NativeMethodsShared.IsWindows) { - // Must be > 1 sec for HFS+ timestamp granularity + // Must be > 1 sec on some file systems for proper timestamp granularity + // TODO: Implement an interface for fetching deterministic timestamps rather than relying on the file System.Threading.Thread.Sleep(1100); } @@ -3366,9 +3365,9 @@ public static string GetPathToCopiedSystemDLL() string pathToSystemDLL = #if FEATURE_INSTALLED_MSBUILD - ToolLocationHelper.GetPathToDotNetFrameworkFile("system.dll", TargetDotNetFrameworkVersion.Version45); + ToolLocationHelper.GetPathToDotNetFrameworkFile("System.dll", TargetDotNetFrameworkVersion.Version45); #else - Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, "system.dll"); + Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, "System.dll"); #endif File.Copy(pathToSystemDLL, tempSystemDLL); From e6465d78ffacee5d04c8d5cacec524fa08f3ce6c Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 7 Nov 2016 15:29:44 -0800 Subject: [PATCH 056/223] Update CI environment to run tests on Ubuntu (#1322) --- netci.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netci.groovy b/netci.groovy index abd612a73b0..f2ea8e76c08 100644 --- a/netci.groovy +++ b/netci.groovy @@ -61,10 +61,9 @@ def project = GithubProject break; case { it.startsWith('Ubuntu') }: - // Do not run tests on Ubuntu. We don't yet have a green test baseline. newJob.with{ steps{ - shell("./cibuild.sh --scope Compile --target ${runtime}") + shell("./cibuild.sh --scope Test --target ${runtime}") } } From 1abf3fc26ff1d5c0aa41b71a42fe52e0042382ad Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 8 Nov 2016 11:40:49 -0800 Subject: [PATCH 057/223] OrcasEngine should not use ProductVersion (#1303) Logic copied over from ProjectCollection.Version, since that type can't be accessed from the deprecated engine --- src/OrcasEngine/Engine/Engine.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/OrcasEngine/Engine/Engine.cs b/src/OrcasEngine/Engine/Engine.cs index 9c429da3331..4cdc00de9bc 100644 --- a/src/OrcasEngine/Engine/Engine.cs +++ b/src/OrcasEngine/Engine/Engine.cs @@ -584,20 +584,25 @@ public static Version Version { if (engineVersion == null) { - // Get the file version from the currently executing assembly. - // Use .CodeBase instead of .Location, because .Location doesn't - // work when Microsoft.Build.Engine.dll has been shadow-copied, for example - // in scenarios where NUnit is loading Microsoft.Build.Engine. + string msbuildPath = null; + try { - engineVersion = new Version(FileVersionInfo.GetVersionInfo(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath).ProductVersion); + // Get the file version from the currently executing assembly. + // Use .CodeBase instead of .Location, because .Location doesn't + // work when Microsoft.Build.Engine.dll has been shadow-copied, for example + // in scenarios where NUnit is loading Microsoft.Build.Engine. + msbuildPath = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath; } catch (InvalidOperationException) { // Workaround for Watson Bug: #161292 people getting relative uri crash here. // Last resort. We may have a problem when the assembly is shadow-copied. - engineVersion = new Version(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion); + msbuildPath = Path.GetFullPath(typeof(Engine).Assembly.Location); } + + var versionInfo = FileVersionInfo.GetVersionInfo(msbuildPath); + engineVersion = new Version(versionInfo.FileMajorPart, versionInfo.FileMinorPart, versionInfo.FileBuildPart, versionInfo.FilePrivatePart); } return engineVersion; From db14c85e981cf271d582e5f9f45785a912dfbc57 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 8 Nov 2016 11:53:08 -0800 Subject: [PATCH 058/223] Project Element cloning asks a new hook if it is OK to clone attributes (#1323) Fixes #1319 --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 2 + .../Construction/ProjectElement.cs | 13 ++++++- .../Construction/ProjectItemElement.cs | 5 +++ .../Construction/ProjectMetadataElement.cs | 17 ++++++--- .../Evaluation/ProjectParser.cs | 14 +++---- .../Construction/ProjectRootElement_Tests.cs | 37 +++++++++++++++++++ 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index da90078155a..cf8242bad1e 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -49,6 +49,7 @@ internal ProjectElement() { } protected internal virtual Microsoft.Build.Construction.ProjectElement Clone(Microsoft.Build.Construction.ProjectRootElement factory) { throw null; } public virtual void CopyFrom(Microsoft.Build.Construction.ProjectElement element) { } protected abstract Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner); + protected virtual bool ShouldCloneXmlAttribute(System.Xml.XmlAttribute attribute) { throw null; } } public abstract partial class ProjectElementContainer : Microsoft.Build.Construction.ProjectElement { @@ -148,6 +149,7 @@ internal ProjectItemElement() { } public Microsoft.Build.Construction.ProjectMetadataElement AddMetadata(string name, string unevaluatedValue, bool expressAsAttribute) { throw null; } public override void CopyFrom(Microsoft.Build.Construction.ProjectElement element) { } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } + protected override bool ShouldCloneXmlAttribute(System.Xml.XmlAttribute attribute) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("#Items={Count} Condition={Condition} Label={Label}")] public partial class ProjectItemGroupElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/src/XMakeBuildEngine/Construction/ProjectElement.cs b/src/XMakeBuildEngine/Construction/ProjectElement.cs index dfe382c8966..9dc045eee1b 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElement.cs @@ -369,7 +369,10 @@ public virtual void CopyFrom(ProjectElement element) // Copy over the attributes from the template element. foreach (XmlAttribute attribute in element.XmlElement.Attributes) { - this.XmlElement.SetAttribute(attribute.LocalName, attribute.NamespaceURI, attribute.Value); + if (ShouldCloneXmlAttribute(attribute)) + { + this.XmlElement.SetAttribute(attribute.LocalName, attribute.NamespaceURI, attribute.Value); + } } // If this element has pure text content, copy that over. @@ -383,6 +386,14 @@ public virtual void CopyFrom(ProjectElement element) this.MarkDirty("CopyFrom", null); } + /// + /// Hook for subclasses to specify whether the given should be cloned or not + /// + protected virtual bool ShouldCloneXmlAttribute(XmlAttribute attribute) + { + return true; + } + ///
/// /// +#if FEATURE_SECURITY_PERMISSIONS [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] +#endif override public void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/XMakeBuildEngine/Errors/InvalidToolsetDefinitionException.cs b/src/XMakeBuildEngine/Errors/InvalidToolsetDefinitionException.cs index 8f427d2deb0..92de2f6072b 100644 --- a/src/XMakeBuildEngine/Errors/InvalidToolsetDefinitionException.cs +++ b/src/XMakeBuildEngine/Errors/InvalidToolsetDefinitionException.cs @@ -93,7 +93,9 @@ public InvalidToolsetDefinitionException(string message, string errorCode, Excep /// /// /// +#if FEATURE_SECURITY_PERMISSIONS [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] +#endif override public void GetObjectData(SerializationInfo info, StreamingContext context) { ErrorUtilities.VerifyThrowArgumentNull(info, "info"); diff --git a/src/XMakeTasks/UnitTests/GenerateResourceOutOfProc_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResourceOutOfProc_Tests.cs index e4264ebf6ff..20fe916b1e9 100644 --- a/src/XMakeTasks/UnitTests/GenerateResourceOutOfProc_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResourceOutOfProc_Tests.cs @@ -1895,8 +1895,8 @@ public void SourceItemMissing() /// Non-existent StateFile yields message /// [Fact] - [Trait("Category", "mono-osx-failing")] [Trait("Category", "mono-windows-failing")] + [PlatformSpecific(Xunit.PlatformID.Windows)] public void StateFileUnwritable() { GenerateResource t = Utilities.CreateTaskOutOfProc(); diff --git a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs index 126f022ac5d..6a1501b51e5 100644 --- a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs @@ -2071,6 +2071,7 @@ public void SourceItemMissing() #else [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/297")] #endif + [PlatformSpecific(Xunit.PlatformID.Windows)] public void StateFileUnwritable() { GenerateResource t = Utilities.CreateTask(); From 75cfbca2b477ff24e1ae498bf8f5789f3a2873bf Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 21 Nov 2016 18:19:29 -0500 Subject: [PATCH 094/223] Fix build on mono/osx. Import the namespaces on Mono, to correspond .. .. with the code using classes from those in GetFixedStringArguments(..) --- src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs index 0857e638053..c0a3b4b358b 100644 --- a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs +++ b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs @@ -12,7 +12,7 @@ using Microsoft.Build.Shared; using System.Text; using System.Runtime.Versioning; -#if !FEATURE_ASSEMBLY_LOADFROM +#if !FEATURE_ASSEMBLY_LOADFROM || MONO using System.Reflection.PortableExecutable; using System.Reflection.Metadata; #endif From 8211b6648422a1b0cab19b8bff3be095720baffe Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 02:20:01 -0400 Subject: [PATCH 095/223] MSBuild.csproj: Use `.dll` extension for Mono builds, same as netcore --- src/XMakeCommandLine/MSBuild.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/XMakeCommandLine/MSBuild.csproj b/src/XMakeCommandLine/MSBuild.csproj index a597bf2538e..62121eee89c 100644 --- a/src/XMakeCommandLine/MSBuild.csproj +++ b/src/XMakeCommandLine/MSBuild.csproj @@ -26,6 +26,9 @@ app.amd64.config MSBuild.ico + + .dll + Program From 1039f6bea238d1d31dc60db06cda728077523292 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 02:20:40 -0400 Subject: [PATCH 096/223] XMakeCommandLine: Extension can be `.dll` or `.exe` depending on the .. .. build. --- src/XMakeCommandLine/XMake.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index e039d48f342..15b99291e34 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -1343,9 +1343,14 @@ private static void GatherAllSwitches( s_exeName = BuildEnvironmentHelper.Instance.CurrentMSBuildExePath; #endif - if (!s_exeName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) +#if (RUNTIME_TYPE_NETCORE || MONO) && !FEATURE_RUN_EXE_IN_TESTS + var msbuildExtn = ".dll"; +#else + var msbuildExtn = ".exe"; +#endif + if (!s_exeName.EndsWith(msbuildExtn, StringComparison.OrdinalIgnoreCase)) { - s_exeName += ".exe"; + s_exeName += msbuildExtn; } // discard the first piece, because that's the path to the executable -- the rest are args From ff934a80d062ca453f3b34a06234456eac74f289 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 22 Nov 2016 11:33:25 -0500 Subject: [PATCH 097/223] Disable FEATURE_RTLMOVEMEMORY for mono builds Commit 63cf735deb821969cb096056c0c429c78cc76fbb introduced use of `RtlMoveMemory`, with the intention to use it only on full framework, but missed disabling it in dir.props . This manifested as: ``` MSBUILD : error MSB1025: An internal failure occurred while running MSBuild. System.EntryPointNotFoundException: GetEnvironmentStrings at (wrapper managed-to-native) Microsoft.Build.Internal.CommunicationsUtilities:GetEnvironmentStrings () at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentCharArray () [0x00007] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentVariables () [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.Utilities.GetEnvironmentProperties () [0x00001] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.get_EnvironmentProperties () [0x0001f] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.InitializeToolsetCollection (Microsoft.Build.Evaluation.ToolsetRegistryReader registryReader, Microsoft.Build.Evaluation.ToolsetConfigurationReader configReader) [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection..ctor (System.Collections.Generic.IDictionary`2[TKey,TValue] globalProperties, System.Collections.Generic.IEnumerable`1[T] loggers, System.Collections.Generic.IEnumerable`1[T] remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, System.Int32 maxNodeCount, System.Boolean onlyLogCriticalEvents) [0x0012b] in <04b748a45d6742ba88de6a1fabdd4609>:0 This is an unhandled exception in MSBuild Engine -- PLEASE OPEN A BUG AGAINST THE MSBUILD TEAM. System.EntryPointNotFoundException: GetEnvironmentStrings at (wrapper managed-to-native) Microsoft.Build.Internal.CommunicationsUtilities:GetEnvironmentStrings () at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentCharArray () [0x00007] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentVariables () [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.Utilities.GetEnvironmentProperties () [0x00001] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.get_EnvironmentProperties () [0x0001f] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.InitializeToolsetCollection (Microsoft.Build.Evaluation.ToolsetRegistryReader registryReader, Microsoft.Build.Evaluation.ToolsetConfigurationReader configReader) [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection..ctor (System.Collections.Generic.IDictionary`2[TKey,TValue] globalProperties, System.Collections.Generic.IEnumerable`1[T] loggers, System.Collections.Generic.IEnumerable`1[T] remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, System.Int32 maxNodeCount, System.Boolean onlyLogCriticalEvents) [0x0012b] in <04b748a45d6742ba88de6a1fabdd4609>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.EntryPointNotFoundException: GetEnvironmentStrings at (wrapper managed-to-native) Microsoft.Build.Internal.CommunicationsUtilities:GetEnvironmentStrings () at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentCharArray () [0x00007] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.CommunicationsUtilities.GetEnvironmentVariables () [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Internal.Utilities.GetEnvironmentProperties () [0x00001] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.get_EnvironmentProperties () [0x0001f] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection.InitializeToolsetCollection (Microsoft.Build.Evaluation.ToolsetRegistryReader registryReader, Microsoft.Build.Evaluation.ToolsetConfigurationReader configReader) [0x00011] in <04b748a45d6742ba88de6a1fabdd4609>:0 at Microsoft.Build.Evaluation.ProjectCollection..ctor (System.Collections.Generic.IDictionary`2[TKey,TValue] globalProperties, System.Collections.Generic.IEnumerable`1[T] loggers, System.Collections.Generic.IEnumerable`1[T] remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, System.Int32 maxNodeCount, System.Boolean onlyLogCriticalEvents) [0x0012b] in <04b748a45d6742ba88de6a1fabdd4609>:0 ``` --- dir.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dir.props b/dir.props index 3dd4a197d90..a0b524b32f7 100644 --- a/dir.props +++ b/dir.props @@ -309,7 +309,7 @@ $(DefineConstants);FEATURE_RESGEN $(DefineConstants);FEATURE_RESOURCE_EXPOSURE $(DefineConstants);FEATURE_RESX_RESOURCE_READER - $(DefineConstants);FEATURE_RTLMOVEMEMORY + $(DefineConstants);FEATURE_RTLMOVEMEMORY $(DefineConstants);FEATURE_RUN_EXE_IN_TESTS $(DefineConstants);FEATURE_SECURITY_PERMISSIONS $(DefineConstants);FEATURE_SECURITY_PRINCIPAL_WINDOWS From d6fddf7e27169c685631f9955d96979d02630f27 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 22 Nov 2016 13:07:34 -0500 Subject: [PATCH 098/223] Add nuget reference to System.Reflection.Metadata for XMakeTasks AssemblyDependency/AssemblyInformation.cs(16,25): error CS0234: The type or namespace name `PortableExecutable' does not exist in the namespace `System.Reflection'. Are you missing an assembly reference? [/Users/ankit/dev/msbuild/src/XMakeTasks/Microsoft.Build.Tasks.csproj] AssemblyDependency/AssemblyInformation.cs(17,25): error CS0234: The type or namespace name `Metadata' does not exist in the namespace `System.Reflection'. Are you missing an assembly reference? [/Users/ankit/dev/msbuild/src/XMakeTasks/Microsoft.Build.Tasks.csproj] AssemblyDependency/AssemblyInformation.cs(383,61): error CS0246: The type or namespace name `MetadataReader' could not be found. Are you missing an assembly reference? [/Users/ankit/dev/msbuild/src/XMakeTasks/Microsoft.Build.Tasks.csproj] AssemblyDependency/AssemblyInformation.cs(383,84): error CS0246: The type or namespace name `CustomAttribute' could not be found. Are you missing an assembly reference? [/Users/ankit/dev/msbuild/src/XMakeTasks/Microsoft.Build.Tasks.csproj] --- src/XMakeTasks/project.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/XMakeTasks/project.json b/src/XMakeTasks/project.json index 33b61914c31..d9729553082 100644 --- a/src/XMakeTasks/project.json +++ b/src/XMakeTasks/project.json @@ -5,7 +5,8 @@ "frameworks": { "net46": { "dependencies": { - "Microsoft.VisualStudio.Setup.Configuration.Interop": "1.2.304-preview5" + "Microsoft.VisualStudio.Setup.Configuration.Interop": "1.2.304-preview5", + "System.Reflection.Metadata": "1.3.0" } }, "netstandard1.3": { @@ -26,4 +27,4 @@ } } } -} \ No newline at end of file +} From 67c466e159921cba8ce574f51573b60755afa7c7 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 22 Nov 2016 13:19:38 -0500 Subject: [PATCH 099/223] cibuild.sh: Bootstrap path depends on the target being built - which is set in dirs.props as `$(BootstrapDestination)`. --- cibuild.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cibuild.sh b/cibuild.sh index 8d013325211..89d9d026e68 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -138,7 +138,6 @@ HOME_DEFAULT="$WORKSPACE/msbuild-CI-home" PROJECT_FILE_ARG='"'"$THIS_SCRIPT_PATH/build.proj"'"' BOOTSTRAP_FILE_ARG='"'"$THIS_SCRIPT_PATH/targets/BootStrapMSBuild.proj"'"' BOOTSTRAPPED_RUNTIME_HOST='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/dotnet"'"' -MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/MSBuild.dll"'"' # Default msbuild arguments TARGET_ARG="Build" @@ -221,6 +220,7 @@ fi case $target in CoreCLR) CONFIGURATION=Debug-NetCore + MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/MSBuild.dll"'"' ;; Mono) @@ -228,6 +228,7 @@ case $target in CONFIGURATION=Debug-MONO EXTRA_ARGS="/p:CscToolExe=mcs /p:CscToolPath=$MONO_BIN_DIR" RUNTIME_HOST_ARGS="--debug" + MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap/MSBuild.dll"'"' ;; *) echo "Unsupported target detected: $target. Aborting." From 55644491d4870b31aaa315aff233f753943245da Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 23 Nov 2016 13:40:59 -0800 Subject: [PATCH 100/223] Allow override of VCTargetsPath property. (#1387) * Add intrinsic function to get ProgramFiles32. MSBuildProgramFiles32 property is not yet defined when it was being in the toolset. Fixes #1384 --- src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs | 5 +++++ src/XMakeCommandLine/app.amd64.config | 10 +++++----- src/XMakeCommandLine/app.config | 10 +++++----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index 2072fb6c73f..5c059fc008d 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -395,6 +395,11 @@ public static string GetVsInstallRoot() return BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory; } + public static string GetProgramFiles32() + { + return FrameworkLocationHelper.programFiles32; + } + #region Debug only intrinsics /// diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index 85bba4f3c67..c59e1d27ea9 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -77,11 +77,11 @@ - - - - - + + + + + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index 4c5f10ad678..a6e06b13eb6 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -71,11 +71,11 @@ - - - - - + + + + + From ee1e95c359b8d507d31a66297412f8b7bc788a27 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 23 Nov 2016 14:20:58 -0800 Subject: [PATCH 101/223] Undo consume Roslyn from new location. (#1391) This change was postponed to another release. Keeping the functionality of consuming Roslyn from a single location, just adjusting the path. Compared to previous release, we will now *always* consume Roslyn from the 32-bit MSBuild folder. This should be fine as the bits are identical. Related to #1339 --- src/Shared/UnitTests/App.config | 2 +- .../Definition/ToolsetLocalReader.cs | 4 +--- src/XMakeCommandLine/app.amd64.config | 2 +- src/XMakeCommandLine/app.config | 2 +- targets/DeployDependencies.proj | 16 ++++++---------- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/Shared/UnitTests/App.config b/src/Shared/UnitTests/App.config index d6407124ae2..20691e6dbad 100644 --- a/src/Shared/UnitTests/App.config +++ b/src/Shared/UnitTests/App.config @@ -46,7 +46,7 @@ - + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs index a243c13c3e0..7b83083536f 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs @@ -57,9 +57,7 @@ protected override IEnumerable ToolsVersions protected override IEnumerable GetPropertyDefinitions(string toolsVersion) { yield return new ToolsetPropertyDefinition(MSBuildConstants.ToolsPath, BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); - yield return new ToolsetPropertyDefinition("RoslynTargetsPath", - System.IO.Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, "Roslyn"), - _sourceLocation); + yield return new ToolsetPropertyDefinition("RoslynTargetsPath", BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); } protected override IEnumerable GetSubToolsetPropertyDefinitions(string toolsVersion, string subToolsetVersion) diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index c59e1d27ea9..28e02901c72 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -74,7 +74,7 @@ - + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index a6e06b13eb6..b5962352ead 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -68,7 +68,7 @@ - + diff --git a/targets/DeployDependencies.proj b/targets/DeployDependencies.proj index 36af3d1b640..dc3dc295f4b 100644 --- a/targets/DeployDependencies.proj +++ b/targets/DeployDependencies.proj @@ -13,11 +13,11 @@ @@ -81,10 +81,6 @@ .NETCoreApp,Version=v1.0 - - $(MSBuildThisFileDirectory)runtimeDependencies\project.json - $(MSBuildThisFileDirectory)runtimeDependencies\project.lock.json - $(RuntimeSystem)-$(RuntimeArchitecture) @@ -96,13 +92,13 @@ $(MSBuildThisFileDirectory)roslyn\project.lock.json - $(DeploymentDir)\Roslyn - $(TestDeploymentDir)\Roslyn + $(DeploymentDir) + $(TestDeploymentDir) @@ -113,7 +109,7 @@ + Outputs="%(RuntimeProjectJson.LockFile).IntentionallyDoesNotExistSoThisAlwaysRuns"> Date: Mon, 28 Nov 2016 14:49:44 -0800 Subject: [PATCH 102/223] Add preserveFormatting overloads. Expose PreserveFormatting as read-only property (#1388) * Add preserveFormatting overloads. Expose value as property * Add public API sources * use TryGet with preserveFormatting * Add TryOpen unit test --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 2 ++ .../Microsoft.Build/Microsoft.Build.cs | 2 ++ .../Construction/ProjectRootElement.cs | 32 ++++++++++++++++++- .../Evaluation/ProjectRootElementCache.cs | 16 ++++++++-- .../Construction/ProjectRootElement_Tests.cs | 23 +++++++++++++ 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index cf8242bad1e..13424e130a9 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -246,6 +246,7 @@ internal ProjectRootElement() { } public System.Collections.Generic.ICollection ItemGroupsReversed { get { throw null; } } public System.Collections.Generic.ICollection Items { get { throw null; } } public System.DateTime LastWriteTimeWhenRead { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } } + public bool PreserveFormatting { get { throw null; } } public Microsoft.Build.Construction.ElementLocation ProjectFileLocation { get { throw null; } } public System.Collections.Generic.ICollection Properties { get { throw null; } } public System.Collections.Generic.ICollection PropertyGroups { get { throw null; } } @@ -317,6 +318,7 @@ public void Save(string path, System.Text.Encoding encoding) { } public void Save(System.Text.Encoding saveEncoding) { } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("Name={Name} #Children={Count} Condition={Condition}")] public partial class ProjectTargetElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs index 19ae83b1aed..d51300a1016 100644 --- a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs +++ b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs @@ -246,6 +246,7 @@ internal ProjectRootElement() { } public System.Collections.Generic.ICollection ItemGroupsReversed { get { throw null; } } public System.Collections.Generic.ICollection Items { get { throw null; } } public System.DateTime LastWriteTimeWhenRead { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } } + public bool PreserveFormatting { get { throw null; } } public Microsoft.Build.Construction.ElementLocation ProjectFileLocation { get { throw null; } } public System.Collections.Generic.ICollection Properties { get { throw null; } } public System.Collections.Generic.ICollection PropertyGroups { get { throw null; } } @@ -317,6 +318,7 @@ public void Save(string path, System.Text.Encoding encoding) { } public void Save(System.Text.Encoding saveEncoding) { } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("Name={Name} #Children={Count} Condition={Condition}")] public partial class ProjectTargetElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 9d9761a8b21..e7f1fa2e244 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -730,6 +730,17 @@ public bool HasUnsavedChanges } } + /// + /// Whether the XML is preserving formatting or not. + /// + public bool PreserveFormatting + { + get + { + return XmlDocument?.PreserveWhitespace ?? false; + } + } + /// /// Version number of this object. /// A host can compare this to a stored version number to determine whether @@ -1106,13 +1117,32 @@ public static ProjectRootElement TryOpen(string path) /// this method returning false does not indicate that it has never been loaded, only that it is not currently in memory. /// public static ProjectRootElement TryOpen(string path, ProjectCollection projectCollection) + { + return TryOpen(path, projectCollection, preserveFormatting: false); + } + + /// + /// Returns the ProjectRootElement for the given path if it has been loaded, or null if it is not currently in memory. + /// Uses the specified project collection. + /// + /// The path of the ProjectRootElement, cannot be null. + /// The to load the project into. + /// + /// The formatting to open with. Must match the formatting in the collection to succeed. + /// + /// The loaded ProjectRootElement, or null if it is not currently in memory. + /// + /// It is possible for ProjectRootElements to be brought into memory and discarded due to memory pressure. Therefore + /// this method returning false does not indicate that it has never been loaded, only that it is not currently in memory. + /// + public static ProjectRootElement TryOpen(string path, ProjectCollection projectCollection, bool preserveFormatting) { ErrorUtilities.VerifyThrowArgumentLength(path, "path"); ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection"); path = FileUtilities.NormalizePath(path); - ProjectRootElement projectRootElement = projectCollection.ProjectRootElementCache.TryGet(path); + ProjectRootElement projectRootElement = projectCollection.ProjectRootElementCache.TryGet(path, preserveFormatting); return projectRootElement; } diff --git a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs index 7c751cd74b9..12f5d25756d 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs @@ -346,8 +346,20 @@ internal void RenameEntry(string oldFullPath, ProjectRootElement projectRootElem /// internal ProjectRootElement TryGet(string projectFile) { - ProjectRootElement result = Get(projectFile, null /* no delegate to load it */, false, /*Since we are not creating a PRE this can be true or false*/ - preserveFormatting: false); + return TryGet(projectFile, preserveFormatting: false); + } + + /// + /// Returns any a ProjectRootElement in the cache with the provided full path, + /// otherwise null. + /// + internal ProjectRootElement TryGet(string projectFile, bool preserveFormatting) + { + ProjectRootElement result = Get( + projectFile, + openProjectRootElement: null, // no delegate to load it + isExplicitlyLoaded: false, // Since we are not creating a PRE this can be true or false + preserveFormatting: preserveFormatting); return result; } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs index 20f6bd6add7..0ca9a106256 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs @@ -1240,6 +1240,29 @@ public void DeepCloneWithMetadataAsAttributes() ValidateDeepCloneAndCopyFrom(pre); } + /// + /// Tests TryOpen when preserveFormatting is the same and different than the cached project. + /// + [Fact] + public void TryOpenWithPreserveFormatting() + { + string project = +@" + +"; + + var collection = new ProjectCollection(); + var projectXml = ProjectRootElement.Create( + XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(project))), + collection, + preserveFormatting: true); + + projectXml.Save(FileUtilities.GetTemporaryFile()); + + Assert.NotNull(ProjectRootElement.TryOpen(projectXml.FullPath, collection, preserveFormatting: true)); + Assert.Null(ProjectRootElement.TryOpen(projectXml.FullPath, collection, preserveFormatting: false)); + } + /// /// Test helper for validating that DeepClone and CopyFrom work as advertised. /// From ed085e75dd9efae32381f44102ce1a98bf406c37 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 29 Nov 2016 10:21:21 -0800 Subject: [PATCH 103/223] Support Directory project path argument (#1385) If Directory.Exists then the current code just uses that as the base directory to search. Needed to add a new error so that the directory path of what was searched is shown instead of it just saying "this directory". I also updated the help text. Closes #1225 --- .../InitializationException.cs | 17 +++++++ src/XMakeCommandLine/Resources/Strings.resx | 18 +++++-- src/XMakeCommandLine/UnitTests/XMake_Tests.cs | 48 +++++++++++++++++++ src/XMakeCommandLine/XMake.cs | 39 ++++++++++----- 4 files changed, 107 insertions(+), 15 deletions(-) diff --git a/src/XMakeCommandLine/InitializationException.cs b/src/XMakeCommandLine/InitializationException.cs index 28aa32e4bf4..02615489dd5 100644 --- a/src/XMakeCommandLine/InitializationException.cs +++ b/src/XMakeCommandLine/InitializationException.cs @@ -173,6 +173,23 @@ internal static void Throw(string messageResourceName, string invalidSwitch, Exc InitializationException.Throw(errorMessage, invalidSwitch); } + /// + /// Throws the exception if the specified condition is not met. + /// + internal static void VerifyThrow(bool condition, string messageResourceName, string invalidSwitch, params object[] args) + { + if (!condition) + { + string errorMessage = AssemblyResources.GetString(messageResourceName); + + ErrorUtilities.VerifyThrow(errorMessage != null, "The resource string must exist."); + + errorMessage = ResourceUtilities.FormatString(errorMessage, args); + + InitializationException.Throw(errorMessage, invalidSwitch); + } + } + /// /// Throws the exception using the given exception context. /// diff --git a/src/XMakeCommandLine/Resources/Strings.resx b/src/XMakeCommandLine/Resources/Strings.resx index f17e740be32..a4740198870 100644 --- a/src/XMakeCommandLine/Resources/Strings.resx +++ b/src/XMakeCommandLine/Resources/Strings.resx @@ -65,6 +65,16 @@ fire this error. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + MSBUILD : Configuration error {0}: {1} {SubString="Configuration"}UE: This prefixes any error from reading the toolset definitions in msbuild.exe.config or the registry. @@ -96,7 +106,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] LOCALIZATION: The following should not be localized: @@ -111,7 +121,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. LOCALIZATION: The following should not be localized: @@ -948,7 +960,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. diff --git a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs index ac0c06dfc36..b98a090fc80 100644 --- a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs +++ b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs @@ -1560,6 +1560,54 @@ internal string[] GetFiles(string path, string searchPattern) return fileNamesToReturn.ToArray(); } } + + /// + /// Verifies that when a directory is specified that a project can be found. + /// + [Fact] + public void TestProcessProjectSwitchDirectory() + { + string projectDirectory = Directory.CreateDirectory(Path.Combine(ObjectModelHelpers.TempProjectDir, Guid.NewGuid().ToString("N"))).FullName; + + try + { + string expectedProject = "project1.proj"; + string[] extensionsToIgnore = null; + IgnoreProjectExtensionsHelper projectHelper = new IgnoreProjectExtensionsHelper(new[] { expectedProject }); + string actualProject = MSBuildApp.ProcessProjectSwitch(new[] { projectDirectory }, extensionsToIgnore, projectHelper.GetFiles); + + Assert.Equal(expectedProject, actualProject); + } + finally + { + RobustDelete(projectDirectory); + } + } + + /// + /// Verifies that when a directory is specified and there are multiple projects that the correct error is thrown. + /// + [Fact] + public void TestProcessProjectSwitchDirectoryMultipleProjects() + { + string projectDirectory = Directory.CreateDirectory(Path.Combine(ObjectModelHelpers.TempProjectDir, Guid.NewGuid().ToString("N"))).FullName; + + try + { + InitializationException exception = Assert.Throws(() => + { + string[] extensionsToIgnore = null; + IgnoreProjectExtensionsHelper projectHelper = new IgnoreProjectExtensionsHelper(new[] { "project1.proj", "project2.proj" }); + MSBuildApp.ProcessProjectSwitch(new[] { projectDirectory }, extensionsToIgnore, projectHelper.GetFiles); + }); + + Assert.Equal(ResourceUtilities.FormatResourceString("AmbiguousProjectDirectoryError", projectDirectory), exception.Message); + } + finally + { + RobustDelete(projectDirectory); + } + } #endregion #region ProcessFileLoggerSwitches diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index ed2b35e3fc4..c9b1d04bb37 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -2199,13 +2199,33 @@ DirectoryGetFiles getFiles { ErrorUtilities.VerifyThrow(parameters.Length <= 1, "It should not be possible to specify more than 1 project at a time."); string projectFile = null; - // We need to look in the current directory for a project file... - if (parameters.Length == 0) + + string projectDirectory = null; + + if (parameters.Length == 1) + { + projectFile = FileUtilities.FixFilePath(parameters[0]); + + if (Directory.Exists(projectFile)) + { + // If the project file is actually a directory then change the directory to be searched + // and null out the project file + projectDirectory = projectFile; + projectFile = null; + } + else + { + InitializationException.VerifyThrow(File.Exists(projectFile), "ProjectNotFoundError", projectFile); + } + } + + // We need to look in a directory for a project file... + if (projectFile == null) { // Get all files in the current directory that have a proj-like extension - string[] potentialProjectFiles = getFiles(".", "*.*proj"); + string[] potentialProjectFiles = getFiles(projectDirectory ?? ".", "*.*proj"); // Get all files in the current directory that have a sln extension - string[] potentialSolutionFiles = getFiles(".", "*.sln"); + string[] potentialSolutionFiles = getFiles(projectDirectory ?? ".", "*.sln"); List extensionsToIgnore = new List(); if (projectsExtensionsToIgnore != null) @@ -2261,12 +2281,12 @@ DirectoryGetFiles getFiles string solutionName = Path.GetFileNameWithoutExtension(potentialSolutionFiles[0]); string projectName = Path.GetFileNameWithoutExtension(potentialProjectFiles[0]); // Compare the names and error if they are not identical - InitializationException.VerifyThrow(String.Compare(solutionName, projectName, StringComparison.OrdinalIgnoreCase) == 0, "AmbiguousProjectError"); + InitializationException.VerifyThrow(String.Compare(solutionName, projectName, StringComparison.OrdinalIgnoreCase) == 0, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // If there is more than one solution file in the current directory we have no idea which one to use else if (potentialSolutionFiles.Length > 1) { - InitializationException.VerifyThrow(false, "AmbiguousProjectError"); + InitializationException.VerifyThrow(false, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // If there is more than one project file in the current directory we may be able to figure it out else if (potentialProjectFiles.Length > 1) @@ -2299,7 +2319,7 @@ DirectoryGetFiles getFiles } } } - InitializationException.VerifyThrow(!isAmbiguousProject, "AmbiguousProjectError"); + InitializationException.VerifyThrow(!isAmbiguousProject, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // if there are no project or solution files in the directory, we can't build else if ((potentialProjectFiles.Length == 0) && @@ -2313,11 +2333,6 @@ DirectoryGetFiles getFiles // If 1 solution and 1 project and they are of the same name build the solution projectFile = (potentialSolutionFiles.Length == 1) ? potentialSolutionFiles[0] : potentialProjectFiles[0]; } - else - { - projectFile = FileUtilities.FixFilePath(parameters[0]); - InitializationException.VerifyThrow(File.Exists(projectFile), "ProjectNotFoundError", projectFile); - } return projectFile; } From 7633e84887113994767fd64de01bfb787b6c43ee Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 29 Nov 2016 10:41:53 -0800 Subject: [PATCH 104/223] Implement /WarnAsError to treat specified warnings as errors (#1355) Specify just /WarnAsError to have all warnings logged as errors as well as have the build fail. Specify a list of warning codes to have just that set of warnings treated as errors as well as have the build fail. Targets will still show as succeeded and the tasks will continue to execute but the overall build result will be a failure. Related to #68 and will close in my next change to add /NoWarn. * Feature switch FEATURE_RESOURCEMANAGER_GETRESOURCESET * Support for command-line arguments having empty values --- dir.props | 2 + ref/net46/Microsoft.Build/Microsoft.Build.cs | 1 + .../BackEnd/BuildManager/BuildManager.cs | 37 +- .../BackEnd/BuildManager/BuildParameters.cs | 15 + .../Logging/BuildEventArgTransportSink.cs | 13 + .../Components/Logging/EventSourceSink.cs | 51 ++- .../Components/Logging/ILoggingService.cs | 32 +- .../Components/Logging/LoggingService.cs | 45 ++- .../BackEnd/Shared/BuildResult.cs | 9 + .../UnitTests/BackEnd/BuildManager_Tests.cs | 95 +++++ .../BackEnd/EventSourceSink_Tests.cs | 87 +++++ .../UnitTests/BackEnd/MockLoggingService.cs | 15 + src/XMakeCommandLine/CommandLineSwitches.cs | 94 +++-- src/XMakeCommandLine/Resources/Strings.resx | 19 + .../UnitTests/CommandLineSwitches_Tests.cs | 326 ++++++++++++++---- src/XMakeCommandLine/XMake.cs | 55 ++- 16 files changed, 782 insertions(+), 114 deletions(-) diff --git a/dir.props b/dir.props index 407c0c2ffda..35cbb91755d 100644 --- a/dir.props +++ b/dir.props @@ -308,6 +308,8 @@ $(DefineConstants);FEATURE_REGISTRYHIVE_DYNDATA $(DefineConstants);FEATURE_RESGEN $(DefineConstants);FEATURE_RESOURCE_EXPOSURE + + $(DefineConstants);FEATURE_RESOURCEMANAGER_GETRESOURCESET $(DefineConstants);FEATURE_RESX_RESOURCE_READER $(DefineConstants);FEATURE_RTLMOVEMEMORY $(DefineConstants);FEATURE_RUN_EXE_IN_TESTS diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 13424e130a9..a5b7e11a2ea 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -940,6 +940,7 @@ public BuildParameters(Microsoft.Build.Evaluation.ProjectCollection projectColle public System.Collections.Generic.ICollection Toolsets { get { throw null; } } public System.Globalization.CultureInfo UICulture { get { throw null; } set { } } public bool UseSynchronousLogging { get { throw null; } set { } } + public System.Collections.Generic.ISet WarningsAsErrors { get { throw null; } set { } } public Microsoft.Build.Execution.BuildParameters Clone() { throw null; } public Microsoft.Build.Evaluation.Toolset GetToolset(string toolsVersion) { throw null; } } diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs index 9f3d793288e..92872a5e736 100644 --- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs +++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs @@ -424,7 +424,7 @@ public void BeginBuild(BuildParameters parameters) } // Set up the logging service. - ILoggingService loggingService = CreateLoggingService(_buildParameters.Loggers, _buildParameters.ForwardingLoggers); + ILoggingService loggingService = CreateLoggingService(_buildParameters.Loggers, _buildParameters.ForwardingLoggers, _buildParameters.WarningsAsErrors); _nodeManager.RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, loggingService as INodePacketHandler); try @@ -575,7 +575,11 @@ public BuildSubmission PendBuildRequest(BuildRequestData requestData) public BuildResult BuildRequest(BuildRequestData requestData) { BuildSubmission submission = PendBuildRequest(requestData); - return submission.Execute(); + BuildResult result = submission.Execute(); + + SetOverallResultIfWarningsAsErrors(result); + + return result; } /// @@ -621,6 +625,12 @@ public void EndBuild() if (loggingService != null) { + // Override the build success if the user specified /warnaserror and any errors were logged outside of a build submission. + if (_overallBuildSuccess && loggingService.HasBuildSubmissionLoggedErrors(BuildEventContext.InvalidSubmissionId)) + { + _overallBuildSuccess = false; + } + loggingService.LogBuildFinished(_overallBuildSuccess); } @@ -1578,6 +1588,9 @@ private void ReportResultsToSubmission(BuildResult result) if (_buildSubmissions.ContainsKey(result.SubmissionId)) { BuildSubmission submission = _buildSubmissions[result.SubmissionId]; + + SetOverallResultIfWarningsAsErrors(result); + submission.CompleteResults(result); // If the request failed because we caught an exception from the loggers, we can assume we will receive no more logging messages for @@ -1723,7 +1736,7 @@ private void OnProjectStarted(object sender, ProjectStartedEventArgs e) /// /// Creates a logging service around the specified set of loggers. /// - private ILoggingService CreateLoggingService(IEnumerable loggers, IEnumerable forwardingLoggers) + private ILoggingService CreateLoggingService(IEnumerable loggers, IEnumerable forwardingLoggers, ISet warningsAsErrors) { int cpuCount = _buildParameters.MaxNodeCount; @@ -1750,6 +1763,7 @@ private ILoggingService CreateLoggingService(IEnumerable loggers, IEnum loggingService.OnLoggingThreadException += _loggingThreadExceptionEventHandler; loggingService.OnProjectStarted += _projectStartedEventHandler; loggingService.OnProjectFinished += _projectFinishedEventHandler; + loggingService.WarningsAsErrors = warningsAsErrors; try { @@ -1820,6 +1834,23 @@ private I ExpectPacketType(INodePacket packet, NodePacketType expectedType) w return castPacket; } + /// + /// Sets the overall result of a build only if the user had specified /warnaserror and there were any errors. + /// This ensures the old behavior stays intact where builds could succeed even if a failure was logged. + /// + private void SetOverallResultIfWarningsAsErrors(BuildResult result) + { + if (result.OverallResult == BuildResultCode.Success) + { + ILoggingService loggingService = ((IBuildComponentHost)this).LoggingService; + + if (loggingService.HasBuildSubmissionLoggedErrors(result.SubmissionId)) + { + result.SetOverallResult(overallResult: false); + } + } + } + /// /// Shutdown the logging service /// diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs index 3249229a840..34459823cfc 100644 --- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs +++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs @@ -200,6 +200,11 @@ public class BuildParameters : INodePacketTranslatable /// private bool _onlyLogCriticalEvents = false; + /// + /// A list of warnings to treat as errors. + /// + private ISet _warningsAsErrors = null; + /// /// The location of the toolset definitions. /// @@ -320,6 +325,7 @@ private BuildParameters(BuildParameters other) _disableInProcNode = other._disableInProcNode; _logTaskInputs = other._logTaskInputs; _logInitialPropertiesAndItems = other._logInitialPropertiesAndItems; + _warningsAsErrors = other._warningsAsErrors == null ? null : new HashSet(other._warningsAsErrors, StringComparer.OrdinalIgnoreCase); } #if FEATURE_THREAD_PRIORITY @@ -583,6 +589,15 @@ public bool OnlyLogCriticalEvents set { _onlyLogCriticalEvents = value; } } + /// + /// A list of warnings to treat as errors. To treat all warnings as errors, set this to an empty . + /// + public ISet WarningsAsErrors + { + get { return _warningsAsErrors; } + set { _warningsAsErrors = value; } + } + /// /// Locations to search for toolsets. /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs index 2305a0e6c55..bce7890e6de 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs @@ -81,6 +81,19 @@ public bool HaveLoggedBuildFinishedEvent set; } + /// + /// This property is ignored by this event sink and relies on the receiver to treat warnings as errors. + /// + public ISet WarningsAsErrors + { + get; + set; + } + + /// + /// This property is ignored by this event sink and relies on the receiver to keep track of whether or not any errors have been logged. + /// + public ISet BuildSubmissionIdsThatHaveLoggedErrors { get; } = null; #endregion #region IBuildEventSink Methods diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs index 7b11f16d6d1..c023231b9bf 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs @@ -5,6 +5,7 @@ //----------------------------------------------------------------------- using System; +using System.Collections.Generic; using Microsoft.Build.Framework; using Microsoft.Build.Shared; @@ -129,6 +130,24 @@ public bool HaveLoggedBuildFinishedEvent get; set; } + + /// + /// A list of warnings to treat as errors. If null, nothing is treated as an error. If an empty set, all warnings are treated as errors. + /// + public ISet WarningsAsErrors + { + get; + set; + } + + /// + /// A list of build submission IDs that have logged errors. If an error is logged outside of a submission, the submission ID is . + /// + public ISet BuildSubmissionIdsThatHaveLoggedErrors + { + get; + } = new HashSet(); + #endregion #region Methods @@ -203,7 +222,34 @@ public void Consume(BuildEventArgs buildEvent) } else if (buildEvent is BuildWarningEventArgs) { - this.RaiseWarningEvent(null, (BuildWarningEventArgs)buildEvent); + BuildWarningEventArgs warningEvent = (BuildWarningEventArgs) buildEvent; + + // Treat this warning as an error if an empty set of warnings was specified or this code was specified + if (WarningsAsErrors != null && (WarningsAsErrors.Count == 0 || WarningsAsErrors.Contains(warningEvent.Code))) + { + BuildErrorEventArgs errorEvent = new BuildErrorEventArgs( + warningEvent.Subcategory, + warningEvent.Code, + warningEvent.File, + warningEvent.LineNumber, + warningEvent.ColumnNumber, + warningEvent.EndLineNumber, + warningEvent.EndColumnNumber, + warningEvent.Message, + warningEvent.HelpKeyword, + warningEvent.SenderName, + warningEvent.Timestamp) + { + BuildEventContext = warningEvent.BuildEventContext, + ProjectFile = warningEvent.ProjectFile, + }; + + this.RaiseErrorEvent(null, errorEvent); + } + else + { + this.RaiseWarningEvent(null, warningEvent); + } } else if (buildEvent is BuildErrorEventArgs) { @@ -308,6 +354,9 @@ private void RaiseMessageEvent(object sender, BuildMessageEventArgs buildEvent) /// ExceptionHandling.IsCriticalException exceptions will not be wrapped private void RaiseErrorEvent(object sender, BuildErrorEventArgs buildEvent) { + // Keep track of build submissions that have logged errors. If there is no build context, add BuildEventContext.InvalidSubmissionId. + BuildSubmissionIdsThatHaveLoggedErrors.Add(buildEvent?.BuildEventContext?.SubmissionId ?? BuildEventContext.InvalidSubmissionId); + if (ErrorRaised != null) { try diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs index 6aab65dfc10..9e4f0c1e068 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs @@ -153,8 +153,24 @@ bool RunningOnRemoteNode get; set; } + + /// + /// Set of warnings to treat as errors. An empty non-null set will treat all warnings as errors. + /// + ISet WarningsAsErrors + { + get; + set; + } #endregion + /// + /// Determines if the specified submission has logged an errors. + /// + /// The ID of the build submission. A value of "0" means that an error was logged outside of any build submission. + /// true if the build submission logged an errors, otherwise false. + bool HasBuildSubmissionLoggedErrors(int submissionId); + #region Register /// @@ -447,6 +463,20 @@ bool HaveLoggedBuildFinishedEvent set; } + /// + /// A list of warnings to treat as errors. If null, nothing is treated as an error. If an empty set, all warnings are treated as errors. + /// + ISet WarningsAsErrors + { + get; + set; + } + + /// + /// A list of build submissions that have logged errors. + /// + ISet BuildSubmissionIdsThatHaveLoggedErrors { get; } + #endregion /// /// Entry point for a sink to consume an event. @@ -461,7 +491,7 @@ bool HaveLoggedBuildFinishedEvent void Consume(BuildEventArgs buildEvent); /// - /// Shutsdown the sink and any resources it may be holding + /// Shuts down the sink and any resources it may be holding /// void ShutDown(); } diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs index 55d343b4f2f..0d0c55e08fd 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Threading; @@ -218,6 +219,11 @@ internal partial class LoggingService : ILoggingService, INodePacketHandler, IBu /// private LoggerMode _logMode = NativeMethodsShared.IsMono ? LoggerMode.Synchronous : LoggerMode.Asynchronous; + /// + /// A list of warnings to treat as errors. + /// + private ISet _warningsAsErrors = null; + #endregion #endregion @@ -444,6 +450,33 @@ public LoggerMode LoggingMode } } + /// + /// Get of warnings to treat as errors. An empty non-null set will treat all warnings as errors. + /// + public ISet WarningsAsErrors + { + get { return _warningsAsErrors; } + set { _warningsAsErrors = value; } + } + + /// + /// Determines if the specified submission has logged an errors. + /// + /// The ID of the build submission. A value of "0" means that an error was logged outside of any build submission. + /// true if the build submission logged an errors, otherwise false. + public bool HasBuildSubmissionLoggedErrors(int submissionId) + { + // Warnings as errors are not tracked if the user did not specify to do so + if (WarningsAsErrors == null) + { + return false; + } + + // Determine if any of the event sinks have logged an error with this submission ID + return (_filterEventSource != null && _filterEventSource.BuildSubmissionIdsThatHaveLoggedErrors.Contains(submissionId)) + || (_eventSinkDictionary != null && _eventSinkDictionary.Values.Any(i => i.BuildSubmissionIdsThatHaveLoggedErrors.Contains(submissionId))); + } + /// /// Return whether or not the LoggingQueue has any events left in it /// @@ -784,7 +817,10 @@ public bool RegisterDistributedLogger(ILogger centralLogger, LoggerDescription f IForwardingLogger localForwardingLogger = null; // create an eventSourceSink which the central logger will register with to receive the events from the forwarding logger - EventSourceSink eventSourceSink = new EventSourceSink(); + EventSourceSink eventSourceSink = new EventSourceSink + { + WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase) + }; // If the logger is already in the list it should not be registered again. if (_iloggerList.Contains(centralLogger)) @@ -1096,8 +1132,11 @@ private void CreateFilterEventSource() { if (_filterEventSource == null) { - _filterEventSource = new EventSourceSink(); - _filterEventSource.Name = "Sink for Distributed/Filter loggers"; + _filterEventSource = new EventSourceSink + { + Name = "Sink for Distributed/Filter loggers", + WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase) + }; } } diff --git a/src/XMakeBuildEngine/BackEnd/Shared/BuildResult.cs b/src/XMakeBuildEngine/BackEnd/Shared/BuildResult.cs index a6fa40adb9f..318b4cd6011 100644 --- a/src/XMakeBuildEngine/BackEnd/Shared/BuildResult.cs +++ b/src/XMakeBuildEngine/BackEnd/Shared/BuildResult.cs @@ -639,6 +639,15 @@ internal BuildResult Clone() return result; } + /// + /// Sets the overall result. + /// + /// true if the result is success, otherwise false. + internal void SetOverallResult(bool overallResult) + { + _baseOverallResult = false; + } + /// /// Creates the target result dictionary. /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index d37f27e5d6d..2dc1be36d1d 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -3594,6 +3594,101 @@ public void Regress265010() } } + /// + /// Verifies that all warnings are treated as errors and that the overall build result is a failure. + /// + [Fact] + public void WarningsAreTreatedAsErrorsAll() + { + string contents = ObjectModelHelpers.CleanupFileContents(@" + + + + + + +"); + _parameters.WarningsAsErrors = new HashSet(); + + Project project = CreateProject(contents, ObjectModelHelpers.MSBuildDefaultToolsVersion, _projectCollection, true); + ProjectInstance instance = _buildManager.GetProjectInstanceForBuild(project); + _buildManager.BeginBuild(_parameters); + BuildResult result1 = _buildManager.BuildRequest(new BuildRequestData(instance, new string[] { "target1" })); + _buildManager.EndBuild(); + + Assert.Equal(0, _logger.WarningCount); + Assert.Equal(2, _logger.ErrorCount); + + Assert.Equal(BuildResultCode.Failure, result1.OverallResult); + Assert.True(result1.HasResultsForTarget("target1")); + } + + /// + /// Verifies that only the specified warnings are treated as errors and that the overall build result is a failure. + /// + [Fact] + public void WarningsAreTreatedAsErrorsSpecific() + { + string contents = ObjectModelHelpers.CleanupFileContents(@" + + + + + + + +"); + _parameters.WarningsAsErrors = new HashSet { "ABC123" }; + + Project project = CreateProject(contents, ObjectModelHelpers.MSBuildDefaultToolsVersion, _projectCollection, true); + ProjectInstance instance = _buildManager.GetProjectInstanceForBuild(project); + _buildManager.BeginBuild(_parameters); + BuildResult result1 = _buildManager.BuildRequest(new BuildRequestData(instance, new string[] { "target1" })); + _buildManager.EndBuild(); + + Assert.Equal(2, _logger.WarningCount); + Assert.Equal(1, _logger.ErrorCount); + + Assert.Equal(BuildResultCode.Failure, result1.OverallResult); + Assert.True(result1.HasResultsForTarget("target1")); + } + + /// + /// Verifies that when building targets which emit warnings, they still show as succeeding but the overall build result is a failure. + /// + [Fact] + public void WarningsAreTreatedAsErrorsButTargetsStillSucceed() + { + string contents = ObjectModelHelpers.CleanupFileContents(@" + + + + + + + + +"); + _parameters.WarningsAsErrors = new HashSet { "ABC123" }; + + Project project = CreateProject(contents, ObjectModelHelpers.MSBuildDefaultToolsVersion, _projectCollection, true); + ProjectInstance instance = _buildManager.GetProjectInstanceForBuild(project); + _buildManager.BeginBuild(_parameters); + BuildResult buildResult = _buildManager.BuildRequest(new BuildRequestData(instance, new string[] { "target1", "target2" })); + _buildManager.EndBuild(); + + Assert.Equal(0, _logger.WarningCount); + Assert.Equal(1, _logger.ErrorCount); + + Assert.Equal(BuildResultCode.Failure, buildResult.OverallResult); + Assert.True(buildResult.HasResultsForTarget("target1")); + Assert.True(buildResult.HasResultsForTarget("target2")); + // The two targets should still show as success because they don't know their warning was changed to an error + // Logging a warning as an error does not change execution, only the final result of the build + Assert.Equal(TargetResultCode.Success, buildResult.ResultsByTarget["target1"].ResultCode); + Assert.Equal(TargetResultCode.Success, buildResult.ResultsByTarget["target2"].ResultCode); + } + /// /// Helper for cache tests. Builds a project and verifies the right cache files are created. /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs index 553eecaa7af..58ad2633ffc 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs @@ -83,6 +83,93 @@ public void ConsumeEventsGoodEventsNoHandlers() eventHelper.RaiseBuildEvent(RaiseEventHelper.GenericStatusEvent); } + /// + /// Verifies that a warning is logged as an error when it's warning code specified. + /// + [Fact] + public void TreatWarningsAsErrorWhenSpecified() + { + BuildWarningEventArgs expectedBuildEvent = RaiseEventHelper.Warning; + + EventSourceSink eventSourceSink = new EventSourceSink() + { + WarningsAsErrors = new HashSet + { + "123", + expectedBuildEvent.Code, + "ABC", + }, + }; + + RaiseEventHelper raiseEventHelper = new RaiseEventHelper(eventSourceSink); + EventHandlerHelper eventHandlerHelper = new EventHandlerHelper(eventSourceSink, null); + + raiseEventHelper.RaiseBuildEvent(RaiseEventHelper.Warning); + + Assert.IsType(eventHandlerHelper.RaisedEvent); + + BuildErrorEventArgs actualBuildEvent = (BuildErrorEventArgs) eventHandlerHelper.RaisedEvent; + + Assert.Equal(expectedBuildEvent.Code, actualBuildEvent.Code); + Assert.Equal(expectedBuildEvent.File, actualBuildEvent.File); + Assert.Equal(expectedBuildEvent.ProjectFile, actualBuildEvent.ProjectFile); + Assert.Equal(expectedBuildEvent.Subcategory, actualBuildEvent.Subcategory); + Assert.Equal(expectedBuildEvent.HelpKeyword, actualBuildEvent.HelpKeyword); + Assert.Equal(expectedBuildEvent.Message, actualBuildEvent.Message); + Assert.Equal(expectedBuildEvent.SenderName, actualBuildEvent.SenderName); + Assert.Equal(expectedBuildEvent.ColumnNumber, actualBuildEvent.ColumnNumber); + Assert.Equal(expectedBuildEvent.EndColumnNumber, actualBuildEvent.EndColumnNumber); + Assert.Equal(expectedBuildEvent.EndLineNumber, actualBuildEvent.EndLineNumber); + Assert.Equal(expectedBuildEvent.LineNumber, actualBuildEvent.LineNumber); + Assert.Equal(expectedBuildEvent.BuildEventContext, actualBuildEvent.BuildEventContext); + Assert.Equal(expectedBuildEvent.ThreadId, actualBuildEvent.ThreadId); + Assert.Equal(expectedBuildEvent.Timestamp, actualBuildEvent.Timestamp); + } + + /// + /// Verifies that a warning is not treated as an error when other warning codes are specified. + /// + [Fact] + public void NotTreatWarningsAsErrorWhenNotSpecified() + { + BuildWarningEventArgs expectedBuildEvent = RaiseEventHelper.Warning; + + EventSourceSink eventSourceSink = new EventSourceSink() + { + WarningsAsErrors = new HashSet + { + "123", + "ABC", + }, + }; + + RaiseEventHelper raiseEventHelper = new RaiseEventHelper(eventSourceSink); + EventHandlerHelper eventHandlerHelper = new EventHandlerHelper(eventSourceSink, null); + + raiseEventHelper.RaiseBuildEvent(RaiseEventHelper.Warning); + + Assert.Equal(expectedBuildEvent, eventHandlerHelper.RaisedEvent); + } + + /// + /// Verifies that a warning is not treated as an error when other warning codes are specified. + /// + [Fact] + public void TreatWarningsAsErrorWhenAllSpecified() + { + EventSourceSink eventSourceSink = new EventSourceSink() + { + WarningsAsErrors = new HashSet(), + }; + + RaiseEventHelper raiseEventHelper = new RaiseEventHelper(eventSourceSink); + EventHandlerHelper eventHandlerHelper = new EventHandlerHelper(eventSourceSink, null); + + raiseEventHelper.RaiseBuildEvent(RaiseEventHelper.Warning); + + Assert.IsType(eventHandlerHelper.RaisedEvent); + } + #region TestsThrowingLoggingExceptions /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs index 7ec91aa0fa6..c3559fac92b 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs @@ -147,6 +147,16 @@ public string[] PropertiesToSerialize set; } + /// + /// List of warnings to treat as errors. + /// + public ISet WarningsAsErrors + { + get; + set; + } + + /// /// Is the logging service on a remote node, this is used to determine if properties need to be serialized /// @@ -475,6 +485,11 @@ public void LogTelemetry(BuildEventContext buildEventContext, string eventName, { } + public bool HasBuildSubmissionLoggedErrors(int submissionId) + { + return false; + } + #endregion } } diff --git a/src/XMakeCommandLine/CommandLineSwitches.cs b/src/XMakeCommandLine/CommandLineSwitches.cs index 8dba43b5e11..be2786a7d77 100644 --- a/src/XMakeCommandLine/CommandLineSwitches.cs +++ b/src/XMakeCommandLine/CommandLineSwitches.cs @@ -102,6 +102,7 @@ internal enum ParameterizedSwitch ClientToServerPipeHandle, ServerToClientPipeHandle, #endif + WarningsAsErrors, NumberOfParameterizedSwitches } @@ -171,7 +172,8 @@ internal ParameterizedSwitchInfo string duplicateSwitchErrorMessage, bool multipleParametersAllowed, string missingParametersErrorMessage, - bool unquoteParameters + bool unquoteParameters, + bool emptyParametersAllowed ) { this.switchNames = switchNames; @@ -180,6 +182,7 @@ bool unquoteParameters this.missingParametersErrorMessage = missingParametersErrorMessage; this.unquoteParameters = unquoteParameters; this.parameterizedSwitch = parameterizedSwitch; + this.emptyParametersAllowed = emptyParametersAllowed; } // names of the switch (without leading switch indicator) @@ -198,6 +201,8 @@ bool unquoteParameters internal bool unquoteParameters; // the switch id internal ParameterizedSwitch parameterizedSwitch; + // indicates if empty parameters are allowed and if so an empty string will be added to the list of parameter values + internal bool emptyParametersAllowed; } @@ -240,41 +245,42 @@ bool unquoteParameters // WARNING: keep this map in the same order as the ParameterizedSwitch enumeration private static readonly ParameterizedSwitchInfo[] s_parameterizedSwitchesMap = { - //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - // Switch Names Switch Id Duplicate Switch Error Multi Params? Missing Parameters Error Unquote? - //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - new ParameterizedSwitchInfo( new string[] { null }, ParameterizedSwitch.Project, "DuplicateProjectSwitchError", false, null, true ), - new ParameterizedSwitchInfo( new string[] { "target", "t"}, ParameterizedSwitch.Target, null, true, "MissingTargetError", true ), - new ParameterizedSwitchInfo( new string[] { "property", "p" }, ParameterizedSwitch.Property, null, true, "MissingPropertyError", true ), - new ParameterizedSwitchInfo( new string[] { "logger", "l" }, ParameterizedSwitch.Logger, null, false, "MissingLoggerError", false ), - new ParameterizedSwitchInfo( new string[] { "distributedlogger", "dl" }, ParameterizedSwitch.DistributedLogger, null, false, "MissingLoggerError", false ), - new ParameterizedSwitchInfo( new string[] { "verbosity", "v" }, ParameterizedSwitch.Verbosity, null, false, "MissingVerbosityError", true ), + //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + // Switch Names Switch Id Duplicate Switch Error Multi Params? Missing Parameters Error Unquote? Empty? + //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + new ParameterizedSwitchInfo( new string[] { null }, ParameterizedSwitch.Project, "DuplicateProjectSwitchError", false, null, true, false ), + new ParameterizedSwitchInfo( new string[] { "target", "t"}, ParameterizedSwitch.Target, null, true, "MissingTargetError", true, false ), + new ParameterizedSwitchInfo( new string[] { "property", "p" }, ParameterizedSwitch.Property, null, true, "MissingPropertyError", true, false ), + new ParameterizedSwitchInfo( new string[] { "logger", "l" }, ParameterizedSwitch.Logger, null, false, "MissingLoggerError", false, false ), + new ParameterizedSwitchInfo( new string[] { "distributedlogger", "dl" }, ParameterizedSwitch.DistributedLogger, null, false, "MissingLoggerError", false, false ), + new ParameterizedSwitchInfo( new string[] { "verbosity", "v" }, ParameterizedSwitch.Verbosity, null, false, "MissingVerbosityError", true, false ), #if FEATURE_XML_SCHEMA_VALIDATION - new ParameterizedSwitchInfo( new string[] { "validate", "val" }, ParameterizedSwitch.Validate, null, false, null, true ), + new ParameterizedSwitchInfo( new string[] { "validate", "val" }, ParameterizedSwitch.Validate, null, false, null, true, false ), #endif - new ParameterizedSwitchInfo( new string[] { "consoleloggerparameters", "clp" }, ParameterizedSwitch.ConsoleLoggerParameters, null, false, "MissingConsoleLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "nodemode", "nmode" }, ParameterizedSwitch.NodeMode, null, false, null, false ), - new ParameterizedSwitchInfo( new string[] { "maxcpucount", "m" }, ParameterizedSwitch.MaxCPUCount, null, false, "MissingMaxCPUCountError", true ), - new ParameterizedSwitchInfo( new string[] { "ignoreprojectextensions", "ignore" }, ParameterizedSwitch.IgnoreProjectExtensions, null, true, "MissingIgnoreProjectExtensionsError", true ), - new ParameterizedSwitchInfo( new string[] { "toolsversion","tv" }, ParameterizedSwitch.ToolsVersion, null, false, "MissingToolsVersionError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters", "flp" }, ParameterizedSwitch.FileLoggerParameters, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters1", "flp1" }, ParameterizedSwitch.FileLoggerParameters1, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters2", "flp2" }, ParameterizedSwitch.FileLoggerParameters2, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters3", "flp3" }, ParameterizedSwitch.FileLoggerParameters3, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters4", "flp4" }, ParameterizedSwitch.FileLoggerParameters4, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters5", "flp5" }, ParameterizedSwitch.FileLoggerParameters5, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters6", "flp6" }, ParameterizedSwitch.FileLoggerParameters6, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters7", "flp7" }, ParameterizedSwitch.FileLoggerParameters7, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters8", "flp8" }, ParameterizedSwitch.FileLoggerParameters8, null, false, "MissingFileLoggerParameterError", true ), - new ParameterizedSwitchInfo( new string[] { "fileloggerparameters9", "flp9" }, ParameterizedSwitch.FileLoggerParameters9, null, false, "MissingFileLoggerParameterError", true ), + new ParameterizedSwitchInfo( new string[] { "consoleloggerparameters", "clp" }, ParameterizedSwitch.ConsoleLoggerParameters, null, false, "MissingConsoleLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "nodemode", "nmode" }, ParameterizedSwitch.NodeMode, null, false, null, false, false ), + new ParameterizedSwitchInfo( new string[] { "maxcpucount", "m" }, ParameterizedSwitch.MaxCPUCount, null, false, "MissingMaxCPUCountError", true, false ), + new ParameterizedSwitchInfo( new string[] { "ignoreprojectextensions", "ignore" }, ParameterizedSwitch.IgnoreProjectExtensions, null, true, "MissingIgnoreProjectExtensionsError", true, false ), + new ParameterizedSwitchInfo( new string[] { "toolsversion","tv" }, ParameterizedSwitch.ToolsVersion, null, false, "MissingToolsVersionError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters", "flp" }, ParameterizedSwitch.FileLoggerParameters, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters1", "flp1" }, ParameterizedSwitch.FileLoggerParameters1, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters2", "flp2" }, ParameterizedSwitch.FileLoggerParameters2, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters3", "flp3" }, ParameterizedSwitch.FileLoggerParameters3, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters4", "flp4" }, ParameterizedSwitch.FileLoggerParameters4, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters5", "flp5" }, ParameterizedSwitch.FileLoggerParameters5, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters6", "flp6" }, ParameterizedSwitch.FileLoggerParameters6, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters7", "flp7" }, ParameterizedSwitch.FileLoggerParameters7, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters8", "flp8" }, ParameterizedSwitch.FileLoggerParameters8, null, false, "MissingFileLoggerParameterError", true, false ), + new ParameterizedSwitchInfo( new string[] { "fileloggerparameters9", "flp9" }, ParameterizedSwitch.FileLoggerParameters9, null, false, "MissingFileLoggerParameterError", true, false ), #if FEATURE_NODE_REUSE - new ParameterizedSwitchInfo( new string[] { "nodereuse", "nr" }, ParameterizedSwitch.NodeReuse, null, false, "MissingNodeReuseParameterError", true ), + new ParameterizedSwitchInfo( new string[] { "nodereuse", "nr" }, ParameterizedSwitch.NodeReuse, null, false, "MissingNodeReuseParameterError", true, false ), #endif - new ParameterizedSwitchInfo( new string[] { "preprocess", "pp" }, ParameterizedSwitch.Preprocess, null, false, null, true ), + new ParameterizedSwitchInfo( new string[] { "preprocess", "pp" }, ParameterizedSwitch.Preprocess, null, false, null, true, false ), #if !FEATURE_NAMED_PIPES_FULL_DUPLEX - new ParameterizedSwitchInfo( new string[] { "clientToServerPipeHandle", "c2s" }, ParameterizedSwitch.ClientToServerPipeHandle, null, false, null, true ), - new ParameterizedSwitchInfo( new string[] { "serverToClientPipeHandle", "s2c" }, ParameterizedSwitch.ServerToClientPipeHandle, null, false, null, true ) + new ParameterizedSwitchInfo( new string[] { "clientToServerPipeHandle", "c2s" }, ParameterizedSwitch.ClientToServerPipeHandle, null, false, null, true, false ), + new ParameterizedSwitchInfo( new string[] { "serverToClientPipeHandle", "s2c" }, ParameterizedSwitch.ServerToClientPipeHandle, null, false, null, true, false ), #endif + new ParameterizedSwitchInfo( new string[] { "warnaserror", "err" }, ParameterizedSwitch.WarningsAsErrors, null, true, null, true, true ), }; /// @@ -343,7 +349,8 @@ internal static bool IsParameterizedSwitch out string duplicateSwitchErrorMessage, out bool multipleParametersAllowed, out string missingParametersErrorMessage, - out bool unquoteParameters + out bool unquoteParameters, + out bool emptyParametersAllowed ) { parameterizedSwitch = ParameterizedSwitch.Invalid; @@ -351,6 +358,7 @@ out bool unquoteParameters multipleParametersAllowed = false; missingParametersErrorMessage = null; unquoteParameters = false; + emptyParametersAllowed = false; foreach (ParameterizedSwitchInfo switchInfo in s_parameterizedSwitchesMap) { @@ -363,6 +371,7 @@ out bool unquoteParameters multipleParametersAllowed = switchInfo.multipleParametersAllowed; missingParametersErrorMessage = switchInfo.missingParametersErrorMessage; unquoteParameters = switchInfo.unquoteParameters; + emptyParametersAllowed = switchInfo.emptyParametersAllowed; break; } } @@ -454,7 +463,8 @@ internal bool SetParameterizedSwitch string commandLineArg, string switchParameters, bool multipleParametersAllowed, - bool unquoteParameters + bool unquoteParameters, + bool emptyParametersAllowed ) { bool parametersStored = false; @@ -481,12 +491,22 @@ bool unquoteParameters // check if the switch has multiple parameters if (multipleParametersAllowed) { - // store all the switch parameters - int emptyParameters; - _parameterizedSwitches[(int)parameterizedSwitch].parameters.AddRange(QuotingUtilities.SplitUnquoted(switchParameters, int.MaxValue, false /* discard empty parameters */, unquoteParameters, out emptyParameters, s_parameterSeparators)); + if (String.Empty.Equals(switchParameters) && emptyParametersAllowed) + { + // Store a null parameter if its allowed + _parameterizedSwitches[(int) parameterizedSwitch].parameters.Add(null); + parametersStored = true; + } + else + { + // store all the switch parameters + int emptyParameters; + _parameterizedSwitches[(int)parameterizedSwitch].parameters.AddRange(QuotingUtilities.SplitUnquoted(switchParameters, int.MaxValue, false /* discard empty parameters */, unquoteParameters, out emptyParameters, s_parameterSeparators)); - // check if they were all stored successfully i.e. they were all non-empty (after removing quoting, if requested) - parametersStored = (emptyParameters == 0); + // check if they were all stored successfully i.e. they were all non-empty (after removing quoting, if requested) + parametersStored = (emptyParameters == 0); + } + } else { diff --git a/src/XMakeCommandLine/Resources/Strings.resx b/src/XMakeCommandLine/Resources/Strings.resx index a4740198870..18bbfd134f7 100644 --- a/src/XMakeCommandLine/Resources/Strings.resx +++ b/src/XMakeCommandLine/Resources/Strings.resx @@ -586,6 +586,25 @@ Copyright (C) Microsoft Corporation. All rights reserved. MSBuild XML and any tasks and loggers it uses. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "warnaserror" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + MSBUILD : Configuration error MSB1043: The application could not start. {0} diff --git a/src/XMakeCommandLine/UnitTests/CommandLineSwitches_Tests.cs b/src/XMakeCommandLine/UnitTests/CommandLineSwitches_Tests.cs index a138a7d9531..60bc3af5ee2 100644 --- a/src/XMakeCommandLine/UnitTests/CommandLineSwitches_Tests.cs +++ b/src/XMakeCommandLine/UnitTests/CommandLineSwitches_Tests.cs @@ -4,8 +4,10 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.IO; - +using System.Linq; +using System.Resources; using Microsoft.Build.CommandLine; using Microsoft.Build.Construction; using Microsoft.Build.Framework; @@ -36,8 +38,9 @@ public void BogusSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.False(CommandLineSwitches.IsParameterizedSwitch("bogus", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.False(CommandLineSwitches.IsParameterizedSwitch("bogus", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Invalid, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -250,29 +253,30 @@ public void FileLoggerParametersIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("flp", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("flp", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.FileLoggerParameters, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("FLP", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("FLP", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.FileLoggerParameters, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("fileLoggerParameters", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("fileLoggerParameters", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.FileLoggerParameters, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("FILELOGGERPARAMETERS", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("FILELOGGERPARAMETERS", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.FileLoggerParameters, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -289,29 +293,30 @@ public void NodeReuseParametersIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("nr", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("nr", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.NodeReuse, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("NR", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("NR", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.NodeReuse, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("nodereuse", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("nodereuse", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.NodeReuse, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("NodeReuse", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("NodeReuse", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.NodeReuse, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -328,8 +333,9 @@ public void ProjectSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch(null, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch(null, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Project, parameterizedSwitch); Assert.NotNull(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -337,7 +343,7 @@ public void ProjectSwitchIdentificationTests() Assert.True(unquoteParameters); // for the virtual project switch, we match on null, not empty string - Assert.False(CommandLineSwitches.IsParameterizedSwitch(String.Empty, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.False(CommandLineSwitches.IsParameterizedSwitch(String.Empty, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Invalid, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -353,36 +359,37 @@ public void IgnoreProjectExtensionsSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("ignoreprojectextensions", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("ignoreprojectextensions", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("IgnoreProjectExtensions", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("IgnoreProjectExtensions", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("IGNOREPROJECTEXTENSIONS", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("IGNOREPROJECTEXTENSIONS", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("ignore", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("ignore", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("IGNORE", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("IGNORE", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); @@ -398,36 +405,37 @@ public void TargetSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("target", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("target", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Target, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("TARGET", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("TARGET", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Target, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Target", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Target", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Target, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("t", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("t", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Target, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("T", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("T", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Target, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); @@ -443,36 +451,37 @@ public void PropertySwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("property", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("property", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Property, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("PROPERTY", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("PROPERTY", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Property, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Property", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Property", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Property, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("p", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("p", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Property, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("P", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("P", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Property, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.True(multipleParametersAllowed); @@ -488,36 +497,37 @@ public void LoggerSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("logger", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("logger", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Logger, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.False(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("LOGGER", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("LOGGER", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Logger, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.False(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Logger", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Logger", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Logger, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.False(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("l", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("l", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Logger, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.False(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("L", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("L", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Logger, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -533,36 +543,37 @@ public void VerbositySwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("verbosity", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("verbosity", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Verbosity, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("VERBOSITY", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("VERBOSITY", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Verbosity, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Verbosity", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Verbosity", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Verbosity, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("v", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("v", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Verbosity, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("V", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("V", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Verbosity, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -608,29 +619,30 @@ public void MaxCPUCountSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("m", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("m", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.MaxCPUCount, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("M", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("M", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.MaxCPUCount, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("maxcpucount", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("maxcpucount", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.MaxCPUCount, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.NotNull(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("MAXCPUCOUNT", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("MAXCPUCOUNT", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.MaxCPUCount, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -647,43 +659,44 @@ public void ValidateSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("validate", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("validate", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("VALIDATE", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("VALIDATE", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Validate", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Validate", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("val", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("val", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("VAL", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("VAL", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("Val", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("Val", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Validate, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -700,15 +713,16 @@ public void PreprocessSwitchIdentificationTests() bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool emptyParametersAllowed; - Assert.True(CommandLineSwitches.IsParameterizedSwitch("preprocess", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("preprocess", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Preprocess, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); Assert.Null(missingParametersErrorMessage); Assert.True(unquoteParameters); - Assert.True(CommandLineSwitches.IsParameterizedSwitch("pp", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)); + Assert.True(CommandLineSwitches.IsParameterizedSwitch("pp", out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out emptyParametersAllowed)); Assert.Equal(CommandLineSwitches.ParameterizedSwitch.Preprocess, parameterizedSwitch); Assert.Null(duplicateSwitchErrorMessage); Assert.False(multipleParametersAllowed); @@ -745,7 +759,7 @@ public void SetParameterizedSwitchTests1() { CommandLineSwitches switches = new CommandLineSwitches(); - Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true)); + Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true, false)); Assert.Equal("/v:q", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Verbosity)); @@ -758,7 +772,7 @@ public void SetParameterizedSwitchTests1() // set it again -- this is bogus, because the /verbosity switch doesn't allow multiple parameters, but for the // purposes of testing the SetParameterizedSwitch() method, it doesn't matter - Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/verbosity:\"diag\";minimal", "\"diag\";minimal", true, true)); + Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/verbosity:\"diag\";minimal", "\"diag\";minimal", true, true, false)); Assert.Equal("/v:q /verbosity:\"diag\";minimal", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Verbosity)); @@ -788,7 +802,7 @@ public void SetParameterizedSwitchTests2() // fake/missing parameters -- this is bogus because the /target switch allows multiple parameters but we're turning // that off here just for testing purposes - Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"", "\"", false, true)); + Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"", "\"", false, true, false)); // switch has been set Assert.Equal("/t:\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); @@ -801,7 +815,7 @@ public void SetParameterizedSwitchTests2() Assert.Equal(0, parameters.Length); // more fake/missing parameters - Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:A,\"\";B", "A,\"\";B", true, true)); + Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:A,\"\";B", "A,\"\";B", true, true, false)); Assert.Equal("/t:\" /t:A,\"\";B", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); @@ -830,7 +844,7 @@ public void SetParameterizedSwitchTests3() Assert.Equal(0, parameters.Length); // don't unquote fake/missing parameters - Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/l:\"", "\"", false, false)); + Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/l:\"", "\"", false, false, false)); Assert.Equal("/l:\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger)); @@ -843,7 +857,7 @@ public void SetParameterizedSwitchTests3() // don't unquote multiple fake/missing parameters -- this is bogus because the /logger switch does not take multiple // parameters, but for testing purposes this is fine - Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/LOGGER:\"\",asm;\"p,a;r\"", "\"\",asm;\"p,a;r\"", true, false)); + Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/LOGGER:\"\",asm;\"p,a;r\"", "\"\",asm;\"p,a;r\"", true, false, false)); Assert.Equal("/l:\" /LOGGER:\"\",asm;\"p,a;r\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger)); @@ -858,6 +872,24 @@ public void SetParameterizedSwitchTests3() Assert.Equal("\"p,a;r\"", parameters[3]); } + [Fact] + public void SetParameterizedSwitchTestsAllowEmpty() + { + CommandLineSwitches switches = new CommandLineSwitches(); + + Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.WarningsAsErrors, "/warnaserror", "", multipleParametersAllowed: true, unquoteParameters: false, emptyParametersAllowed: true)); + + Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.WarningsAsErrors)); + + string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.WarningsAsErrors]; + + Assert.NotNull(parameters); + + Assert.True(parameters.Length > 0); + + Assert.Null(parameters.Last()); + } + [Fact] public void AppendErrorTests1() { @@ -970,14 +1002,14 @@ public void AppendParameterizedSwitchesTests1() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); - switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true); + switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true, false); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.False(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); CommandLineSwitches switchesRight = new CommandLineSwitches(); - switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:build", "build", true, true); + switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:build", "build", true, true, false); Assert.False(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); @@ -1008,13 +1040,13 @@ public void AppendParameterizedSwitchesTests2() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); - switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/target:Clean", "Clean", true, true); + switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/target:Clean", "Clean", true, true, false); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); CommandLineSwitches switchesRight = new CommandLineSwitches(); - switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"RESOURCES\";build", "\"RESOURCES\";build", true, true); + switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"RESOURCES\";build", "\"RESOURCES\";build", true, true, false); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); @@ -1037,13 +1069,13 @@ public void AppendParameterizedSwitchesTests3() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); - switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true); + switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true, false); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); CommandLineSwitches switchesRight = new CommandLineSwitches(); - switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "Rhubarb.proj", "Rhubarb.proj", false, true); + switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "Rhubarb.proj", "Rhubarb.proj", false, true, false); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); @@ -1090,7 +1122,8 @@ public void InvalidToolsVersionErrors() true, new StringWriter(), false, - false); + false, + warningsAsErrors: null); } finally { @@ -1105,7 +1138,7 @@ public void TestHaveAnySwitchesBeenSet() // Check if method works with parameterized switch CommandLineSwitches switches = new CommandLineSwitches(); Assert.False(switches.HaveAnySwitchesBeenSet()); - switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true); + switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true, false); Assert.True(switches.HaveAnySwitchesBeenSet()); // Check if method works with parameterless switches @@ -1152,6 +1185,173 @@ public void ExtractAnyLoggerParameterPickLast() Assert.Equal("v=q", result); } + /// + /// Verifies that when the /warnaserror switch is not specified, the set of warnings is null. + /// + [Fact] + public void ProcessWarnAsErrorSwitchNotSpecified() + { + CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); + + MSBuildApp.GatherCommandLineSwitches(new ArrayList(new[] { "" }), commandLineSwitches); + + Assert.Null(MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches)); + } + + /// + /// Verifies that the /warnaserror switch is parsed properly when codes are specified. + /// + [Fact] + public void ProcessWarnAsErrorSwitchWithCodes() + { + ISet expectedWarningsAsErors = new HashSet(StringComparer.OrdinalIgnoreCase) { "a", "B", "c", "D", "e" }; + + CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); + + MSBuildApp.GatherCommandLineSwitches(new ArrayList(new[] + { + "\"/warnaserror: a,B ; c \"", // Leading, trailing, leading and trailing whitespace + "/warnaserror:A,b,C", // Repeats of different case + "\"/warnaserror:, ,,\"", // Empty items + "/err:D,d;E,e", // A different source with new items and uses the short form + "/warnaserror:a", // A different source with a single duplicate + "/warnaserror:a,b", // A different source with multiple duplicates + }), commandLineSwitches); + + ISet actualWarningsAsErrors = MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches); + + Assert.NotNull(actualWarningsAsErrors); + + Assert.Equal(expectedWarningsAsErors, actualWarningsAsErrors, StringComparer.OrdinalIgnoreCase); + } + + /// + /// Verifies that an empty /warnaserror switch clears the list of codes. + /// + [Fact] + public void ProcessWarnAsErrorSwitchEmptySwitchClearsSet() + { + CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); + + MSBuildApp.GatherCommandLineSwitches(new ArrayList(new[] + { + "/warnaserror:a;b;c", + "/warnaserror", + }), commandLineSwitches); + + ISet actualWarningsAsErrors = MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches); + + Assert.NotNull(actualWarningsAsErrors); + + Assert.Equal(0, actualWarningsAsErrors.Count); + } + + /// + /// Verifies that when values are specified after an empty /warnaserror switch that they are added to the cleared list. + /// + [Fact] + public void ProcessWarnAsErrorSwitchValuesAfterEmptyAddOn() + { + ISet expectedWarningsAsErors = new HashSet(StringComparer.OrdinalIgnoreCase) { "e", "f", "g" }; + + CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); + + MSBuildApp.GatherCommandLineSwitches(new ArrayList(new[] + { + "/warnaserror:a;b;c", + "/warnaserror", + "/warnaserror:e;f;g", + }), commandLineSwitches); + + ISet actualWarningsAsErrors = MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches); + + Assert.NotNull(actualWarningsAsErrors); + + Assert.Equal(expectedWarningsAsErors, actualWarningsAsErrors, StringComparer.OrdinalIgnoreCase); + } + + /// + /// Verifies that the /warnaserror switch is parsed properly when no codes are specified. + /// + [Fact] + public void ProcessWarnAsErrorSwitchEmpty() + { + CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); + + MSBuildApp.GatherCommandLineSwitches(new ArrayList(new [] { "/warnaserror" }), commandLineSwitches); + + ISet actualWarningsAsErrors = MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches); + + Assert.NotNull(actualWarningsAsErrors); + + Assert.Equal(0, actualWarningsAsErrors.Count); + } + +#if FEATURE_RESOURCEMANAGER_GETRESOURCESET + /// + /// Verifies that help messages are correctly formed with the right width and leading spaces. + /// + [Fact] + public void HelpMessagesAreValid() + { + ResourceManager resourceManager = new ResourceManager("MSBuild.Strings", typeof(AssemblyResources).Assembly); + + const string switchLeadingSpaces = " "; + const string otherLineLeadingSpaces = " "; + const string examplesLeadingSpaces = " "; + + foreach (KeyValuePair item in resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, createIfNotExists: true, tryParents: true) + .Cast().Where(i => i.Key is string && ((string)i.Key).StartsWith("HelpMessage_")) + .Select(i => new KeyValuePair((string)i.Key, (string)i.Value))) + { + string[] helpMessageLines = item.Value.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + + for (int i = 0; i < helpMessageLines.Length; i++) + { + // All lines should be 80 characters or less + Assert.True(helpMessageLines[i].Length <= 80, $"Line {i + 1} of '{item.Key}' should be no longer than 80 characters."); + + if (i == 0) + { + if (helpMessageLines[i].Trim().StartsWith("/") || helpMessageLines[i].Trim().StartsWith("@")) + { + // If the first line in a switch it needs a certain amount of leading spaces + Assert.True(helpMessageLines[i].StartsWith(switchLeadingSpaces), $"Line {i + 1} of '{item.Key}' should start with '{switchLeadingSpaces}'."); + } + else + { + // Otherwise it should have no leading spaces because it's a section + Assert.False(helpMessageLines[i].StartsWith(" "), $"Line {i + 1} of '{item.Key}' should not have any leading spaces."); + } + } + else + { + // Ignore empty lines + if (!String.IsNullOrWhiteSpace(helpMessageLines[i])) + { + + if (item.Key.Contains("Examples")) + { + // Examples require a certain number of leading spaces + Assert.True(helpMessageLines[i].StartsWith(examplesLeadingSpaces), $"Line {i + 1} of '{item.Key}' should start with '{examplesLeadingSpaces}'."); + } + else if (helpMessageLines[i].Trim().StartsWith("/") || helpMessageLines[i].Trim().StartsWith("@")) + { + // Switches require a certain number of leading spaces + Assert.True(helpMessageLines[i].StartsWith(switchLeadingSpaces), $"Line {i + 1} of '{item.Key}' should start with '{switchLeadingSpaces}'."); + } + else + { + // All other lines require a certain number of leading spaces + Assert.True(helpMessageLines[i].StartsWith(otherLineLeadingSpaces), $"Line {i + 1} of '{item.Key}' should start with '{otherLineLeadingSpaces}'."); + } + } + } + } + } + } +#endif + /// /// Verifies that a switch collection has an error registered for the given command line arg. /// diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index c9b1d04bb37..69d26aa88ff 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -11,6 +11,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; using System.Security; using System.Text; @@ -546,6 +547,7 @@ string [] commandLine TextWriter preprocessWriter = null; bool debugger = false; bool detailedSummary = false; + ISet warningsAsErrors = null; CommandLineSwitches switchesFromAutoResponseFile; CommandLineSwitches switchesNotFromAutoResponseFile; @@ -572,6 +574,7 @@ string [] commandLine ref preprocessWriter, ref debugger, ref detailedSummary, + ref warningsAsErrors, recursing: false )) { @@ -600,7 +603,7 @@ string [] commandLine #if FEATURE_XML_SCHEMA_VALIDATION needToValidateProject, schemaFile, #endif - cpuCount, enableNodeReuse, preprocessWriter, debugger, detailedSummary)) + cpuCount, enableNodeReuse, preprocessWriter, debugger, detailedSummary, warningsAsErrors)) { exitType = ExitType.BuildError; } @@ -891,7 +894,8 @@ internal static bool BuildProject bool enableNodeReuse, TextWriter preprocessWriter, bool debugger, - bool detailedSummary + bool detailedSummary, + ISet warningsAsErrors ) { if (String.Equals(Path.GetExtension(projectFile), ".vcproj", StringComparison.OrdinalIgnoreCase) || @@ -1055,6 +1059,7 @@ bool detailedSummary parameters.ToolsetDefinitionLocations = Microsoft.Build.Evaluation.ToolsetDefinitionLocations.ConfigurationFile | Microsoft.Build.Evaluation.ToolsetDefinitionLocations.Registry; parameters.DetailedSummary = detailedSummary; parameters.LogTaskInputs = logTaskInputs; + parameters.WarningsAsErrors = warningsAsErrors; if (!String.IsNullOrEmpty(toolsVersion)) { @@ -1424,6 +1429,7 @@ internal static void GatherCommandLineSwitches(ArrayList commandLineArgs, Comman bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; + bool allowEmptyParameters; // Special case: for the switch "/m" or "/maxCpuCount" we wish to pretend we saw "/m:" // This allows a subsequent /m:n on the command line to override it. @@ -1444,9 +1450,9 @@ internal static void GatherCommandLineSwitches(ArrayList commandLineArgs, Comman { GatherParameterlessCommandLineSwitch(commandLineSwitches, parameterlessSwitch, switchParameters, duplicateSwitchErrorMessage, unquotedCommandLineArg); } - else if (CommandLineSwitches.IsParameterizedSwitch(switchName, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)) + else if (CommandLineSwitches.IsParameterizedSwitch(switchName, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters, out allowEmptyParameters)) { - GatherParameterizedCommandLineSwitch(commandLineSwitches, parameterizedSwitch, switchParameters, duplicateSwitchErrorMessage, multipleParametersAllowed, missingParametersErrorMessage, unquoteParameters, unquotedCommandLineArg); + GatherParameterizedCommandLineSwitch(commandLineSwitches, parameterizedSwitch, switchParameters, duplicateSwitchErrorMessage, multipleParametersAllowed, missingParametersErrorMessage, unquoteParameters, unquotedCommandLineArg, allowEmptyParameters); } else { @@ -1677,7 +1683,8 @@ private static void GatherParameterizedCommandLineSwitch bool multipleParametersAllowed, string missingParametersErrorMessage, bool unquoteParameters, - string unquotedCommandLineArg + string unquotedCommandLineArg, + bool allowEmptyParameters ) { if (// switch must have parameters @@ -1696,7 +1703,7 @@ string unquotedCommandLineArg } // save the parameters after unquoting and splitting them if necessary - if (!commandLineSwitches.SetParameterizedSwitch(parameterizedSwitch, unquotedCommandLineArg, switchParameters, multipleParametersAllowed, unquoteParameters)) + if (!commandLineSwitches.SetParameterizedSwitch(parameterizedSwitch, unquotedCommandLineArg, switchParameters, multipleParametersAllowed, unquoteParameters, allowEmptyParameters)) { // if parsing revealed there were no real parameters, flag an error, unless the parameters are optional if (missingParametersErrorMessage != null) @@ -1786,6 +1793,7 @@ private static bool ProcessCommandLineSwitches ref TextWriter preprocessWriter, ref bool debugger, ref bool detailedSummary, + ref ISet warningsAsErrors, bool recursing ) { @@ -1889,6 +1897,7 @@ bool recursing ref preprocessWriter, ref debugger, ref detailedSummary, + ref warningsAsErrors, recursing: true ); } @@ -1923,6 +1932,8 @@ bool recursing #endif detailedSummary = commandLineSwitches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.DetailedSummary); + warningsAsErrors = ProcessWarnAsErrorSwitch(commandLineSwitches); + // figure out which loggers are going to listen to build events string[][] groupedFileLoggerParameters = commandLineSwitches.GetFileLoggerParameters(); @@ -2030,6 +2041,37 @@ internal static TextWriter ProcessPreprocessSwitch(string[] parameters) return writer; } + internal static ISet ProcessWarnAsErrorSwitch(CommandLineSwitches commandLineSwitches) + { + // TODO: Parse an environment variable as well? + + if (!commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.WarningsAsErrors)) + { + return null; + } + + string[] parameters = commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.WarningsAsErrors]; + + ISet warningsAsErrors = new HashSet(StringComparer.OrdinalIgnoreCase); + + foreach (string code in parameters + .SelectMany(parameter => parameter?.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) ?? new string[] { null })) + { + if (code == null) + { + // An empty /warnaserror is added as "null". In this case, the list is cleared + // so that all warnings are treated errors + warningsAsErrors.Clear(); + } + else if(!String.IsNullOrWhiteSpace(code)) + { + warningsAsErrors.Add(code.Trim()); + } + } + + return warningsAsErrors; + } + /// /// Uses the input from thinNodeMode switch to start a local node server /// @@ -3137,6 +3179,7 @@ private static void ShowHelpMessage() Console.WriteLine(AssemblyResources.GetString("HelpMessage_18_DistributedLoggerSwitch")); Console.WriteLine(AssemblyResources.GetString("HelpMessage_21_DistributedFileLoggerSwitch")); Console.WriteLine(AssemblyResources.GetString("HelpMessage_11_LoggerSwitch")); + Console.WriteLine(AssemblyResources.GetString("HelpMessage_28_WarnAsErrorSwitch")); #if FEATURE_XML_SCHEMA_VALIDATION Console.WriteLine(AssemblyResources.GetString("HelpMessage_15_ValidateSwitch")); #endif From 4287837b1b447905625593a926d60ab5e756e71d Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 29 Nov 2016 12:41:30 -0800 Subject: [PATCH 105/223] Implement /NoWarn switch (#1366) You cannot suppress all warnings, if you specify empty `/warnasmessage` or `/nowarn`, you get an error message. Warnings are mutated into just a message. Ignore the first commit which is the implementation of /WarnAsError Closes #68 Closes #47 Closes #910 So this: ``` MyProject.proj(3,18): warning MSB4130: The condition "true or true and true" may have been evaluated incorrectly in an earlier version of MSBuild. Please verify that the order of the AND and OR clauses is written as intended. To avoid this warning, add parentheses to make the evaluation order explicit. ``` Becomes this in with Verbosity=Detailed ``` MyProject.proj(3,18): message MSB4130: The condition "true or true and true" may have been evaluated incorrectly in an earlier version of MSBuild. Please verify that the order of the AND and OR clauses is written as intended. To avoid this warning, add parentheses to make the evaluation order explicit. ``` Here is the help message for review: ``` /warnasmessage[:code[;code2]] List of warning codes to treats as low importance messages. Use a semicolon or a comma to separate multiple warning codes. (Short form: /nowarn[:c;[c2]]) Example: /warnasmessage:MSB3026 ``` --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 1 + .../BackEnd/BuildManager/BuildManager.cs | 5 +- .../BackEnd/BuildManager/BuildParameters.cs | 15 ++++ .../Logging/BuildEventArgTransportSink.cs | 10 +++ .../Components/Logging/EventSourceSink.cs | 37 +++++++++- .../Components/Logging/ILoggingService.cs | 18 +++++ .../Components/Logging/LoggingService.cs | 20 +++++- .../BackEnd/EventSourceSink_Tests.cs | 69 +++++++++++++++++++ .../UnitTests/BackEnd/MockLoggingService.cs | 8 +++ src/XMakeCommandLine/CommandLineSwitches.cs | 2 + src/XMakeCommandLine/Resources/Strings.resx | 25 ++++++- .../UnitTests/CommandLineSwitches_Tests.cs | 56 +++++++++++++-- src/XMakeCommandLine/XMake.cs | 35 +++++++++- 13 files changed, 286 insertions(+), 15 deletions(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index a5b7e11a2ea..336c12ced25 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -941,6 +941,7 @@ public BuildParameters(Microsoft.Build.Evaluation.ProjectCollection projectColle public System.Globalization.CultureInfo UICulture { get { throw null; } set { } } public bool UseSynchronousLogging { get { throw null; } set { } } public System.Collections.Generic.ISet WarningsAsErrors { get { throw null; } set { } } + public System.Collections.Generic.ISet WarningsAsMessages { get { throw null; } set { } } public Microsoft.Build.Execution.BuildParameters Clone() { throw null; } public Microsoft.Build.Evaluation.Toolset GetToolset(string toolsVersion) { throw null; } } diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs index 92872a5e736..0cb3cdd8a8d 100644 --- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs +++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs @@ -424,7 +424,7 @@ public void BeginBuild(BuildParameters parameters) } // Set up the logging service. - ILoggingService loggingService = CreateLoggingService(_buildParameters.Loggers, _buildParameters.ForwardingLoggers, _buildParameters.WarningsAsErrors); + ILoggingService loggingService = CreateLoggingService(_buildParameters.Loggers, _buildParameters.ForwardingLoggers, _buildParameters.WarningsAsErrors, _buildParameters.WarningsAsMessages); _nodeManager.RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, loggingService as INodePacketHandler); try @@ -1736,7 +1736,7 @@ private void OnProjectStarted(object sender, ProjectStartedEventArgs e) /// /// Creates a logging service around the specified set of loggers. /// - private ILoggingService CreateLoggingService(IEnumerable loggers, IEnumerable forwardingLoggers, ISet warningsAsErrors) + private ILoggingService CreateLoggingService(IEnumerable loggers, IEnumerable forwardingLoggers, ISet warningsAsErrors, ISet warningsAsMessages) { int cpuCount = _buildParameters.MaxNodeCount; @@ -1764,6 +1764,7 @@ private ILoggingService CreateLoggingService(IEnumerable loggers, IEnum loggingService.OnProjectStarted += _projectStartedEventHandler; loggingService.OnProjectFinished += _projectFinishedEventHandler; loggingService.WarningsAsErrors = warningsAsErrors; + loggingService.WarningsAsMessages = warningsAsMessages; try { diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs index 34459823cfc..5ef4bda7a87 100644 --- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs +++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildParameters.cs @@ -205,6 +205,11 @@ public class BuildParameters : INodePacketTranslatable /// private ISet _warningsAsErrors = null; + /// + /// A list of warnings to treat as low importance messages. + /// + private ISet _warningsAsMessages = null; + /// /// The location of the toolset definitions. /// @@ -326,6 +331,7 @@ private BuildParameters(BuildParameters other) _logTaskInputs = other._logTaskInputs; _logInitialPropertiesAndItems = other._logInitialPropertiesAndItems; _warningsAsErrors = other._warningsAsErrors == null ? null : new HashSet(other._warningsAsErrors, StringComparer.OrdinalIgnoreCase); + _warningsAsMessages = other._warningsAsMessages == null ? null : new HashSet(other._warningsAsMessages, StringComparer.OrdinalIgnoreCase); } #if FEATURE_THREAD_PRIORITY @@ -598,6 +604,15 @@ public ISet WarningsAsErrors set { _warningsAsErrors = value; } } + /// + /// A list of warnings to treat as low importance messages. + /// + public ISet WarningsAsMessages + { + get { return _warningsAsMessages; } + set { _warningsAsMessages = value; } + } + /// /// Locations to search for toolsets. /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs index bce7890e6de..64e1d9e8f6c 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/BuildEventArgTransportSink.cs @@ -90,6 +90,16 @@ public ISet WarningsAsErrors set; } + /// + /// This property is ignored by this event sink and relies on the receiver to treat warnings as low importance messages. + /// + public ISet WarningsAsMessages + { + get; + set; + } + + /// /// This property is ignored by this event sink and relies on the receiver to keep track of whether or not any errors have been logged. /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs index c023231b9bf..c13dcb89f32 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/EventSourceSink.cs @@ -140,6 +140,15 @@ public ISet WarningsAsErrors set; } + /// + /// A list of warnings to treat as low importance messages. + /// + public ISet WarningsAsMessages + { + get; + set; + } + /// /// A list of build submission IDs that have logged errors. If an error is logged outside of a submission, the submission ID is . /// @@ -224,9 +233,33 @@ public void Consume(BuildEventArgs buildEvent) { BuildWarningEventArgs warningEvent = (BuildWarningEventArgs) buildEvent; - // Treat this warning as an error if an empty set of warnings was specified or this code was specified - if (WarningsAsErrors != null && (WarningsAsErrors.Count == 0 || WarningsAsErrors.Contains(warningEvent.Code))) + if (WarningsAsMessages != null && WarningsAsMessages.Contains(warningEvent.Code)) + { + // Treat this warning as a message with low importance if its in the list + BuildMessageEventArgs errorEvent = new BuildMessageEventArgs( + warningEvent.Subcategory, + warningEvent.Code, + warningEvent.File, + warningEvent.LineNumber, + warningEvent.ColumnNumber, + warningEvent.EndLineNumber, + warningEvent.EndColumnNumber, + warningEvent.Message, + warningEvent.HelpKeyword, + warningEvent.SenderName, + MessageImportance.Low, + warningEvent.Timestamp) + { + BuildEventContext = warningEvent.BuildEventContext, + ProjectFile = warningEvent.ProjectFile, + }; + + this.RaiseMessageEvent(null, errorEvent); + + } + else if (WarningsAsErrors != null && (WarningsAsErrors.Count == 0 || WarningsAsErrors.Contains(warningEvent.Code))) { + // Treat this warning as an error if an empty set of warnings was specified or this code was specified BuildErrorEventArgs errorEvent = new BuildErrorEventArgs( warningEvent.Subcategory, warningEvent.Code, diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs index 9e4f0c1e068..7a6caf13b81 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/ILoggingService.cs @@ -162,6 +162,15 @@ ISet WarningsAsErrors get; set; } + + /// + /// A list of warnings to treat as low importance messages. + /// + ISet WarningsAsMessages + { + get; + set; + } #endregion /// @@ -472,6 +481,15 @@ ISet WarningsAsErrors set; } + /// + /// A list of warnings to treat as low importance messages. + /// + ISet WarningsAsMessages + { + get; + set; + } + /// /// A list of build submissions that have logged errors. /// diff --git a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs index 0d0c55e08fd..fc3ac97b501 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Logging/LoggingService.cs @@ -224,6 +224,11 @@ internal partial class LoggingService : ILoggingService, INodePacketHandler, IBu /// private ISet _warningsAsErrors = null; + /// + /// A list of warnings to treat as low importance messages. + /// + private ISet _warningsAsMessages = null; + #endregion #endregion @@ -459,6 +464,15 @@ public ISet WarningsAsErrors set { _warningsAsErrors = value; } } + /// + /// A list of warnings to treat as low importance messages. + /// + public ISet WarningsAsMessages + { + get { return _warningsAsMessages; } + set { _warningsAsMessages = value; } + } + /// /// Determines if the specified submission has logged an errors. /// @@ -819,7 +833,8 @@ public bool RegisterDistributedLogger(ILogger centralLogger, LoggerDescription f // create an eventSourceSink which the central logger will register with to receive the events from the forwarding logger EventSourceSink eventSourceSink = new EventSourceSink { - WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase) + WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase), + WarningsAsMessages = WarningsAsMessages == null ? null : new HashSet(WarningsAsMessages, StringComparer.OrdinalIgnoreCase), }; // If the logger is already in the list it should not be registered again. @@ -1135,7 +1150,8 @@ private void CreateFilterEventSource() _filterEventSource = new EventSourceSink { Name = "Sink for Distributed/Filter loggers", - WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase) + WarningsAsErrors = WarningsAsErrors == null ? null : new HashSet(WarningsAsErrors, StringComparer.OrdinalIgnoreCase), + WarningsAsMessages = WarningsAsMessages == null ? null : new HashSet(WarningsAsMessages, StringComparer.OrdinalIgnoreCase), }; } } diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs index 58ad2633ffc..e7a38f30fca 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/EventSourceSink_Tests.cs @@ -170,6 +170,75 @@ public void TreatWarningsAsErrorWhenAllSpecified() Assert.IsType(eventHandlerHelper.RaisedEvent); } + /// + /// Verifies that a warning is logged as a low importance message when it's warning code is specified. + /// + [Fact] + public void TreatWarningsAsMessagesWhenSpecified() + { + BuildWarningEventArgs expectedBuildEvent = RaiseEventHelper.Warning; + + EventSourceSink eventSourceSink = new EventSourceSink() + { + WarningsAsMessages = new HashSet + { + "FOO", + expectedBuildEvent.Code, + "BAR", + }, + }; + + RaiseEventHelper raiseEventHelper = new RaiseEventHelper(eventSourceSink); + EventHandlerHelper eventHandlerHelper = new EventHandlerHelper(eventSourceSink, null); + + raiseEventHelper.RaiseBuildEvent(RaiseEventHelper.Warning); + + Assert.IsType(eventHandlerHelper.RaisedEvent); + + BuildMessageEventArgs actualBuildEvent = (BuildMessageEventArgs)eventHandlerHelper.RaisedEvent; + + Assert.Equal(expectedBuildEvent.BuildEventContext, actualBuildEvent.BuildEventContext); + Assert.Equal(expectedBuildEvent.Code, actualBuildEvent.Code); + Assert.Equal(expectedBuildEvent.ColumnNumber, actualBuildEvent.ColumnNumber); + Assert.Equal(expectedBuildEvent.EndColumnNumber, actualBuildEvent.EndColumnNumber); + Assert.Equal(expectedBuildEvent.EndLineNumber, actualBuildEvent.EndLineNumber); + Assert.Equal(expectedBuildEvent.File, actualBuildEvent.File); + Assert.Equal(expectedBuildEvent.HelpKeyword, actualBuildEvent.HelpKeyword); + Assert.Equal(MessageImportance.Low, actualBuildEvent.Importance); + Assert.Equal(expectedBuildEvent.LineNumber, actualBuildEvent.LineNumber); + Assert.Equal(expectedBuildEvent.Message, actualBuildEvent.Message); + Assert.Equal(expectedBuildEvent.ProjectFile, actualBuildEvent.ProjectFile); + Assert.Equal(expectedBuildEvent.SenderName, actualBuildEvent.SenderName); + Assert.Equal(expectedBuildEvent.Subcategory, actualBuildEvent.Subcategory); + Assert.Equal(expectedBuildEvent.ThreadId, actualBuildEvent.ThreadId); + Assert.Equal(expectedBuildEvent.Timestamp, actualBuildEvent.Timestamp); + } + + /// + /// Verifies that a warning is not treated as a low importance message when other warning codes are specified. + /// + [Fact] + public void NotTreatWarningsAsMessagesWhenNotSpecified() + { + BuildWarningEventArgs expectedBuildEvent = RaiseEventHelper.Warning; + + EventSourceSink eventSourceSink = new EventSourceSink() + { + WarningsAsMessages = new HashSet + { + "123", + "ABC", + }, + }; + + RaiseEventHelper raiseEventHelper = new RaiseEventHelper(eventSourceSink); + EventHandlerHelper eventHandlerHelper = new EventHandlerHelper(eventSourceSink, null); + + raiseEventHelper.RaiseBuildEvent(RaiseEventHelper.Warning); + + Assert.Equal(expectedBuildEvent, eventHandlerHelper.RaisedEvent); + } + #region TestsThrowingLoggingExceptions /// diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs index c3559fac92b..6b8269d6eae 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/MockLoggingService.cs @@ -156,6 +156,14 @@ public ISet WarningsAsErrors set; } + /// + /// List of warnings to treat as low importance messages. + /// + public ISet WarningsAsMessages + { + get; + set; + } /// /// Is the logging service on a remote node, this is used to determine if properties need to be serialized diff --git a/src/XMakeCommandLine/CommandLineSwitches.cs b/src/XMakeCommandLine/CommandLineSwitches.cs index be2786a7d77..d37b937dbb1 100644 --- a/src/XMakeCommandLine/CommandLineSwitches.cs +++ b/src/XMakeCommandLine/CommandLineSwitches.cs @@ -103,6 +103,7 @@ internal enum ParameterizedSwitch ServerToClientPipeHandle, #endif WarningsAsErrors, + WarningsAsMessages, NumberOfParameterizedSwitches } @@ -281,6 +282,7 @@ bool emptyParametersAllowed new ParameterizedSwitchInfo( new string[] { "serverToClientPipeHandle", "s2c" }, ParameterizedSwitch.ServerToClientPipeHandle, null, false, null, true, false ), #endif new ParameterizedSwitchInfo( new string[] { "warnaserror", "err" }, ParameterizedSwitch.WarningsAsErrors, null, true, null, true, true ), + new ParameterizedSwitchInfo( new string[] { "warnasmessage", "nowarn" }, ParameterizedSwitch.WarningsAsMessages, null, true, "MissingWarnAsMessageParameterError", true, false ), }; /// diff --git a/src/XMakeCommandLine/Resources/Strings.resx b/src/XMakeCommandLine/Resources/Strings.resx index 18bbfd134f7..7af49bc1705 100644 --- a/src/XMakeCommandLine/Resources/Strings.resx +++ b/src/XMakeCommandLine/Resources/Strings.resx @@ -601,7 +601,22 @@ Copyright (C) Microsoft Corporation. All rights reserved. build will fail. - LOCALIZATION: "warnaserror" should not be localized. + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. @@ -975,6 +990,14 @@ Copyright (C) Microsoft Corporation. All rights reserved. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1050: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + + From b71b6194bbc8c80abf4cd3ea5a44155d3f1213be Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 11:24:34 -0600 Subject: [PATCH 109/223] make implicitness a property of the import element--PP does not work --- src/Shared/XMakeAttributes.cs | 1 + .../Construction/ProjectElementContainer.cs | 2 +- .../ProjectImplicitImportElement.cs | 73 --------------- .../Construction/ProjectImportElement.cs | 51 +++++++++-- src/XMakeBuildEngine/Evaluation/Evaluator.cs | 12 --- .../Evaluation/ProjectParser.cs | 89 +++++++++---------- src/XMakeBuildEngine/Microsoft.Build.csproj | 5 +- 7 files changed, 88 insertions(+), 145 deletions(-) delete mode 100644 src/XMakeBuildEngine/Construction/ProjectImplicitImportElement.cs diff --git a/src/Shared/XMakeAttributes.cs b/src/Shared/XMakeAttributes.cs index 965f88712f4..b34759d7653 100644 --- a/src/Shared/XMakeAttributes.cs +++ b/src/Shared/XMakeAttributes.cs @@ -43,6 +43,7 @@ internal static class XMakeAttributes internal const string taskParameter = "TaskParameter"; internal const string itemName = "ItemName"; internal const string propertyName = "PropertyName"; + internal const string sdk = "Sdk"; internal const string toolsVersion = "ToolsVersion"; internal const string runtime = "Runtime"; internal const string msbuildRuntime = "MSBuildRuntime"; diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index 62896004f97..d6c82e9b2ad 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -551,7 +551,7 @@ private static bool HasXmlRepresentation(ProjectElement element) // Xml tree. It's implied by other parts of the project file but exists directly // only on the ProjectElement side. - return !(element is ProjectImplicitImportElement); + return (element as ProjectImportElement)?.Implicit != true; } private string GetElementIndentation(XmlElementWithLocation xmlElement) diff --git a/src/XMakeBuildEngine/Construction/ProjectImplicitImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImplicitImportElement.cs deleted file mode 100644 index e178ae80042..00000000000 --- a/src/XMakeBuildEngine/Construction/ProjectImplicitImportElement.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -//----------------------------------------------------------------------- -// -// Definition of ProjectImportElement class. -//----------------------------------------------------------------------- - -using System.Diagnostics; -using System.Xml; -using Microsoft.Build.Shared; - -using ProjectXmlUtilities = Microsoft.Build.Internal.ProjectXmlUtilities; - -namespace Microsoft.Build.Construction -{ - /// - /// Represents an import element that does not physically exist in the - /// project XML, but is implied by the project's SDK definition. - /// - [DebuggerDisplay("Implicit Project={Project} Condition={Condition}")] - internal class ProjectImplicitImportElement : ProjectElement - { - private string _project; - - private ProjectImplicitImportElement(ProjectRootElement containingProject) - { - this.ContainingProject = containingProject; - } - - internal new string ElementName => "ImplicitImport"; - - public string Project - { - get { return _project; } - - set - { - ErrorUtilities.VerifyThrowArgumentLength(value, XMakeAttributes.project); - _project = value; - } - } - - /// - /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. - /// Validates the project value. - /// Caller should then ensure the element is added to a parent - /// - internal static ProjectImplicitImportElement CreateDisconnected(string project, ProjectRootElement containingProject) - { - ProjectImplicitImportElement import = new ProjectImplicitImportElement(containingProject) - { - Project = project - }; - - return import; - } - - /// - /// Overridden to verify that the potential parent and siblings - /// are acceptable. Throws InvalidOperationException if they are not. - /// - internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) - { - ErrorUtilities.VerifyThrowInvalidOperation(parent is ProjectRootElement, "OM_CannotAcceptParent"); - } - - /// - protected override ProjectElement CreateNewInstance(ProjectRootElement owner) - { - return owner.CreateImportElement(this.Project); - } - } -} diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index 87547968bf8..81a21974470 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -19,6 +19,9 @@ namespace Microsoft.Build.Construction [DebuggerDisplay("Project={Project} Condition={Condition}")] public class ProjectImportElement : ProjectElement { + internal bool Implicit { get; } = false; + private string _implicitProject = null; + /// /// Initialize a parented ProjectImportElement /// @@ -36,6 +39,15 @@ private ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootEleme { } + /// + /// Initialize an unparented implicit ProjectImportElement + /// + private ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject, bool isImplicit) + : this(xmlElement, containingProject) + { + Implicit = isImplicit; + } + /// /// Gets or sets the Project value. /// @@ -44,25 +56,34 @@ public string Project get { return - FileUtilities.FixFilePath( - ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.project)); + FileUtilities.FixFilePath(Implicit + ? _implicitProject + : ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.project)); } set { ErrorUtilities.VerifyThrowArgumentLength(value, XMakeAttributes.project); - ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.project, value); - MarkDirty("Set Import Project {0}", value); + + if (Implicit) + { + _implicitProject = value; + } + else + { + ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.project, value); + MarkDirty("Set Import Project {0}", value); + } } } /// /// Location of the project attribute /// - public ElementLocation ProjectLocation - { - get { return XmlElement.GetAttributeLocation(XMakeAttributes.project); } - } + /// + /// For an implicit import, the location points to the Sdk attribute on the Project element. + /// + public ElementLocation ProjectLocation => XmlElement.GetAttributeLocation(Implicit ? XMakeAttributes.sdk : XMakeAttributes.project); /// /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. @@ -80,6 +101,20 @@ internal static ProjectImportElement CreateDisconnected(string project, ProjectR return import; } + /// + /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. + /// Validates the project value. + /// Caller should then ensure the element is added to a parent + /// + internal static ProjectImportElement CreateDisconnected(string project, ProjectRootElement containingProject, bool isImplicit) + { + ProjectImportElement import = new ProjectImportElement(containingProject.XmlElement, containingProject, isImplicit); + + import.Project = project; + + return import; + } + /// /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. diff --git a/src/XMakeBuildEngine/Evaluation/Evaluator.cs b/src/XMakeBuildEngine/Evaluation/Evaluator.cs index cd42aaf4e28..076835549a0 100644 --- a/src/XMakeBuildEngine/Evaluation/Evaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/Evaluator.cs @@ -1140,18 +1140,6 @@ child is ProjectItemElement || continue; } - ProjectImplicitImportElement implicitImport = element as ProjectImplicitImportElement; - if (implicitImport != null) - { - var substituteRegularImport = new ProjectImportElement(currentProjectOrImport.XmlElement, implicitImport.Parent, - implicitImport.ContainingProject); - substituteRegularImport.Project = implicitImport.Project; - - EvaluateImportElement(currentProjectOrImport.DirectoryPath, substituteRegularImport); - - continue; - } - ErrorUtilities.ThrowInternalError("Unexpected child type"); } diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 1074b573640..d0910a173fb 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -187,69 +187,45 @@ private void ParseProjectElement(XmlElementWithLocation element) // so we have to set it now _project.SetProjectRootElementFromParser(element, _project); + ParseProjectRootElementChildren(element); + } + + /// + /// Parse the child of a ProjectRootElement + /// + private void ParseProjectRootElementChildren(XmlElementWithLocation element) + { + string initialImportPath = null; + string finalImportPath = null; + if (element.HasAttribute("Sdk")) { // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop // TODO: version? - var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), + initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), element.GetAttribute("Sdk"), "Sdk.props"); - var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), + finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), element.GetAttribute("Sdk"), "Sdk.targets"); + } - // Desired approach: - - //ProjectElement child = - // ProjectImportElement.CreateDisconnected( - // Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), element.GetAttribute("Sdk"), "Sdk.props"), - // _project); - //_project.AppendChild(child); - - // But this doesn't work because it gets doubly considered: at the beginning of _project, - // and at the end of the Project element's children (where it gets created). - - // Instead, create an XML element directly and inject it in the right place. - - if (File.Exists(initialImportPath)) - { - ProjectElement child = - ProjectImplicitImportElement.CreateDisconnected( - Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), element.GetAttribute("Sdk"), "Sdk.props"), - _project); - _project.AppendChild(child); - - //var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - //implicitImportElement.SetAttribute(XMakeAttributes.project, - // initialImportPath); - - //// TODO: make this - - //element.PrependChild(implicitImportElement); - } - - if (File.Exists(finalImportPath)) - { - var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + if (initialImportPath != null && File.Exists(initialImportPath)) + { + ProjectElement child = ProjectImportElement.CreateDisconnected(initialImportPath, _project, + isImplicit: true); + _project.PrependChild(child); - implicitImportElement.SetAttribute(XMakeAttributes.project, - finalImportPath); + //var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - // TODO: make this + //implicitImportElement.SetAttribute(XMakeAttributes.project, + // initialImportPath); - element.AppendChild(implicitImportElement); - } + //// TODO: make this + //element.PrependChild(implicitImportElement); } - ParseProjectRootElementChildren(element); - } - /// - /// Parse the child of a ProjectRootElement - /// - private void ParseProjectRootElementChildren(XmlElementWithLocation element) - { foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; @@ -306,6 +282,23 @@ private void ParseProjectRootElementChildren(XmlElementWithLocation element) _project.AppendParentedChildNoChecks(child); } + + + if (finalImportPath!= null && File.Exists(finalImportPath)) + { + ProjectElement child = ProjectImportElement.CreateDisconnected(finalImportPath, _project, + isImplicit: true); + _project.AppendChild(child); + + //var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + + //implicitImportElement.SetAttribute(XMakeAttributes.project, + // finalImportPath); + + //// TODO: make this + + //element.AppendChild(implicitImportElement); + } } /// diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index 49995fce177..376f0ac3b1d 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -1,4 +1,4 @@ - + v1.5 @@ -356,7 +356,6 @@ - @@ -767,4 +766,4 @@ --> - + \ No newline at end of file From b1077467e7cd7906285d190e734aed3562f0503a Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 15:12:09 -0600 Subject: [PATCH 110/223] back to implicit xml element--fixes preprocessor that walks only over the XML tree --- src/Shared/XMakeAttributes.cs | 1 + .../Construction/ProjectImportElement.cs | 52 ++++--------- .../Evaluation/Preprocessor.cs | 19 ++++- .../Evaluation/ProjectParser.cs | 78 +++++++++---------- 4 files changed, 65 insertions(+), 85 deletions(-) diff --git a/src/Shared/XMakeAttributes.cs b/src/Shared/XMakeAttributes.cs index b34759d7653..3df2a54acf8 100644 --- a/src/Shared/XMakeAttributes.cs +++ b/src/Shared/XMakeAttributes.cs @@ -40,6 +40,7 @@ internal static class XMakeAttributes internal const string taskName = "TaskName"; internal const string continueOnError = "ContinueOnError"; internal const string project = "Project"; + internal const string @implicit = "_Implicit"; internal const string taskParameter = "TaskParameter"; internal const string itemName = "ItemName"; internal const string propertyName = "PropertyName"; diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index 81a21974470..5fd0b6ac781 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -19,9 +19,6 @@ namespace Microsoft.Build.Construction [DebuggerDisplay("Project={Project} Condition={Condition}")] public class ProjectImportElement : ProjectElement { - internal bool Implicit { get; } = false; - private string _implicitProject = null; - /// /// Initialize a parented ProjectImportElement /// @@ -39,15 +36,6 @@ private ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootEleme { } - /// - /// Initialize an unparented implicit ProjectImportElement - /// - private ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject, bool isImplicit) - : this(xmlElement, containingProject) - { - Implicit = isImplicit; - } - /// /// Gets or sets the Project value. /// @@ -56,34 +44,34 @@ public string Project get { return - FileUtilities.FixFilePath(Implicit - ? _implicitProject - : ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.project)); + FileUtilities.FixFilePath(ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.project)); } set { ErrorUtilities.VerifyThrowArgumentLength(value, XMakeAttributes.project); - if (Implicit) - { - _implicitProject = value; - } - else - { - ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.project, value); - MarkDirty("Set Import Project {0}", value); - } + ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.project, value); + MarkDirty("Set Import Project {0}", value); } } + /// + /// Gets the Implicit state of the element: true if the element was not in the read XML. + /// + internal bool Implicit + { + get { return XmlElement.HasAttribute(XMakeAttributes.@implicit); } + } + + /// /// Location of the project attribute /// /// /// For an implicit import, the location points to the Sdk attribute on the Project element. /// - public ElementLocation ProjectLocation => XmlElement.GetAttributeLocation(Implicit ? XMakeAttributes.sdk : XMakeAttributes.project); + public ElementLocation ProjectLocation => XmlElement.GetAttributeLocation(XMakeAttributes.project); /// /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. @@ -101,20 +89,6 @@ internal static ProjectImportElement CreateDisconnected(string project, ProjectR return import; } - /// - /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. - /// Validates the project value. - /// Caller should then ensure the element is added to a parent - /// - internal static ProjectImportElement CreateDisconnected(string project, ProjectRootElement containingProject, bool isImplicit) - { - ProjectImportElement import = new ProjectImportElement(containingProject.XmlElement, containingProject, isImplicit); - - import.Project = project; - - return import; - } - /// /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. diff --git a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs index 9cc61894af4..f47913b4381 100644 --- a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs +++ b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs @@ -166,13 +166,16 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) { // To display what the tag looked like string importCondition = ((XmlElement)child).GetAttribute(XMakeAttributes.condition); + string condition = importCondition.Length > 0 ? $" Condition=\"{importCondition}\"" : String.Empty; string importProject = ((XmlElement)child).GetAttribute(XMakeAttributes.project); + string importSdk = ((XmlElement)child).GetAttribute(XMakeAttributes.sdk); IList resolvedList; if (!_importTable.TryGetValue(child as XmlElement, out resolvedList)) { // Import didn't resolve to anything; just display as a comment and move on - string closedImportTag = " 0) ? " Condition=\"" + importCondition + "\"" : String.Empty) + " />"; + string closedImportTag = + $""; destination.AppendChild(destinationDocument.CreateComment(closedImportTag)); continue; @@ -183,8 +186,18 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) ProjectRootElement resolved = resolvedList[i]; XmlDocument innerDocument = resolved.XmlDocument; - string importTag = " 0) ? " Condition=\"" + importCondition + "\"" : String.Empty) + ">"; - destination.AppendChild(destinationDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n" + importTag + "\r\n\r\n" + resolved.FullPath.Replace("--", "__") + "\r\n" + new String('=', 140) + "\r\n")); + string sdk = importSdk.Length > 0 ? $" {XMakeAttributes.sdk}=\"{importSdk}\"" : String.Empty; + string importTag = + $" "; + + if (((XmlElement)child).GetAttribute(XMakeAttributes.@implicit).Length > 0) + { + importTag = + $" Import of \"{importProject}\" from Sdk \"{importSdk}\" was implied by the {XMakeElements.project} element's {XMakeAttributes.sdk} attribute."; + } + + destination.AppendChild(destinationDocument.CreateComment( + $"\r\n{new String('=', 140)}\r\n{importTag}\r\n\r\n{resolved.FullPath.Replace("--", "__")}\r\n{new String('=', 140)}\r\n")); _filePaths.Push(resolved.FullPath); CloneChildrenResolvingImports(innerDocument, destination); diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index d0910a173fb..91c24e030d3 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -47,7 +47,7 @@ internal class ProjectParser /// /// Valid attributes on import element /// - private readonly static string[] s_validAttributesOnImport = new string[] { XMakeAttributes.condition, XMakeAttributes.label, XMakeAttributes.project }; + private readonly static string[] s_validAttributesOnImport = new string[] { XMakeAttributes.condition, XMakeAttributes.label, XMakeAttributes.project, XMakeAttributes.sdk, XMakeAttributes.@implicit }; /// /// Valid attributes on usingtask element @@ -187,45 +187,54 @@ private void ParseProjectElement(XmlElementWithLocation element) // so we have to set it now _project.SetProjectRootElementFromParser(element, _project); - ParseProjectRootElementChildren(element); - } - - /// - /// Parse the child of a ProjectRootElement - /// - private void ParseProjectRootElementChildren(XmlElementWithLocation element) - { - string initialImportPath = null; - string finalImportPath = null; - if (element.HasAttribute("Sdk")) { // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop // TODO: version? - initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), - element.GetAttribute("Sdk"), "Sdk.props"); + // TODO: multiples - finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), + // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. + var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), + element.GetAttribute("Sdk"), "Sdk.props"); + var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), element.GetAttribute("Sdk"), "Sdk.targets"); - } - if (initialImportPath != null && File.Exists(initialImportPath)) - { - ProjectElement child = ProjectImportElement.CreateDisconnected(initialImportPath, _project, - isImplicit: true); - _project.PrependChild(child); + if (File.Exists(initialImportPath)) + { + var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + + // TODO: make this + implicitImportElement.SetAttribute(XMakeAttributes.project, + initialImportPath); + implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {element.GetAttribute("Sdk")}"); + implicitImportElement.SetAttribute(XMakeAttributes.sdk, element.GetAttribute("Sdk")); + + element.PrependChild(implicitImportElement); + } - //var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + if (File.Exists(finalImportPath)) + { + var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - //implicitImportElement.SetAttribute(XMakeAttributes.project, - // initialImportPath); + // TODO: make this + implicitImportElement.SetAttribute(XMakeAttributes.project, + finalImportPath); + implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {element.GetAttribute("Sdk")}"); + implicitImportElement.SetAttribute(XMakeAttributes.sdk, element.GetAttribute("Sdk")); - //// TODO: make this + element.AppendChild(implicitImportElement); + } - //element.PrependChild(implicitImportElement); } + ParseProjectRootElementChildren(element); + } + /// + /// Parse the child of a ProjectRootElement + /// + private void ParseProjectRootElementChildren(XmlElementWithLocation element) + { foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; @@ -282,23 +291,6 @@ private void ParseProjectRootElementChildren(XmlElementWithLocation element) _project.AppendParentedChildNoChecks(child); } - - - if (finalImportPath!= null && File.Exists(finalImportPath)) - { - ProjectElement child = ProjectImportElement.CreateDisconnected(finalImportPath, _project, - isImplicit: true); - _project.AppendChild(child); - - //var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - //implicitImportElement.SetAttribute(XMakeAttributes.project, - // finalImportPath); - - //// TODO: make this - - //element.AppendChild(implicitImportElement); - } } /// From d408ca307903c9d08600b46fd989abd55dff6f2e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 16:59:07 -0600 Subject: [PATCH 111/223] Make Implicit field public so it can be observed from the public OM --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 1 + src/XMakeBuildEngine/Construction/ProjectImportElement.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 13424e130a9..3e152d97305 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -83,6 +83,7 @@ public override void CopyFrom(Microsoft.Build.Construction.ProjectElement elemen public partial class ProjectImportElement : Microsoft.Build.Construction.ProjectElement { internal ProjectImportElement() { } + public bool Implicit { get { throw null; } } public string Project { get { throw null; } set { } } public Microsoft.Build.Construction.ElementLocation ProjectLocation { get { throw null; } } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index 5fd0b6ac781..cadc341a1ac 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -59,7 +59,8 @@ public string Project /// /// Gets the Implicit state of the element: true if the element was not in the read XML. /// - internal bool Implicit + // TODO: *should* this be public? if it's not, you can't determine if an import is implicit from the public OM. + public bool Implicit { get { return XmlElement.HasAttribute(XMakeAttributes.@implicit); } } From 7b81fdfeae3d75bafbd121c2e5a8389e08769a0d Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 16:59:44 -0600 Subject: [PATCH 112/223] Disposable TemporaryEnvironment --- src/Shared/UnitTests/ObjectModelHelpers.cs | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/Shared/UnitTests/ObjectModelHelpers.cs b/src/Shared/UnitTests/ObjectModelHelpers.cs index 1dba58015d9..acf81244c13 100644 --- a/src/Shared/UnitTests/ObjectModelHelpers.cs +++ b/src/Shared/UnitTests/ObjectModelHelpers.cs @@ -1513,6 +1513,7 @@ public AlternativeTempPath() Path = System.IO.Path.GetFullPath($"TMP_{Guid.NewGuid()}"); Directory.CreateDirectory(_path); + // TODO: this could use TemporaryEnvironment _oldtempPaths = SetTempPath(_path); } @@ -1581,6 +1582,40 @@ private static TempPaths GetTempPaths() } } + internal class TemporaryEnvironment : IDisposable + { + private bool _disposed; + private readonly string _name; + private readonly string _originalValue; + + public TemporaryEnvironment(string name, string value) + { + _name = name; + _originalValue = Environment.GetEnvironmentVariable(name); + + Environment.SetEnvironmentVariable(name, value); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + Environment.SetEnvironmentVariable(_name, _originalValue); + } + + _disposed = true; + } + } + } + internal class TestProjectWithFiles : IDisposable { private bool _disposed; From ef4b933992b0abfe2ba336c9dddfa240189534fd Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 17:00:01 -0600 Subject: [PATCH 113/223] What? you want a TEST? --- .../ProjectImportElement_Tests.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs index ddb95a5330e..72f65602515 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs @@ -287,5 +287,47 @@ public void ImportWithRelativePath() } } } + + [Fact] + public void SdkImportsAreInImportList() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, string.Empty); + File.WriteAllText(sdkTargetsPath, string.Empty); + + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) + { + string content = @" + + "; + + ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); + + List imports = Helpers.MakeList(project.Imports); + + Assert.Equal(2, imports.Count); + Assert.Equal(sdkPropsPath, imports[0].Project); + Assert.True(imports[0].Implicit); + Assert.Equal(sdkTargetsPath, imports[1].Project); + Assert.True(imports[1].Implicit); + } + } + finally + { + if (Directory.Exists(testSdkDirectory)) + { + FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); + } + } + } } } From 769ce6b3dd5d216a8d5f4b8a15a831552d3b3eaf Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 18:23:26 -0600 Subject: [PATCH 114/223] Do not require additional files in CreateFilesInDirectory --- src/Shared/UnitTests/ObjectModelHelpers.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Shared/UnitTests/ObjectModelHelpers.cs b/src/Shared/UnitTests/ObjectModelHelpers.cs index acf81244c13..cde7435aa1b 100644 --- a/src/Shared/UnitTests/ObjectModelHelpers.cs +++ b/src/Shared/UnitTests/ObjectModelHelpers.cs @@ -1264,6 +1264,11 @@ internal static string[] CreateFiles(params string[] files) /// internal static string[] CreateFilesInDirectory(string rootDirectory, params string[] files) { + if (files == null) + { + return null; + } + Assert.True(Directory.Exists(rootDirectory), $"Directory {rootDirectory} does not exist"); var result = new string[files.Length]; From 0aa0ef0039e79d029ce7def3ae6148ebef9cacf0 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 23 Nov 2016 18:24:14 -0600 Subject: [PATCH 115/223] Test to verify that editing via the OM doesn't serialize implicit imports (it currently does) --- .../Construction/ConstructionEditing_Tests.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs index 6f5e4401a47..74c9d2271b9 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs @@ -3199,6 +3199,62 @@ private static string ComposeExpectedProjectString(string expectedItem) return expected; } + /// + /// Add a property to an empty project + /// should add to new property group + /// + [Fact] + public void AddProperty_WithSdk_KeepsSdkAndImplicitImports() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, ""); + File.WriteAllText(sdkTargetsPath, ""); + + using (new Helpers.TemporaryEnvironment("MSBUILDMAGICIMPORTDIRECTORY", testSdkRoot)) + { + using (var testProject = new Helpers.TestProjectWithFiles(@" + + ", null)) + { + + string content = @" + + "; + + File.WriteAllText(testProject.ProjectFile, content); + + var p = new Project(testProject.ProjectFile); + + var addedProperty = p.Xml.AddProperty("propName", "propValue"); + + var updated = Path.Combine(testProject.TestRoot, "updated.proj"); + + p.Save(updated); + + var updatedContents = File.ReadAllText(updated); + + Assert.False(updatedContents.Contains(" Date: Sat, 26 Nov 2016 23:31:59 -0800 Subject: [PATCH 116/223] Use MSBuildSDKsPath environment variable for path to Sdks --- src/XMakeBuildEngine/Evaluation/Preprocessor.cs | 2 ++ src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 9 +++++---- .../Construction/ConstructionEditing_Tests.cs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs index f47913b4381..58359da06fd 100644 --- a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs +++ b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs @@ -93,6 +93,8 @@ private XmlDocument Preprocess() XmlDocument destinationDocument = (XmlDocument)outerDocument.CloneNode(false /* shallow */); + // TODO: Remove Sdk attribute from destination document and put it in a comment (so that if you do a build on a preprocessed file it won't try to import the Sdk imports twice) + _filePaths.Push(_project.FullPath); if (!String.IsNullOrEmpty(_project.FullPath)) // Ignore in-memory projects diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 91c24e030d3..a96ea3cd430 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -192,12 +192,13 @@ private void ParseProjectElement(XmlElementWithLocation element) // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop // TODO: version? // TODO: multiples + // TODO: Don't null ref if MSBuildSDKsPath isn't defined // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. - var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), - element.GetAttribute("Sdk"), "Sdk.props"); - var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBUILDMAGICIMPORTDIRECTORY"), - element.GetAttribute("Sdk"), "Sdk.targets"); + var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + element.GetAttribute("Sdk"), "Sdk", "Sdk.props"); + var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + element.GetAttribute("Sdk"), "Sdk", "Sdk.targets"); if (File.Exists(initialImportPath)) { diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs index 74c9d2271b9..9cf21a3abd3 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs @@ -3219,7 +3219,7 @@ public void AddProperty_WithSdk_KeepsSdkAndImplicitImports() File.WriteAllText(sdkPropsPath, ""); File.WriteAllText(sdkTargetsPath, ""); - using (new Helpers.TemporaryEnvironment("MSBUILDMAGICIMPORTDIRECTORY", testSdkRoot)) + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) { using (var testProject = new Helpers.TestProjectWithFiles(@" From e5c9de95e299366c9c58d6f5db8c46423d2c292b Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 28 Nov 2016 10:59:38 -0600 Subject: [PATCH 117/223] Remove implicit elements from XML at Save() time --- .../Construction/ProjectRootElement.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index e7f1fa2e244..dccc3ca2844 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -1745,8 +1745,23 @@ public void Save(Encoding saveEncoding) { using (ProjectWriter projectWriter = new ProjectWriter(_projectFileLocation.File, saveEncoding)) { - projectWriter.Initialize(XmlDocument); - XmlDocument.Save(projectWriter); + var xmlWithNoImplicits = (XmlDocument)XmlDocument.Clone(); + + var implicitElements = + xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); + + if (implicitElements == null) + { + ErrorUtilities.ThrowInternalError("SelectNodes returned null when trying to find implicit elements."); + } + + foreach (XmlNode implicitElement in implicitElements) + { + implicitElement.ParentNode.RemoveChild(implicitElement); + } + + projectWriter.Initialize(xmlWithNoImplicits); + xmlWithNoImplicits.Save(projectWriter); } _encoding = saveEncoding; From 291254db2bee0dd742c3f2bd3321091c92f8252b Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 28 Nov 2016 13:05:14 -0600 Subject: [PATCH 118/223] Multiple ;-delimited Sdks in Project attribute --- .../Evaluation/ProjectParser.cs | 65 ++++++++++--------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index a96ea3cd430..f57eaf34c77 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -191,41 +191,46 @@ private void ParseProjectElement(XmlElementWithLocation element) { // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop // TODO: version? - // TODO: multiples - // TODO: Don't null ref if MSBuildSDKsPath isn't defined + // TODO: Don't null ref if MSBuildSDKsPath isn't defined - // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. - var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), - element.GetAttribute("Sdk"), "Sdk", "Sdk.props"); - var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), - element.GetAttribute("Sdk"), "Sdk", "Sdk.targets"); + var sdksString = element.GetAttribute("Sdk"); - if (File.Exists(initialImportPath)) - { - var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - // TODO: make this - implicitImportElement.SetAttribute(XMakeAttributes.project, - initialImportPath); - implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {element.GetAttribute("Sdk")}"); - implicitImportElement.SetAttribute(XMakeAttributes.sdk, element.GetAttribute("Sdk")); - - element.PrependChild(implicitImportElement); - } + var sdkNames = sdksString.Contains(";") ? sdksString.Split(';') : new[] {sdksString}; - if (File.Exists(finalImportPath)) + foreach (var sdkName in sdkNames) { - var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - // TODO: make this - implicitImportElement.SetAttribute(XMakeAttributes.project, - finalImportPath); - implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {element.GetAttribute("Sdk")}"); - implicitImportElement.SetAttribute(XMakeAttributes.sdk, element.GetAttribute("Sdk")); - - element.AppendChild(implicitImportElement); + // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. + var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + sdkName, "Sdk", "Sdk.props"); + var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + sdkName, "Sdk", "Sdk.targets"); + + if (File.Exists(initialImportPath)) + { + var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + + // TODO: make this + implicitImportElement.SetAttribute(XMakeAttributes.project, + initialImportPath); + implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {sdkName}"); + implicitImportElement.SetAttribute(XMakeAttributes.sdk, sdkName); + + element.PrependChild(implicitImportElement); + } + + if (File.Exists(finalImportPath)) + { + var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); + + // TODO: make this + implicitImportElement.SetAttribute(XMakeAttributes.project, + finalImportPath); + implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {sdkName}"); + implicitImportElement.SetAttribute(XMakeAttributes.sdk, sdkName); + + element.AppendChild(implicitImportElement); + } } - } ParseProjectRootElementChildren(element); From 7419c055c8b4354a140d2947f4b6fcbc6f79c41a Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 28 Nov 2016 13:30:01 -0600 Subject: [PATCH 119/223] Use named constant for Sdk attribute --- src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index f57eaf34c77..4d8906e6e2f 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -187,13 +187,13 @@ private void ParseProjectElement(XmlElementWithLocation element) // so we have to set it now _project.SetProjectRootElementFromParser(element, _project); - if (element.HasAttribute("Sdk")) + if (element.HasAttribute(XMakeAttributes.sdk)) { // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop // TODO: version? // TODO: Don't null ref if MSBuildSDKsPath isn't defined - var sdksString = element.GetAttribute("Sdk"); + var sdksString = element.GetAttribute(XMakeAttributes.sdk); var sdkNames = sdksString.Contains(";") ? sdksString.Split(';') : new[] {sdksString}; From 7603edf22e4bf20041c305f07d20eed6920cd4db Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 30 Nov 2016 08:46:28 -0800 Subject: [PATCH 120/223] Fix error code from bad merge (#1411) --- src/XMakeCommandLine/Resources/Strings.resx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/XMakeCommandLine/Resources/Strings.resx b/src/XMakeCommandLine/Resources/Strings.resx index 7af49bc1705..f2786756359 100644 --- a/src/XMakeCommandLine/Resources/Strings.resx +++ b/src/XMakeCommandLine/Resources/Strings.resx @@ -991,9 +991,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. A file location to be embedded in a string. - MSBUILD : error MSB1050: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. - {StrBegin="MSBUILD : error MSB1050: "} + {StrBegin="MSBUILD : error MSB1051: "} UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. @@ -1002,7 +1002,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. From d398f20ef19d26feae149e8472dc531549a937cb Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 28 Nov 2016 13:30:09 -0600 Subject: [PATCH 121/223] Allow version specifier in Project Sdk attribute We expect to treat versions specified after a slash in the Sdk attribute as a "minimum supported version", but that is not fully designed yet. For the first iteration of Sdk support, ignore the version entirely, but allow it to be specified. --- src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 4d8906e6e2f..3ebed23d5c7 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -190,15 +190,25 @@ private void ParseProjectElement(XmlElementWithLocation element) if (element.HasAttribute(XMakeAttributes.sdk)) { // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop - // TODO: version? // TODO: Don't null ref if MSBuildSDKsPath isn't defined var sdksString = element.GetAttribute(XMakeAttributes.sdk); - var sdkNames = sdksString.Contains(";") ? sdksString.Split(';') : new[] {sdksString}; + var sdks = sdksString.Contains(";") ? sdksString.Split(';') : new[] {sdksString}; - foreach (var sdkName in sdkNames) + foreach (var sdk in sdks) { + var slashIndex = sdk.LastIndexOf("/", StringComparison.Ordinal); + string sdkName = slashIndex > 0 ? sdk.Substring(0, slashIndex) : sdk; + + // TODO: do something other than just ignore the version + + if (sdkName.Contains("/")) + { + ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.sdk), + "InvalidSdkFormatTooManySlashes"); + } + // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), sdkName, "Sdk", "Sdk.props"); From e30f3d332e1275198fcf7c542c153b5e3041835d Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 28 Nov 2016 14:10:35 -0600 Subject: [PATCH 122/223] [Test Needed] Error on file containing _Implicit attr --- src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 3ebed23d5c7..38f20ead98a 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -573,6 +573,16 @@ private ProjectImportElement ParseProjectImportElement(XmlElementWithLocation el ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); + if (element.HasAttribute(XMakeAttributes.@implicit)) + { + // the implicit attribute is only allowed on Import, but only if MSBuild itself + // put it there. If a user specified it in a project, error just like we would + // when encountering an unknown attribute. + ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute( + element.Location.Line == 0 && element.Location.Column == 0, + element.GetAttributeWithLocation(XMakeAttributes.@implicit)); + } + return new ProjectImportElement(element, parent, _project); } From 350e21b8f71104bacb1e306289fd5f9be5f6d676 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 11:16:49 -0600 Subject: [PATCH 123/223] Sdk Preprocessor output test --- .../Evaluation/Preprocessor_Tests.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs index 420116641ad..71acdfd07e5 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs @@ -844,5 +844,96 @@ public void ProjectMetadata() Helpers.VerifyAssertLineByLine(expected, writer.ToString()); } + + [Fact] + public void SdkImportsAreInPreprocessedOutput() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk", "Sdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, @" + + true + +"); + File.WriteAllText(sdkTargetsPath, @" + + true + +"); + + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) + { + string content = @" + +

v1

+
+
"; + + var project = new Project(ProjectRootElement.Create(XmlReader.Create(new StringReader(content)))); + + StringWriter writer = new StringWriter(); + + project.SaveLogicalProject(writer); + + string expected = ObjectModelHelpers.CleanupFileContents( + $@" + + + + true + + + +

v1

+
+ + + true + + +
"); + Helpers.VerifyAssertLineByLine(expected, writer.ToString()); + } + } + finally + { + if (Directory.Exists(testSdkDirectory)) + { + FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); + } + } + } } } From 9f11ecf207dc3d17d1b79caaeb249e0ab666ec2e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 11:39:11 -0600 Subject: [PATCH 124/223] Move ProjectSdkImplicitImport tests to own file --- .../ProjectImportElement_Tests.cs | 42 ------------- .../ProjectSdkImplicitImport_Tests.cs | 63 +++++++++++++++++++ ...Microsoft.Build.Engine.OM.UnitTests.csproj | 1 + 3 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs index 72f65602515..ddb95a5330e 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectImportElement_Tests.cs @@ -287,47 +287,5 @@ public void ImportWithRelativePath() } } } - - [Fact] - public void SdkImportsAreInImportList() - { - var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); - var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk"); - - try - { - Directory.CreateDirectory(testSdkDirectory); - - string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); - string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); - - File.WriteAllText(sdkPropsPath, string.Empty); - File.WriteAllText(sdkTargetsPath, string.Empty); - - using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) - { - string content = @" - - "; - - ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); - - List imports = Helpers.MakeList(project.Imports); - - Assert.Equal(2, imports.Count); - Assert.Equal(sdkPropsPath, imports[0].Project); - Assert.True(imports[0].Implicit); - Assert.Equal(sdkTargetsPath, imports[1].Project); - Assert.True(imports[1].Implicit); - } - } - finally - { - if (Directory.Exists(testSdkDirectory)) - { - FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); - } - } - } } } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs new file mode 100644 index 00000000000..b2f68db4c8e --- /dev/null +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +//----------------------------------------------------------------------- + +using System.Collections.Generic; +using System.IO; +using System.Xml; +using Microsoft.Build.Construction; +using Microsoft.Build.Shared; +using Xunit; + +namespace Microsoft.Build.UnitTests.OM.Construction +{ + /// + /// Tests for the ProjectImportElement class when imports are implicit through an Sdk specification. + /// + public class ProjectSdkImplicitImport_Tests + { + [Fact] + public void SdkImportsAreInImportList() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk", "Sdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, ""); + File.WriteAllText(sdkTargetsPath, ""); + + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) + { + string content = @" + + "; + + ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); + + List imports = Helpers.MakeList(project.Imports); + + Assert.Equal(2, imports.Count); + Assert.Equal(sdkPropsPath, imports[0].Project); + Assert.True(imports[0].Implicit); + Assert.Equal(sdkTargetsPath, imports[1].Project); + Assert.True(imports[1].Implicit); + } + } + finally + { + if (Directory.Exists(testSdkRoot)) + { + FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); + } + } + } + + + } +} diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj index 2304aeb7c2e..f2291356166 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj @@ -85,6 +85,7 @@ + From 2fa8e4e3394981cb331c15b1af259c15a58b7d0b Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 14:30:47 -0600 Subject: [PATCH 125/223] Use Implicit instead of HasXmlRepresentation --- src/XMakeBuildEngine/Construction/ProjectElement.cs | 5 +++++ .../Construction/ProjectElementContainer.cs | 13 ++----------- .../Construction/ProjectImportElement.cs | 10 ---------- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectElement.cs b/src/XMakeBuildEngine/Construction/ProjectElement.cs index 9dc045eee1b..bf02acc75f9 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElement.cs @@ -292,6 +292,11 @@ public ElementLocation Location get { return XmlElement.Location; } } + /// + /// Gets the Implicit state of the element: true if the element was not in the read XML. + /// + public bool Implicit => XmlElement.HasAttribute(XMakeAttributes.@implicit); + /// /// Gets the name of the associated element. /// Useful for display in some circumstances. diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index d6c82e9b2ad..f24ffe3e5c8 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -455,7 +455,7 @@ internal void UpdateElementValue(ProjectElement child) /// internal void AddToXml(ProjectElement child) { - if (!HasXmlRepresentation(child)) + if (child.Implicit) { return; } @@ -545,15 +545,6 @@ internal void AddToXml(ProjectElement child) } } - private static bool HasXmlRepresentation(ProjectElement element) - { - // The implicit-import element is special: it has no direct representation in the - // Xml tree. It's implied by other parts of the project file but exists directly - // only on the ProjectElement side. - - return (element as ProjectImportElement)?.Implicit != true; - } - private string GetElementIndentation(XmlElementWithLocation xmlElement) { if (xmlElement.PreviousSibling?.NodeType != XmlNodeType.Whitespace) @@ -634,7 +625,7 @@ private void AddInitialChild(ProjectElement child) _count++; - if (HasXmlRepresentation(child)) + if (!child.Implicit) { MarkDirty("Add child element named '{0}'", child.ElementName); } diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index cadc341a1ac..c03ed0f3fc4 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -56,16 +56,6 @@ public string Project } } - /// - /// Gets the Implicit state of the element: true if the element was not in the read XML. - /// - // TODO: *should* this be public? if it's not, you can't determine if an import is implicit from the public OM. - public bool Implicit - { - get { return XmlElement.HasAttribute(XMakeAttributes.@implicit); } - } - - /// /// Location of the project attribute /// From c08546363a828c9aec9520030483af6bd3bd607e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 14:46:56 -0600 Subject: [PATCH 126/223] Implicit -> IsImplicit This better matches the MSBuild convention. --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 2 +- ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs | 1 + src/XMakeBuildEngine/Construction/ProjectElement.cs | 2 +- src/XMakeBuildEngine/Construction/ProjectElementContainer.cs | 4 ++-- .../Construction/ProjectSdkImplicitImport_Tests.cs | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 3e152d97305..e2b87002e6c 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -39,6 +39,7 @@ internal ProjectElement() { } public virtual string Condition { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public virtual Microsoft.Build.Construction.ElementLocation ConditionLocation { get { throw null; } } public Microsoft.Build.Construction.ProjectRootElement ContainingProject { get { throw null; } } + public bool IsImplicit { get { throw null; } } public string Label { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public Microsoft.Build.Construction.ElementLocation LabelLocation { get { throw null; } } public Microsoft.Build.Construction.ElementLocation Location { get { throw null; } } @@ -83,7 +84,6 @@ public override void CopyFrom(Microsoft.Build.Construction.ProjectElement elemen public partial class ProjectImportElement : Microsoft.Build.Construction.ProjectElement { internal ProjectImportElement() { } - public bool Implicit { get { throw null; } } public string Project { get { throw null; } set { } } public Microsoft.Build.Construction.ElementLocation ProjectLocation { get { throw null; } } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } diff --git a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs index d51300a1016..cd0cf466b78 100644 --- a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs +++ b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs @@ -39,6 +39,7 @@ internal ProjectElement() { } public virtual string Condition { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public virtual Microsoft.Build.Construction.ElementLocation ConditionLocation { get { throw null; } } public Microsoft.Build.Construction.ProjectRootElement ContainingProject { get { throw null; } } + public bool IsImplicit { get { throw null; } } public string Label { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public Microsoft.Build.Construction.ElementLocation LabelLocation { get { throw null; } } public Microsoft.Build.Construction.ElementLocation Location { get { throw null; } } diff --git a/src/XMakeBuildEngine/Construction/ProjectElement.cs b/src/XMakeBuildEngine/Construction/ProjectElement.cs index bf02acc75f9..2cd34d3a166 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElement.cs @@ -295,7 +295,7 @@ public ElementLocation Location /// /// Gets the Implicit state of the element: true if the element was not in the read XML. /// - public bool Implicit => XmlElement.HasAttribute(XMakeAttributes.@implicit); + public bool IsImplicit => XmlElement.HasAttribute(XMakeAttributes.@implicit); /// /// Gets the name of the associated element. diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index f24ffe3e5c8..7df034ab0ca 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -455,7 +455,7 @@ internal void UpdateElementValue(ProjectElement child) /// internal void AddToXml(ProjectElement child) { - if (child.Implicit) + if (child.IsImplicit) { return; } @@ -625,7 +625,7 @@ private void AddInitialChild(ProjectElement child) _count++; - if (!child.Implicit) + if (!child.IsImplicit) { MarkDirty("Add child element named '{0}'", child.ElementName); } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs index b2f68db4c8e..d76da60d6c2 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs @@ -44,9 +44,9 @@ public void SdkImportsAreInImportList() Assert.Equal(2, imports.Count); Assert.Equal(sdkPropsPath, imports[0].Project); - Assert.True(imports[0].Implicit); + Assert.True(imports[0].IsImplicit); Assert.Equal(sdkTargetsPath, imports[1].Project); - Assert.True(imports[1].Implicit); + Assert.True(imports[1].IsImplicit); } } finally From 4dd1af713bcbd96494b873e876ac6b7796a9e02e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 15:29:01 -0600 Subject: [PATCH 127/223] Remove SelectNodes null check (just fail if it goes that wrong) --- src/XMakeBuildEngine/Construction/ProjectRootElement.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index dccc3ca2844..47fd87e87cc 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -1750,11 +1750,6 @@ public void Save(Encoding saveEncoding) var implicitElements = xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); - if (implicitElements == null) - { - ErrorUtilities.ThrowInternalError("SelectNodes returned null when trying to find implicit elements."); - } - foreach (XmlNode implicitElement in implicitElements) { implicitElement.ParentNode.RemoveChild(implicitElement); From 61e14a8a482d6b01e4773474c33e932e20c99a8e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 15:31:57 -0600 Subject: [PATCH 128/223] Remove misleading ProjectLocation remark --- src/XMakeBuildEngine/Construction/ProjectImportElement.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index c03ed0f3fc4..1bf6cfc9269 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -59,9 +59,6 @@ public string Project /// /// Location of the project attribute /// - /// - /// For an implicit import, the location points to the Sdk attribute on the Project element. - /// public ElementLocation ProjectLocation => XmlElement.GetAttributeLocation(XMakeAttributes.project); /// From f9e09eb88d43f9652df5e86dc7108b83ffc37e07 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 15:35:50 -0600 Subject: [PATCH 129/223] Preprocess Sdk attr for conditioned imports too --- src/XMakeBuildEngine/Evaluation/Preprocessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs index 58359da06fd..db777a63236 100644 --- a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs +++ b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs @@ -171,13 +171,14 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) string condition = importCondition.Length > 0 ? $" Condition=\"{importCondition}\"" : String.Empty; string importProject = ((XmlElement)child).GetAttribute(XMakeAttributes.project); string importSdk = ((XmlElement)child).GetAttribute(XMakeAttributes.sdk); + string sdk = importSdk.Length > 0 ? $" {XMakeAttributes.sdk}=\"{importSdk}\"" : String.Empty; IList resolvedList; if (!_importTable.TryGetValue(child as XmlElement, out resolvedList)) { // Import didn't resolve to anything; just display as a comment and move on string closedImportTag = - $""; + $""; destination.AppendChild(destinationDocument.CreateComment(closedImportTag)); continue; @@ -188,7 +189,6 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) ProjectRootElement resolved = resolvedList[i]; XmlDocument innerDocument = resolved.XmlDocument; - string sdk = importSdk.Length > 0 ? $" {XMakeAttributes.sdk}=\"{importSdk}\"" : String.Empty; string importTag = $" "; From b47e0e073095a940f2f50a5fc3e9e4c48e560077 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 29 Nov 2016 17:31:52 -0600 Subject: [PATCH 130/223] Add string error for badly-formed Sdk attribute --- src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 2 +- src/XMakeBuildEngine/Resources/Strings.resx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 38f20ead98a..dbf0ff10d7b 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -206,7 +206,7 @@ private void ParseProjectElement(XmlElementWithLocation element) if (sdkName.Contains("/")) { ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.sdk), - "InvalidSdkFormatTooManySlashes"); + "InvalidSdkFormat"); } // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. diff --git a/src/XMakeBuildEngine/Resources/Strings.resx b/src/XMakeBuildEngine/Resources/Strings.resx index f59ea3b00b0..ba2599043ae 100644 --- a/src/XMakeBuildEngine/Resources/Strings.resx +++ b/src/XMakeBuildEngine/Resources/Strings.resx @@ -1169,6 +1169,10 @@ MSB4228: The name "{0}" is not valid for metadata expressed as an attribute (on element <{1}>) {StrBegin="MSB4228: "} + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + MSB4189: <{1}> is not a valid child of the <{0}> element. {StrBegin="MSB4189: "} From efdb4875b1303d317fe0e431273f32d7f07a9fcf Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 06:57:15 -0600 Subject: [PATCH 131/223] Clone() isn't available in Core --- src/XMakeBuildEngine/Construction/ProjectRootElement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 47fd87e87cc..cc18da73fb0 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -1745,7 +1745,7 @@ public void Save(Encoding saveEncoding) { using (ProjectWriter projectWriter = new ProjectWriter(_projectFileLocation.File, saveEncoding)) { - var xmlWithNoImplicits = (XmlDocument)XmlDocument.Clone(); + var xmlWithNoImplicits = (XmlDocument)XmlDocument.CloneNode(deep: true); var implicitElements = xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); From d83721a9b39c59d67a6c8721d93bae26b65c4eb5 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 07:25:23 -0600 Subject: [PATCH 132/223] Disable GitVersioning in CI to work around #1409 --- src/dir.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dir.targets b/src/dir.targets index 5157ba9a7ce..610cd316957 100644 --- a/src/dir.targets +++ b/src/dir.targets @@ -77,8 +77,8 @@ - + Condition="'$(MSBuildRuntimeType)' == 'Full' and '$(JENKINS_URL)' == ''" /> + $(DefineConstants);STATIC_VERSION_NUMBER From 9801c6d9e76dfc5721f5143e2e051c95fcd20a2b Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 08:24:54 -0600 Subject: [PATCH 133/223] Default MSBuildSDKsPath location to {tools}\Sdks --- src/Shared/BuildEnvironmentHelper.cs | 13 +++++++++++++ src/Shared/Constants.cs | 5 +++++ .../Definition/ToolsetLocalReader.cs | 1 + .../Evaluation/IntrinsicFunctions.cs | 5 +++++ src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 6 ++---- src/XMakeCommandLine/app.amd64.config | 1 + src/XMakeCommandLine/app.config | 1 + 7 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs index 97447eb2e94..374f897424a 100644 --- a/src/Shared/BuildEnvironmentHelper.cs +++ b/src/Shared/BuildEnvironmentHelper.cs @@ -443,6 +443,19 @@ public BuildEnvironment(string processNameCommandLine, bool runningTests, bool r /// internal string MSBuildToolsDirectory64 { get; private set; } + /// + /// Path to the Sdks folder for this MSBuild instance. + /// + internal string MSBuildSDKsPath + { + get + { + // Allow an environment-variable override of the default SDK location + return Environment.GetEnvironmentVariable("MSBuildSDKsPath") ?? + Path.Combine(CurrentMSBuildToolsDirectory, "Sdks"); + } + } + /// /// Full path to the current MSBuild configuration file. /// diff --git a/src/Shared/Constants.cs b/src/Shared/Constants.cs index 99d7a4ffded..17670cc9903 100644 --- a/src/Shared/Constants.cs +++ b/src/Shared/Constants.cs @@ -21,6 +21,11 @@ internal static class MSBuildConstants /// internal const string ToolsPath64 = "MSBuildToolsPath64"; + /// + /// Name of the property that indicates the root of the SDKs folder + /// + internal const string SdksPath = "MSBuildSDKsPath"; + /// /// The most current Visual Studio Version known to this version of MSBuild. /// diff --git a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs index 7b83083536f..ea0961b9a22 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs @@ -57,6 +57,7 @@ protected override IEnumerable ToolsVersions protected override IEnumerable GetPropertyDefinitions(string toolsVersion) { yield return new ToolsetPropertyDefinition(MSBuildConstants.ToolsPath, BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); + yield return new ToolsetPropertyDefinition(MSBuildConstants.SdksPath, BuildEnvironmentHelper.Instance.MSBuildSDKsPath, _sourceLocation); yield return new ToolsetPropertyDefinition("RoslynTargetsPath", BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); } diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index 5c059fc008d..2952b978120 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -390,6 +390,11 @@ public static string GetToolsDirectory64() return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64; } + public static string GetMSBuildSDKsPath() + { + return BuildEnvironmentHelper.Instance.MSBuildSDKsPath; + } + public static string GetVsInstallRoot() { return BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory; diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index dbf0ff10d7b..b6c56acf353 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -189,8 +189,6 @@ private void ParseProjectElement(XmlElementWithLocation element) if (element.HasAttribute(XMakeAttributes.sdk)) { - // TODO: don't get root of SDKs from the environment, use a built-in or toolset prop - // TODO: Don't null ref if MSBuildSDKsPath isn't defined var sdksString = element.GetAttribute(XMakeAttributes.sdk); @@ -210,9 +208,9 @@ private void ParseProjectElement(XmlElementWithLocation element) } // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. - var initialImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + var initialImportPath = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, sdkName, "Sdk", "Sdk.props"); - var finalImportPath = Path.Combine(Environment.GetEnvironmentVariable("MSBuildSDKsPath"), + var finalImportPath = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, sdkName, "Sdk", "Sdk.targets"); if (File.Exists(initialImportPath)) diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index 28e02901c72..580d15eb1fd 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -60,6 +60,7 @@ + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index b5962352ead..5dbaca1e18e 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -54,6 +54,7 @@ + From 46340d4ace9855ba9f7a191094ea1100ab1bdf0f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 30 Nov 2016 09:20:28 -0800 Subject: [PATCH 134/223] Preserve Culture metadata on satellite assemblies (#1404) Satellite assemblies are produced only with TargetPath metadata, which makes rediscovering their culture later in the build very difficult. Simply preserving it as a distinct metadatum makes scenarios such as NuGet packaging of Roslyn analyzers that are localized much easier. --- src/XMakeTasks/Microsoft.Common.CurrentVersion.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets index eaf7a158701..eb0e0786c11 100644 --- a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets @@ -5323,6 +5323,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. %(EmbeddedResource.Culture)\$(TargetName).resources.dll + %(EmbeddedResource.Culture) From 94214d356ccb3d9135aba21ee48046e30ab77a6d Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 12:54:26 -0600 Subject: [PATCH 135/223] Use MSBuildExtensionsPath-equivalent instead of ToolsPath for Sdk parent folder --- src/Shared/BuildEnvironmentHelper.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs index 374f897424a..6c4f0db142e 100644 --- a/src/Shared/BuildEnvironmentHelper.cs +++ b/src/Shared/BuildEnvironmentHelper.cs @@ -450,9 +450,19 @@ internal string MSBuildSDKsPath { get { + string defaultSdkPath; + + if (VisualStudioInstallRootDirectory != null) + { + defaultSdkPath = Path.Combine(VisualStudioInstallRootDirectory, "MSBuild", "Sdks"); + } + else + { + defaultSdkPath = Path.Combine(CurrentMSBuildToolsDirectory, "Sdks"); + } + // Allow an environment-variable override of the default SDK location - return Environment.GetEnvironmentVariable("MSBuildSDKsPath") ?? - Path.Combine(CurrentMSBuildToolsDirectory, "Sdks"); + return Environment.GetEnvironmentVariable("MSBuildSDKsPath") ?? defaultSdkPath; } } From fd8c6560af339d6d9e87cb5346fa4e879d7fa106 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 13:03:45 -0600 Subject: [PATCH 136/223] Use only 2-element Path.Combine for downlevel compat --- src/Shared/BuildEnvironmentHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs index 6c4f0db142e..823f9904f0a 100644 --- a/src/Shared/BuildEnvironmentHelper.cs +++ b/src/Shared/BuildEnvironmentHelper.cs @@ -454,7 +454,8 @@ internal string MSBuildSDKsPath if (VisualStudioInstallRootDirectory != null) { - defaultSdkPath = Path.Combine(VisualStudioInstallRootDirectory, "MSBuild", "Sdks"); + // Can't use the N-argument form of Combine because it doesn't exist on .NET 3.5 + defaultSdkPath = FileUtilities.CombinePaths(VisualStudioInstallRootDirectory, "MSBuild", "Sdks"); } else { From b3f22f8663e5141d035f083d00b1367d4d0cb108 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 13:11:54 -0600 Subject: [PATCH 137/223] Error when importing from non-existent SDK The if-exists checks meant that if you had a badly defined MSBuildSDKsPath or an SDK name that didn't exist, you would get no error and just silently get no imports. That's no good. This adds the implicit import unconditionally, requiring all SDKs to have both an Sdk.props and an Sdk.targets for the moment. --- src/XMakeBuildEngine/Evaluation/ProjectParser.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index b6c56acf353..53b43c2faf3 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -213,7 +213,8 @@ private void ParseProjectElement(XmlElementWithLocation element) var finalImportPath = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, sdkName, "Sdk", "Sdk.targets"); - if (File.Exists(initialImportPath)) + // TODO: don't require all SDKs to have both props and targets + // if (File.Exists(initialImportPath)) { var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); @@ -226,7 +227,8 @@ private void ParseProjectElement(XmlElementWithLocation element) element.PrependChild(implicitImportElement); } - if (File.Exists(finalImportPath)) + // TODO: don't require all SDKs to have both props and targets + // if (File.Exists(finalImportPath)) { var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); From 2b5610ebe60644fdf559c03e26f0814277f786e4 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 13:41:37 -0600 Subject: [PATCH 138/223] Fix AddProperty_WithSdk_KeepsSdkAndImplicitImports --- .../UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs index 9cf21a3abd3..36da85c8a71 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ConstructionEditing_Tests.cs @@ -3207,7 +3207,7 @@ private static string ComposeExpectedProjectString(string expectedItem) public void AddProperty_WithSdk_KeepsSdkAndImplicitImports() { var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); - var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk", "Sdk"); try { From a21ff8cb3c78a0ab01a2ab7334a3d93ffcf95b4e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 16:53:58 -0600 Subject: [PATCH 139/223] Do not reveal implicit elements through RawXml The initial implementation caused errors when editing a project in Visual Studio. The Roslyn Project System uses Project.Xml.RawXml to decide what to show to the user, and handles edits by saving that file. When RawXml had _Implicit elements, that made the first save create an invalid project with a literal _Implicit attribute in its imports (as well as imports from both the Sdk attribute and the now-present Import elements). To fix this, do the same transformation for RawXml that was being done for Save. --- .../Construction/ProjectRootElement.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index cc18da73fb0..7ffab359a19 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -705,8 +705,10 @@ public string RawXml { using (ProjectWriter projectWriter = new ProjectWriter(stringWriter)) { - projectWriter.Initialize(XmlDocument); - XmlDocument.Save(projectWriter); + var xmlWithNoImplicits = RemoveImplicits(); + + projectWriter.Initialize(xmlWithNoImplicits); + xmlWithNoImplicits.Save(projectWriter); } return stringWriter.ToString(); @@ -1745,15 +1747,7 @@ public void Save(Encoding saveEncoding) { using (ProjectWriter projectWriter = new ProjectWriter(_projectFileLocation.File, saveEncoding)) { - var xmlWithNoImplicits = (XmlDocument)XmlDocument.CloneNode(deep: true); - - var implicitElements = - xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); - - foreach (XmlNode implicitElement in implicitElements) - { - implicitElement.ParentNode.RemoveChild(implicitElement); - } + var xmlWithNoImplicits = RemoveImplicits(); projectWriter.Initialize(xmlWithNoImplicits); xmlWithNoImplicits.Save(projectWriter); @@ -1785,6 +1779,20 @@ public void Save(Encoding saveEncoding) #endif } + private XmlDocument RemoveImplicits() + { + var xmlWithNoImplicits = (XmlDocument) XmlDocument.CloneNode(deep: true); + + var implicitElements = + xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); + + foreach (XmlNode implicitElement in implicitElements) + { + implicitElement.ParentNode.RemoveChild(implicitElement); + } + return xmlWithNoImplicits; + } + /// /// Save the project to the file system, if dirty or the path is different. /// Creates any necessary directories. From cad9a09a0fa15bc1101d1cb84ba6c7940715a316 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 17:09:32 -0600 Subject: [PATCH 140/223] Remove implicit nodes on Save(TextWriter) This was missed in e5c9de95e299366c9c58d6f5db8c46423d2c292b. --- src/XMakeBuildEngine/Construction/ProjectRootElement.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 7ffab359a19..3060c0a9781 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -1826,8 +1826,10 @@ public void Save(TextWriter writer) { using (ProjectWriter projectWriter = new ProjectWriter(writer)) { - projectWriter.Initialize(XmlDocument); - XmlDocument.Save(projectWriter); + var xmlWithNoImplicits = RemoveImplicits(); + + projectWriter.Initialize(xmlWithNoImplicits); + xmlWithNoImplicits.Save(projectWriter); } _versionOnDisk = Version; From 1d821a806648e7baa2cb352bbe926465f4e75dfa Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 18:04:52 -0600 Subject: [PATCH 141/223] If there are no implicit elements, do not clone This fixes unit test failures that arose because cloning the XmlDocument caused a spurious `\n` character to be inserted after the XML declaration tag in the saved output. --- .../Construction/ProjectRootElement.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 3060c0a9781..2af810ef0f3 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -157,6 +157,11 @@ public class ProjectRootElement : ProjectElementContainer /// private BuildEventContext _buildEventContext; + /// + /// Xpath expression that will find any element with the implicit attribute + /// + private static readonly string ImplicitAttributeXpath = $"//*[@{XMakeAttributes.@implicit}]"; + /// /// Initialize a ProjectRootElement instance from a XmlReader. /// May throw InvalidProjectFileException. @@ -1781,15 +1786,21 @@ public void Save(Encoding saveEncoding) private XmlDocument RemoveImplicits() { + if (XmlDocument.SelectSingleNode(ImplicitAttributeXpath) == null) + { + return XmlDocument; + } + var xmlWithNoImplicits = (XmlDocument) XmlDocument.CloneNode(deep: true); var implicitElements = - xmlWithNoImplicits.SelectNodes($"//*[@{XMakeAttributes.@implicit}]"); + xmlWithNoImplicits.SelectNodes(ImplicitAttributeXpath); foreach (XmlNode implicitElement in implicitElements) { implicitElement.ParentNode.RemoveChild(implicitElement); } + return xmlWithNoImplicits; } From f4109429878d96627dd699796dfe15df29bbfbf2 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 30 Nov 2016 19:36:20 -0600 Subject: [PATCH 142/223] Update legacy package version number --- src/BuildValues.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index ce1bcc895a2..573d25cb51e 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00076 + 00077 - \ No newline at end of file + From d39a6e815225c7b02b1b902d1c6795e4c9adb8dd Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 30 Nov 2016 23:17:15 -0800 Subject: [PATCH 143/223] Fix more warnings, enable /warnaserror (#1412) * Fix warnings when building .NET Core Most of these were caused because something was #if'd out * Enable warnings as errors in CI Added 3 warnings to the /NoWarn list as well * Fix warning MSB3270 and remove it from the suppression list * Suppress AL1053 --- Samples/Dependency/Dependency.csproj | 2 +- cibuild.cmd | 8 ++++- cibuild.sh | 8 ++++- src/Shared/Compat/TypeExtensions.cs | 18 +++++----- src/Shared/Compat/XmlCharType.cs | 1 - src/Shared/NodeEndpointOutOfProcBase.cs | 6 +++- src/Shared/TaskHostConfiguration.cs | 35 ++++++++++++++++-- .../UnitTests/NativeMethodsShared_Tests.cs | 2 +- ...Microsoft.Build.Utilities.UnitTests.csproj | 2 +- .../UnitTests/ToolLocationHelper_Tests.cs | 2 +- .../Communications/NodeEndpointOutOfProc.cs | 11 ++++-- .../NodeProviderOutOfProcBase.cs | 5 ++- .../BackEnd/Node/NodeConfiguration.cs | 36 +++++++++++++------ .../Collections/ConvertingEnumerable.cs | 4 +-- src/XMakeBuildEngine/Definition/Toolset.cs | 2 ++ .../Definition/ToolsetReader.cs | 2 +- .../Evaluation/IntrinsicFunctions.cs | 2 +- .../UnitTests/BackEnd/TaskBuilder_Tests.cs | 2 ++ .../XmlReaderWithoutLocation_Tests.cs | 2 +- .../Microsoft.Build.Engine.UnitTests.csproj | 3 +- ...Microsoft.Build.Engine.OM.UnitTests.csproj | 2 +- ...crosoft.Build.CommandLine.UnitTests.csproj | 1 + src/XMakeCommandLine/XMake.cs | 2 +- .../AssemblyDependency/AssemblyInformation.cs | 5 +-- src/XMakeTasks/GenerateResource.cs | 12 +++++-- src/XMakeTasks/GetReferenceAssemblyPaths.cs | 2 ++ 26 files changed, 130 insertions(+), 47 deletions(-) diff --git a/Samples/Dependency/Dependency.csproj b/Samples/Dependency/Dependency.csproj index 1f3a5df317f..15f622986a4 100644 --- a/Samples/Dependency/Dependency.csproj +++ b/Samples/Dependency/Dependency.csproj @@ -27,7 +27,7 @@ - + diff --git a/cibuild.cmd b/cibuild.cmd index 5e8ba3862ad..df5eb5e052e 100644 --- a/cibuild.cmd +++ b/cibuild.cmd @@ -139,10 +139,16 @@ if /i "%TARGET%"=="CoreCLR" ( set MSBUILD_CUSTOM_PATH="%~dp0bin\Bootstrap\15.0\Bin\MSBuild.exe" ) +:: The set of warnings to suppress for now +:: warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. +:: warning MSB3026: Could not copy "XXX" to "XXX". Beginning retry 1 in 1000ms. +:: warning AL1053: The version '1.2.3.4-foo' specified for the 'product version' is not in the normal 'major.minor.build.revision' format +SET _NOWARN=MSB3277;MSB3026;AL1053 + echo. echo ** Rebuilding MSBuild with locally built binaries -call "%~dp0build.cmd" /t:%TARGET_ARG% /p:Configuration=%BUILD_CONFIGURATION% %LOCALIZED_BUILD_ARGUMENT% +call "%~dp0build.cmd" /t:%TARGET_ARG% /p:Configuration=%BUILD_CONFIGURATION% %LOCALIZED_BUILD_ARGUMENT% "/nowarn:%_NOWARN%" /warnaserror if %ERRORLEVEL% NEQ 0 ( echo. diff --git a/cibuild.sh b/cibuild.sh index 8c79b372e4f..5ded7aa3ae7 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -298,6 +298,12 @@ if [[ $BOOTSTRAP_ONLY = true ]]; then exit $? fi +# The set of warnings to suppress for now +# warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. +# warning MSB3026: Could not copy "XXX" to "XXX". Beginning retry 1 in 1000ms. +# warning AL1053: The version '1.2.3.4-foo' specified for the 'product version' is not in the normal 'major.minor.build.revision' format +_NOWARN="MSB3277;MSB3026;AL1053" + echo echo "** Rebuilding MSBuild with locally built binaries" -runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_BOOTSTRAPPED_EXE" "/t:$TARGET_ARG $BUILD_MSBUILD_ARGS" "$LOCAL_BUILD_LOG_PATH" +runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_BOOTSTRAPPED_EXE" "/t:$TARGET_ARG $BUILD_MSBUILD_ARGS /warnaserror /nowarn:\"$_NOWARN\"" "$LOCAL_BUILD_LOG_PATH" diff --git a/src/Shared/Compat/TypeExtensions.cs b/src/Shared/Compat/TypeExtensions.cs index 9f47fad072b..43495511ded 100644 --- a/src/Shared/Compat/TypeExtensions.cs +++ b/src/Shared/Compat/TypeExtensions.cs @@ -577,15 +577,15 @@ private static bool FilterApplyMethodBase( { testForParamArray = true; } - else - { - // From our existing code, our policy here is that if a parameterInfo - // is optional then all subsequent parameterInfos shall be optional. - - // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate. - if (!parameterInfos[argumentTypes.Length].IsOptional) - testForParamArray = true; - } + //else + //{ + // // From our existing code, our policy here is that if a parameterInfo + // // is optional then all subsequent parameterInfos shall be optional. + + // // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate. + // if (!parameterInfos[argumentTypes.Length].IsOptional) + // testForParamArray = true; + //} #endregion } diff --git a/src/Shared/Compat/XmlCharType.cs b/src/Shared/Compat/XmlCharType.cs index 46237198c2f..72bf292fc21 100644 --- a/src/Shared/Compat/XmlCharType.cs +++ b/src/Shared/Compat/XmlCharType.cs @@ -21,7 +21,6 @@ namespace System.Xml { - /// /// /// /// The XmlCharType class is used for quick character type recognition diff --git a/src/Shared/NodeEndpointOutOfProcBase.cs b/src/Shared/NodeEndpointOutOfProcBase.cs index 54529e2a714..78190e4ae15 100644 --- a/src/Shared/NodeEndpointOutOfProcBase.cs +++ b/src/Shared/NodeEndpointOutOfProcBase.cs @@ -458,7 +458,11 @@ private void PacketPumpProc() } #endif } - catch (IOException e) + catch (IOException +#if FEATURE_NAMED_PIPES_FULL_DUPLEX + e +#endif + ) { // We will get here when: // 1. The host (OOP main node) connects to us, it immediately checks for user privileges diff --git a/src/Shared/TaskHostConfiguration.cs b/src/Shared/TaskHostConfiguration.cs index 156f181d778..612e5440fa3 100644 --- a/src/Shared/TaskHostConfiguration.cs +++ b/src/Shared/TaskHostConfiguration.cs @@ -92,6 +92,7 @@ internal class TaskHostConfiguration : INodePacket /// private Dictionary _taskParameters; +#if FEATURE_APPDOMAIN /// /// Constructor /// @@ -115,9 +116,7 @@ public TaskHostConfiguration IDictionary buildProcessEnvironment, CultureInfo culture, CultureInfo uiCulture, -#if FEATURE_APPDOMAIN AppDomainSetup appDomainSetup, -#endif int lineNumberOfTask, int columnNumberOfTask, string projectFileOfTask, @@ -126,6 +125,38 @@ public TaskHostConfiguration string taskLocation, IDictionary taskParameters ) +#else + /// + /// Constructor + /// + /// The ID of the node being configured. + /// The startup directory for the task being executed. + /// The set of environment variables to apply to the task execution process. + /// The culture of the thread that will execute the task. + /// The UI culture of the thread that will execute the task. + /// The line number of the location from which this task was invoked. + /// The column number of the location from which this task was invoked. + /// The project file from which this task was invoked. + /// Flag to continue with the build after a the task failed + /// Name of the task. + /// Location of the assembly the task is to be loaded from. + /// Parameters to apply to the task. + public TaskHostConfiguration + ( + int nodeId, + string startupDirectory, + IDictionary buildProcessEnvironment, + CultureInfo culture, + CultureInfo uiCulture, + int lineNumberOfTask, + int columnNumberOfTask, + string projectFileOfTask, + bool continueOnError, + string taskName, + string taskLocation, + IDictionary taskParameters + ) +#endif { ErrorUtilities.VerifyThrowInternalLength(taskName, "taskName"); ErrorUtilities.VerifyThrowInternalLength(taskLocation, "taskLocation"); diff --git a/src/Shared/UnitTests/NativeMethodsShared_Tests.cs b/src/Shared/UnitTests/NativeMethodsShared_Tests.cs index e3a45fdbc05..07ab7a34e17 100644 --- a/src/Shared/UnitTests/NativeMethodsShared_Tests.cs +++ b/src/Shared/UnitTests/NativeMethodsShared_Tests.cs @@ -125,7 +125,7 @@ public void TestGetProcAddress() Assert.NotEqual(processHandle, NativeMethodsShared.NullIntPtr); //Actually call the method - GetProcessIdDelegate processIdDelegate = (GetProcessIdDelegate)Marshal.GetDelegateForFunctionPointer(processHandle, typeof(GetProcessIdDelegate)); + GetProcessIdDelegate processIdDelegate = Marshal.GetDelegateForFunctionPointer(processHandle); uint processId = processIdDelegate(); //Make sure the return value is the same as retrieved from the .net methods to make sure everything works diff --git a/src/Utilities/UnitTests/Microsoft.Build.Utilities.UnitTests.csproj b/src/Utilities/UnitTests/Microsoft.Build.Utilities.UnitTests.csproj index 3f52ec4cca7..734154c6a4f 100644 --- a/src/Utilities/UnitTests/Microsoft.Build.Utilities.UnitTests.csproj +++ b/src/Utilities/UnitTests/Microsoft.Build.Utilities.UnitTests.csproj @@ -63,7 +63,7 @@ - + False $(CompilerToolsDir)\Microsoft.Build.Tasks.CodeAnalysis.dll diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index d46828a90f0..0819318e8d3 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -1091,6 +1091,7 @@ public void GetPathToWindowsSdk() #pragma warning restore 618 +#if FEATURE_CODETASKFACTORY private static string s_verifyToolsetAndToolLocationHelperProjectCommonContent = @" string currentInstallFolderLocation = null; @@ -1144,7 +1145,6 @@ public void GetPathToWindowsSdk() } "; -#if FEATURE_CODETASKFACTORY [Fact] public void VerifyToolsetAndToolLocationHelperAgree() { diff --git a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeEndpointOutOfProc.cs b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeEndpointOutOfProc.cs index f6a0b805166..bab017c9ca3 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeEndpointOutOfProc.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeEndpointOutOfProc.cs @@ -44,6 +44,7 @@ internal class NodeEndpointOutOfProc : NodeEndpointOutOfProcBase #region Constructors and Factories +#if FEATURE_NAMED_PIPES_FULL_DUPLEX /// /// Instantiates an endpoint to act as a client /// @@ -51,13 +52,19 @@ internal class NodeEndpointOutOfProc : NodeEndpointOutOfProcBase /// The component host. /// Whether this node may be reused for a later build. internal NodeEndpointOutOfProc( -#if FEATURE_NAMED_PIPES_FULL_DUPLEX string pipeName, + IBuildComponentHost host, + bool enableReuse) #else + /// + /// Instantiates an endpoint to act as a client + /// + internal NodeEndpointOutOfProc( string clientToServerPipeHandle, string serverToClientPipeHandle, + IBuildComponentHost host, + bool enableReuse) #endif - IBuildComponentHost host, bool enableReuse) { ErrorUtilities.VerifyThrowArgumentNull(host, "host"); _componentHost = host; diff --git a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs index e3827974237..69f8ed7fde2 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs @@ -485,9 +485,6 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) processSecurityAttributes.nLength = Marshal.SizeOf(); threadSecurityAttributes.nLength = Marshal.SizeOf(); - BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION(); - - CommunicationsUtilities.Trace("Launching node from {0}", msbuildLocation); #if RUNTIME_TYPE_NETCORE @@ -523,6 +520,8 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) CommunicationsUtilities.Trace("Successfully launched msbuild.exe node with PID {0}", process.Id); return process.Id; #else + BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION(); + string exeName = msbuildLocation; bool result = BackendNativeMethods.CreateProcess diff --git a/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs b/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs index 19f28325f5a..6bf372bbfbf 100644 --- a/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs +++ b/src/XMakeBuildEngine/BackEnd/Node/NodeConfiguration.cs @@ -39,6 +39,7 @@ internal class NodeConfiguration : INodePacket /// private LoggerDescription[] _forwardingLoggers; +#if FEATURE_APPDOMAIN /// /// Constructor /// @@ -50,19 +51,34 @@ public NodeConfiguration ( int nodeId, BuildParameters buildParameters, - LoggerDescription[] forwardingLoggers -#if FEATURE_APPDOMAIN - , AppDomainSetup appDomainSetup -#endif + LoggerDescription[] forwardingLoggers, + AppDomainSetup appDomainSetup ) { _nodeId = nodeId; _buildParameters = buildParameters; _forwardingLoggers = forwardingLoggers; -#if FEATURE_APPDOMAIN _appDomainSetup = appDomainSetup; -#endif } +#else + /// + /// Constructor + /// + /// The node id. + /// The build parameters + /// The forwarding loggers. + public NodeConfiguration + ( + int nodeId, + BuildParameters buildParameters, + LoggerDescription[] forwardingLoggers + ) + { + _nodeId = nodeId; + _buildParameters = buildParameters; + _forwardingLoggers = forwardingLoggers; + } +#endif /// /// Private constructor for deserialization @@ -117,7 +133,7 @@ public AppDomainSetup AppDomainSetup } #endif - #region INodePacket Members +#region INodePacket Members /// /// Retrieves the packet type. @@ -129,9 +145,9 @@ public NodePacketType Type { return NodePacketType.NodeConfiguration; } } - #endregion +#endregion - #region INodePacketTranslatable Members +#region INodePacketTranslatable Members /// /// Translates the packet to/from binary form. @@ -156,7 +172,7 @@ internal static INodePacket FactoryForDeserialization(INodePacketTranslator tran configuration.Translate(translator); return configuration; } - #endregion +#endregion /// /// We need to clone this object since it gets modified for each node which is launched. diff --git a/src/XMakeBuildEngine/Collections/ConvertingEnumerable.cs b/src/XMakeBuildEngine/Collections/ConvertingEnumerable.cs index 561f6285ef0..2333e2efa6e 100644 --- a/src/XMakeBuildEngine/Collections/ConvertingEnumerable.cs +++ b/src/XMakeBuildEngine/Collections/ConvertingEnumerable.cs @@ -12,7 +12,7 @@ namespace Microsoft.Build.Collections { /// - /// Enumerable that uses a provided delegate to + /// Enumerable that uses a provided Converter delegate to /// convert each item from a backing enumerator as it is returned. /// /// Type of underlying enumerator @@ -55,7 +55,7 @@ IEnumerator IEnumerable.GetEnumerator() } /// - /// Enumerable that uses a provided delegate to + /// Enumerable that uses a provided Converter delegate to /// convert each item from a backing enumerator as it is returned. /// /// Type of underlying enumerator diff --git a/src/XMakeBuildEngine/Definition/Toolset.cs b/src/XMakeBuildEngine/Definition/Toolset.cs index 64b5cf41116..96b37698bce 100644 --- a/src/XMakeBuildEngine/Definition/Toolset.cs +++ b/src/XMakeBuildEngine/Definition/Toolset.cs @@ -108,11 +108,13 @@ public class Toolset : INodePacketTranslatable /// private const string Dev10LightSwitchInstallKeyRegistryPath = @"Software\Microsoft\DevDiv\vs\Servicing\10.0\vslscore"; +#if FEATURE_WIN32_REGISTRY /// /// Null if it hasn't been figured out yet; true if (some variation of) Visual Studio 2010 is installed on /// the current machine, false otherwise. /// private static bool? s_dev10IsInstalled = null; +#endif /// /// Name of the tools version diff --git a/src/XMakeBuildEngine/Definition/ToolsetReader.cs b/src/XMakeBuildEngine/Definition/ToolsetReader.cs index fe2124f6b2b..50a953a3eb7 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetReader.cs @@ -80,12 +80,12 @@ protected abstract string DefaultOverrideToolsVersion get; } +#if FEATURE_WIN32_REGISTRY || FEATURE_SYSTEM_CONFIGURATION /// /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// -#if FEATURE_WIN32_REGISTRY || FEATURE_SYSTEM_CONFIGURATION internal static string ReadAllToolsets(Dictionary toolsets, PropertyDictionary environmentProperties, PropertyDictionary globalProperties, ToolsetDefinitionLocations locations) { return ReadAllToolsets(toolsets, diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index 2952b978120..123d22aa246 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -417,6 +417,7 @@ internal static List __GetListTest() #endregion +#if FEATURE_WIN32_REGISTRY /// /// Following function will parse a keyName and returns the basekey for it. /// It will also store the subkey name in the out parameter. @@ -424,7 +425,6 @@ internal static List __GetListTest() /// The return value shouldn't be null. /// Taken from: \ndp\clr\src\BCL\Microsoft\Win32\Registry.cs /// -#if FEATURE_WIN32_REGISTRY private static RegistryKey GetBaseKeyFromKeyName(string keyName, RegistryView view, out string subKeyName) { if (keyName == null) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs index e39533ff52b..acd7b383683 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/TaskBuilder_Tests.cs @@ -31,6 +31,7 @@ namespace Microsoft.Build.UnitTests.BackEnd /// public class TaskBuilder_Tests : ITargetBuilderCallback { +#if FEATURE_CODEDOM /// /// Task definition for a task that outputs items containing null metadata. /// @@ -142,6 +143,7 @@ public override bool Execute() } } "; +#endif /// /// The mock component host and logger diff --git a/src/XMakeBuildEngine/UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs index 08853bee70c..6636e35f94b 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs @@ -43,7 +43,7 @@ public override string BaseURI get { return _wrappedReader.BaseURI; } } - public new void Close() + protected override void Dispose(bool disposing) { _wrappedReader.Dispose(); } diff --git a/src/XMakeBuildEngine/UnitTests/Microsoft.Build.Engine.UnitTests.csproj b/src/XMakeBuildEngine/UnitTests/Microsoft.Build.Engine.UnitTests.csproj index 9cec557e143..167407c58ad 100644 --- a/src/XMakeBuildEngine/UnitTests/Microsoft.Build.Engine.UnitTests.csproj +++ b/src/XMakeBuildEngine/UnitTests/Microsoft.Build.Engine.UnitTests.csproj @@ -9,6 +9,7 @@ Microsoft.Build.Engine.UnitTests Microsoft.Build.Engine.UnitTests true + None @@ -210,7 +211,7 @@ {16cd7635-7cf4-4c62-a77b-cf87d0f09a58} Microsoft.Build - + False $(CompilerToolsDir)\Microsoft.Build.Tasks.CodeAnalysis.dll diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj index f2291356166..88d73037777 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj @@ -131,7 +131,7 @@ Designer - + diff --git a/src/XMakeCommandLine/UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj b/src/XMakeCommandLine/UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj index 858df0f5062..1a88668fdaf 100644 --- a/src/XMakeCommandLine/UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj +++ b/src/XMakeCommandLine/UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj @@ -12,6 +12,7 @@ Microsoft.Build.CommandLine.UnitTests Microsoft.Build.CommandLine.UnitTests true + None diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index 93e91a1ba49..b1ce975ab02 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -536,8 +536,8 @@ string [] commandLine List distributedLoggerRecords = null; #if FEATURE_XML_SCHEMA_VALIDATION bool needToValidateProject = false; -#endif string schemaFile = null; +#endif int cpuCount = 1; #if FEATURE_NODE_REUSE bool enableNodeReuse = true; diff --git a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs index 0857e638053..76f2c66d340 100644 --- a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs +++ b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs @@ -32,12 +32,13 @@ internal class AssemblyInformation : DisposableBase private IMetaDataDispenser _metadataDispenser = null; private IMetaDataAssemblyImport _assemblyImport = null; private static Guid s_importerGuid = new Guid(((GuidAttribute)Attribute.GetCustomAttribute(typeof(IMetaDataImport), typeof(GuidAttribute), false)).Value); + private readonly Assembly _assembly; #endif private string _sourceFile; private FrameworkName _frameworkName; +#if FEATURE_ASSEMBLY_LOADFROM && !MONO private static string s_targetFrameworkAttribute = "System.Runtime.Versioning.TargetFrameworkAttribute"; - private readonly Assembly _assembly; - +#endif // Borrowed from genman. private const int GENMAN_STRING_BUF_SIZE = 1024; private const int GENMAN_LOCALE_BUF_SIZE = 64; diff --git a/src/XMakeTasks/GenerateResource.cs b/src/XMakeTasks/GenerateResource.cs index 7477e65ba30..6f665c6f757 100644 --- a/src/XMakeTasks/GenerateResource.cs +++ b/src/XMakeTasks/GenerateResource.cs @@ -146,11 +146,13 @@ public sealed partial class GenerateResource : TaskExtension // Contains the list of paths from which inputs will not be taken into account during up-to-date check. private ITaskItem[] _excludedInputPaths; +#if FEATURE_APPDOMAIN /// /// The task items that we remoted across the appdomain boundary /// we use this list to disconnect the task items once we're done. /// private List _remotedTaskItems; +#endif /// /// Satellite input assemblies. @@ -880,6 +882,7 @@ private static ITaskItem[] CloneValuesInThisAppDomain(IList remoteVal return clonedOutput; } +#if FEATURE_APPDOMAIN /// /// Remember this TaskItem so that we can disconnect it when this Task has finished executing /// Only if we're passing TaskItems to another AppDomain is this necessary. This call @@ -893,6 +896,7 @@ private void RecordItemsForDisconnectIfNecessary(IEnumerable items) _remotedTaskItems.AddRange(items); } } +#endif /// /// Computes the path to ResGen.exe for use in logging and for passing to the @@ -2195,11 +2199,13 @@ internal string StronglyTypedClassName /// private ITaskItem[] _assemblyFiles; +#if FEATURE_ASSEMBLY_LOADFROM /// /// The AssemblyNameExtensions for each of the referenced assemblies in "assemblyFiles". /// This is populated lazily. /// private AssemblyNameExtension[] _assemblyNames; +#endif /// /// List of input files to process. @@ -2285,7 +2291,7 @@ internal bool StronglyTypedResourceSuccessfullyCreated /// private bool _useSourcePath = false; - #endregion +#endregion /// /// Process all files. @@ -2436,7 +2442,7 @@ internal Assembly ResolveAssembly(object sender, ResolveEventArgs args) } #endif - #region Code from ResGen.EXE +#region Code from ResGen.EXE /// /// Read all resources from a file and write to a new file in the chosen format @@ -3780,7 +3786,7 @@ public Entry(string name, object value) public string name; public object value; } - #endregion // Code from ResGen.EXE +#endregion // Code from ResGen.EXE } #if FEATURE_ASSEMBLY_LOADFROM diff --git a/src/XMakeTasks/GetReferenceAssemblyPaths.cs b/src/XMakeTasks/GetReferenceAssemblyPaths.cs index 045654058cd..6f6409f0031 100644 --- a/src/XMakeTasks/GetReferenceAssemblyPaths.cs +++ b/src/XMakeTasks/GetReferenceAssemblyPaths.cs @@ -26,6 +26,7 @@ public class GetReferenceAssemblyPaths : TaskExtension /// private const string WARNONNOREFERENCEASSEMBLYDIRECTORY = "MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY"; +#if FEATURE_GAC /// /// This is the sentinel assembly for .NET FX 3.5 SP1 /// Used to determine if SP1 of 3.5 is installed @@ -36,6 +37,7 @@ public class GetReferenceAssemblyPaths : TaskExtension /// Cache in a static whether or not we have found the 35sp1sentinel assembly. /// private static bool? s_net35SP1SentinelAssemblyFound; +#endif /// /// Hold the reference assembly paths based on the passed in targetframeworkmoniker. From a66f1cdcfca7910f9460f44343030f238b632258 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 1 Dec 2016 10:15:42 -0800 Subject: [PATCH 144/223] Add NormalizeDirectory() and NormalizePath() to IntrinsicFunctions (#1405) * Add NormalizeDirectory() and NormalizePath() to IntrinsicFunctions * Allow multiple paths to be passed in so this methods can also be a used as Path.Combine() * Fix PathToLongException message in NormalizePath Closes #55 --- src/Shared/FileUtilities.cs | 2 +- .../Evaluation/IntrinsicFunctions.cs | 22 +++++++++++++++++++ .../UnitTests/Evaluation/Expander_Tests.cs | 18 +++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs index 4dbb517ab7e..cb850beab74 100644 --- a/src/Shared/FileUtilities.cs +++ b/src/Shared/FileUtilities.cs @@ -323,7 +323,7 @@ internal static string NormalizePath(string path) // we reluctantly have to restrict things here. if (length >= MaxPath) { - throw new PathTooLongException(path); + throw new PathTooLongException(); } // Avoid creating new strings unnecessarily diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index 123d22aa246..65449545884 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text.RegularExpressions; using Microsoft.Build.Internal; @@ -375,6 +376,27 @@ internal static string EnsureTrailingSlash(string path) return FileUtilities.EnsureTrailingSlash(path); } + /// + /// Gets the canonicalized full path of the provided directory and ensures it contains the correct directory separator characters for the current operating system + /// while ensuring it has a trailing slash. + /// + /// One or more directory paths to combine and normalize. + /// A canonicalized full directory path with the correct directory separators and a trailing slash. + internal static string NormalizeDirectory(params string[] path) + { + return EnsureTrailingSlash(NormalizePath(path)); + } + + /// + /// Gets the canonicalized full path of the provided path and ensures it contains the correct directory separator characters for the current operating system. + /// + /// One or more paths to combine and normalize. + /// A canonicalized full path with the correct directory separators. + internal static string NormalizePath(params string[] path) + { + return FileUtilities.NormalizePath(Path.Combine(path)); + } + public static string GetCurrentToolsDirectory() { return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs index c37a39fc4a8..94d04b33081 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs @@ -2777,6 +2777,24 @@ public void PropertyFunctionDoesTaskHostExist_Whitespace() } #endif + [Fact] + public void PropertyFunctionNormalizeDirectory() + { + Expander expander = new Expander(new PropertyDictionary(new[] + { + ProjectPropertyInstance.Create("MyPath", "one"), + ProjectPropertyInstance.Create("MySecondPath", "two"), + })); + + Assert.Equal( + $"{Path.GetFullPath("one")}{Path.DirectorySeparatorChar}", + expander.ExpandIntoStringLeaveEscaped(@"$([MSBuild]::NormalizeDirectory($(MyPath)))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance)); + + Assert.Equal( + $"{Path.GetFullPath(Path.Combine("one", "two"))}{Path.DirectorySeparatorChar}", + expander.ExpandIntoStringLeaveEscaped(@"$([MSBuild]::NormalizeDirectory($(MyPath), $(MySecondPath)))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance)); + } + /// /// Expand property function that tests for existence of the task host /// From 112b38c2ad2b53c7aef8008eb7a8e5d00548f6cb Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 1 Dec 2016 14:54:53 -0600 Subject: [PATCH 145/223] Repoint README badges to ci2 (#1422) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 67f9c9ab943..dd2705dacc5 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ The current development branch is `xplat`. It builds for .NET Core and the full | Runtime\OS | Windows | Ubuntu 14.04 | Ubuntu 16.04 |Mac OS X| |:------|:------:|:------:|:------:|:------:| -| **Full Framework** |[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_Desktop)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_Desktop)| N/A | N/A | N/A | -|**.NET Core**|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu14.04_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu14.04_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu16.04_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu16.04_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_OSX_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_OSX_CoreCLR)| +| **Full Framework** |[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_Desktop)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_Desktop)| N/A | N/A | N/A | +|**.NET Core**|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu14.04_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu14.04_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu16.04_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu16.04_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_OSX_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_OSX_CoreCLR)| Full-framework-only build from `master` (deprecated): -[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_master_Windows_NT_Desktop)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_master_Windows_NT_Desktop) +[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_master_Windows_NT_Desktop)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_master_Windows_NT_Desktop) [![Join the chat at https://gitter.im/Microsoft/msbuild](https://badges.gitter.im/Microsoft/msbuild.svg)](https://gitter.im/Microsoft/msbuild?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From f7eaa0e6ce4ba8c17458dba43eb9f39f6d3f2b9a Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 1 Dec 2016 16:54:05 -0600 Subject: [PATCH 146/223] Remove escape-hatch for NoReferenceAssemblyDirectoryFound (#1367) When this message was converted to a warning (for #173), we added an escape-hatch environment variable to revert to the previous warning-only behavior. A comment indicated that the escape hatch should be removed before the next major release, so I'm removing it (and its test). --- src/XMakeTasks/GetReferenceAssemblyPaths.cs | 19 ++--------- .../UnitTests/GetReferencePaths_Tests.cs | 34 ------------------- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/src/XMakeTasks/GetReferenceAssemblyPaths.cs b/src/XMakeTasks/GetReferenceAssemblyPaths.cs index 6f6409f0031..735a703c833 100644 --- a/src/XMakeTasks/GetReferenceAssemblyPaths.cs +++ b/src/XMakeTasks/GetReferenceAssemblyPaths.cs @@ -22,10 +22,6 @@ public class GetReferenceAssemblyPaths : TaskExtension { #region Data /// - /// Environment variable name for the override error on missing reference assembly directory. - /// - private const string WARNONNOREFERENCEASSEMBLYDIRECTORY = "MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY"; - #if FEATURE_GAC /// /// This is the sentinel assembly for .NET FX 3.5 SP1 @@ -291,21 +287,10 @@ private IList GetPaths(string rootPath, FrameworkNameVersioning framewor } // No reference assembly paths could be found, log an error so an invalid build will not be produced. - // 1/26/16: Note this was changed from a warning to an error (see GitHub #173). Also added the escape hatch - // (set MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY = 1) in case this causes issues. - // TODO: This should be removed for Dev15 + // 1/26/16: Note this was changed from a warning to an error (see GitHub #173). if (pathsToReturn.Count == 0) { - var warn = Environment.GetEnvironmentVariable(WARNONNOREFERENCEASSEMBLYDIRECTORY); - - if (string.Equals(warn, "1", StringComparison.Ordinal)) - { - Log.LogWarningWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString()); - } - else - { - Log.LogErrorWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString()); - } + Log.LogErrorWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString()); } return pathsToReturn; diff --git a/src/XMakeTasks/UnitTests/GetReferencePaths_Tests.cs b/src/XMakeTasks/UnitTests/GetReferencePaths_Tests.cs index 4a0aaf8799e..b83338be34b 100644 --- a/src/XMakeTasks/UnitTests/GetReferencePaths_Tests.cs +++ b/src/XMakeTasks/UnitTests/GetReferencePaths_Tests.cs @@ -171,40 +171,6 @@ public void TestGeneralFrameworkMonikerNonExistent() engine.AssertLogContains("ERROR MSB3644: " + message); } - /// - /// Test the case where the target framework moniker is empty when using MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY - /// override. Expect there to be a warning logged. - /// TODO: This should be removed for Dev15 (override feature removed) - /// - [Fact] - public void TestGeneralFrameworkMonikerNonExistentOverrideError() - { - MockEngine engine = new MockEngine(); - GetReferenceAssemblyPaths getReferencePaths = new GetReferenceAssemblyPaths(); - getReferencePaths.BuildEngine = engine; - // Make a framework which does not exist, intentional misspelling of framework - getReferencePaths.TargetFrameworkMoniker = ".NetFramewok, Version=v99.0"; - - try - { - Environment.SetEnvironmentVariable("MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY", "1"); - bool success = getReferencePaths.Execute(); - Assert.True(success); - } - finally - { - Environment.SetEnvironmentVariable("MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY", null); - } - - string[] returnedPaths = getReferencePaths.ReferenceAssemblyPaths; - Assert.Equal(0, returnedPaths.Length); - string displayName = getReferencePaths.TargetFrameworkMonikerDisplayName; - Assert.Null(displayName); - FrameworkNameVersioning frameworkMoniker = new FrameworkNameVersioning(getReferencePaths.TargetFrameworkMoniker); - string message = ResourceUtilities.FormatResourceString("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkMoniker.ToString()); - engine.AssertLogContains("WARNING MSB3644: " + message); - } - /// /// Test the case where there is a good target framework moniker passed in. /// From fb7221c9f2a51b93e36f368c0f67eabf14487879 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 2 Dec 2016 15:59:47 -0600 Subject: [PATCH 147/223] Revert "Disable GitVersioning in CI to work around #1409" (#1424) This reverts commit d83721a9b39c59d67a6c8721d93bae26b65c4eb5. --- src/dir.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dir.targets b/src/dir.targets index 610cd316957..5157ba9a7ce 100644 --- a/src/dir.targets +++ b/src/dir.targets @@ -77,8 +77,8 @@ - + Condition="'$(MSBuildRuntimeType)' == 'Full'" /> + $(DefineConstants);STATIC_VERSION_NUMBER From 04f14bea593b4541553a32b1984e08ca448f8565 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Sun, 4 Dec 2016 06:50:38 -0600 Subject: [PATCH 148/223] Test DeepClone of project with Sdk Test case for #1431 --- .../ProjectSdkImplicitImport_Tests.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs index d76da60d6c2..cb3e8979b5a 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs @@ -58,6 +58,55 @@ public void SdkImportsAreInImportList() } } + [Fact] + public void ProjectWithSdkImportsIsCloneable() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk", "Sdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, ""); + File.WriteAllText(sdkTargetsPath, ""); + + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) + { + // Based on the new-console-project CLI template (but not matching exactly + // should not be a deal-breaker). + string content = @" + + Exe + netcoreapp1.0 + + + + + + + + + + + +"; + ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); + + var clone = project.DeepClone(); + } + } + finally + { + if (Directory.Exists(testSdkRoot)) + { + FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); + } + } + } } } From 8db3670d0f0efe5a1804f70b8876f76e6cdc5ca5 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Sun, 4 Dec 2016 07:26:14 -0600 Subject: [PATCH 149/223] Consider Implicit status to find insertion loc Fixes #1431. If a project had an Sdk attribute (and thus implicit Import elements), calling DeepClone on it could throw: ``` Unhandled Exception: System.ArgumentException: The reference node is not a child of this node. at System.Xml.XmlNode.InsertAfter(XmlNode newChild, XmlNode refChild) at Microsoft.Build.Construction.ProjectElementContainer.AddToXml(ProjectElement child) at Microsoft.Build.Construction.ProjectElementContainer.InsertAfterChild(ProjectElement child, ProjectElement reference) at Microsoft.Build.Construction.ProjectElementContainer.DeepClone(ProjectRootElement factory, ProjectElementContainer parent) at Microsoft.Build.Construction.ProjectElementContainer.DeepClone(ProjectRootElement factory, ProjectElementContainer parent) at Microsoft.Build.Construction.ProjectRootElement.DeepClone() ``` This was because we traverse the ProjectElement tree to find a sibling XML element to insert next to. If an adjacent ProjectElement's XML element has no physical representation, it is unparented and therefore not a good target for manipulations. Add an implicitness check to the existing is-valid-for-referencing check to cause the next-XML-tree-sibling search to pass over implicit elements. --- .../Construction/ProjectElementContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index 7df034ab0ca..a21752b05d2 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -485,9 +485,9 @@ internal void AddToXml(ProjectElement child) // If none is found, then the node being added is inserted as the only node of its kind ProjectElement referenceSibling; - Predicate siblingIsSameAsChild = _ => _.ExpressedAsAttribute == false; + Predicate siblingIsExplicitElement = _ => _.ExpressedAsAttribute == false && _.IsImplicit == false; - if (TrySearchLeftSiblings(child.PreviousSibling, siblingIsSameAsChild, out referenceSibling)) + if (TrySearchLeftSiblings(child.PreviousSibling, siblingIsExplicitElement, out referenceSibling)) { // Add after previous sibling XmlElement.InsertAfter(child.XmlElement, referenceSibling.XmlElement); @@ -503,7 +503,7 @@ internal void AddToXml(ProjectElement child) } } } - else if (TrySearchRightSiblings(child.NextSibling, siblingIsSameAsChild, out referenceSibling)) + else if (TrySearchRightSiblings(child.NextSibling, siblingIsExplicitElement, out referenceSibling)) { // Add as first child XmlElement.InsertBefore(child.XmlElement, referenceSibling.XmlElement); From 19df8c8051e9a70c17f3ae95d2cc6f6cef8ca273 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Sun, 4 Dec 2016 07:29:55 -0600 Subject: [PATCH 150/223] Version 00078 for deprecated packages --- src/BuildValues.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index 573d25cb51e..ffd7d17e2bd 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -1,4 +1,4 @@ - + - 00077 + 00078 From 2ca4d2dacd51d009dc1dcf8a28bbd62352e75b44 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 6 Dec 2016 09:58:02 -0600 Subject: [PATCH 151/223] Regression test for #1445 Simulates the Roslyn Project System's "Reloadable projects" feature that is used to edit a project without unloading it from VS first. --- .../ProjectSdkImplicitImport_Tests.cs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs index cb3e8979b5a..da7dc82624b 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectSdkImplicitImport_Tests.cs @@ -108,5 +108,60 @@ public void ProjectWithSdkImportsIsCloneable() } } } + + [Fact] + public void ProjectWithSdkImportsIsRemoveable() + { + var testSdkRoot = Path.Combine(Path.GetTempPath(), "MSBuildUnitTest"); + var testSdkDirectory = Path.Combine(testSdkRoot, "MSBuildUnitTestSdk", "Sdk"); + + try + { + Directory.CreateDirectory(testSdkDirectory); + + string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); + string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); + + File.WriteAllText(sdkPropsPath, ""); + File.WriteAllText(sdkTargetsPath, ""); + + using (new Helpers.TemporaryEnvironment("MSBuildSDKsPath", testSdkRoot)) + { + // Based on the new-console-project CLI template (but not matching exactly + // should not be a deal-breaker). + string content = @" + + Exe + netcoreapp1.0 + + + + + + + + + + + +"; + + ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); + ProjectRootElement clone = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); + + clone.DeepCopyFrom(project); + + clone.RemoveAllChildren(); + } + } + finally + { + if (Directory.Exists(testSdkRoot)) + { + FileUtilities.DeleteWithoutTrailingBackslash(testSdkDirectory, true); + } + } + } + } } From 14860fc2716a66755973e71bca5266a4612d4560 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 6 Dec 2016 10:00:28 -0600 Subject: [PATCH 152/223] Ignore implicit elements in RemoveFromXml() Fixes #1445. When RemoveAllChildren was called on an Sdk-using project after DeepCopyFrom()'ing into the project, it threw an Xml exception because the code was trying to remove an element that the Xml tree didn't know about. As with AddToXml, the solution is to ignore implicit elements. --- src/XMakeBuildEngine/Construction/ProjectElementContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index a21752b05d2..1212a65c7b5 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -567,6 +567,11 @@ private string GetElementIndentation(XmlElementWithLocation xmlElement) internal void RemoveFromXml(ProjectElement child) { + if (child.IsImplicit) + { + return; + } + if (child.ExpressedAsAttribute) { XmlElement.RemoveAttribute(child.XmlElement.Name); From 6c723e9e133e5cc77ea0255bb51b577e3b178e97 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 6 Dec 2016 10:58:35 -0600 Subject: [PATCH 153/223] Version 00079 for deprecated packages --- src/BuildValues.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildValues.props b/src/BuildValues.props index ffd7d17e2bd..85a764505a8 100644 --- a/src/BuildValues.props +++ b/src/BuildValues.props @@ -8,6 +8,6 @@ prerelease version number and without the leading zeroes foo-20 is smaller than foo-4. --> - 00078 + 00079 From 91644e0e10b74e67b8bc2411f2a016b572291c5c Mon Sep 17 00:00:00 2001 From: Benjamin Baumann Date: Wed, 7 Dec 2016 01:04:05 +0100 Subject: [PATCH 154/223] Avoid lc.exe response file below 4.6 (#1414) Response file arguments are not supported by lc.exe until version 4.6. --- src/XMakeTasks/LC.cs | 14 +++++++------- src/XMakeTasks/UnitTests/LC_Tests.cs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/XMakeTasks/LC.cs b/src/XMakeTasks/LC.cs index 0d9ce176621..6970637c375 100644 --- a/src/XMakeTasks/LC.cs +++ b/src/XMakeTasks/LC.cs @@ -178,15 +178,15 @@ private void AddCommands(CommandLineBuilderExtension commandLine) /// /// Generates response file with arguments for lc.exe - /// Used when targeting framework version is 4.0 or later + /// Used when targeting framework version is 4.6 or later /// /// command line builder class to add arguments to the response file protected internal override void AddResponseFileCommands(CommandLineBuilderExtension commandLine) { Version targetFramework = Util.GetTargetFrameworkVersion(TargetFrameworkVersion); - // Don't generate response file on versions of the framework < 4.0 - // They will use the 2.x SDK lc.exe which does not understand response files - if (targetFramework.CompareTo(new Version("4.0")) < 0) + // Don't generate response file on versions of the framework < 4.6 + // They will use an older lc.exe which does not understand response files + if (targetFramework.CompareTo(new Version("4.6")) < 0) { return; } @@ -196,15 +196,15 @@ protected internal override void AddResponseFileCommands(CommandLineBuilderExten /// /// Generates command line arguments for lc.exe - /// Used when targeting framework version is less than 4.0 + /// Used when targeting framework version is less than 4.6 /// /// command line builder class to add arguments to the command line protected internal override void AddCommandLineCommands(CommandLineBuilderExtension commandLine) { Version targetFramework = Util.GetTargetFrameworkVersion(TargetFrameworkVersion); - // If the target framework version is < 4.0, we will be using lc.exe from an older SDK + // If the target framework version is < 4.6, we will be using lc.exe from an older SDK // In this case, we want to use command line parameters instead of a response file - if (targetFramework.CompareTo(new Version("4.0")) >= 0) + if (targetFramework.CompareTo(new Version("4.6")) >= 0) { return; } diff --git a/src/XMakeTasks/UnitTests/LC_Tests.cs b/src/XMakeTasks/UnitTests/LC_Tests.cs index 2e7f715c609..3cf5fcfd760 100644 --- a/src/XMakeTasks/UnitTests/LC_Tests.cs +++ b/src/XMakeTasks/UnitTests/LC_Tests.cs @@ -53,7 +53,7 @@ public void SimpleValidArgumentsResponseFile() task.OutputDirectory = "bin\\debug"; task.ReferencedAssemblies = new TaskItem[] { new TaskItem("LicensedControl.dll"), new TaskItem("OtherControl.dll") }; task.NoLogo = true; - task.TargetFrameworkVersion = "4.0"; + task.TargetFrameworkVersion = "4.6"; CommandLine.ValidateHasParameter(task, "/complist:complist.licx", true /* use response file */); CommandLine.ValidateHasParameter(task, "/complist:othersrc.txt", true /* use response file */); From 07b0b369171f8cf93930945dec77dc4f32e9df28 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 6 Dec 2016 18:16:12 -0600 Subject: [PATCH 155/223] Redo consume Roslyn from new location (#1406) --- src/Shared/UnitTests/App.config | 2 +- src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs | 4 +++- src/XMakeCommandLine/app.amd64.config | 2 +- src/XMakeCommandLine/app.config | 2 +- targets/DeployDependencies.proj | 8 ++++---- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Shared/UnitTests/App.config b/src/Shared/UnitTests/App.config index 20691e6dbad..d6407124ae2 100644 --- a/src/Shared/UnitTests/App.config +++ b/src/Shared/UnitTests/App.config @@ -46,7 +46,7 @@ - + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs index ea0961b9a22..a1918da4a9b 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs @@ -58,7 +58,9 @@ protected override IEnumerable GetPropertyDefinitions { yield return new ToolsetPropertyDefinition(MSBuildConstants.ToolsPath, BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); yield return new ToolsetPropertyDefinition(MSBuildConstants.SdksPath, BuildEnvironmentHelper.Instance.MSBuildSDKsPath, _sourceLocation); - yield return new ToolsetPropertyDefinition("RoslynTargetsPath", BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); + yield return new ToolsetPropertyDefinition("RoslynTargetsPath", + System.IO.Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, "Roslyn"), + _sourceLocation); } protected override IEnumerable GetSubToolsetPropertyDefinitions(string toolsVersion, string subToolsetVersion) diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index 580d15eb1fd..89f818d2779 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -75,7 +75,7 @@ - + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index 5dbaca1e18e..1a4efb99763 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -69,7 +69,7 @@ - + diff --git a/targets/DeployDependencies.proj b/targets/DeployDependencies.proj index dc3dc295f4b..dda51b0dbb8 100644 --- a/targets/DeployDependencies.proj +++ b/targets/DeployDependencies.proj @@ -13,11 +13,11 @@ @@ -92,8 +92,8 @@ $(MSBuildThisFileDirectory)roslyn\project.lock.json - $(DeploymentDir) - $(TestDeploymentDir) + $(DeploymentDir)\Roslyn + $(TestDeploymentDir)\Roslyn From 0d15a6b65d068a68edf8e24537c891c0206299c1 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Wed, 7 Dec 2016 08:16:15 -0800 Subject: [PATCH 156/223] Log a message when nothing is specified to Error and Warning tasks (#1440) Logs "(No message specified)" Closes #1350 --- src/XMakeTasks/Error.cs | 5 +- src/XMakeTasks/Resources/Strings.resx | 4 ++ .../UnitTests/ErrorWarningMessage_Tests.cs | 52 ++++++++++++------- src/XMakeTasks/Warning.cs | 5 +- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/XMakeTasks/Error.cs b/src/XMakeTasks/Error.cs index 1d08e307688..184ee13c0c7 100644 --- a/src/XMakeTasks/Error.cs +++ b/src/XMakeTasks/Error.cs @@ -94,10 +94,7 @@ public string HelpKeyword /// public override bool Execute() { - if (Text != null || Code != null) - { - Log.LogError(null, Code, HelpKeyword, File, 0, 0, 0, 0, (Text == null) ? String.Empty : Text); - } + Log.LogError(null, Code, HelpKeyword, File, 0, 0, 0, 0, Text ?? TaskResources.GetString("ErrorAndWarning.EmptyMessage")); // careful to return false. Otherwise the build would continue. return false; diff --git a/src/XMakeTasks/Resources/Strings.resx b/src/XMakeTasks/Resources/Strings.resx index 46b08ab913e..27a88662e01 100644 --- a/src/XMakeTasks/Resources/Strings.resx +++ b/src/XMakeTasks/Resources/Strings.resx @@ -2624,6 +2624,10 @@ + + + (No message specified) + - $(BaseVersion)-$(BuildNumberMajor)-$(BuildNumberMinor) - - - true - - - - - - - - - - - - - $(TraversalBuildDependsOn); - BuildPackages; - - - - - - - - - - - - - - - - - - - - - From 63900f5b7dda872f53fcd5f3dc13e2a63e78536c Mon Sep 17 00:00:00 2001 From: Sarabeth-Jaffe-Microsoft Date: Tue, 13 Dec 2016 14:49:02 -0800 Subject: [PATCH 163/223] Added link to up for grabs issues, small formatting changes, cruft removal --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dd2705dacc5..7eed983b64d 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Full-framework-only build from `master` (deprecated): * Clone the sources: `git clone https://github.com/Microsoft/msbuild.git` -### Building -## Building MSBuild with VS 2015 +## Building +### Building MSBuild with VS 2015 For the full supported experience, you will need to have Visual Studio 2015. You can open the solution in Visual Studio 2017 RC, but you will encounter issues building with the provided scripts. To get started on **Visual Studio 2015**: @@ -36,7 +36,7 @@ To get started on **Visual Studio 2015**: 3. Build the code using the `cibuild.cmd` script. 5. Open src/MSBuild.sln solution in Visual Studio 2015. -## Building MSBuild in Unix (Mac & Linux) +### Building MSBuild in Unix (Mac & Linux) MSBuild's xplat branch allows MSBuild to be run on Unix Systems. Set-up instructions can be viewed on the wiki: [Building Testing and Debugging on .Net Core MSBuild](https://github.com/Microsoft/msbuild/wiki/Building-Testing-and-Debugging-on-.Net-Core-MSBuild) ## Localization @@ -45,14 +45,13 @@ You can turn on localized builds via the `/p:LocalizedBuild=true` command line a ### How to Engage, Contribute and Provide Feedback This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +#### Getting Started Before you contribute, please read through the contributing and developer guides to get an idea of what kinds of pull requests we will or won't accept. * [Contributing Guide](https://github.com/Microsoft/msbuild/wiki/Contributing-Code) * [Developer Guide](https://github.com/Microsoft/msbuild/wiki/Building-Testing-and-Debugging) -Want to get more familiar with what's going on in the code? -* [Pull requests](https://github.com/Microsoft/msbuild/pulls): [Open](https://github.com/Microsoft/msbuild/pulls?q=is%3Aopen+is%3Apr)/[Closed](https://github.com/Microsoft/msbuild/pulls?q=is%3Apr+is%3Aclosed) -* [Issues](https://github.com/Microsoft/msbuild/issues) +Looking for something to work on? This list of [up for grabs issues](https://github.com/Microsoft/msbuild/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs) is a great place to start. You are also encouraged to start a discussion by filing an issue or creating a gist. From 39c48801426a0aa7a18dbb43a981dd6af8765881 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 14 Dec 2016 16:49:08 -0500 Subject: [PATCH 164/223] cibuilsh.sh: Update the bootstrap build to use for Host=Mono case . (#1480) https://github.com/Microsoft/msbuild/issues/1382 The old build was missing support for $(MSBuildRuntimeType)=="Mono", and thus broke the mono build. It showed up as: /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: The "Nerdbank.GitVersioning.Tasks.GetBuildVersion" task failed unexpectedly. [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: This is an unhandled exception from a task -- PLEASE OPEN A BUG AGAINST THE TASK OWNER. [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.DllNotFoundException: git2-e0902fb [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: at (wrapper managed-to-native) LibGit2Sharp.Core.NativeMethods:git_libgit2_init () [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods+LibraryLifetimeObject..ctor () [0x00006] in <87b5f73d0fac4785ae61b1930424cc93>:0 [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods..cctor () [0x00078] in <87b5f73d0fac4785ae61b1930424cc93>:0 [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: --- End of inner exception stack trace --- [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: at LibGit2Sharp.Core.Proxy.git_repository_open (System.String path) [0x00013] in <87b5f73d0fac4785ae61b1930424cc93>:0 [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] /Users/builder/data/lanes/2907/63900f5b/source/msbuild/packages/Nerdbank.GitVersioning/1.5.46/build/Nerdbank.GitVersioning.targets(43,5): error MSB4018: at LibGit2Sharp.Repository..ctor (System.String path, LibGit2Sharp.RepositoryOptions options) [0x00055] in <87b5f73d0fac4785ae61b1930424cc93>:0 [/Users/builder/data/lanes/2907/63900f5b/source/msbuild/src/Framework/Microsoft.Build.Framework.csproj] --- cibuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuild.sh b/cibuild.sh index bc717861ea7..11d6e39b03c 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -135,7 +135,7 @@ BOOTSTRAP_ONLY=false THIS_SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" PACKAGES_DIR="$THIS_SCRIPT_PATH/packages" TOOLS_DIR="$THIS_SCRIPT_PATH/Tools" -MSBUILD_DOWNLOAD_URL="https://github.com/Microsoft/msbuild/releases/download/mono-hosted-msbuild-v0.2/mono_msbuild_bootstrap_5e01f07.zip" +MSBUILD_DOWNLOAD_URL="https://github.com/Microsoft/msbuild/releases/download/mono-hosted-msbuild-v0.03/mono_msbuild_d25dd923839404bd64cc63f420e75acf96fc75c4.zip" MSBUILD_ZIP="$PACKAGES_DIR/msbuild.zip" HOME_DEFAULT="$WORKSPACE/msbuild-CI-home" TEMP_DEFAULT="$WORKSPACE/tmp" From ccdabf44e66bbaaa0105e6e6acfd8308117a480e Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 8 Dec 2016 16:53:03 -0500 Subject: [PATCH 165/223] [warnings] Don't reference `PresentationFramework` on non-windows .. platforms. --- .../UnitTests/Microsoft.Build.Tasks.UnitTests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj b/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj index 74aa6a09ea5..94c24e40821 100644 --- a/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj +++ b/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj @@ -185,11 +185,11 @@ - + - \ No newline at end of file + From 9032e46321d906b0d0f2db0b0425978026f91be7 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 8 Dec 2016 16:54:27 -0500 Subject: [PATCH 166/223] [warnings] Disable CS0612 warning for Assembly.LoadWithPartialName(..) CS0612 is emitted when you have an `Obsolete` attribute with no arguments. https://msdn.microsoft.com/en-us/library/h0h063ka.aspx --- src/XMakeBuildEngine/Evaluation/Expander.cs | 4 ++-- src/XMakeTasks/CodeTaskFactory.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/Expander.cs b/src/XMakeBuildEngine/Evaluation/Expander.cs index 0ece36fc2a3..0d46d6a4e1c 100644 --- a/src/XMakeBuildEngine/Evaluation/Expander.cs +++ b/src/XMakeBuildEngine/Evaluation/Expander.cs @@ -3362,12 +3362,12 @@ private static Type GetTypeFromAssembly(string typeName, string candidateAssembl // Try to load the assembly with the computed name #if FEATURE_GAC -#pragma warning disable 618 +#pragma warning disable 618, 612 // Unfortunately Assembly.Load is not an alternative to LoadWithPartialName, since // Assembly.Load requires the full assembly name to be passed to it. // Therefore we must ignore the deprecated warning. Assembly candidateAssembly = Assembly.LoadWithPartialName(candidateAssemblyName); -#pragma warning restore 618 +#pragma warning restore 618, 612 #else Assembly candidateAssembly = null; try diff --git a/src/XMakeTasks/CodeTaskFactory.cs b/src/XMakeTasks/CodeTaskFactory.cs index 6fb9a56841e..07b33f58ffd 100644 --- a/src/XMakeTasks/CodeTaskFactory.cs +++ b/src/XMakeTasks/CodeTaskFactory.cs @@ -620,7 +620,7 @@ private void AddReferenceAssemblyToReferenceList(List referenceAssemblyL { if (!referenceAssembly.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || !referenceAssembly.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { -#pragma warning disable 618 +#pragma warning disable 618, 612 // Unfortunately Assembly.Load is not an alternative to LoadWithPartialName, since // Assembly.Load requires the full assembly name to be passed to it. // Therefore we must ignore the deprecated warning. @@ -646,7 +646,7 @@ private void AddReferenceAssemblyToReferenceList(List referenceAssemblyL candidateAssemblyLocation = candidateAssembly.Location; } } -#pragma warning restore 618 +#pragma warning restore 618, 612 } } else From 3794ed11aa7091f6768fc30170905955a2eb40a3 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 9 Dec 2016 10:35:35 -0500 Subject: [PATCH 167/223] [cibuild.sh] Switch mono builds to use csc.exe instead of mcs.exe This was prompted by the switch to using `/warnaserror` and mcs giving ~990 errors for a build, mostly because mcs raised CS0219 for cases like: ``` using System; class Bar { public static void Main() { string a = String.Empty; int i = 0; Console.WriteLine ($"i : {i}"); } } /* $ mcs b.cs b.cs(7,10): warning CS0219: The variable `a' is assigned but its value is never used Compilation succeeded - 1 warning(s) $ mono /Library/Frameworks/Mono.framework/Versions/4.8.0/lib/mono/msbuild/15.0/bin/csc.exe b.cs Microsoft (R) Visual C# Compiler version 2.0.0.60620 Copyright (C) Microsoft Corporation. All rights reserved. $ mono /Library/Frameworks/Mono.framework/Versions/4.8.0/lib/mono/msbuild/15.0/bin/csc.exe /w:4 b.cs Microsoft (R) Visual C# Compiler version 2.0.0.60620 Copyright (C) Microsoft Corporation. All rights reserved. */ ``` And switching to csc.exe should be fine. --- cibuild.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cibuild.sh b/cibuild.sh index 11d6e39b03c..4410ddf280b 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -147,7 +147,7 @@ BOOTSTRAPPED_RUNTIME_HOST='"'"$THIS_SCRIPT_PATH/bin/Bootstrap-NetCore/dotnet"'"' # Default msbuild arguments TARGET_ARG="Build" EXTRA_ARGS="" - +CSC_ARGS="" #parse command line args while [ $# -gt 0 ] @@ -231,7 +231,7 @@ case $target in Mono) setMonoDir CONFIGURATION=Debug-MONO - EXTRA_ARGS="/p:CscToolExe=mcs /p:CscToolPath=$MONO_BIN_DIR" + CSC_ARGS="/p:CscToolExe=csc.exe /p:CscToolPath=$PACKAGES_DIR/msbuild/ /p:DebugType=portable" RUNTIME_HOST_ARGS="--debug" MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap/MSBuild.dll"'"' ;; @@ -284,7 +284,7 @@ restoreBuildTools echo echo "** Rebuilding MSBuild with downloaded binaries" -runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_EXE" "/t:Rebuild $BUILD_MSBUILD_ARGS" "$BOOTSTRAP_BUILD_LOG_PATH" +runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_EXE" "/t:Rebuild $BUILD_MSBUILD_ARGS $CSC_ARGS" "$BOOTSTRAP_BUILD_LOG_PATH" if [[ $BUILD_ONLY = true ]]; then exit $? @@ -299,6 +299,12 @@ if [[ $BOOTSTRAP_ONLY = true ]]; then exit $? fi +# Microsoft.Net.Compilers package is available now, so we can use the latest csc.exe +if [ "$host" = "Mono" ]; then + CSC_EXE="$PACKAGES_DIR/microsoft.net.compilers/2.0.0-beta3/tools/csc.exe" + CSC_ARGS="/p:CscToolExe=csc.exe /p:CscToolPath=`dirname $CSC_EXE` /p:DebugType=portable" +fi + # The set of warnings to suppress for now # warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. # warning MSB3026: Could not copy "XXX" to "XXX". Beginning retry 1 in 1000ms. @@ -307,4 +313,4 @@ _NOWARN="MSB3277;MSB3026;AL1053" echo echo "** Rebuilding MSBuild with locally built binaries" -runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_BOOTSTRAPPED_EXE" "/t:$TARGET_ARG $BUILD_MSBUILD_ARGS /warnaserror /nowarn:\"$_NOWARN\"" "$LOCAL_BUILD_LOG_PATH" +runMSBuildWith "$RUNTIME_HOST" "$RUNTIME_HOST_ARGS" "$MSBUILD_BOOTSTRAPPED_EXE" "/t:$TARGET_ARG $BUILD_MSBUILD_ARGS $CSC_ARGS /warnaserror /nowarn:\"$_NOWARN\"" "$LOCAL_BUILD_LOG_PATH" From 7ec8ec40f66e71b7abd25f4c13a7773241fe3deb Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 9 Dec 2016 10:47:54 -0500 Subject: [PATCH 168/223] [warnings] Ignore MSB3276 warning Microsoft.Build -> /Users/ankit/dev/msbuild/bin/Debug-MONO/Output/Microsoft.Build.dll Consider app.config remapping of assembly "mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089" from Version "2.0.0.0" [/Library/Frameworks/Mono.framework/Versions/4.8.0/lib/mono/2.0-api/mscorlib.dll] to Version "4.0.0.0" [/Library/Frameworks/Mono.framework/Versions/4.8.0/lib/mono/4.5/mscorlib.dll] to solve conflict and get rid of warning. /Users/ankit/dev/msbuild/bin/Bootstrap/Microsoft.Common.CurrentVersion.targets(1911,5): error MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. [/Users/ankit/dev/msbuild/src/XMakeCommandLine/MSBuild.csproj] MSBuild -> /Users/ankit/dev/msbuild/bin/Debug-MONO/Output/MSBuild.dll --- cibuild.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cibuild.sh b/cibuild.sh index 4410ddf280b..91935d34cc4 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -306,10 +306,13 @@ if [ "$host" = "Mono" ]; then fi # The set of warnings to suppress for now +# warning MSB3276: Found conflicts between different versions of the same dependent assembly. +# - Microsoft.VisualStudio.Setup.Configuration.Interop.dll (referenced from Utilities project) references mscorlib 2.0 and thus conflicting +# with mscorlib 4.0 # warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. # warning MSB3026: Could not copy "XXX" to "XXX". Beginning retry 1 in 1000ms. # warning AL1053: The version '1.2.3.4-foo' specified for the 'product version' is not in the normal 'major.minor.build.revision' format -_NOWARN="MSB3277;MSB3026;AL1053" +_NOWARN="MSB3276;MSB3277;MSB3026;AL1053" echo echo "** Rebuilding MSBuild with locally built binaries" From afff527fd85477894239eb4e91a01cb8a7436d3a Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 20 Oct 2016 23:58:54 -0400 Subject: [PATCH 169/223] [tests] Disable WinMDTests for Mono --- src/XMakeTasks/UnitTests/AssemblyDependency/WinMDTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/XMakeTasks/UnitTests/AssemblyDependency/WinMDTests.cs b/src/XMakeTasks/UnitTests/AssemblyDependency/WinMDTests.cs index 1f899b491a6..3c2dc3bd42e 100644 --- a/src/XMakeTasks/UnitTests/AssemblyDependency/WinMDTests.cs +++ b/src/XMakeTasks/UnitTests/AssemblyDependency/WinMDTests.cs @@ -11,6 +11,7 @@ namespace Microsoft.Build.UnitTests.ResolveAssemblyReference_Tests /// /// Unit tests for the ResolveAssemblyReference task. /// + [Trait("Category", "non-mono-tests")] public sealed class WinMDTests : ResolveAssemblyReferenceTestFixture { #region AssemblyInformationIsWinMDFile Tests @@ -725,4 +726,4 @@ public void DotNetAssemblyDependsOnAWinMDFileWithVersion255() } #endregion } -} \ No newline at end of file +} From d549f46088cfc7e64639a28fcd393c839ccb92a7 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 02:26:43 -0400 Subject: [PATCH 170/223] [tests] Fix CommandLine related XMakeAppTests - Quoting the msbuild executable filename, on Unix fails as it is being used directly with Process class, with no shell involved. So, it fails as the `\"/path/to/msbuild.dll\"` doesn't exist. - It still fails as it tries to execute MSBuild.* from a "local" copy, which does not have the dependent assemblies next to it. Fixes: --- src/XMakeCommandLine/UnitTests/XMake_Tests.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs index b98a090fc80..df99c96c57e 100644 --- a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs +++ b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs @@ -829,7 +829,15 @@ public void GetCommandLineQuotedExe() Assert.True(File.Exists(_pathToArbitraryBogusFile)); bool successfulExit; - string output = RunnerUtilities.ExecMSBuild('"' + RunnerUtilities.PathToCurrentlyRunningMsBuildExe + '"', msbuildParameters, out successfulExit); + string pathToMSBuildExe = RunnerUtilities.PathToCurrentlyRunningMsBuildExe; + // This @pathToMSBuildExe is used directly with Process, so don't quote it on + // Unix + if (NativeMethodsShared.IsWindows) + { + pathToMSBuildExe = "\"" + pathToMSBuildExe + "\""; + } + + string output = RunnerUtilities.ExecMSBuild(pathToMSBuildExe, msbuildParameters, out successfulExit); Assert.False(successfulExit); Assert.Contains(RunnerUtilities.PathToCurrentlyRunningMsBuildExe + (NativeMethodsShared.IsWindows ? " /v:diag " : " -v:diag ") + _pathToArbitraryBogusFile, output, StringComparison.OrdinalIgnoreCase); From 8d23021918721a8633935b845db7117b8d941da3 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 22 Sep 2016 21:31:37 -0400 Subject: [PATCH 171/223] [tests] Disable 2 BuildManager tests that trigger a .. .. `CreateProcess`(pinvoke) code path, which fails on OSX. --- src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index 2dc1be36d1d..fb05639b10e 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -1468,6 +1468,7 @@ public void CancelledBuildWithDelay20() /// wait until the task finishes normally (cancellation not supported.) /// [Fact] + [Trait("Category", "mono-osx-failing")] public void CancelledBuildInTaskHostWithDelay20() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 != null) @@ -1538,6 +1539,7 @@ public void CancelledBuildWithDelay40() /// cancel the task and exit out after a short period wherein we wait for the task to exit cleanly. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void CancelledBuildInTaskHostWithDelay40() { string contents = ObjectModelHelpers.CleanupFileContents(@" From 60199a884643124b86822701ced7724cfc477f46 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 20:26:45 -0400 Subject: [PATCH 172/223] [tests] Fix XMake_Tests.ConfigurationInvalid for mono/osx Use RunnerUtilities.PathToCurrentlyRunningMsBuildExe to get the actual executable filename, instead of hardcoding `msbuild.exe`. --- src/XMakeCommandLine/UnitTests/XMake_Tests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs index df99c96c57e..c60a7a31d43 100644 --- a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs +++ b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs @@ -592,8 +592,9 @@ public void ConfigurationInvalid() Environment.SetEnvironmentVariable("MSBuildOldOM", ""); startDirectory = CopyMSBuild(); - var newPathToMSBuildExe = Path.Combine(startDirectory, "msbuild.exe"); - var pathToConfigFile = Path.Combine(startDirectory, "msbuild.exe.config"); + var msbuildExeName = Path.GetFileName(RunnerUtilities.PathToCurrentlyRunningMsBuildExe); + var newPathToMSBuildExe = Path.Combine(startDirectory, msbuildExeName); + var pathToConfigFile = Path.Combine(startDirectory, msbuildExeName + ".config"); string configContent = @" From 989ff90b1eb76ef674e1c9c16449ff6cda4eee33 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 9 Dec 2016 18:29:04 -0500 Subject: [PATCH 173/223] [tests] Fix CommandLine tests on mono/osx Add USE_MSBUILD_DLL_EXTN when .dll extension is being used, which is on CoreCLR and Mono, currently. Earlier, FEATURE_RUN_EXE_IN_TESTS was being overloaded with this meaning and the dll/exe indication was just a side effect. FEATURE_RUN_EXE_IN_TESTS is meant to indicate whether a runtime executable like mono/corerun should be used to run msbuild, in a test. The tests used FEATURE_RUN_EXE_IN_TESTS to choose .dll/.exe extension for msbuild, which meant that it would need to be enabled for Mono, but we don't need to use mono binary explictly to run assemblies. So, the USE_MSBUILD_DLL_EXTN was created to have the specific meaning. Fixes: Microsoft.Build.UnitTests.XMakeAppTests.GetCommandLineQuotedExeOnPath [FAIL] Microsoft.Build.UnitTests.XMakeAppTests.GetCommandLine [FAIL] Microsoft.Build.UnitTests.XMakeAppTests.GetCommandLineQuotedExe [FAIL] Microsoft.Build.UnitTests.XMakeAppTests.ResponseFileInProjectDirectoryWinsOverMainMSBuildRsp [FAIL] Microsoft.Build.UnitTests.XMakeAppTests.ProjectDirectoryIsMSBuildExeDirectory [FAIL] --- dir.props | 2 ++ src/Utilities/UnitTests/ToolLocationHelper_Tests.cs | 6 +++--- .../UnitTests/BuildEnvironmentHelper_Tests.cs | 6 +++--- src/XMakeCommandLine/UnitTests/XMake_Tests.cs | 6 +++--- src/XMakeCommandLine/XMake.cs | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/dir.props b/dir.props index dc31616df0c..cd44b29982a 100644 --- a/dir.props +++ b/dir.props @@ -313,6 +313,7 @@ $(DefineConstants);FEATURE_RESX_RESOURCE_READER $(DefineConstants);FEATURE_RTLMOVEMEMORY $(DefineConstants);FEATURE_RUN_EXE_IN_TESTS + $(DefineConstants);USE_MSBUILD_DLL_EXTN $(DefineConstants);FEATURE_SECURITY_PERMISSIONS $(DefineConstants);FEATURE_SECURITY_PRINCIPAL_WINDOWS $(DefineConstants);FEATURE_SPECIAL_FOLDERS @@ -363,6 +364,7 @@ $(DefineConstants);FEATURE_PROCESSSTARTINFO_ENVIRONMENT $(DefineConstants);FEATURE_RUNTIMEINFORMATION + $(DefineConstants);USE_MSBUILD_DLL_EXTN diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index 0819318e8d3..3f8619c358e 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -31,10 +31,10 @@ sealed public class ToolLocationHelper_Tests { private readonly ITestOutputHelper _output; -#if FEATURE_RUN_EXE_IN_TESTS - private const string MSBuildExeName = "MSBuild.exe"; -#else +#if USE_MSBUILD_DLL_EXTN private const string MSBuildExeName = "MSBuild.dll"; +#else + private const string MSBuildExeName = "MSBuild.exe"; #endif public ToolLocationHelper_Tests(ITestOutputHelper output) diff --git a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs index 829c8bfc209..a8125632dc4 100644 --- a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs @@ -13,10 +13,10 @@ namespace Microsoft.Build.Engine.UnitTests { public class BuildEnvironmentHelper_Tests { -#if FEATURE_RUN_EXE_IN_TESTS - private const string MSBuildExeName = "MSBuild.exe"; -#else +#if USE_MSBUILD_DLL_EXTN private const string MSBuildExeName = "MSBuild.dll"; +#else + private const string MSBuildExeName = "MSBuild.exe"; #endif [Fact] public void GetExecutablePath() diff --git a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs index c60a7a31d43..6dddf2b5f23 100644 --- a/src/XMakeCommandLine/UnitTests/XMake_Tests.cs +++ b/src/XMakeCommandLine/UnitTests/XMake_Tests.cs @@ -24,10 +24,10 @@ namespace Microsoft.Build.UnitTests { public class XMakeAppTests { -#if FEATURE_RUN_EXE_IN_TESTS - private const string MSBuildExeName = "MSBuild.exe"; -#else +#if USE_MSBUILD_DLL_EXTN private const string MSBuildExeName = "MSBuild.dll"; +#else + private const string MSBuildExeName = "MSBuild.exe"; #endif private const string AutoResponseFileName = "MSBuild.rsp"; diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index 1d25a8f0dd7..17d5bc98583 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -1353,7 +1353,7 @@ private static void GatherAllSwitches( s_exeName = BuildEnvironmentHelper.Instance.CurrentMSBuildExePath; #endif -#if (RUNTIME_TYPE_NETCORE || MONO) && !FEATURE_RUN_EXE_IN_TESTS +#if USE_MSBUILD_DLL_EXTN var msbuildExtn = ".dll"; #else var msbuildExtn = ".exe"; From e0347d5d233c30b09c97c1be497e51435a165c1f Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 18:03:22 -0400 Subject: [PATCH 174/223] [tests] Disable BuildManager test Regress265010 .. .. which also fails because of out-of-proc not being supported on OSX. --- src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index fb05639b10e..2a1cdf358b2 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -3534,6 +3534,7 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData_P2P_MP() [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] #else [Fact] + [Trait("Category", "mono-osx-failing")] #endif public void Regress265010() { From ba703ec5610657ae749949559ea958324bf19780 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 19:00:48 -0400 Subject: [PATCH 175/223] [tests] AssemblyFoldersFromConfig_Tests - Use Path.Combine for .. .. constructing the paths. This fixes the tests on OSX. --- .../AssemblyFoldersFromConfig_Tests.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/XMakeTasks/UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs b/src/XMakeTasks/UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs index 23d759165e6..9c39252aeb7 100644 --- a/src/XMakeTasks/UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs +++ b/src/XMakeTasks/UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs @@ -20,14 +20,14 @@ public AssemblyFoldersFromConfig_Tests() { s_existentFiles.AddRange(new[] { - @"c:\assemblyfromconfig\folder1\assemblyfromconfig1.dll", - @"c:\assemblyfromconfig\folder2\assemblyfromconfig2.dll", - @"c:\assemblyfromconfig\folder3_x86\assemblyfromconfig3_x86.dll", - - @"c:\assemblyfromconfig\folder_x86\assemblyfromconfig_common.dll", - @"c:\assemblyfromconfig\folder_x64\assemblyfromconfig_common.dll", - @"c:\assemblyfromconfig\folder5010x64\v5assembly.dll", - @"c:\assemblyfromconfig\folder501000x86\v5assembly.dll" + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder1", "assemblyfromconfig1.dll"), + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder2", "assemblyfromconfig2.dll"), + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder3_x86", "assemblyfromconfig3_x86.dll"), + + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder_x86", "assemblyfromconfig_common.dll"), + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder_x64", "assemblyfromconfig_common.dll"), + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder5010x64", "v5assembly.dll"), + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder501000x86", "v5assembly.dll") }); } @@ -51,7 +51,7 @@ public void AssemblyFoldersFromConfigTest() Execute(t); Assert.Equal(1, t.ResolvedFiles.Length); - Assert.Equal(@"c:\assemblyfromconfig\folder2\assemblyfromconfig2.dll", t.ResolvedFiles[0].ItemSpec); + Assert.Equal(Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder2", "assemblyfromconfig2.dll"), t.ResolvedFiles[0].ItemSpec); AssertNoCase(moniker, t.ResolvedFiles[0].GetMetadata("ResolvedFrom")); } finally @@ -81,7 +81,7 @@ public void AssemblyFoldersFromConfigPlatformSpecificAssemblyFirstTest() Execute(t); Assert.Equal(1, t.ResolvedFiles.Length); - Assert.Equal(@"c:\assemblyfromconfig\folder_x86\assemblyfromconfig_common.dll", t.ResolvedFiles[0].ItemSpec); + Assert.Equal(Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder_x86", "assemblyfromconfig_common.dll"), t.ResolvedFiles[0].ItemSpec); AssertNoCase(moniker, t.ResolvedFiles[0].GetMetadata("ResolvedFrom")); } finally @@ -111,7 +111,7 @@ public void AasemblyFoldersFromConfigNormalizeNetFrameworkVersion() Execute(t); Assert.Equal(1, t.ResolvedFiles.Length); - Assert.Equal(@"c:\assemblyfromconfig\folder501000x86\v5assembly.dll", t.ResolvedFiles[0].ItemSpec); + Assert.Equal(Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder501000x86", "v5assembly.dll"), t.ResolvedFiles[0].ItemSpec); AssertNoCase(moniker, t.ResolvedFiles[0].GetMetadata("ResolvedFrom")); // Try again changing only the processor architecture @@ -126,7 +126,7 @@ public void AasemblyFoldersFromConfigNormalizeNetFrameworkVersion() Execute(t); Assert.Equal(1, t.ResolvedFiles.Length); - Assert.Equal(@"c:\assemblyfromconfig\folder5010x64\v5assembly.dll", t.ResolvedFiles[0].ItemSpec); + Assert.Equal(Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder5010x64", "v5assembly.dll"), t.ResolvedFiles[0].ItemSpec); AssertNoCase(moniker, t.ResolvedFiles[0].GetMetadata("ResolvedFrom")); } finally @@ -191,43 +191,43 @@ public void AssemblyFoldersFromConfigFileMalformed() } } - private const string TestFile = @" + private readonly string TestFile = @" Test Assemblies v5.0 - c:\assemblyfromconfig\folder1\ + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder1") + @" Test Assemblies2 v4.5.25000 - c:\assemblyfromconfig\folder2\ + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder2") + @" v4.0 - c:\assemblyfromconfig\folder3\ + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder3") + @" Platform Specific v4.5.25000 - c:\assemblyfromconfig\folder_x64 + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder_x64") + @" x64 v4.5 - c:\assemblyfromconfig\folder_x86 + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder_x86") + @" x86 v5.0.1.0 - c:\assemblyfromconfig\folder5010x64\ + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder5010x64") + @" x64 v5.0.100.0 - c:\assemblyfromconfig\folder501000x86\ + " + Path.Combine(s_rootPathPrefix, "assemblyfromconfig", "folder501000x86") + @" x86 From 4aeaa46a2336416cb3b938420ee20be303a62aa4 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 21 Oct 2016 18:40:26 -0400 Subject: [PATCH 176/223] [tests] ExtensionsPath tests: Use the current tools version in the .. generated app.config, on mono/osx. Fixes: ImportFromMSBuildExtensionsPathTests.FallbackImportWithUndefinedProperty --- .../Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs index 12bfa0b07fb..6fc06be76ad 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs @@ -692,8 +692,8 @@ public void FallbackImportWithUndefinedProperty()
- - + + From 3c7482a17819b22a29b31a08e7905c64cb9c1a78 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 17:59:00 -0400 Subject: [PATCH 177/223] [tests] Disable BuildManager out-of-proc tests for Mono/OSX Out of proc builds are not supported on OSX yet. https://github.com/Microsoft/msbuild/issues/1240 --- .../UnitTests/BackEnd/BuildManager_Tests.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index 2a1cdf358b2..59260e68eb1 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -206,6 +206,8 @@ public void VerifyEnvironmentSavedBetweenCalls() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -268,6 +270,8 @@ public void ShutdownNodesAfterParallelBuild() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -281,6 +285,8 @@ public void SimpleBuildOutOfProcess() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -527,6 +533,8 @@ public void MsBuildForwardAllPropertiesFromChildLaunchChildNode() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -677,6 +685,8 @@ public void OutOfProcNodeForwardCertainpropertiesAlsoGetResultsFromCache() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -733,6 +743,8 @@ public void ForwardNoPropertiesLaunchChildNode() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -810,6 +822,8 @@ public override bool Execute() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2042,6 +2056,8 @@ public void Regress251333() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2192,6 +2208,8 @@ public void ProjectInstanceTransfersToOOPNode() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2579,6 +2597,8 @@ public void NonOverlappingEntrypointTargetsShouldNotInfluenceEachOthersResults() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2708,6 +2728,8 @@ public void Regress473114() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2817,6 +2839,8 @@ public void VerifyMultipleRequestForSameProjectWithErrors_Simple() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2956,6 +2980,8 @@ public void VerifyMultipleRequestForSameProjectWithErrors_OnErrorChain() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -3067,6 +3093,8 @@ public void VerifyMultipleRequestForSameProjectWithErrors_ErrorAndContinue() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif From 800fc707823211026f22494da09d8d09f2b45e8c Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 15:48:41 -0400 Subject: [PATCH 178/223] [tests] Disable Out of proc BuildManager related tests on mono Issue: https://github.com/Microsoft/msbuild/issues/1240 Disables: Microsoft.Build.UnitTests.BackEnd.BuildManager_Tests.OutOfProcNodeForwardCertainpropertiesAlsoGetResultsFromCache Microsoft.Build.UnitTests.BackEnd.BuildManager_Tests.ProjectInstanceTransfersToOOPNode --- .../UnitTests/BackEnd/BuildManager_Tests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index 59260e68eb1..eefd5997f31 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -596,6 +596,8 @@ public void OutOfProcNodeForwardCertainproperties() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -2133,6 +2135,8 @@ public void Regress239661_NodeUnavailable() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1240")] #else [Fact] #endif @@ -3456,6 +3460,8 @@ public void TestSimultaneousSubmissionsWithLegacyThreadingData_P2P() ///
#if RUNTIME_TYPE_NETCORE [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/933")] +#elif MONO + [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/1245")] #else [Fact] #endif From 65cadc25b663d441762091614c87d203d35d445e Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 01:59:59 -0400 Subject: [PATCH 179/223] [tests] Disable encoding related tests for mono - CreateCSharpManifestResourceName_Tests.cs:Regress249540 --- .../UnitTests/CreateCSharpManifestResourceName_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs b/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs index 1c2178eede3..84efc771773 100644 --- a/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs +++ b/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs @@ -98,6 +98,7 @@ public void Regress172107() #else [Fact] #endif + [Trait("Category", "mono-osx-failing")] public void Regress249540() { // Special character is 'Ä' in UTF8: 0xC3 84 From cf257d15616a3528af666fd3e669ea0926210d96 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 01:43:36 -0400 Subject: [PATCH 180/223] [tests] Disable failing Exec_Tests.CanEncodeTest for mono/osx Notes: Assert.False(Exec.CanEncodeString(defaultEncoding.CodePage, nonAnsiCharacters)); - this fails on OSX - should this actually be True? --- src/XMakeTasks/UnitTests/Exec_Tests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XMakeTasks/UnitTests/Exec_Tests.cs b/src/XMakeTasks/UnitTests/Exec_Tests.cs index 128b1b9311a..83b162d8d64 100644 --- a/src/XMakeTasks/UnitTests/Exec_Tests.cs +++ b/src/XMakeTasks/UnitTests/Exec_Tests.cs @@ -384,6 +384,7 @@ public void ExecTaskUtf8AlwaysWithAnsi() #else [Fact] #endif + [Trait("Category", "mono-osx-failing")] public void ExecTaskUtf8NeverWithNonAnsi() { RunExec(true, EncodingUtilities.CurrentSystemOemEncoding.EncodingName, "Never", false); @@ -765,6 +766,7 @@ public void ConsoleToMSBuild() [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/623")] #else [Fact] + [Trait("Category", "mono-osx-failing")] #endif public void CanEncodeTest() { From 2890bb367c374ceca60928d489aa43706201b77f Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 22:56:46 -0400 Subject: [PATCH 181/223] [tests] TaskItem_Tests.Escaping{2,3} - Disable Task Host tests for .. .. mono/osx. --- src/XMakeBuildEngine/UnitTests/Instance/TaskItem_Tests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/UnitTests/Instance/TaskItem_Tests.cs b/src/XMakeBuildEngine/UnitTests/Instance/TaskItem_Tests.cs index 0e41d4ff541..97d4e3130c8 100644 --- a/src/XMakeBuildEngine/UnitTests/Instance/TaskItem_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Instance/TaskItem_Tests.cs @@ -217,7 +217,7 @@ public void Escaping1() /// /// Flushing an item through a task run in the task host also should not mess up special characters on the metadata. /// -#if RUNTIME_TYPE_NETCORE +#if RUNTIME_TYPE_NETCORE || MONO [Fact(Skip = "FEATURE: TASKHOST")] #else [Fact] @@ -278,7 +278,7 @@ public void Escaping2() /// /// Flushing an item through a task run in the task host also should not mess up the escaping of the itemspec either. /// -#if RUNTIME_TYPE_NETCORE +#if RUNTIME_TYPE_NETCORE || MONO [Fact(Skip = "FEATURE: TASKHOST")] #else [Fact] From c003812bb86b46b413334ccebb413b76fcca1853 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 02:01:25 -0400 Subject: [PATCH 182/223] [tests] Disable failing ToolLocationHelper_Tests.ResolveSDKFromRegistryAndDisk .. on mono/osx --- src/Utilities/UnitTests/ToolLocationHelper_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index 3f8619c358e..9298232e3d6 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -4119,6 +4119,7 @@ public void ResolveSDKFromRegistry() /// and make sure we get the expected results. ///
[Fact] + [Trait("Category", "mono-osx-failing")] public void ResolveSDKFromRegistryAndDisk() { Dictionary targetPlatforms = new Dictionary(); From 6d19072604ae55ef68b1c6de3871c5169a947ecb Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2016 17:38:25 -0500 Subject: [PATCH 183/223] [tests] Disable failing VB related tests on mono/osx Microsoft.Build.UnitTests.WriteCodeFragment_Tests.OneAttributeNoParamsVb [FAIL] Microsoft.Build.UnitTests.WriteCodeFragment_Tests.MultilineAttributeVB [FAIL] Microsoft.Build.UnitTests.WriteCodeFragment_Tests.OneAttributePositionalAndNamedParamsVisualBasic [FAIL] --- src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs b/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs index 69345ca6caf..67028d33b09 100644 --- a/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs +++ b/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs @@ -250,6 +250,7 @@ public void OneAttributeNoParams() /// Test with the VB language ///
[Fact] + [Trait("Category", "mono-osx-failing")] public void OneAttributeNoParamsVb() { WriteCodeFragment task = new WriteCodeFragment(); @@ -479,6 +480,7 @@ public void MultilineAttributeCSharp() /// Multi line argument values should cause a verbatim string to be used /// [Fact] + [Trait("Category", "mono-osx-failing")] public void MultilineAttributeVB() { var lines = new []{ "line 1", "line 2", "line 3" }; @@ -614,6 +616,7 @@ public void OneAttributePositionalAndNamedParams() /// These can also be combined with named params. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void OneAttributePositionalAndNamedParamsVisualBasic() { WriteCodeFragment task = new WriteCodeFragment(); From 26c6e81aea01d89b5d8b29eb3b6898132313ad62 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 25 Oct 2016 01:32:30 -0400 Subject: [PATCH 184/223] [tests] Disable failing TestGetPathToBuildToolsFile_32Bit test for .. mono/osx . --- src/Utilities/UnitTests/ToolLocationHelper_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index 9298232e3d6..3a00372c35a 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -746,6 +746,7 @@ public void TestGetPathToBuildToolsFile() [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/722")] #else [Fact] + [Trait("Category", "mono-osx-failing")] #endif public void TestGetPathToBuildToolsFile_32Bit() { From 93515847990550509c07ca28f4168e3d908ee06f Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 24 Oct 2016 21:21:07 -0400 Subject: [PATCH 185/223] [tests] Disable failing Exec_Tests.NoTempFileLeaks on mono/osx Notes: This is comparing a "local" tmp path with the default Path.GetTempPath, which shouldn't match. I'm not sure why this works on netcore or windows! --- src/XMakeTasks/UnitTests/Exec_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeTasks/UnitTests/Exec_Tests.cs b/src/XMakeTasks/UnitTests/Exec_Tests.cs index 83b162d8d64..648fd5a6d37 100644 --- a/src/XMakeTasks/UnitTests/Exec_Tests.cs +++ b/src/XMakeTasks/UnitTests/Exec_Tests.cs @@ -41,6 +41,7 @@ private ExecWrapper PrepareExecWrapper(string command) /// lying around. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void NoTempFileLeaks() { using (var alternativeTemp = new Helpers.AlternativeTempPath()) From b1d06e6436edc48475e12278f0f088825f52f9b3 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2016 18:05:13 -0500 Subject: [PATCH 186/223] [tests] Disable failing GenerateResource InProc tests on mono/osx DontLockP2PReferenceWhenResolvingSystemTypes and .. on mono/osx. - They fail on mono/osx as it tries to use csc.exe Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.References.DontLockP2PReferenceWhenResolvingSystemTypes - Use Path.Combine to construct paths. Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.References.ReferencedAssemblySpecifiedUsingRelativePath --- src/XMakeTasks/UnitTests/GenerateResource_Tests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs index 6a1501b51e5..1a8b41d8570 100644 --- a/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs +++ b/src/XMakeTasks/UnitTests/GenerateResource_Tests.cs @@ -2487,6 +2487,7 @@ public class References [Fact] [Trait("Category", "netcore-osx-failing")] [Trait("Category", "netcore-linux-failing")] // https://github.com/Microsoft/msbuild/issues/309 + [Trait("Category", "mono-osx-failing")] // https://github.com/Microsoft/msbuild/issues/677 public void DontLockP2PReferenceWhenResolvingSystemTypes() { // This WriteLine is a hack. On a slow machine, the Tasks unittest fails because remoting @@ -2538,7 +2539,7 @@ public class Class1 ObjectModelHelpers.BuildTempProjectFileExpectSuccess("lib1.csproj"); - string p2pReference = Path.Combine(ObjectModelHelpers.TempProjectDir, @"bin\debug\lib1.dll"); + string p2pReference = Path.Combine(ObjectModelHelpers.TempProjectDir, "bin", "debug", "lib1.dll"); Assert.True(File.Exists(p2pReference)); // "lib1.dll doesn't exist." // ------------------------------------------------------------------------------- @@ -2666,6 +2667,7 @@ public class Class1 [Fact] [Trait("Category", "netcore-osx-failing")] [Trait("Category", "netcore-linux-failing")] // https://github.com/Microsoft/msbuild/issues/309 + [Trait("Category", "mono-osx-failing")] // https://github.com/Microsoft/msbuild/issues/677 public void ReferencedAssemblySpecifiedUsingRelativePath() { // This WriteLine is a hack. On a slow machine, the Tasks unittest fails because remoting From bcb0a1feb3764c5a08e82d54b8c004ae4e26ab11 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2016 18:25:07 -0500 Subject: [PATCH 187/223] [tests] Fix CopyToDestinationFolderWithSymbolicLinkCheck on .. mono/osx. Use `NativeMethodsShared.IsWindows` instead of `RuntimeInformation.IsOSPlatform(OSPlatform.Windows)`. The latter depends on which platform the library was built to target. --- src/XMakeTasks/UnitTests/Copy_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeTasks/UnitTests/Copy_Tests.cs b/src/XMakeTasks/UnitTests/Copy_Tests.cs index 3c608f8c596..bafe1ae1197 100644 --- a/src/XMakeTasks/UnitTests/Copy_Tests.cs +++ b/src/XMakeTasks/UnitTests/Copy_Tests.cs @@ -2226,7 +2226,7 @@ public void CopyToDestinationFolderWithSymbolicLinkCheck() { var isPrivileged = true; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (NativeMethodsShared.IsWindows) { if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null))) { From cf09213be7aa22bc56b1ca938d45c642d3b802a4 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 13 Dec 2016 14:14:08 -0500 Subject: [PATCH 188/223] [tests] Disable failing WriteLinesWriteOnlyWhenDifferentTest on mono/osx Microsoft.Build.UnitTests.ReadLinesFromFile_Tests.WriteLinesWriteOnlyWhenDifferentTest --- src/XMakeTasks/UnitTests/ReadLinesFromFile_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeTasks/UnitTests/ReadLinesFromFile_Tests.cs b/src/XMakeTasks/UnitTests/ReadLinesFromFile_Tests.cs index 33ac6941abe..f325c9040b7 100644 --- a/src/XMakeTasks/UnitTests/ReadLinesFromFile_Tests.cs +++ b/src/XMakeTasks/UnitTests/ReadLinesFromFile_Tests.cs @@ -310,6 +310,7 @@ public void Encoding() } [Fact] + [Trait("Category", "mono-osx-failing")] public void WriteLinesWriteOnlyWhenDifferentTest() { string file = FileUtilities.GetTemporaryFile(); From 161f1802b4afed825eda2c00df7288389eb9bb26 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 21 Oct 2016 18:40:26 -0400 Subject: [PATCH 189/223] [tests] ExtensionsPath tests: Use the current tools version in the .. generated app.config . Fixes: ImportFromMSBuildExtensionsPathTests.FallbackImportWithFileNotFoundWhenPropertyNotDefined --- .../Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs index 6fc06be76ad..2640c0d795a 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/ImportFromMSBuildExtensionsPath_Tests.cs @@ -759,8 +759,8 @@ public void FallbackImportWithFileNotFoundWhenPropertyNotDefined()
- - + + @@ -784,7 +784,8 @@ public void FallbackImportWithFileNotFoundWhenPropertyNotDefined() projectCollection.RegisterLogger(logger); Assert.Throws(() => projectCollection.LoadProject(mainProjectPath)); - logger.AssertLogContains(@"MSB4226: The imported project ""$(UndefinedProperty)\filenotfound.props"" was not found. Also, tried to find"); + logger.AssertLogContains(@"MSB4226: The imported project """ + Path.Combine("$(UndefinedProperty)", "filenotfound.props") + + @""" was not found. Also, tried to find"); } finally { From 01d0671f8802ae3505611ea4ddf3b208389beed8 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 13 Dec 2016 13:59:56 -0500 Subject: [PATCH 190/223] [tests] Don't check for exact IO exception message, as that can differ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .. between .NET and mono . Expected: ···t be evaluated. The path is not of a legal form. Actual: ···t be evaluated. The specified path is not of a legal form (em··· Fixes Microsoft.Build.UnitTests.Evaluation.Expander_Tests.PropertyFunctionStaticMethodGetPathOfFileAboveInMemoryProject --- src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs index 2827e0546e6..56c394fd89c 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs @@ -2695,7 +2695,7 @@ public void PropertyFunctionStaticMethodGetPathOfFileAboveInMemoryProject() ObjectModelHelpers.CreateInMemoryProject("$([MSBuild]::GetPathOfFileAbove('foo'))"); }); - Assert.Equal("The expression \"[MSBuild]::GetPathOfFileAbove(foo, \'\')\" cannot be evaluated. The path is not of a legal form.", exception.Message); + Assert.True(exception.Message.StartsWith("The expression \"[MSBuild]::GetPathOfFileAbove(foo, \'\')\" cannot be evaluated.")); } /// From 8b241a90e83f95a4d89382818658d666635e5155 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 13 Dec 2016 16:38:39 -0500 Subject: [PATCH 191/223] [tests] Disable failing CreateCSharpManifestResourceName_Tests.Regress172107 .. on mono/osx. --- .../UnitTests/CreateCSharpManifestResourceName_Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs b/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs index 84efc771773..3069a73fbdb 100644 --- a/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs +++ b/src/XMakeTasks/UnitTests/CreateCSharpManifestResourceName_Tests.cs @@ -48,6 +48,7 @@ public void Basic() #else [Fact] #endif + [Trait("Category", "mono-osx-failing")] public void Regress172107() { // Can't embed the 'Ã' directly because the string is Unicode already and the Unicode<-->ANSI transform From 3bfcf96f5506eb0b5c500d354348602a0f623431 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 13 Dec 2016 16:44:55 -0500 Subject: [PATCH 192/223] [tests] Disable failing MSBuildTask_Tests.PropertyOverridesContainSemicolon .. on mono/osx. - Fix the path issues in test - the remaining problem is that is it trying to invoke `csc.exe` from mono's framework directory. The correct fix would be the mono specific targets file which overrides `CscTool*` properties. --- src/XMakeTasks/UnitTests/MSBuild_Tests.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/XMakeTasks/UnitTests/MSBuild_Tests.cs b/src/XMakeTasks/UnitTests/MSBuild_Tests.cs index d46bc3f2b74..4c678f4f99f 100644 --- a/src/XMakeTasks/UnitTests/MSBuild_Tests.cs +++ b/src/XMakeTasks/UnitTests/MSBuild_Tests.cs @@ -329,6 +329,7 @@ public void LogErrorWhenBuildingVCProj() #else [Fact] #endif + [Trait("Category", "mono-osx-failing")] public void PropertyOverridesContainSemicolon() { ObjectModelHelpers.DeleteTempProjectDirectory(); @@ -339,7 +340,7 @@ public void PropertyOverridesContainSemicolon() // Just a normal console application project. ObjectModelHelpers.CreateFileInTempProjectDirectory( - @"bug'533'369\Sub;Dir\ConsoleApplication1\ConsoleApplication1.csproj", @" + Path.Combine("bug'533'369", "Sub;Dir", "ConsoleApplication1", "ConsoleApplication1.csproj"), @" @@ -377,7 +378,7 @@ public void PropertyOverridesContainSemicolon() // Just a normal console application project. ObjectModelHelpers.CreateFileInTempProjectDirectory( - @"bug'533'369\Sub;Dir\ConsoleApplication1\Program.cs", @" + Path.Combine("bug'533'369", "Sub;Dir", "ConsoleApplication1", "Program.cs"), @" using System; namespace ConsoleApplication32 @@ -401,7 +402,7 @@ static void Main(string[] args) // is coming from another property which is produced by CreateProperty and has // some special characters in it. ObjectModelHelpers.CreateFileInTempProjectDirectory( - @"bug'533'369\Sub;Dir\TeamBuild.proj", @" + Path.Combine("bug'533'369", "Sub;Dir", "TeamBuild.proj"), @" @@ -418,9 +419,9 @@ static void Main(string[] args) "); - ObjectModelHelpers.BuildTempProjectFileExpectSuccess(@"bug'533'369\Sub;Dir\TeamBuild.proj"); + ObjectModelHelpers.BuildTempProjectFileExpectSuccess(Path.Combine("bug'533'369", "Sub;Dir", "TeamBuild.proj")); - ObjectModelHelpers.AssertFileExistsInTempProjectDirectory(@"bug'533'369\Sub;Dir\binaries\ConsoleApplication1.exe"); + ObjectModelHelpers.AssertFileExistsInTempProjectDirectory(Path.Combine("bug'533'369", "Sub;Dir", "binaries", "ConsoleApplication1.exe")); } /// From e547c85f6e1afb57a8aa8ad796637199b17ea5c8 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 14 Dec 2016 17:01:34 -0500 Subject: [PATCH 193/223] [tests] Disable some failing tests on mono/osx MSBuildExtensionsPathWithGlobalOverride MSBuildExtensionsPath32WithEnvironmentOverride MSBuildExtensionsPath32WithGlobalOverride --- src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs index b3659b17de9..66dbf6d4ea0 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Evaluator_Tests.cs @@ -2091,6 +2091,7 @@ public void MSBuildExtensionsPathWithEnvironmentOverride() /// should win over whatever MSBuild thinks the default is. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void MSBuildExtensionsPathWithGlobalOverride() { Project project = new Project(new ProjectCollection()); @@ -2147,6 +2148,7 @@ public void MSBuildExtensionsPath32Default() /// of seeing whether our value wins. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void MSBuildExtensionsPath32WithEnvironmentOverride() { string originalMSBuildExtensionsPath32Value = Environment.GetEnvironmentVariable("MSBuildExtensionsPath32"); @@ -2170,6 +2172,7 @@ public void MSBuildExtensionsPath32WithEnvironmentOverride() /// of seeing whether our value wins. /// [Fact] + [Trait("Category", "mono-osx-failing")] public void MSBuildExtensionsPath32WithGlobalOverride() { Project project = new Project(new ProjectCollection()); From f4a57ac503576fdece99c8746bd4710db8a4390c Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 16 Dec 2016 07:20:38 -0800 Subject: [PATCH 194/223] Print process module path when waiting for debugger to attach (#1487) --- src/XMakeCommandLine/XMake.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index 1d25a8f0dd7..7adcbb19688 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -492,7 +492,8 @@ string [] commandLine #endif case "2": // Sometimes easier to attach rather than deal with JIT prompt - Console.WriteLine($"Waiting for debugger to attach (PID {Process.GetCurrentProcess().Id}). Press enter to continue..."); + Process currentProcess = Process.GetCurrentProcess(); + Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}). Press enter to continue..."); Console.ReadLine(); break; } @@ -1825,7 +1826,8 @@ bool recursing if (!Debugger.IsAttached) { - Console.WriteLine("Waiting for debugger to attach... (PID {0})", Process.GetCurrentProcess().Id); + Process currentProcess = Process.GetCurrentProcess(); + Console.WriteLine($"Waiting for debugger to attach... ({currentProcess.MainModule.FileName} PID {currentProcess.Id})"); while (!Debugger.IsAttached) { Thread.Sleep(100); From 7e02d8738a96878feaa37d28c7aba546342363cb Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:05:13 -0800 Subject: [PATCH 195/223] Refactor / fix build environment discovery. - Implements changes outlined in #1461. - Attempted to simply logic and combine discovery of MSBuild and Visual Studio (if avilable). - Defines a BuildEnvironmentMode (VisualStudio, Standalone, None) which can be used (internally) accessed to make decisions on which features should light up. --- src/Shared/BuildEnvironmentHelper.cs | 466 ++++++++++-------- .../UnitTests/BuildEnvironmentHelper_Tests.cs | 270 +++++++--- 2 files changed, 462 insertions(+), 274 deletions(-) diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs index 823f9904f0a..833cd026e6c 100644 --- a/src/Shared/BuildEnvironmentHelper.cs +++ b/src/Shared/BuildEnvironmentHelper.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Collections.Generic; +using System.Text.RegularExpressions; namespace Microsoft.Build.Shared { @@ -22,7 +23,8 @@ internal class BuildEnvironmentHelper private static readonly string[] s_testRunners = { "XUNIT", "NUNIT", "MSTEST", "VSTEST", "TASKRUNNER", - "VSTESTHOST", "QTAGENT32", "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST" + "VSTESTHOST", "QTAGENT32", "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST", + "JetBrains.ReSharper.TaskRunner.CLR4.x64", "JetBrains.ReSharper.TaskRunner.CLR45" }; private static readonly string[] s_testAssemblies = @@ -45,7 +47,7 @@ internal class BuildEnvironmentHelper /// /// Name of MSBuild executable files. /// - private static readonly string[] s_msBuildExeNames = {"MSBuild.exe", "MSBuild.dll"}; + private static readonly string[] s_msBuildExeNames = { "MSBuild.exe", "MSBuild.dll" }; /// /// Gets the cached Build Environment instance. @@ -75,48 +77,25 @@ public static BuildEnvironment Instance /// /// Find the location of MSBuild.exe based on the current environment. /// + /// + /// This defines the order and precedence for various methods of discovering MSBuild and associated toolsets. + /// At a high level, an install under Visual Studio is preferred as the user may have SDKs installed to a + /// specific instance of Visual Studio and build will only succeed if we can discover those. See + /// https://github.com/Microsoft/msbuild/issues/1461 for details. + /// /// Build environment. private static BuildEnvironment Initialize() { - // Get the executable we are running - var processNameCommandLine = s_getProcessFromCommandLine(); - var processNameCurrentProcess = s_getProcessFromRunningProcess(); - var executingAssembly = s_getExecutingAssmblyPath(); - var currentDirectory = s_getCurrentDirectory(); - var appContextBaseDirectory = s_getAppContextBaseDirectory(); - - - // Check if our current process name is in the list of own test runners - var runningTests = CheckIfRunningTests(processNameCommandLine, processNameCurrentProcess); - - // Check to see if we're running inside of Visual Studio - bool runningInVisualStudio; - var visualStudioPath = GetVisualStudioPath(out runningInVisualStudio); - + // See https://github.com/Microsoft/msbuild/issues/1461 for specification of ordering and details. var possibleLocations = new Func[] { - // Check explicit %MSBUILD_EXE_PATH% environment variable. - () => TryFromEnvironmentVariable(runningTests, runningInVisualStudio, visualStudioPath), - - // See if we're running from MSBuild.exe - () => TryFromCurrentProcess(processNameCommandLine, runningTests, runningInVisualStudio, visualStudioPath), - () => TryFromCurrentProcess(processNameCurrentProcess, runningTests, runningInVisualStudio, visualStudioPath), - - // Try from our current executing assembly (e.g. path to Microsoft.Build.dll) - () => TryFromFolder(Path.GetDirectoryName(executingAssembly), runningTests, runningInVisualStudio, visualStudioPath), - - // Try based on the Visual Studio Root - ()=> TryFromVisualStudioRoot(visualStudioPath, runningTests, runningInVisualStudio), - -#if !CLR2COMPATIBILITY // Assemblies compiled against anything older than .NET 4.0 won't have a System.AppContext - // Try the base directory that the assembly resolver uses to probe for assemblies. - // Under certain scenarios the assemblies are loaded from spurious locations like the NuGet package cache - // but the toolset files are copied to the app's directory via "contentFiles". - () => TryFromFolder(appContextBaseDirectory, runningTests, runningInVisualStudio, visualStudioPath), -#endif - - // Try from the current directory - () => TryFromFolder(currentDirectory, runningTests, runningInVisualStudio, visualStudioPath), + TryFromEnvironmentVariable, + TryFromVisualStudioProcess, + TryFromMSBuildProcess, + TryFromMSBuildAssembly, + TryFromDevConsole, + TryFromSetupApi, + TryFromAppContextBaseDirectory }; foreach (var location in possibleLocations) @@ -126,190 +105,217 @@ private static BuildEnvironment Initialize() return env; } - ErrorUtilities.ThrowInvalidOperation("Shared.CanNotFindValidMSBuildLocation"); - return null; // Not reachable + // If we can't find a suitable environment, continue in the 'None' mode. For the CurrentMSBuildExePath + // value we will use the current running process. This is likely wrong, but many things use the + // CurrentMSBuildToolsDirectory value which must be set for basic functionality to work. + return new BuildEnvironment( + BuildEnvironmentMode.None, + s_getProcessFromRunningProcess(), + runningTests: CheckIfRunningTests(), + runningInVisualStudio: false, + visualStudioPath: null); } - private static BuildEnvironment TryFromVisualStudioRoot(string visualStudioPath, bool runningTests, bool runningInVisualStudio) + private static BuildEnvironment TryFromEnvironmentVariable() { - if (string.IsNullOrEmpty(visualStudioPath)) return null; + var msBuildExePath = Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH"); - var msbuildFromVisualStudioRoot = FileUtilities.CombinePaths(visualStudioPath, "MSBuild", CurrentToolsVersion, "Bin"); - return TryFromFolder(msbuildFromVisualStudioRoot, runningTests, runningInVisualStudio, visualStudioPath); + return TryFromStandaloneMSBuildExe(msBuildExePath); } - private static BuildEnvironment TryFromCurrentProcess(string runningProcess, bool runningTests, bool runningInVisualStudio, string visualStudioPath) + private static BuildEnvironment TryFromVisualStudioProcess() { - // No need to check the current process if we know we're running in VS or a test harness - if (runningTests || runningInVisualStudio) return null; - if (!IsProcessInList(runningProcess, s_msBuildProcess)) return null; - - return IsValidMSBuildPath(runningProcess) - ? new BuildEnvironment(runningProcess, runningTests, runningInVisualStudio, visualStudioPath) - : null; + var vsProcess = s_getProcessFromRunningProcess(); + if (!IsProcessInList(vsProcess, s_visualStudioProcess)) return null; + + var vsRoot = FileUtilities.GetFolderAbove(vsProcess, 3); + string msBuildExe = GetMSBuildExeFromVsRoot(vsRoot); + + return new BuildEnvironment( + BuildEnvironmentMode.VisualStudio, + msBuildExe, + runningTests: false, + runningInVisualStudio: true, + visualStudioPath: vsRoot); } - private static BuildEnvironment TryFromEnvironmentVariable(bool runningTests, bool runningInVisualStudio, string visualStudioPath) + private static BuildEnvironment TryFromMSBuildProcess() { - var msBuildExePath = Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH"); - - return IsValidMSBuildPath(msBuildExePath) - ? new BuildEnvironment(msBuildExePath, runningTests, runningInVisualStudio, visualStudioPath) - : null; - } + var msBuildExe = s_getProcessFromRunningProcess(); + if (!IsProcessInList(msBuildExe, s_msBuildProcess)) return null; - private static BuildEnvironment TryFromFolder(string folder, bool runningTests, bool runningInVisualStudio, string visualStudioPath) - { - if (string.IsNullOrEmpty(folder)) return null; + // First check if we're in a VS installation + if (NativeMethodsShared.IsWindows && + Regex.IsMatch(msBuildExe, $@".*\\MSBuild\\{CurrentToolsVersion}\\Bin\\.*MSBuild\.exe", RegexOptions.IgnoreCase)) + { + return new BuildEnvironment( + BuildEnvironmentMode.VisualStudio, + msBuildExe, + runningTests: false, + runningInVisualStudio: false, + visualStudioPath: GetVsRootFromMSBuildAssembly(msBuildExe)); + } - return ( - s_msBuildExeNames.Select(msbuildFileName => Path.Combine(folder, msbuildFileName)) - .Where(IsValidMSBuildPath) - .Select(msBuildPath => new BuildEnvironment(msBuildPath, runningTests, runningInVisualStudio, visualStudioPath)) - ).FirstOrDefault(); + // Standalone mode running in MSBuild.exe + return new BuildEnvironment( + BuildEnvironmentMode.Standalone, + msBuildExe, + runningTests: false, + runningInVisualStudio: false, + visualStudioPath: null); } - /// - /// Determine whether the given path is considered to be an acceptable path to MSBuild. - /// - /// - /// If we are running in an orphaned way (i.e. running from Microsoft.Build.dll in someone else's process), - /// that folder will not be sufficient as a build tools folder (e.g. we can't launch MSBuild.exe from that - /// location). At minimum, it must have MSBuild.exe and MSBuild.exe.config. - /// - /// Full path to MSBuild.exe - /// True when the path to MSBuild is valid. - private static bool IsValidMSBuildPath(string path) + private static BuildEnvironment TryFromMSBuildAssembly() { - bool msbuildExeExists = !string.IsNullOrEmpty(path) && - s_msBuildExeNames.Any(i => i.Equals(Path.GetFileName(path), StringComparison.OrdinalIgnoreCase)) && - File.Exists(path); -#if FEATURE_SYSTEM_CONFIGURATION - // If we can read toolsets out of msbuild.exe.config, we must - // try to do so. - return msbuildExeExists && - File.Exists($"{path}.config"); -#else - // On .NET Core, we can't read the contents of msbuild.exe.config, - // so it doesn't matter if it exists. - return msbuildExeExists; -#endif - } + var buildAssembly = s_getExecutingAssemblyPath(); + if (buildAssembly == null) return null; - private static bool CheckIfRunningTests(string processNameCommandLine, string processNameCurrentProcess) - { - // First check if we're running in a known test runner. - if (IsProcessInList(processNameCommandLine, s_testRunners) || - IsProcessInList(processNameCurrentProcess, s_testRunners)) + // Check for MSBuild.[exe|dll] next to the current assembly + var msBuildExe = Path.Combine(FileUtilities.GetFolderAbove(buildAssembly), "MSBuild.exe"); + var msBuildDll = Path.Combine(FileUtilities.GetFolderAbove(buildAssembly), "MSBuild.dll"); + + // First check if we're in a VS installation + if (NativeMethodsShared.IsWindows && + Regex.IsMatch(buildAssembly, $@".*\\MSBuild\\{CurrentToolsVersion}\\Bin\\.*", RegexOptions.IgnoreCase)) { -#if FEATURE_APPDOMAIN - // If we are, then ensure we're running MSBuild's tests by seeing if any of our assemblies are loaded. - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + // In a Visual Studio path we must have MSBuild.exe + if (File.Exists(msBuildExe)) { - if (s_testAssemblies.Any(item => item.Equals(assembly.GetName().Name, StringComparison.InvariantCultureIgnoreCase))) - return true; + return new BuildEnvironment( + BuildEnvironmentMode.VisualStudio, + msBuildExe, + runningTests: CheckIfRunningTests(), + runningInVisualStudio: false, + visualStudioPath: GetVsRootFromMSBuildAssembly(buildAssembly)); } -#else - return true; -#endif } - return false; + // We're not in VS, check for MSBuild.exe / dll to consider this a standalone environment. + string msBuildPath = null; + if (File.Exists(msBuildExe)) msBuildPath = msBuildExe; + else if (File.Exists(msBuildDll)) msBuildPath = msBuildDll; + + if (!string.IsNullOrEmpty(msBuildPath)) + { + // Standalone mode with toolset + return new BuildEnvironment( + BuildEnvironmentMode.Standalone, + msBuildPath, + runningTests: CheckIfRunningTests(), + runningInVisualStudio: false, + visualStudioPath: null); + } + + return null; + } - /// - /// Look for Visual Studio - /// - /// True if running in Visual Studio - /// Path to Visual Studio install root. - private static string GetVisualStudioPath(out bool runningInVisualStudio) + private static BuildEnvironment TryFromDevConsole() { - var processNameCommandLine = s_getProcessFromCommandLine(); - var processNameCurrentProcess = s_getProcessFromRunningProcess(); + // VSINSTALLDIR and VisualStudioVersion are set from the Developer Command Prompt. + var vsInstallDir = Environment.GetEnvironmentVariable("VSINSTALLDIR"); + var vsVersion = Environment.GetEnvironmentVariable("VisualStudioVersion"); + + if (string.IsNullOrEmpty(vsInstallDir) || string.IsNullOrEmpty(vsVersion) || + vsVersion != CurrentVisualStudioVersion || !Directory.Exists(vsInstallDir)) return null; - // Check to see if we're running inside of Visual Studio - runningInVisualStudio = IsProcessInList(processNameCommandLine, s_visualStudioProcess) || - IsProcessInList(processNameCurrentProcess, s_visualStudioProcess); + return new BuildEnvironment( + BuildEnvironmentMode.VisualStudio, + GetMSBuildExeFromVsRoot(vsInstallDir), + runningTests: false, + runningInVisualStudio: false, + visualStudioPath: vsInstallDir); + } + + private static BuildEnvironment TryFromSetupApi() + { + Version v = new Version(CurrentVisualStudioVersion); + var instances = s_getVisualStudioInstances() + .Where(i => i.Version.Major == v.Major && i.Version.Minor == v.Minor && Directory.Exists(i.Path)) + .ToList(); - // Define the order in which we will look for Visual Studio. Stop when the first instance - // is found. - var possibleLocations = new Func[] + if (instances.Count == 0) return null; + + if (instances.Count > 1) { - () => TryGetVsFromProcess(processNameCommandLine), - () => TryGetVsFromProcess(processNameCurrentProcess), - () => TryGetVsFromEnvironment(), - () => TryGetVsFromInstalled(), - () => TryGetVsFromMSBuildLocation(processNameCommandLine), - () => TryGetVsFromMSBuildLocation(processNameCurrentProcess) - }; + // TODO: Warn user somehow. We may have picked the wrong one. + } - return possibleLocations.Select(location => location()).FirstOrDefault(path => !string.IsNullOrEmpty(path)); + return new BuildEnvironment( + BuildEnvironmentMode.VisualStudio, + GetMSBuildExeFromVsRoot(instances[0].Path), + runningTests: false, + runningInVisualStudio: false, + visualStudioPath: instances[0].Path); } - private static string TryGetVsFromProcess(string process) + private static BuildEnvironment TryFromAppContextBaseDirectory() { - // Check to see if we're running inside of Visual Studio - // This assumes running from VS\Common7\IDE\.exe. - return IsProcessInList(process, s_visualStudioProcess) - ? FileUtilities.GetFolderAbove(process, 3) - : null; + // Assemblies compiled against anything older than .NET 4.0 won't have a System.AppContext + // Try the base directory that the assembly resolver uses to probe for assemblies. + // Under certain scenarios the assemblies are loaded from spurious locations like the NuGet package cache + // but the toolset files are copied to the app's directory via "contentFiles". + + var appContextBaseDirectory = s_getAppContextBaseDirectory(); + if (string.IsNullOrEmpty(appContextBaseDirectory)) return null; + + // Look for possible MSBuild exe names in the AppContextBaseDirectory + return s_msBuildExeNames + .Select((name) => TryFromStandaloneMSBuildExe(Path.Combine(appContextBaseDirectory, name))) + .FirstOrDefault(env => env != null); } - private static string TryGetVsFromEnvironment() + private static BuildEnvironment TryFromStandaloneMSBuildExe(string msBuildExePath) { - // VSInstallDir is set from the Developer Command Prompt - var vsInstallDir = Environment.GetEnvironmentVariable("VSINSTALLDIR"); - var vsVersion = Environment.GetEnvironmentVariable("VisualStudioVersion"); - - if (!string.IsNullOrEmpty(vsInstallDir) && - !string.IsNullOrEmpty(vsVersion) && - vsVersion == CurrentVisualStudioVersion && - Directory.Exists(vsInstallDir)) + if (!string.IsNullOrEmpty(msBuildExePath) && File.Exists(msBuildExePath)) { - return vsInstallDir; + // MSBuild.exe was found outside of Visual Studio. Assume Standalone mode. + return new BuildEnvironment( + BuildEnvironmentMode.Standalone, + msBuildExePath, + runningTests: CheckIfRunningTests(), + runningInVisualStudio: false, + visualStudioPath: null); } return null; } - private static string TryGetVsFromInstalled() + private static string GetVsRootFromMSBuildAssembly(string msBuildAssembly) { - var instances = s_getVisualStudioInstances(); - Version v = new Version(CurrentVisualStudioVersion); + return FileUtilities.GetFolderAbove(msBuildAssembly, + Regex.IsMatch(msBuildAssembly, $@".\\MSBuild\\{CurrentToolsVersion}\\Bin\\Amd64\\MSBuild\.exe", RegexOptions.IgnoreCase) + ? 5 + : 4); + } - // Get the first instance of Visual Studio that matches our Major/Minor compatible version - return instances.FirstOrDefault( - i => i.Version.Major == v.Major && i.Version.Minor == v.Minor && Directory.Exists(i.Path))?.Path; + private static string GetMSBuildExeFromVsRoot(string visualStudioRoot) + { + return FileUtilities.CombinePaths(visualStudioRoot, "MSBuild", CurrentToolsVersion, "Bin", "MSBuild.exe"); } - private static string TryGetVsFromMSBuildLocation(string process) + private static bool CheckIfRunningTests() { - // Check assuming we're running in VS\MSBuild\15.0\Bin\MSBuild.exe + var runningProcess = s_getProcessFromRunningProcess(); - if (IsProcessInList(process, s_msBuildProcess)) + // First check if we're running in a known test runner. + if (IsProcessInList(runningProcess, s_testRunners)) { - var vsPath = FileUtilities.GetFolderAbove(process, 4); - var devEnv = FileUtilities.CombinePaths(vsPath, "Common7", "IDE", "devenv.exe"); - - // Make sure VS is actually there before we suggest this root. - if (File.Exists(devEnv)) - { - return vsPath; - } - - // VS\MSBuild\15.0\Bin\amd64\MSBuild.exe - var vsPath64 = FileUtilities.GetFolderAbove(process, 5); - var devEnv64 = FileUtilities.CombinePaths(vsPath64, "Common7", "IDE", "devenv.exe"); - - // Make sure VS is actually there before we suggest this root. - if (File.Exists(devEnv64)) +#if FEATURE_APPDOMAIN + // If we are, then ensure we're running MSBuild's tests by seeing if any of our assemblies are loaded. + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { - return vsPath64; + if ( + s_testAssemblies.Any( + item => item.Equals(assembly.GetName().Name, StringComparison.InvariantCultureIgnoreCase))) + return true; } +#else + return true; +#endif } - - return null; + return false; } /// @@ -320,16 +326,11 @@ private static string TryGetVsFromMSBuildLocation(string process) /// private static bool IsProcessInList(string processName, string[] processList) { - return processList.Any(s => Path.GetFileNameWithoutExtension(processName)?.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0); - } - - private static string GetProcessFromCommandLine() - { -#if FEATURE_GET_COMMANDLINE - return Environment.GetCommandLineArgs()[0]; -#else - return null; -#endif + return + processList.Any( + s => + Path.GetFileNameWithoutExtension(processName)? + .IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0); } private static string GetProcessFromRunningProcess() @@ -337,16 +338,11 @@ private static string GetProcessFromRunningProcess() return Process.GetCurrentProcess().MainModule.FileName; } - private static string GetExecutingAssmblyPath() + private static string GetExecutingAssemblyPath() { return FileUtilities.ExecutingAssemblyPath; } - private static string GetCurrentDirectory() - { - return Directory.GetCurrentDirectory(); - } - private static string GetAppContextBaseDirectory() { #if !CLR2COMPATIBILITY // Assemblies compiled against anything older than .NET 4.0 won't have a System.AppContext @@ -359,28 +355,24 @@ private static string GetAppContextBaseDirectory() /// /// Resets the current singleton instance (for testing). /// - internal static void ResetInstance_ForUnitTestsOnly(Func getProcessFromCommandLine = null, - Func getProcessFromRunningProcess = null, Func getExecutingAssmblyPath = null, - Func getCurrentDirectory = null, Func getAppContextBaseDirectory = null, + internal static void ResetInstance_ForUnitTestsOnly(Func getProcessFromRunningProcess = null, + Func getExecutingAssemblyPath = null, Func getAppContextBaseDirectory = null, Func> getVisualStudioInstances = null) { - s_getProcessFromCommandLine = getProcessFromCommandLine ?? GetProcessFromCommandLine; s_getProcessFromRunningProcess = getProcessFromRunningProcess ?? GetProcessFromRunningProcess; - s_getExecutingAssmblyPath = getExecutingAssmblyPath ?? GetExecutingAssmblyPath; - s_getCurrentDirectory = getCurrentDirectory ?? GetCurrentDirectory; - s_getVisualStudioInstances = getVisualStudioInstances ?? VisualStudioLocationHelper.GetInstances; + s_getExecutingAssemblyPath = getExecutingAssemblyPath ?? GetExecutingAssemblyPath; s_getAppContextBaseDirectory = getAppContextBaseDirectory ?? GetAppContextBaseDirectory; - + s_getVisualStudioInstances = getVisualStudioInstances ?? VisualStudioLocationHelper.GetInstances; + BuildEnvironmentHelperSingleton.s_instance = Initialize(); } - private static Func s_getProcessFromCommandLine = GetProcessFromRunningProcess; private static Func s_getProcessFromRunningProcess = GetProcessFromRunningProcess; - private static Func s_getExecutingAssmblyPath = GetExecutingAssmblyPath; - private static Func s_getCurrentDirectory = GetCurrentDirectory; + private static Func s_getExecutingAssemblyPath = GetExecutingAssemblyPath; private static Func s_getAppContextBaseDirectory = GetAppContextBaseDirectory; private static Func> s_getVisualStudioInstances = VisualStudioLocationHelper.GetInstances; + private static class BuildEnvironmentHelperSingleton { // Explicit static constructor to tell C# compiler @@ -392,41 +384,81 @@ static BuildEnvironmentHelperSingleton() } } + /// + /// Enum which defines which environment / mode MSBuild is currently running. + /// + internal enum BuildEnvironmentMode + { + /// + /// Running from Visual Studio directly or from MSBuild installed under an instance of Visual Studio. + /// Toolsets and extensions will be loaded from the Visual Studio instance. + /// + VisualStudio, + + /// + /// Running in a standalone toolset mode. All toolsets and extensions paths are relative to the app + /// running and not dependent on Visual Studio. (e.g. dotnet CLI, open source clone of our repo) + /// + Standalone, + + /// + /// Running without any defined toolsets. Most functionality limited. Likely will not be able to + /// build or evaluate a project. (e.g. reference to Microsoft.*.dll without a toolset definition + /// or Visual Studio instance installed). + /// + None + } + /// /// Defines the current environment for build tools. /// internal class BuildEnvironment { - public BuildEnvironment(string processNameCommandLine, bool runningTests, bool runningInVisualStudio, string visualStudioPath) + public BuildEnvironment(BuildEnvironmentMode mode, string currrentMSBuildExePath, bool runningTests, bool runningInVisualStudio, string visualStudioPath) { + Mode = mode; RunningTests = runningTests; RunningInVisualStudio = runningInVisualStudio; - CurrentMSBuildExePath = processNameCommandLine; - CurrentMSBuildToolsDirectory = Path.GetDirectoryName(processNameCommandLine); - CurrentMSBuildConfigurationFile = string.Concat(processNameCommandLine, ".config"); + CurrentMSBuildExePath = currrentMSBuildExePath; + CurrentMSBuildToolsDirectory = Path.GetDirectoryName(currrentMSBuildExePath); + CurrentMSBuildConfigurationFile = string.Concat(currrentMSBuildExePath, ".config"); VisualStudioInstallRootDirectory = visualStudioPath; - var isAmd64 = FileUtilities.EnsureNoTrailingSlash(CurrentMSBuildToolsDirectory) - .EndsWith("amd64", StringComparison.OrdinalIgnoreCase); - - if (isAmd64) + if (mode == BuildEnvironmentMode.VisualStudio) { - MSBuildToolsDirectory32 = FileUtilities.GetFolderAbove(CurrentMSBuildToolsDirectory); - MSBuildToolsDirectory64 = CurrentMSBuildToolsDirectory; + var isAmd64 = FileUtilities.EnsureNoTrailingSlash(CurrentMSBuildToolsDirectory) + .EndsWith("amd64", StringComparison.OrdinalIgnoreCase); + + if (isAmd64) + { + MSBuildToolsDirectory32 = FileUtilities.GetFolderAbove(CurrentMSBuildToolsDirectory); + MSBuildToolsDirectory64 = CurrentMSBuildToolsDirectory; + } + else + { + MSBuildToolsDirectory32 = CurrentMSBuildToolsDirectory; + MSBuildToolsDirectory64 = Path.Combine(CurrentMSBuildToolsDirectory, "amd64"); + } } else { MSBuildToolsDirectory32 = CurrentMSBuildToolsDirectory; - MSBuildToolsDirectory64 = Path.Combine(CurrentMSBuildToolsDirectory, "amd64"); + MSBuildToolsDirectory64 = CurrentMSBuildToolsDirectory; } + + MSBuildExtensionsPath = mode == BuildEnvironmentMode.VisualStudio + ? Path.Combine(VisualStudioInstallRootDirectory, "MSBuild") + : CurrentMSBuildToolsDirectory; } + internal BuildEnvironmentMode Mode { get; } + /// /// Gets the flag that indicates if we are running in a test harness. /// - internal bool RunningTests { get; private set; } + internal bool RunningTests { get; } /// /// Returns true when the entry point application is Visual Studio. @@ -441,7 +473,7 @@ public BuildEnvironment(string processNameCommandLine, bool runningTests, bool r /// /// Path to the MSBuild 64-bit (AMD64) tools directory. /// - internal string MSBuildToolsDirectory64 { get; private set; } + internal string MSBuildToolsDirectory64 { get; } /// /// Path to the Sdks folder for this MSBuild instance. @@ -470,7 +502,7 @@ internal string MSBuildSDKsPath /// /// Full path to the current MSBuild configuration file. /// - internal string CurrentMSBuildConfigurationFile { get; private set; } + internal string CurrentMSBuildConfigurationFile { get; } /// /// Full path to current MSBuild.exe. @@ -492,6 +524,12 @@ internal string MSBuildSDKsPath /// Path to the root Visual Studio install directory /// (e.g. 'c:\Program Files (x86)\Microsoft Visual Studio 15.0') /// - internal string VisualStudioInstallRootDirectory { get; private set; } + internal string VisualStudioInstallRootDirectory { get; } + + /// + /// MSBuild extensions path. On Standalone this defaults to the MSBuild folder. In + /// VisualStudio mode this folder will be %VSINSTALLDIR%\MSBuild. + /// + internal string MSBuildExtensionsPath { get; set; } } } \ No newline at end of file diff --git a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs index 829c8bfc209..22fcd3b49ac 100644 --- a/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BuildEnvironmentHelper_Tests.cs @@ -21,69 +21,144 @@ public class BuildEnvironmentHelper_Tests [Fact] public void GetExecutablePath() { - // This test will fail when CurrentDirectory is changed in another test. We will change it here - // to the path to Microsoft.Build.dll (debug build output folder). This is what it *should* be - // anyway. - var msbuildPath = Path.GetDirectoryName(AssemblyUtilities.GetAssemblyLocation(typeof(Project).GetTypeInfo().Assembly)); - Directory.SetCurrentDirectory(msbuildPath); - - string path = Path.Combine(Directory.GetCurrentDirectory(), MSBuildExeName).ToLowerInvariant(); - string configPath = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile.ToLowerInvariant(); - string directoryName = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory.ToLowerInvariant(); - string executablePath = BuildEnvironmentHelper.Instance.CurrentMSBuildExePath.ToLowerInvariant(); - - Assert.Equal(configPath, executablePath + ".config"); - Assert.Equal(path, executablePath); - Assert.Equal(directoryName, Path.GetDirectoryName(path)); + var msbuildPath = Path.GetDirectoryName(FileUtilities.ExecutingAssemblyPath); + string expectedMSBuildPath = Path.Combine(msbuildPath, MSBuildExeName).ToLowerInvariant(); + + string configFilePath = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile.ToLowerInvariant(); + string toolsDirectoryPath = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory.ToLowerInvariant(); + string actualMSBuildPath = BuildEnvironmentHelper.Instance.CurrentMSBuildExePath.ToLowerInvariant(); + + Assert.Equal(configFilePath, actualMSBuildPath + ".config"); + Assert.Equal(expectedMSBuildPath, actualMSBuildPath); + Assert.Equal(toolsDirectoryPath, Path.GetDirectoryName(expectedMSBuildPath)); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); } [Fact] public void FindBuildEnvironmentByEnvironmentVariable() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyStandaloneEnviroment(MSBuildExeName)) { var path = env.BuildDirectory; - var msBuildPath = Path.Combine(path, "msbuild.exe"); - var msBuildConfig = Path.Combine(path, "msbuild.exe.config"); + var msBuildPath = Path.Combine(path, MSBuildExeName); + var msBuildConfig = Path.Combine(path, $"{MSBuildExeName}.config"); Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", env.MSBuildExePath); - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(path, BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory); Assert.Equal(msBuildPath, BuildEnvironmentHelper.Instance.CurrentMSBuildExePath); Assert.Equal(msBuildConfig, BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile); Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); + Assert.Null(BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); } } [Fact] - public void FindBuildEnvironmentFromCommandLine() + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] + public void FindBuildEnvironmentFromCommandLineVisualStudio() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // All we know about is path to msbuild.exe as the command-line arg[0] - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); Assert.Equal(env.BuildDirectory64, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); + } + } + + [Fact] + public void FindBuildEnvironmentFromCommandLineStandalone() + { + // Path will not be under a Visual Studio install like path. + using (var env = new EmptyStandaloneEnviroment(MSBuildExeName)) + { + // All we know about is path to msbuild.exe as the command-line arg[0] + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnEmptyInstances); + + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); + Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); } } [Fact] - public void FindBuildEnvironmentFromRunningProcess() + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] + public void FindBuildEnvironmentFromRunningProcessVisualStudio() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // All we know about is path to msbuild.exe as the current process - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); Assert.Equal(env.BuildDirectory64, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); + } + } + + [Fact] + public void FindBuildEnvironmentFromRunningProcessStandalone() + { + // Path will not be under a Visual Studio install like path. + using (var env = new EmptyStandaloneEnviroment(MSBuildExeName)) + { + // All we know about is path to msbuild.exe as the current process + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnEmptyInstances); + + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); + Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); + } + } + + [Fact] + public void FindBuildEnvironmentFromExecutingAssemblyAsDll() + { + // Ensure the correct file is found (.dll not .exe) + using (var env = new EmptyStandaloneEnviroment("MSBuild.dll")) + { + // All we know about is path to msbuild.exe as the current process + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnEmptyInstances); + + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); + Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); + } + } + + [Fact] + public void FindBuildEnvironmentFromAppContextDirectory() + { + using (var env = new EmptyStandaloneEnviroment(MSBuildExeName)) + { + // Only the app base directory will be available + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, () => env.BuildDirectory, ReturnEmptyInstances); + + // Make sure we get the right MSBuild entry point. On .NET Core this will be MSBuild.dll, otherwise MSBuild.exe + Assert.Equal(MSBuildExeName, Path.GetFileName(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath)); + + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); + Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.False(BuildEnvironmentHelper.Instance.RunningInVisualStudio); + Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.Standalone, BuildEnvironmentHelper.Instance.Mode); } } @@ -92,16 +167,17 @@ public void FindBuildEnvironmentFromRunningProcess() [Trait("Category", "nonosxtests")] public void FindBuildEnvironmentFromVisualStudioRoot() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // All we know about is path to DevEnv.exe - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.DevEnvPath, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.DevEnvPath, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); Assert.Equal(env.BuildDirectory64, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); Assert.True(BuildEnvironmentHelper.Instance.RunningInVisualStudio); Assert.False(BuildEnvironmentHelper.Instance.RunningTests); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } @@ -110,13 +186,14 @@ public void FindBuildEnvironmentFromVisualStudioRoot() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByEnvironment() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { Environment.SetEnvironmentVariable("VSINSTALLDIR", env.TempFolderRoot); Environment.SetEnvironmentVariable("VisualStudioVersion", "15.0"); - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } @@ -125,12 +202,13 @@ public void BuildEnvironmentDetectsVisualStudioByEnvironment() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByMSBuildProcess() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // We only know we're in msbuild.exe, we should still be able to attempt to find Visual Studio - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } @@ -139,12 +217,13 @@ public void BuildEnvironmentDetectsVisualStudioByMSBuildProcess() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByMSBuildProcessAmd64() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // We only know we're in amd64\msbuild.exe, we should still be able to attempt to find Visual Studio - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath64, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.MSBuildExePath64, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } @@ -153,10 +232,10 @@ public void BuildEnvironmentDetectsVisualStudioByMSBuildProcessAmd64() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioFromSetupInstance() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // This test has no context to find MSBuild other than Visual Studio root. - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnNull, ReturnNull, + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, () => new List { @@ -165,25 +244,26 @@ public void BuildEnvironmentDetectsVisualStudioFromSetupInstance() }); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } [Fact] public void BuildEnvironmentVisualStudioNotFoundWhenVersionMismatch() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { // This test has no context to find MSBuild other than Visual Studio root. - Assert.Throws(() => - { - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnNull, ReturnNull, - () => - new List - { - new VisualStudioInstance("Invalid path", @"c:\_doesnotexist", new Version("15.0")), - new VisualStudioInstance("VS", env.TempFolderRoot, new Version("14.0")), - }); - }); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, + () => + new List + { + new VisualStudioInstance("Invalid path", @"c:\_doesnotexist", new Version("15.0")), + new VisualStudioInstance("VS", env.TempFolderRoot, new Version("14.0")), + }); + + Assert.Null(BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.None, BuildEnvironmentHelper.Instance.Mode); } } @@ -203,12 +283,13 @@ public void BuildEnvironmentDetectsRunningTests() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByProcessName() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.DevEnvPath, ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.DevEnvPath, () => env.MSBuildExePath, ReturnNull, ReturnEmptyInstances); Assert.True(BuildEnvironmentHelper.Instance.RunningInVisualStudio); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } @@ -217,47 +298,61 @@ public void BuildEnvironmentDetectsVisualStudioByProcessName() [Trait("Category", "nonosxtests")] public void BuildEnvironmentDetectsVisualStudioByBlendProcess() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.BlendPath, ReturnNull, () => env.MSBuildExePath, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.BlendPath, () => env.MSBuildExePath, ReturnNull, ReturnEmptyInstances); Assert.True(BuildEnvironmentHelper.Instance.RunningInVisualStudio); Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentFindsAmd64() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", env.MSBuildExePath); - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => env.DevEnvPath, ReturnNull, + ReturnNull, ReturnEmptyInstances); Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); Assert.Equal(env.BuildDirectory64, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } [Fact] + [Trait("Category", "nonlinuxtests")] + [Trait("Category", "nonosxtests")] public void BuildEnvironmentFindsAmd64RunningInAmd64() { - using (var env = new EmptyBuildEnviroment()) + using (var env = new EmptyVSEnviroment()) { - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", env.MSBuildExePath64); - BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnNull, ReturnNull); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(()=>env.MSBuildExePath64, ReturnNull, ReturnNull, ReturnEmptyInstances); Assert.Equal(env.BuildDirectory, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32); Assert.Equal(env.BuildDirectory64, BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64); + Assert.Equal(env.TempFolderRoot, BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.VisualStudio, BuildEnvironmentHelper.Instance.Mode); } } [Fact] - public void FindBuildEnvironmentThrowsWhenNotAvailable() + public void BuildEnvironmentNoneWhenNotAvailable() { - using (new EmptyBuildEnviroment()) + using (new EmptyStandaloneEnviroment(MSBuildExeName)) { - Assert.Throws(() => BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(ReturnNull, ReturnNull, ReturnNull, ReturnNull, ReturnNull)); + var entryProcess = Path.Combine(Path.GetTempPath(), "foo.exe"); + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(() => entryProcess, ReturnNull, ReturnNull, + ReturnEmptyInstances); + + Assert.Equal(entryProcess, BuildEnvironmentHelper.Instance.CurrentMSBuildExePath); + Assert.Equal(Path.GetDirectoryName(entryProcess), BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory); + Assert.Null(BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory); + Assert.Equal(BuildEnvironmentMode.None, BuildEnvironmentHelper.Instance.Mode); } } @@ -266,7 +361,12 @@ private static string ReturnNull() return null; } - private class EmptyBuildEnviroment : IDisposable + private static IEnumerable ReturnEmptyInstances() + { + return new List(); + } + + private class EmptyVSEnviroment : IDisposable { public string TempFolderRoot { get; } @@ -289,7 +389,7 @@ private class EmptyBuildEnviroment : IDisposable ["VisualStudioVersion"] = Environment.GetEnvironmentVariable("VisualStudioVersion"), }; - public EmptyBuildEnviroment() + public EmptyVSEnviroment() { try { @@ -332,5 +432,55 @@ public void Dispose() BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(); } } + + private class EmptyStandaloneEnviroment : IDisposable + { + public string TempFolderRoot { get; } + + public string BuildDirectory { get; } + + public string MSBuildExeName { get; } + + public string MSBuildExePath => Path.Combine(BuildDirectory, MSBuildExeName); + + private readonly Dictionary _originalEnvironment = new Dictionary + { + ["MSBUILD_EXE_PATH"] = Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH"), + ["VSINSTALLDIR"] = Environment.GetEnvironmentVariable("VSINSTALLDIR"), + ["VisualStudioVersion"] = Environment.GetEnvironmentVariable("VisualStudioVersion"), + }; + + public EmptyStandaloneEnviroment(string msBuildExeName, bool writeFakeFiles = true) + { + try + { + MSBuildExeName = msBuildExeName; + TempFolderRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + BuildDirectory = Path.Combine(TempFolderRoot, "MSBuild"); + + Directory.CreateDirectory(BuildDirectory); + if (writeFakeFiles) + { + File.WriteAllText(MSBuildExePath, string.Empty); + File.WriteAllText($"{MSBuildExePath}.config", string.Empty); + } + } + catch (Exception) + { + FileUtilities.DeleteDirectoryNoThrow(BuildDirectory, true); + throw; + } + } + + public void Dispose() + { + FileUtilities.DeleteDirectoryNoThrow(TempFolderRoot, true); + + foreach (var env in _originalEnvironment) + Environment.SetEnvironmentVariable(env.Key, env.Value); + + BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly(); + } + } } } From c3f7f72d26600b67ed105925ef19cc25cb8fe1f1 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:11:49 -0800 Subject: [PATCH 196/223] Improve MSBuildExtensionsPath discovery. Use build-in intrinsic function to get the MSBuildExtensionsPath property based on the current environment. Related to #1418 --- src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs | 5 +++++ src/XMakeCommandLine/app.amd64.config | 4 ++-- src/XMakeCommandLine/app.config | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index d78e6d9a78a..b7e7f8f99e0 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -448,6 +448,11 @@ public static string GetProgramFiles32() return FrameworkLocationHelper.programFiles32; } + public static string GetMSBuildExtensionsPath() + { + return BuildEnvironmentHelper.Instance.MSBuildExtensionsPath; + } + #region Debug only intrinsics /// diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index 89f818d2779..7814222fc50 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -72,8 +72,8 @@ - - + + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index 1a4efb99763..255ec9374bb 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -66,8 +66,8 @@ - - + + From c56af8eb70bbee209d7986a10b508c8eeb0f78f6 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:16:52 -0800 Subject: [PATCH 197/223] Remove pre-check for toolsets in config file This optimization doesn't apply if we always store toolset information in the config file. --- src/Shared/ToolsetElement.cs | 27 ------------------- .../Definition/ToolsetReader.cs | 16 ++++------- 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/src/Shared/ToolsetElement.cs b/src/Shared/ToolsetElement.cs index fdb62287889..16d0ad89b61 100644 --- a/src/Shared/ToolsetElement.cs +++ b/src/Shared/ToolsetElement.cs @@ -77,33 +77,6 @@ internal static ToolsetConfigurationSection ReadToolsetConfigurationSection(Conf return configurationSection; } - - /// - /// Creating a ToolsetConfigurationReader, and also reading toolsets from the - /// configuration file, are a little expensive. To try to avoid this cost if it's - /// not necessary, we'll check if the file exists first. If it exists, we'll scan for - /// the string "toolsVersion" to see if it might actually have any tools versions - /// defined in it. - /// - /// True if there may be toolset definitions, otherwise false - internal static bool ConfigurationFileMayHaveToolsets() - { - bool result; - - try - { - var configFile = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile; - result = File.Exists(configFile) && File.ReadAllText(configFile).Contains("toolsVersion"); - } - catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) - { - // There was some problem reading the config file: let the configuration reader - // encounter it - result = true; - } - - return result; - } } /// diff --git a/src/XMakeBuildEngine/Definition/ToolsetReader.cs b/src/XMakeBuildEngine/Definition/ToolsetReader.cs index 50a953a3eb7..8368046d737 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetReader.cs @@ -131,21 +131,15 @@ ToolsetDefinitionLocations locations #if FEATURE_SYSTEM_CONFIGURATION if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { - if (configurationReader == null && ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets()) + if (configurationReader == null) { - // We haven't been passed in a fake configuration reader by a unit test, - // and it looks like we have a .config file to read, so create a real - // configuration reader configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties); } - if (configurationReader != null) - { - // Accumulation of properties is okay in the config file because it's deterministically ordered - defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties, - initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration, - out defaultOverrideToolsVersionFromConfiguration); - } + // Accumulation of properties is okay in the config file because it's deterministically ordered + defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties, + initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration, + out defaultOverrideToolsVersionFromConfiguration); } #endif From df3a18768bbfc5360f45eaf3f42facd8b8073fdf Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:19:00 -0800 Subject: [PATCH 198/223] Don't read config file for toolsets in 'None' mode. If we didn't find a toolset (Standalone or VisualStudio mode) then do not check MSBuild config file for toolset. This will fallback to the entrypoint config file. --- .../Definition/ToolsetConfigurationReader.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/XMakeBuildEngine/Definition/ToolsetConfigurationReader.cs b/src/XMakeBuildEngine/Definition/ToolsetConfigurationReader.cs index bff7403d572..8942903b69f 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetConfigurationReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetConfigurationReader.cs @@ -258,12 +258,12 @@ private Dictionary ComputeDistinctListOfSearchPa /// private static Configuration ReadApplicationConfiguration() { - var msbuildExeConfig = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile; - - // When running from the command-line or from VS, use the msbuild.exe.config file - if (!BuildEnvironmentHelper.Instance.RunningTests && File.Exists(msbuildExeConfig)) + // When running from the command-line or from VS, use the msbuild.exe.config file. + if (BuildEnvironmentHelper.Instance.Mode != BuildEnvironmentMode.None && + !BuildEnvironmentHelper.Instance.RunningTests && + File.Exists(BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile)) { - var configFile = new ExeConfigurationFileMap { ExeConfigFilename = msbuildExeConfig }; + var configFile = new ExeConfigurationFileMap { ExeConfigFilename = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile }; return ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None); } From 238b77686278bebc1ecd2af0a5aae36bf137f114 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:20:45 -0800 Subject: [PATCH 199/223] Remove unused code. --- src/Shared/FrameworkLocationHelper.cs | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/Shared/FrameworkLocationHelper.cs b/src/Shared/FrameworkLocationHelper.cs index 261aaa30c9b..f9dadad2da5 100644 --- a/src/Shared/FrameworkLocationHelper.cs +++ b/src/Shared/FrameworkLocationHelper.cs @@ -1107,27 +1107,7 @@ private static void RedirectVersionsIfNecessary(ref Version dotNetFrameworkVersi } } -#if FEATURE_SYSTEM_CONFIGURATION - /// - /// Reads the application configuration file. - /// - private static Configuration ReadApplicationConfiguration() - { - var msbuildExeConfig = BuildEnvironmentHelper.Instance.CurrentMSBuildConfigurationFile; - - // When running from the command-line or from VS, use the msbuild.exe.config file - if (!BuildEnvironmentHelper.Instance.RunningTests && File.Exists(msbuildExeConfig)) - { - var configFile = new ExeConfigurationFileMap { ExeConfigFilename = msbuildExeConfig }; - return ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None); - } - - // When running tests or the expected config file doesn't exist, fall-back to default - return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - } -#endif - - #endregion +#endregion private class VisualStudioSpec { From 699f5c6c92e9372ef5677c31dbbac6fa64d1aad5 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Wed, 14 Dec 2016 16:21:04 -0800 Subject: [PATCH 200/223] Removing failing test that no longer applies. This test no longer applies as it does not run in 'VisualStudio' mode so ToolsPath32 and ToolsPath64 are not different. This could be re-written to emulate a VisualStudio environment and then try to extract the path, but at limited value. BuildEnvironmentHelper tests should cover the scenario. --- .../UnitTests/ToolLocationHelper_Tests.cs | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs index 0819318e8d3..3ad5ffc7096 100644 --- a/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs +++ b/src/Utilities/UnitTests/ToolLocationHelper_Tests.cs @@ -776,69 +776,6 @@ public void TestGetPathToBuildToolsFile_32Bit() Assert.Equal(tv12path, ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", ToolLocationHelper.CurrentToolsVersion, UtilitiesDotNetFrameworkArchitecture.Bitness32)); } -#if RUNTIME_TYPE_NETCORE - [Fact(Skip = "https://github.com/Microsoft/msbuild/issues/722")] -#else - [Fact] -#endif - public void TestGetPathToBuildToolsFile_64Bit() - { - if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles(x86)"))) - { - // 32-bit machine, so just ignore - return; - } - - string net20Path = ToolLocationHelper.GetPathToDotNetFrameworkFile("msbuild.exe", TargetDotNetFrameworkVersion.Version20, UtilitiesDotNetFrameworkArchitecture.Bitness64); - - if (net20Path != null) - { - Assert.Equal(net20Path, ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", "2.0", UtilitiesDotNetFrameworkArchitecture.Bitness64)); - } - - string net35Path = ToolLocationHelper.GetPathToDotNetFrameworkFile("msbuild.exe", TargetDotNetFrameworkVersion.Version35, UtilitiesDotNetFrameworkArchitecture.Bitness64); - - if (net35Path != null) - { - Assert.Equal(net35Path, ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", "3.5", UtilitiesDotNetFrameworkArchitecture.Bitness64)); - } - - Assert.Equal( - ToolLocationHelper.GetPathToDotNetFrameworkFile("msbuild.exe", TargetDotNetFrameworkVersion.Version40, UtilitiesDotNetFrameworkArchitecture.Bitness64), - ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", "4.0", UtilitiesDotNetFrameworkArchitecture.Bitness64) - ); - - var toolsPath32 = ProjectCollection.GlobalProjectCollection.GetToolset(ObjectModelHelpers.MSBuildDefaultToolsVersion).Properties["MSBuildToolsPath32"]; - var toolsPath64 = Path.Combine(Path.GetFullPath(toolsPath32.EvaluatedValue), "amd64"); - var tv12path = Path.Combine(toolsPath64, "msbuild.exe"); - bool created = false; - - try - { - // When building normally, the AMD64 folder will not exist. The method we're testing will return null if the path - // doesn't exist or msbuild.exe is not located in that path. - if (!Directory.Exists(toolsPath64)) - { - Directory.CreateDirectory(toolsPath64); - created = true; - if (!File.Exists(tv12path)) - { - File.WriteAllText(tv12path, string.Empty); - } - } - - Assert.Equal(tv12path, ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", ObjectModelHelpers.MSBuildDefaultToolsVersion, UtilitiesDotNetFrameworkArchitecture.Bitness64)); - Assert.Equal(tv12path, ToolLocationHelper.GetPathToBuildToolsFile("msbuild.exe", ToolLocationHelper.CurrentToolsVersion, UtilitiesDotNetFrameworkArchitecture.Bitness64)); - } - finally - { - if (created) - { - FileUtilities.DeleteDirectoryNoThrow(toolsPath64, true); - } - } - } - [Fact] public void TestGetDotNetFrameworkSdkRootRegistryKey() { From 2021769de2070ace2e2f21dc14092da44aa91e4e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Sun, 18 Dec 2016 12:08:09 -0800 Subject: [PATCH 201/223] Add AssemblyResolve handler for in-memory assemblies in CodeTaskFactory (#1486) * Add AssemblyResolve handler for in-memory assemblies in CodeTaskFactory Closes #954 --- src/XMakeTasks/CodeTaskFactory.cs | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/XMakeTasks/CodeTaskFactory.cs b/src/XMakeTasks/CodeTaskFactory.cs index 6fb9a56841e..7303f598029 100644 --- a/src/XMakeTasks/CodeTaskFactory.cs +++ b/src/XMakeTasks/CodeTaskFactory.cs @@ -30,6 +30,37 @@ namespace Microsoft.Build.Tasks /// public class CodeTaskFactory : ITaskFactory { + /// + /// This dictionary keeps track of custom references to compiled assemblies. The in-memory assembly is loaded from a byte + /// stream and as such its dependencies cannot be found unless they are in the MSBuild.exe directory or the GAC. They + /// cannot be found even if they are already loaded in the AppDomain. This dictionary knows the FullName of the assembly + /// and a reference to the assembly itself. In the handler, the dictionary + /// is used to return the loaded assemblies as a way to allow custom references that are not in the normal assembly Load + /// context. + /// + private static readonly IDictionary s_knownReferenceAssemblies = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + + static CodeTaskFactory() + { + // The handler is not detached because it only returns assemblies for custom references that cannot be found in the normal Load context + AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; + } + + /// + /// Handles the event to return assemblies loaded from custom references. + /// + /// + /// + /// + private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) + { + Assembly assembly = null; + // Return the assembly loaded from the custom reference if the FullName matches what is being looked for + s_knownReferenceAssemblies.TryGetValue(args.Name, out assembly); + + return assembly; + } + /// /// Default assemblies names to reference during inline code compilation - from the .NET Framework /// @@ -657,6 +688,7 @@ private void AddReferenceAssemblyToReferenceList(List referenceAssemblyL if (candidateAssembly != null) { candidateAssemblyLocation = candidateAssembly.Location; + s_knownReferenceAssemblies[candidateAssembly.FullName] = candidateAssembly; } } catch (BadImageFormatException e) From d00f784379da5082c417b8b03478e12e27b9e71b Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Tue, 20 Dec 2016 23:47:43 +0100 Subject: [PATCH 202/223] Don't use mscoree.dll on Nano Server (or .NET Core); it is part of NetFX and not available on .NET Core (#1495) Fixes #1233 --- dir.props | 1 + src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs | 4 ++++ src/XMakeTasks/NativeMethods.cs | 2 ++ 3 files changed, 7 insertions(+) diff --git a/dir.props b/dir.props index cd44b29982a..276a30aa41c 100644 --- a/dir.props +++ b/dir.props @@ -346,6 +346,7 @@ $(DefineConstants);FEATURE_WIN32_REGISTRY $(DefineConstants);FEATURE_WORKINGSET $(DefineConstants);FEATURE_VISUALSTUDIOSETUP + $(DefineConstants);FEATURE_MSCOREE diff --git a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs index d235640fc45..264cdee763d 100644 --- a/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs +++ b/src/XMakeTasks/AssemblyDependency/AssemblyInformation.cs @@ -457,6 +457,7 @@ protected override void DisposeUnmanagedResources() /// The CLR runtime version or empty if the path does not exist. internal static string GetRuntimeVersion(string path) { +#if FEATURE_MSCOREE if (NativeMethodsShared.IsWindows) { StringBuilder runtimeVersion = null; @@ -489,6 +490,9 @@ internal static string GetRuntimeVersion(string path) { return ManagedRuntimeVersionReader.GetRuntimeVersion(path); } +#else + return ManagedRuntimeVersionReader.GetRuntimeVersion(path); +#endif } diff --git a/src/XMakeTasks/NativeMethods.cs b/src/XMakeTasks/NativeMethods.cs index 78edfb81a46..a0e7e4f29d3 100644 --- a/src/XMakeTasks/NativeMethods.cs +++ b/src/XMakeTasks/NativeMethods.cs @@ -1304,6 +1304,7 @@ internal enum AssemblyComparisonResult [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CertFreeCertificateContext(IntPtr CertContext); +#if FEATURE_MSCOREE /// /// Get the runtime version for a given file /// @@ -1314,6 +1315,7 @@ internal enum AssemblyComparisonResult /// HResult [DllImport(MscoreeDLL, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern uint GetFileVersion(String szFullPath, StringBuilder szBuffer, int cchBuffer, out uint dwLength); +#endif #endregion #region Methods From c07d1db67f80ac9d018723270b9f3405721586bf Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 20 Dec 2016 18:06:43 -0500 Subject: [PATCH 203/223] cibuild.sh: Improve mono builds (#1502) * cibuild.sh: For mono host or target builds, check if mono is installed * cibuild.sh: Print path to mono and version * cibuild.sh: Setup explicit mono specific CSC_ARGS only when host=Mono --- cibuild.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cibuild.sh b/cibuild.sh index 91935d34cc4..a858664738c 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -222,6 +222,16 @@ if [ "$target" = "" ]; then target=CoreCLR fi +if [ "$host" = "Mono" ]; then + # check if mono is available + echo "debug: which mono: `which mono`" + echo "MONO_BIN_DIR: $MONO_BIN_DIR" + if [ "`which mono`" = "" -a "$MONO_BIN_DIR" = "" ]; then + echo "** Error: Building with host Mono, requires Mono to be installed." + exit 1 + fi +fi + case $target in CoreCLR) CONFIGURATION=Debug-NetCore @@ -231,7 +241,6 @@ case $target in Mono) setMonoDir CONFIGURATION=Debug-MONO - CSC_ARGS="/p:CscToolExe=csc.exe /p:CscToolPath=$PACKAGES_DIR/msbuild/ /p:DebugType=portable" RUNTIME_HOST_ARGS="--debug" MSBUILD_BOOTSTRAPPED_EXE='"'"$THIS_SCRIPT_PATH/bin/Bootstrap/MSBuild.dll"'"' ;; @@ -262,6 +271,12 @@ case $host in setMonoDir RUNTIME_HOST="${MONO_BIN_DIR}mono" MSBUILD_EXE="$PACKAGES_DIR/msbuild/MSBuild.exe" + CSC_ARGS="/p:CscToolExe=csc.exe /p:CscToolPath=$PACKAGES_DIR/msbuild/ /p:DebugType=portable" + + if [[ "$MONO_BIN_DIR" != "" ]]; then + echo "** Using mono from $RUNTIME_HOST" + $RUNTIME_HOST --version + fi downloadMSBuildForMono ;; From 7acd48c077a4d38dcbcb3062c7ea306d10f38e5a Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 20 Dec 2016 18:06:53 -0500 Subject: [PATCH 204/223] Add Mono CI build results to README.md (#1500) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7eed983b64d..3958078414b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ The current development branch is `xplat`. It builds for .NET Core and the full |:------|:------:|:------:|:------:|:------:| | **Full Framework** |[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_Desktop)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_Desktop)| N/A | N/A | N/A | |**.NET Core**|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu14.04_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu14.04_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu16.04_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu16.04_CoreCLR)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_OSX_CoreCLR)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_OSX_CoreCLR)| +|**Mono**|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_Mono)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_Mono)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu14.04_Mono)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu14.04_Mono)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu16.04_Mono)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu16.04_Mono)|[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_OSX_Mono)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_OSX_Mono)| Full-framework-only build from `master` (deprecated): [![Build Status](https://ci2.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_master_Windows_NT_Desktop)](https://ci2.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_master_Windows_NT_Desktop) From 468a19f25332d00b1e9e505880251b7996d0b706 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 3 Jan 2017 14:26:31 -0800 Subject: [PATCH 205/223] Checker for Microbuild output (#1473) * Checker for Microbuild output Checker for MSBuild's internal build that verifies that the layout looks good, assemblies are signed, etc. Not intended to general use (internal build only). --- build/MicrobuildTest.ps1 | 415 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 build/MicrobuildTest.ps1 diff --git a/build/MicrobuildTest.ps1 b/build/MicrobuildTest.ps1 new file mode 100644 index 00000000000..7d3faa61ae3 --- /dev/null +++ b/build/MicrobuildTest.ps1 @@ -0,0 +1,415 @@ +param ( + [Parameter(Mandatory = $false)] + [string] $CPVSDrop +) + +function CombineAndNormalize([string[]] $paths) { + $combined = [System.IO.Path]::Combine($paths) + return [System.IO.Path]::GetFullPath($combined) +} + +function Log ($a) { + Write-Host `n + Write-Host $a.ToString() +} + +function Test-AssemblyStrongNamed($assemblyPath) { + [System.Reflection.Assembly]::ReflectionOnlyLoadFrom($assemblyPath).GetName().GetPublicKeyToken().Count -gt 0 +} + +class BuildInstance { + static $languages = @("cs", "de", "en", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-Hans", "zh-Hant") + + [string] $Root + + [string[]] $AssemblyNames = @( + "Microsoft.Build.dll", + "Microsoft.Build.Framework.dll", + "Microsoft.Build.Tasks.Core.dll", + "Microsoft.Build.Utilities.Core.dll" + ) + + [string[]] $SatelliteAssemblyNames = @( + "Microsoft.Build.Conversion.Core.resources.dll", + "Microsoft.Build.Engine.resources.dll", + "Microsoft.Build.resources.dll", + "Microsoft.Build.Tasks.Core.resources.dll", + "Microsoft.Build.Utilities.Core.resources.dll", + "MSBuild.resources.dll", + "MSBuildTaskHost.resources.dll" + ) + + BuildInstance([String] $root) { + $this.Root = $root + } + + [string[]] BuildFiles() { + return $this.ResolvedAssemblies() + $this.ResolvedSatelliteAssemblies() + } + + [string[]] ResolvedAssemblies() { + return $this.AssemblyNames | foreach{CombineAndNormalize($this.Root, $_)} + } + + [string[]] ResolvedSatelliteAssemblies() { + $satellites = @() + + if (-Not ($this.IsLocalized())) { + return $satellites + } + + foreach ($l in [BuildInstance]::languages) { + foreach ($s in $this.SatelliteAssemblyNames) { + $satellites += CombineAndNormalize(@($this.Root, $l, $s)) + } + } + + return $satellites + } + + [bool] IsLocalized() { + return $this.Root -match ".*(x86|x64).*" + } + + [String] ToString() { + return $this.Root + "`n`n" + (($this.BuildFiles() | foreach{"`t`t" + $_.ToString()}) -join "`n") + } + + Check([Checker] $checker) { + $checker.Check($this) + } +} + +class FullFrameworkBuildInstance : BuildInstance{ + FullFrameworkBuildInstance([String] $root) : base ($root) { + ([BuildInstance]$this).AssemblyNames += @( + "MSBuild.exe", + "MSBuildTaskHost.exe", + "Microsoft.Build.Conversion.Core.dll", + "Microsoft.Build.Engine.dll" + ) + } +} + +class NetCoreBuildInstance : BuildInstance{ + NetCoreBuildInstance([String] $root) : base ($root) { + ([BuildInstance]$this).AssemblyNames += "MSBuild.dll" + } +} + +class NugetPackage{ + [String] $Path + + NugetPackage([string] $Path) { + $this.Path = $Path + } + + Check([Checker] $checker) { + $checker.Check($this) + } + + [string] ToString() { + return "NugetPackage: $($this.Path)" + } +} + +class VsixPackage{ + static [string] $PackageName = "Microsoft.Build.vsix" + [String] $Path + + VsixPackage([string] $path) { + $this.Path = CombineAndNormalize($path, [VsixPackage]::PackageName) + } + + Check([Checker] $checker) { + $checker.Check($this) + } + + [string] ToString() { + return "Vsix package: $($this.Path)" + } +} + +class Layout { + + [String] $FFx86; + [String] $FFx64; + [String] $FFAnyCPU; + [String] $CoreAnyCPU; + [String] $NugetPackagePath; + [String] $VsixPath; + + [BuildInstance[]] $BuildInstances + [NugetPackage[]] $NugetPackages + [VsixPackage] $VsixPackage + + Layout($FFx86, $FFx64, $FFAnyCPU, $CoreAnyCPU, $NugetPackagePath, $VsixPath) { + $this.FFx86 = $FFx86 + $this.FFx64 = $FFx64 + $this.FFAnyCPU = $FFAnyCPU + $this.CoreAnyCPU = $CoreAnyCPU + $this.NugetPackagePath = $NugetPackagePath + $this.VsixPath = $VsixPath + + $this.BuildInstances = @( + [FullFrameworkBuildInstance]::new($this.FFx86), + [FullFrameworkBuildInstance]::new($this.FFx64), + [FullFrameworkBuildInstance]::new($this.FFAnyCPU), + [NetCoreBuildInstance]::new($this.CoreAnyCPU) + ) + + $this.NugetPackages = Get-ChildItem $nugetPackagePath *.nupkg | foreach {[NugetPackage]::new($_.FullName)} + $this.VsixPackage = [VsixPackage]::new($VsixPath) + } + + [String] ToString() { + $instances = ($this.BuildInstances | foreach{ "`t" + $_.ToString() }) -join "`n`n" + $nugets = ($this.NugetPackages | foreach{"`t" + $_.ToString()}) -join "`n" + return "Build Instances:`n$instances`n`nNuget Packages`n$($nugets)`n`n$($this.VsixPackage.ToString())" + } + + static [Layout] FromMicrobuild() { + $root = $env:BUILD_REPOSITORY_LOCALPATH + + $layout = [Layout]::new( + (CombineAndNormalize @($root, $env:FFBinPath86)), + (CombineAndNormalize @($root, $env:FFBinPath64)), + (CombineAndNormalize @($root, $env:BinPath)), + (CombineAndNormalize @($root, $env:BinPathNetCore)), + (CombineAndNormalize @($root, $env:NugetPackagePathPath)), + (CombineAndNormalize @($root, $env:SetupLayoutPath))) + + return $layout + } + + static [Layout] FromCPVSDrop([string] $root) { + + $layout = [Layout]::new( + (CombineAndNormalize @($root, "bin\x86\Windows_NT\Release\Output")), + (CombineAndNormalize @($root, "bin\x64\Windows_NT\Release\Output")), + (CombineAndNormalize @($root, "bin\Release\Output")), + (CombineAndNormalize @($root, "bin\Release-NetCore\Output")), + (CombineAndNormalize @($root, "bin\Packages")), + (CombineAndNormalize @($root, "pkg"))) + + return $layout + } + + Check([Checker] $checker) { + $checker.Check($this) + + $this.BuildInstances | foreach {$_.Check($checker)} + $this.NugetPackages | foreach {$_.Check($checker)} + $this.VsixPackage.Check($checker) + } +} + +class Diagnostic{ + [String] $Type + [String] $Message + + Diagnostic([String] $type, [String] $message) { + $this.Type = $type + $this.Message = $message + } +} + +class Checker{ + [Diagnostic[]] $Diagnostics = @() + + Check($obj) { + $diags = $this.HandleObject($obj) + + if ($diags -ne $null) { + $this.Diagnostics += $diags + } + } + + [Diagnostic[]] HandleObject($obj) { + $type = $obj.GetType() + + $diags = @() + + if ($type -eq [Layout]) { + $diags = $this.CheckLayout($obj) + } + elseif ($type -eq [FullFrameworkBuildInstance]) { + $diags = $this.CheckFullFrameworkBuildInstance($obj) + } + elseif ($type -eq [NetCoreBuildInstance]) { + $diags = $this.CheckNetCoreBuildInstance($obj) + } + elseif ($type -eq [NugetPackage]) { + $diags = $this.CheckNugetPackage($obj) + } + elseif ($type -eq [VsixPackage]) { + $diags = $this.CheckVSixPackage($obj) + } + else { + $diags = $this.HandleUnknownType($obj, $type) + } + + return $diags + } + + [Diagnostic[]] HandleUnknownType($obj, [Type] $type) { + throw [System.NotImplementedException] + } + + [Diagnostic[]] CheckLayout([Layout] $l) {return @()} + [Diagnostic[]] CheckFullFrameworkBuildInstance([FullFrameworkBuildInstance] $b) {return @()} + [Diagnostic[]] CheckNetCoreBuildInstance([NetCoreBuildInstance] $b) {return @()} + [Diagnostic[]] CheckNugetPackage([NugetPackage] $n) {return @()} + [Diagnostic[]] CheckVSixPackage([VsixPackage] $v) {return @()} + + [Diagnostic] NewDiagnostic([String] $message) { + return [Diagnostic]::new($this.GetType().Name, $message) + } +} + +class TestChecker : Checker{ + [Diagnostic[]] CheckLayout([Layout] $l) {return $this.NewDiagnostic("Checked Layout")} + [Diagnostic[]] CheckFullFrameworkBuildInstance([FullFrameworkBuildInstance] $b) {return $this.NewDiagnostic("Checked FF Build Instance: $($b.Root)")} + [Diagnostic[]] CheckNetCoreBuildInstance([NetCoreBuildInstance] $b) {return $this.NewDiagnostic("Checked Core Build Instance: $($b.Root)")} + [Diagnostic[]] CheckNugetPackage([NugetPackage] $n) {return $this.NewDiagnostic("Checked Nuget Package: $($n.Path)")} + [Diagnostic[]] CheckVSixPackage([VsixPackage] $v) {return $this.NewDiagnostic("Checked VsixPackage: $($v.Path)")} +} + +class FileChecker : Checker{ + $ExpectedNumberOfNugetPackages = 7 + + [Diagnostic[]] CheckPathExists([string] $path) { + if (-Not (Test-Path $path)) { + return $this.NewDiagnostic("Path does not exist: $path"); + } + + return @() + } + + [Diagnostic[]] CheckLayout([Layout] $l) { + $diags = @() + + $diags += $this.CheckPathExists($l.FFx86) + $diags += $this.CheckPathExists($l.FFx64) + $diags += $this.CheckPathExists($l.FFAnyCPU) + $diags += $this.CheckPathExists($l.CoreAnyCPU) + $diags += $this.CheckPathExists($l.NugetPackagePath) + $diags += $this.CheckPathExists($l.VsixPath) + + if ($l.NugetPackages.Count -ne $this.ExpectedNumberOfNugetPackages) { + $diags += $this.NewDiagnostic("There should be $($this.ExpectedNumberOfNugetPackages) nuget packages in $($l.NugetPackagePath) but $($l.NugetPackages.Count) were found") + } + + return $diags + } + + [Diagnostic[]] CheckBuildInstance([BuildInstance] $b) { + return $b.BuildFiles() | foreach{$this.CheckPathExists($_)} + } + + [Diagnostic[]] CheckFullFrameworkBuildInstance([FullFrameworkBuildInstance] $b) { + return $this.CheckBuildInstance($b) + } + + [Diagnostic[]] CheckNetCoreBuildInstance([NetCoreBuildInstance] $b) { + return $this.CheckBuildInstance($b) + } + + [Diagnostic[]] CheckNugetPackage([NugetPackage] $n) { + return $this.CheckPathExists($n.Path) + } + + [Diagnostic[]] CheckVSixPackage([VsixPackage] $v) { + return $this.CheckPathExists($v.Path) + } +} + +class RealSignedChecker : Checker { + [Diagnostic[]] CheckIsSigned([String] $assembly) { + if (-Not (Test-Path $assembly)) { + return @() + } + + $signature = Get-AuthenticodeSignature $assembly + + $looksRealSigned = $signature.Status -eq [System.Management.Automation.SignatureStatus]::Valid + $looksRealSigned = $looksRealSigned -and ($signature.SignatureType -eq [System.Management.Automation.SignatureType]::Authenticode) + $looksRealSigned = $looksRealSigned -and ($signature.SignerCertificate.Issuer -match ".*Microsoft.*Redmond.*") + $looksRealSigned = $looksRealSigned -and (-not ($signature.SignerCertificate.Issuer -match "Test")) + + if (-Not $looksRealSigned) { + $strongNamed = Test-AssemblyStrongNamed($assembly) + return $this.NewDiagnostic("Assembly not real signed: $assembly.`nStrong named: $strongNamed; CertificateIssuer: [$($signature.SignerCertificate.Issuer)]") + } + + return @() + } + + [Diagnostic[]] CheckBuildInstance([BuildInstance] $b) { + return $b.BuildFiles() | foreach{$this.CheckIsSigned($_)} + } + + [Diagnostic[]] CheckFullFrameworkBuildInstance([FullFrameworkBuildInstance] $b) { + return $this.CheckBuildInstance($b) + } + + [Diagnostic[]] CheckNetCoreBuildInstance([NetCoreBuildInstance] $b) { + return $this.CheckBuildInstance($b) + } +} + +class NugetVersionChecker : Checker { + [Diagnostic[]] CheckNugetPackage([NugetPackage] $n) { + $packageNameRegex = "Microsoft\.Build\..*\d+\.\d+\.\d+.*\.nupkg" + $packageName = [System.IO.Path]::GetFileName($n.Path) + + if (-Not ($packageName -match $packageNameRegex)) { + return $this.NewDiagnostic("Package `"$packageName`" does not match regex `"$packageNameRegex`"") + } + + return @() + } +} + +[String[]] $diagnostics = @() + +$layout = $null + +if ($CPVSDrop) { + Log "Used `$CPVSDrop=$CPVSDrop" + $layout = [Layout]::FromCPVSDrop($CPVSDrop) +} +else { + Log "Running inside microbuild environment" + $layout = [Layout]::FromMicrobuild() +} + +Log $layout + +# $checkers = @([TestChecker]::new()) +$checkers = @( + [FileChecker]::new(), + [RealSignedChecker]::new(), + [NugetVersionChecker]::new() + ) + +$checkers | foreach{$layout.Check($_)} + +$diagnosticCount = 0 + +Log "Failed checks:" + +foreach ($checker in $checkers) { + $diags = $checker.Diagnostics + + $diagnosticCount += $diags.Count + + $diags | foreach{Log "$($_.Type): $($_.Message)"} +} + +if ($diagnosticCount -eq 0) { + Log "No failed checks" +} +else { + Log "$diagnosticCount failed checks" +} From bdb4af3e3753238a874a9ccb02a7f2d7dbb49ab8 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 3 Jan 2017 14:31:53 -0800 Subject: [PATCH 206/223] Generate targets in metaproj (#1497) * Generate targets in metaproj This allows users to access any target when building a solution. The target may or may not exist but this will create the corresponding targets in the `.metaproj`. I had to pass along the target names from the build request all the way down to the solution generator via ReadOnlyCollections. Closes #1275 Might be related to #1494 --- .../BackEnd/BuildManager/BuildManager.cs | 2 +- .../Shared/BuildRequestConfiguration.cs | 7 + .../Solution/SolutionProjectGenerator.cs | 75 ++- .../Instance/ProjectInstance.cs | 12 +- .../Construction/SolutionFile_Tests.cs | 268 +++++------ .../SolutionProjectGenerator_Tests.cs | 450 ++++++++++-------- 6 files changed, 462 insertions(+), 352 deletions(-) diff --git a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs index 0cb3cdd8a8d..04a4519bd7e 100644 --- a/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs +++ b/src/XMakeBuildEngine/BackEnd/BuildManager/BuildManager.cs @@ -911,7 +911,7 @@ internal void LoadSolutionIntoConfiguration(BuildRequestConfiguration config, Bu } ErrorUtilities.VerifyThrow(FileUtilities.IsSolutionFilename(config.ProjectFullPath), "{0} is not a solution", config.ProjectFullPath); - ProjectInstance[] instances = ProjectInstance.LoadSolutionForBuild(config.ProjectFullPath, config.Properties, config.ExplicitToolsVersionSpecified ? config.ToolsVersion : null, _buildParameters, ((IBuildComponentHost)this).LoggingService, buildEventContext, false /* loaded by solution parser*/); + ProjectInstance[] instances = ProjectInstance.LoadSolutionForBuild(config.ProjectFullPath, config.Properties, config.ExplicitToolsVersionSpecified ? config.ToolsVersion : null, _buildParameters, ((IBuildComponentHost)this).LoggingService, buildEventContext, false /* loaded by solution parser*/, config.TargetNames); // The first instance is the traversal project, which goes into this configuration config.Project = instances[0]; diff --git a/src/XMakeBuildEngine/BackEnd/Shared/BuildRequestConfiguration.cs b/src/XMakeBuildEngine/BackEnd/Shared/BuildRequestConfiguration.cs index 4f05fb4afc0..ff12ccc1111 100644 --- a/src/XMakeBuildEngine/BackEnd/Shared/BuildRequestConfiguration.cs +++ b/src/XMakeBuildEngine/BackEnd/Shared/BuildRequestConfiguration.cs @@ -140,6 +140,11 @@ internal class BuildRequestConfiguration : IEquatable #endregion + /// + /// The target names that were requested to execute. + /// + internal IReadOnlyCollection TargetNames { get; } + /// /// Initializes a configuration from a BuildRequestData structure. Used by the BuildManager. /// Figures out the correct tools version to use, falling back to the provided default if necessary. @@ -172,6 +177,7 @@ internal BuildRequestConfiguration(int configId, BuildRequestData data, string d _explicitToolsVersionSpecified = data.ExplicitToolsVersionSpecified; _toolsVersion = ResolveToolsVersion(data, defaultToolsVersion, getToolset); _globalProperties = data.GlobalPropertiesDictionary; + TargetNames = new List(data.TargetNames); // The following information only exists when the request is populated with an existing project. if (data.ProjectInstance != null) @@ -237,6 +243,7 @@ private BuildRequestConfiguration(int configId, BuildRequestConfiguration other) _globalProperties = other._globalProperties; this.IsCacheable = other.IsCacheable; _configId = configId; + TargetNames = other.TargetNames; } /// diff --git a/src/XMakeBuildEngine/Construction/Solution/SolutionProjectGenerator.cs b/src/XMakeBuildEngine/Construction/Solution/SolutionProjectGenerator.cs index 3e99890b068..973c36e6418 100644 --- a/src/XMakeBuildEngine/Construction/Solution/SolutionProjectGenerator.cs +++ b/src/XMakeBuildEngine/Construction/Solution/SolutionProjectGenerator.cs @@ -8,8 +8,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Xml; @@ -52,6 +55,11 @@ internal class SolutionProjectGenerator /// private const string SolutionConfigurationAndPlatformProperties = "Configuration=$(Configuration); Platform=$(Platform)"; + /// + /// A known list of target names to create. This is for backwards compatibility. + /// + private readonly ISet _knownTargetNames = ImmutableHashSet.Create(StringComparer.OrdinalIgnoreCase, "Build", "Clean", "Rebuild", "Publish"); + /// /// Version 2.0 /// @@ -103,6 +111,11 @@ internal class SolutionProjectGenerator /// private ILoggingService _loggingService; + /// + /// The list of targets specified to use. + /// + private readonly IReadOnlyCollection _targetNames = new Collection(); + /// /// The solution configuration selected for this build. /// @@ -121,7 +134,8 @@ private SolutionProjectGenerator IDictionary globalProperties, string toolsVersionOverride, BuildEventContext projectBuildEventContext, - ILoggingService loggingService + ILoggingService loggingService, + IReadOnlyCollection targetNames ) { _solutionFile = solution; @@ -129,6 +143,17 @@ ILoggingService loggingService _toolsVersionOverride = toolsVersionOverride; _projectBuildEventContext = projectBuildEventContext; _loggingService = loggingService; + + if (targetNames != null) + { + // Special target names are generated for each project like My_Project:Clean. If the user specified a value like + // that then we need to split by the first colon and assume the rest is a real target name. This works unless the + // target has a colon in it and the user is not trying to run it in a specific project. At the time of writing this + // we figured it unlikely that a target name would have a colon in it... + + // The known target names are also removed from the list in case something like /t:Build was specified it is just ignored + _targetNames = targetNames.Select(i => i.Split(new[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries).Last()).Except(_knownTargetNames, StringComparer.OrdinalIgnoreCase).ToList(); + } } #endregion // Constructors @@ -144,6 +169,7 @@ ILoggingService loggingService /// Tools Version override (may be null). This should be any tools version explicitly passed to the command-line or from an MSBuild ToolsVersion parameter. /// The logging context for this project. /// The logging service. + /// A collection of target names the user requested to be built. /// An array of ProjectInstances. The first instance is the traversal project, the remaining are the metaprojects for each project referenced in the solution. internal static ProjectInstance[] Generate ( @@ -151,7 +177,8 @@ internal static ProjectInstance[] Generate IDictionary globalProperties, string toolsVersionOverride, BuildEventContext projectBuildEventContext, - ILoggingService loggingService + ILoggingService loggingService, + IReadOnlyCollection targetNames = default(IReadOnlyCollection) ) { SolutionProjectGenerator projectGenerator = new SolutionProjectGenerator @@ -160,7 +187,8 @@ ILoggingService loggingService globalProperties, toolsVersionOverride, projectBuildEventContext, - loggingService + loggingService, + targetNames ); return projectGenerator.Generate(); @@ -745,6 +773,12 @@ private void EvaluateAndAddProjects(List projectsInOrder, Lis AddTraversalTargetForProject(traversalInstance, project, projectConfiguration, "Rebuild", "BuildOutput", canBuildDirectly); AddTraversalTargetForProject(traversalInstance, project, projectConfiguration, "Publish", null, canBuildDirectly); + // Add any other targets specified by the user + foreach (string targetName in _targetNames) + { + AddTraversalTargetForProject(traversalInstance, project, projectConfiguration, targetName, null, canBuildDirectly); + } + // If we cannot build the project directly, then we need to generate a metaproject for it. if (!canBuildDirectly) { @@ -767,6 +801,10 @@ private void AddStandardTraversalTargets(ProjectInstance traversalInstance, List AddTraversalReferencesTarget(traversalInstance, "Clean", null); AddTraversalReferencesTarget(traversalInstance, "Rebuild", "CollectedBuildOutput"); AddTraversalReferencesTarget(traversalInstance, "Publish", null); + foreach (string targetName in _targetNames) + { + AddTraversalReferencesTarget(traversalInstance, targetName, null); + } } /// @@ -832,10 +870,10 @@ private ProjectInstance CreateTraversalInstance(string wrapperProjectToolsVersio // These are just dummies necessary to make the evaluation into a project instance succeed when // any custom imported targets have declarations like BeforeTargets="Build" // They'll be replaced momentarily with the real ones. - traversalProject.AddTarget("Build"); - traversalProject.AddTarget("Rebuild"); - traversalProject.AddTarget("Clean"); - traversalProject.AddTarget("Publish"); + foreach (string targetName in _knownTargetNames.Union(_targetNames)) + { + traversalProject.AddTarget(targetName); + } // For debugging purposes: some information is lost when evaluating into a project instance, // so make it possible to see what we have at this point. @@ -857,10 +895,10 @@ private ProjectInstance CreateTraversalInstance(string wrapperProjectToolsVersio ); // Make way for the real ones - traversalInstance.RemoveTarget("Build"); - traversalInstance.RemoveTarget("Rebuild"); - traversalInstance.RemoveTarget("Clean"); - traversalInstance.RemoveTarget("Publish"); + foreach (string targetName in _knownTargetNames.Union(_targetNames)) + { + traversalInstance.RemoveTarget(targetName); + } AddStandardTraversalTargets(traversalInstance, projectsInOrder); @@ -1050,6 +1088,11 @@ private ProjectInstance CreateMetaproject(ProjectInstance traversalProject, Proj AddMetaprojectTargetForWebProject(traversalProject, metaprojectInstance, project, "Clean"); AddMetaprojectTargetForWebProject(traversalProject, metaprojectInstance, project, "Rebuild"); AddMetaprojectTargetForWebProject(traversalProject, metaprojectInstance, project, "Publish"); + + foreach (string targetName in _targetNames) + { + AddMetaprojectTargetForWebProject(traversalProject, metaprojectInstance, project, targetName); + } } else if ((project.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) || (project.CanBeMSBuildProjectFile(out unknownProjectTypeErrorMessage))) @@ -1061,6 +1104,11 @@ private ProjectInstance CreateMetaproject(ProjectInstance traversalProject, Proj AddMetaprojectTargetForManagedProject(traversalProject, metaprojectInstance, project, projectConfiguration, null, targetOutputItemName); AddMetaprojectTargetForManagedProject(traversalProject, metaprojectInstance, project, projectConfiguration, "Rebuild", targetOutputItemName); AddMetaprojectTargetForManagedProject(traversalProject, metaprojectInstance, project, projectConfiguration, "Publish", null); + + foreach (string targetName in _targetNames) + { + AddMetaprojectTargetForManagedProject(traversalProject, metaprojectInstance, project, projectConfiguration, targetName, null); + } } else { @@ -1068,6 +1116,11 @@ private ProjectInstance CreateMetaproject(ProjectInstance traversalProject, Proj AddMetaprojectTargetForUnknownProjectType(traversalProject, metaprojectInstance, project, "Clean", unknownProjectTypeErrorMessage); AddMetaprojectTargetForUnknownProjectType(traversalProject, metaprojectInstance, project, "Rebuild", unknownProjectTypeErrorMessage); AddMetaprojectTargetForUnknownProjectType(traversalProject, metaprojectInstance, project, "Publish", unknownProjectTypeErrorMessage); + + foreach (string targetName in _targetNames) + { + AddMetaprojectTargetForUnknownProjectType(traversalProject, metaprojectInstance, project, targetName, unknownProjectTypeErrorMessage); + } } return metaprojectInstance; diff --git a/src/XMakeBuildEngine/Instance/ProjectInstance.cs b/src/XMakeBuildEngine/Instance/ProjectInstance.cs index 70b30f4e226..3b2f31414ad 100644 --- a/src/XMakeBuildEngine/Instance/ProjectInstance.cs +++ b/src/XMakeBuildEngine/Instance/ProjectInstance.cs @@ -1716,7 +1716,7 @@ void INodePacketTranslatable.Translate(INodePacketTranslator translator) /// /// Creates a set of project instances which represent the project dependency graph for a solution build. /// - internal static ProjectInstance[] LoadSolutionForBuild(string projectFile, PropertyDictionary globalPropertiesInstances, string toolsVersion, BuildParameters buildParameters, ILoggingService loggingService, BuildEventContext projectBuildEventContext, bool isExplicitlyLoaded) + internal static ProjectInstance[] LoadSolutionForBuild(string projectFile, PropertyDictionary globalPropertiesInstances, string toolsVersion, BuildParameters buildParameters, ILoggingService loggingService, BuildEventContext projectBuildEventContext, bool isExplicitlyLoaded, IReadOnlyCollection targetNames) { ErrorUtilities.VerifyThrowArgumentLength(projectFile, "projectFile"); ErrorUtilities.VerifyThrowArgumentNull(globalPropertiesInstances, "globalPropertiesInstances"); @@ -1748,7 +1748,7 @@ internal static ProjectInstance[] LoadSolutionForBuild(string projectFile, Prope } else { - projectInstances = GenerateSolutionWrapper(projectFile, globalProperties, toolsVersion, loggingService, projectBuildEventContext); + projectInstances = GenerateSolutionWrapper(projectFile, globalProperties, toolsVersion, loggingService, projectBuildEventContext, targetNames); } } @@ -1785,7 +1785,7 @@ internal static ProjectInstance[] LoadSolutionForBuild(string projectFile, Prope } string toolsVersionToUse = Utilities.GenerateToolsVersionToUse(explicitToolsVersion: null, toolsVersionFromProject: toolsVersion, getToolset: buildParameters.GetToolset, defaultToolsVersion: Constants.defaultSolutionWrapperProjectToolsVersion); - projectInstances = GenerateSolutionWrapper(projectFile, globalProperties, toolsVersionToUse, loggingService, projectBuildEventContext); + projectInstances = GenerateSolutionWrapper(projectFile, globalProperties, toolsVersionToUse, loggingService, projectBuildEventContext, targetNames); } } @@ -2010,6 +2010,7 @@ internal void VerifyThrowNotImmutable() /// The ToolsVersion to use when generating the wrapper. /// The logging service used to log messages etc. from the solution wrapper generator. /// The build event context in which this project is being constructed. + /// A collection of target names that the user requested be built. /// The ProjectRootElement for the root traversal and each of the metaprojects. private static ProjectInstance[] GenerateSolutionWrapper ( @@ -2017,7 +2018,8 @@ private static ProjectInstance[] GenerateSolutionWrapper IDictionary globalProperties, string toolsVersion, ILoggingService loggingService, - BuildEventContext projectBuildEventContext + BuildEventContext projectBuildEventContext, + IReadOnlyCollection targetNames ) { SolutionFile sp = SolutionFile.Parse(projectFile); @@ -2035,7 +2037,7 @@ BuildEventContext projectBuildEventContext // It's needed to determine which tags to put in, whether to put a ToolsVersion parameter // on the task tags, and what MSBuildToolsPath to use when scanning child projects // for dependency information. - ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, globalProperties, toolsVersion, projectBuildEventContext, loggingService); + ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, globalProperties, toolsVersion, projectBuildEventContext, loggingService, targetNames); return instances; } diff --git a/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs index d2a09f6e740..522eb8e0860 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/SolutionFile_Tests.cs @@ -167,8 +167,8 @@ public void ParseEtpProject() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solution = ParseSolutionHelper(solutionFileContents); //Project should get added to the solution @@ -235,12 +235,12 @@ public void CanBeMSBuildFile() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject Project('{NNNNNNNN-9925-4D57-9DAF-E0A9D936ABDB}') = 'someproja', 'someproja.proj', '{CCCCCCCC-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; @@ -308,8 +308,8 @@ public void ParseNestedEtpProjectSingleLevel() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solution = ParseSolutionHelper(solutionFileContents); @@ -334,8 +334,8 @@ public void TestVSAndSolutionVersionParsing() @" Microsoft Visual Studio Solution File, Format Version 11.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionPriorToDev12 = ParseSolutionHelper(solutionFileContentsPriorToDev12); @@ -350,8 +350,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = 12.0.20311.0 VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12 = ParseSolutionHelper(solutionFileContentsDev12); @@ -368,8 +368,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted1 = ParseSolutionHelper(solutionFileContentsDev12Corrupted1); @@ -383,8 +383,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted2 = ParseSolutionHelper(solutionFileContentsDev12Corrupted2); @@ -398,8 +398,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = VSPRO_PLATFORM 12.0.20311.0 MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted3 = ParseSolutionHelper(solutionFileContentsDev12Corrupted3); @@ -413,8 +413,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = 12.0.20311.0VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted4 = ParseSolutionHelper(solutionFileContentsDev12Corrupted4); @@ -428,8 +428,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = ...12..0,.20311.0 VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted5 = ParseSolutionHelper(solutionFileContentsDev12Corrupted5); @@ -443,8 +443,8 @@ public void TestVSAndSolutionVersionParsing() VisualStudioVersion = 12.0.20311.0 VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solutionDev12Corrupted6 = ParseSolutionHelper(solutionFileContentsDev12Corrupted6); @@ -523,8 +523,8 @@ public void ParseNestedEtpProjectMultipleLevel() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solution = ParseSolutionHelper(solutionFileContents); @@ -582,8 +582,8 @@ public void MalformedEtpProjFile() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; SolutionFile solution = ParseSolutionHelper(solutionFileContents); string errCode, ignoredKeyword; @@ -615,8 +615,8 @@ public void MissingEtpProjFile() @" Microsoft Visual Studio Solution File, Format Version 8.00 Project('{FE3BBBB6-72D5-11D2-9ACE-00C04F79A2A4}') = 'someproj', 'someproj.etp', '{AD0F3D02-9925-4D57-9DAF-E0A9D936ABDB}' - ProjectSection(ProjectDependencies) = postProject - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject"; // Delete the someproj.etp file if it exists File.Delete(proj1Path); @@ -766,20 +766,20 @@ public void ParseSolutionFileWithDescriptionInformation() Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'AnyProject', 'AnyProject\AnyProject.csproj', '{2CAB0FBD-15D8-458B-8E63-1B5B840E9798}' EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - Description = Some description of this solution - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Description = Some description of this solution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CAB0FBD-15D8-458B-8E63-1B5B840E9798}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; try @@ -1100,96 +1100,96 @@ public void BuildableProjects() Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{A5EE8128-B08E-4533-86C5-E46714981680}' EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.ActiveCfg = Debug|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.Build.0 = Debug|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.Deploy.0 = Debug|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.ActiveCfg = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.Build.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.Deploy.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.ActiveCfg = Debug|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.Build.0 = Debug|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.Deploy.0 = Debug|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.ActiveCfg = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.Build.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.Deploy.0 = Debug|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Any CPU.ActiveCfg = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.ActiveCfg = Release|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.Build.0 = Release|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.Deploy.0 = Release|ARM - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.Build.0 = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.Deploy.0 = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.ActiveCfg = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.Build.0 = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.Deploy.0 = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.ActiveCfg = Release|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.Build.0 = Release|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.Deploy.0 = Release|x64 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.ActiveCfg = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.Build.0 = Release|Win32 - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.Deploy.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.ActiveCfg = Debug|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.Build.0 = Debug|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.Deploy.0 = Debug|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.ActiveCfg = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.Build.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.Deploy.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x64.ActiveCfg = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.ActiveCfg = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.Build.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.Deploy.0 = Debug|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Any CPU.ActiveCfg = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.ActiveCfg = Release|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.Build.0 = Release|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.Deploy.0 = Release|ARM - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.Build.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.Deploy.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.ActiveCfg = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.Build.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.Deploy.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x64.ActiveCfg = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.ActiveCfg = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.Build.0 = Release|Win32 - {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.Deploy.0 = Release|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.ActiveCfg = Debug|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.Build.0 = Debug|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.Deploy.0 = Debug|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.ActiveCfg = Release|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.Build.0 = Release|Win32 - {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.Deploy.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {A5526AEA-E0A2-496D-94B7-2BBE835C83F8} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} - {FF6AEDF3-950A-46DD-910B-52BC69B9C99A} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} - {024E8607-06B0-440D-8741-5A888DC4B176} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.ActiveCfg = Debug|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.Build.0 = Debug|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|ARM.Deploy.0 = Debug|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.Build.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|Win32.Deploy.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.ActiveCfg = Debug|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.Build.0 = Debug|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x64.Deploy.0 = Debug|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.ActiveCfg = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.Build.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Debug|x86.Deploy.0 = Debug|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Any CPU.ActiveCfg = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.ActiveCfg = Release|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.Build.0 = Release|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|ARM.Deploy.0 = Release|ARM + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.Build.0 = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Mixed Platforms.Deploy.0 = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.ActiveCfg = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.Build.0 = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|Win32.Deploy.0 = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.ActiveCfg = Release|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.Build.0 = Release|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x64.Deploy.0 = Release|x64 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.ActiveCfg = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.Build.0 = Release|Win32 + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8}.Release|x86.Deploy.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.ActiveCfg = Debug|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.Build.0 = Debug|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|ARM.Deploy.0 = Debug|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.ActiveCfg = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.Build.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|Win32.Deploy.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x64.ActiveCfg = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.ActiveCfg = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.Build.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Debug|x86.Deploy.0 = Debug|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Any CPU.ActiveCfg = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.ActiveCfg = Release|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.Build.0 = Release|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|ARM.Deploy.0 = Release|ARM + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.Build.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Mixed Platforms.Deploy.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.ActiveCfg = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.Build.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|Win32.Deploy.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x64.ActiveCfg = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.ActiveCfg = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.Build.0 = Release|Win32 + {024E8607-06B0-440D-8741-5A888DC4B176}.Release|x86.Deploy.0 = Release|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.ActiveCfg = Debug|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.Build.0 = Debug|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Debug|x86.Deploy.0 = Debug|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.ActiveCfg = Release|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.Build.0 = Release|Win32 + {A5EE8128-B08E-4533-86C5-E46714981680}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A5526AEA-E0A2-496D-94B7-2BBE835C83F8} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} + {FF6AEDF3-950A-46DD-910B-52BC69B9C99A} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} + {024E8607-06B0-440D-8741-5A888DC4B176} = {892B5932-9AA8-46F9-A857-8967DCDBE4F5} + EndGlobalSection EndGlobal "; diff --git a/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs b/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs index 00f1dd3f5b8..412fb8d17c7 100644 --- a/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Construction/SolutionProjectGenerator_Tests.cs @@ -352,23 +352,23 @@ public void SolutionPassesSubToolsetToChildProjects2() Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary2"", ""ClassLibrary2.csproj"", ""{84AA5584-4B0F-41DE-95AA-589E1447EDA0}"" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.Build.0 = Release|Any CPU - {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.Build.0 = Release|Any CPU + {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; @@ -516,30 +516,30 @@ public void SolutionWithMissingDependencies() Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 11 Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `Project2\B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}` - ProjectSection(ProjectDependencies) = postProject - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} + EndProjectSection EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = preSolution - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.ActiveCfg = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.Build.0 = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.ActiveCfg = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = preSolution + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.ActiveCfg = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.Build.0 = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.ActiveCfg = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal ".Replace("`", "\""); @@ -562,48 +562,48 @@ public void SolutionConfigurationWithDependencies() Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `A`, `Project1\A.csproj`, `{786E302A-96CE-43DC-B640-D6B6CC9BF6C0}` EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `Project2\B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}` - ProjectSection(ProjectDependencies) = postProject - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} + EndProjectSection EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `Project3\C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}` EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = preSolution - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|x64.ActiveCfg = Debug|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|x64.Build.0 = Debug|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.Build.0 = Release|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|x64.ActiveCfg = Release|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|x64.Build.0 = Release|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|x64.ActiveCfg = Debug|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|x64.Build.0 = Debug|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|Any CPU.Build.0 = Release|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|x64.ActiveCfg = Release|Any CPU - {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|x64.Build.0 = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.ActiveCfg = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.Build.0 = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.ActiveCfg = Release|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = preSolution + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|x64.ActiveCfg = Debug|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|x64.Build.0 = Debug|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.Build.0 = Release|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|x64.ActiveCfg = Release|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|x64.Build.0 = Release|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|x64.ActiveCfg = Debug|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Debug|x64.Build.0 = Debug|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|Any CPU.Build.0 = Release|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|x64.ActiveCfg = Release|Any CPU + {786E302A-96CE-43DC-B640-D6B6CC9BF6C0}.Release|x64.Build.0 = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.ActiveCfg = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|x64.Build.0 = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.ActiveCfg = Release|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal ".Replace("`", "\""); @@ -651,29 +651,29 @@ public void SolutionConfigurationWithDependenciesRelaysItsOutputs() Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 11 Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}` - ProjectSection(ProjectDependencies) = postProject - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} + EndProjectSection EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}` EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `D`, `D.csproj`, `{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}` EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = preSolution - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = preSolution + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; const string projectBravoFileContents = @@ -1109,30 +1109,30 @@ public void SolutionWithDependenciesHasCorrectToolsVersionInMetaprojs() @" Microsoft Visual Studio Solution File, Format Version 12.00 Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ConsoleApplication2', 'ConsoleApplication2\ConsoleApplication2.csproj', '{5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}' - ProjectSection(ProjectDependencies) = postProject - {E0D295A1-CAFA-4E68-9929-468657DAAC6C} = {E0D295A1-CAFA-4E68-9929-468657DAAC6C} - EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {E0D295A1-CAFA-4E68-9929-468657DAAC6C} = {E0D295A1-CAFA-4E68-9929-468657DAAC6C} + EndProjectSection EndProject Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', 'ConsoleApplication1\ConsoleApplication1.vbproj', '{E0D295A1-CAFA-4E68-9929-468657DAAC6C}' EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.Build.0 = Release|Any CPU - {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.Build.0 = Release|Any CPU + {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; @@ -1788,37 +1788,37 @@ public void BadFrameworkMonkierExpectBuildToFail() @"Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'WebSite1', '..\WebSite1\', '{6B8F98F2-C976-4029-9321-5CCD73A174DA}' - ProjectSection(WebsiteProperties) = preProject - TargetFrameworkMoniker = 'SuperCoolReallyAwesomeFramework,Version=v1.0' - Debug.AspNetCompiler.VirtualPath = '/WebSite1' - Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Debug.AspNetCompiler.Updateable = 'true' - Debug.AspNetCompiler.ForceOverwrite = 'true' - Debug.AspNetCompiler.FixedNames = 'false' - Debug.AspNetCompiler.Debug = 'True' - Release.AspNetCompiler.VirtualPath = '/WebSite1' - Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Release.AspNetCompiler.Updateable = 'true' - Release.AspNetCompiler.ForceOverwrite = 'true' - Release.AspNetCompiler.FixedNames = 'false' - Release.AspNetCompiler.Debug = 'False' - VWDPort = '45602' - DefaultWebSiteLanguage = 'Visual Basic' - EndProjectSection + ProjectSection(WebsiteProperties) = preProject + TargetFrameworkMoniker = 'SuperCoolReallyAwesomeFramework,Version=v1.0' + Debug.AspNetCompiler.VirtualPath = '/WebSite1' + Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Debug.AspNetCompiler.Updateable = 'true' + Debug.AspNetCompiler.ForceOverwrite = 'true' + Debug.AspNetCompiler.FixedNames = 'false' + Debug.AspNetCompiler.Debug = 'True' + Release.AspNetCompiler.VirtualPath = '/WebSite1' + Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Release.AspNetCompiler.Updateable = 'true' + Release.AspNetCompiler.ForceOverwrite = 'true' + Release.AspNetCompiler.FixedNames = 'false' + Release.AspNetCompiler.Debug = 'False' + VWDPort = '45602' + DefaultWebSiteLanguage = 'Visual Basic' + EndProjectSection EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; @@ -1880,37 +1880,37 @@ public void BadFrameworkMonkierExpectBuildToFail2() @"Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'WebSite1', '..\WebSite1\', '{6B8F98F2-C976-4029-9321-5CCD73A174DA}' - ProjectSection(WebsiteProperties) = preProject - TargetFrameworkMoniker = 'Oscar the grouch' - Debug.AspNetCompiler.VirtualPath = '/WebSite1' - Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Debug.AspNetCompiler.Updateable = 'true' - Debug.AspNetCompiler.ForceOverwrite = 'true' - Debug.AspNetCompiler.FixedNames = 'false' - Debug.AspNetCompiler.Debug = 'True' - Release.AspNetCompiler.VirtualPath = '/WebSite1' - Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Release.AspNetCompiler.Updateable = 'true' - Release.AspNetCompiler.ForceOverwrite = 'true' - Release.AspNetCompiler.FixedNames = 'false' - Release.AspNetCompiler.Debug = 'False' - VWDPort = '45602' - DefaultWebSiteLanguage = 'Visual Basic' - EndProjectSection + ProjectSection(WebsiteProperties) = preProject + TargetFrameworkMoniker = 'Oscar the grouch' + Debug.AspNetCompiler.VirtualPath = '/WebSite1' + Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Debug.AspNetCompiler.Updateable = 'true' + Debug.AspNetCompiler.ForceOverwrite = 'true' + Debug.AspNetCompiler.FixedNames = 'false' + Debug.AspNetCompiler.Debug = 'True' + Release.AspNetCompiler.VirtualPath = '/WebSite1' + Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Release.AspNetCompiler.Updateable = 'true' + Release.AspNetCompiler.ForceOverwrite = 'true' + Release.AspNetCompiler.FixedNames = 'false' + Release.AspNetCompiler.Debug = 'False' + VWDPort = '45602' + DefaultWebSiteLanguage = 'Visual Basic' + EndProjectSection EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; @@ -1973,37 +1973,37 @@ public void TestTargetFrameworkVersionGreaterThan4() Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'WebSite1', '..\WebSite1\', '{6B8F98F2-C976-4029-9321-5CCD73A174DA}' - ProjectSection(WebsiteProperties) = preProject - TargetFrameworkMoniker = '.NETFramework,Version=v4.34' - Debug.AspNetCompiler.VirtualPath = '/WebSite1' - Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Debug.AspNetCompiler.Updateable = 'true' - Debug.AspNetCompiler.ForceOverwrite = 'true' - Debug.AspNetCompiler.FixedNames = 'false' - Debug.AspNetCompiler.Debug = 'True' - Release.AspNetCompiler.VirtualPath = '/WebSite1' - Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' - Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' - Release.AspNetCompiler.Updateable = 'true' - Release.AspNetCompiler.ForceOverwrite = 'true' - Release.AspNetCompiler.FixedNames = 'false' - Release.AspNetCompiler.Debug = 'False' - VWDPort = '45602' - DefaultWebSiteLanguage = 'Visual Basic' - EndProjectSection + ProjectSection(WebsiteProperties) = preProject + TargetFrameworkMoniker = '.NETFramework,Version=v4.34' + Debug.AspNetCompiler.VirtualPath = '/WebSite1' + Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Debug.AspNetCompiler.Updateable = 'true' + Debug.AspNetCompiler.ForceOverwrite = 'true' + Debug.AspNetCompiler.FixedNames = 'false' + Debug.AspNetCompiler.Debug = 'True' + Release.AspNetCompiler.VirtualPath = '/WebSite1' + Release.AspNetCompiler.PhysicalPath = '..\WebSite1\' + Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\' + Release.AspNetCompiler.Updateable = 'true' + Release.AspNetCompiler.ForceOverwrite = 'true' + Release.AspNetCompiler.FixedNames = 'false' + Release.AspNetCompiler.Debug = 'False' + VWDPort = '45602' + DefaultWebSiteLanguage = 'Visual Basic' + EndProjectSection EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; @@ -2031,6 +2031,54 @@ public void TestTargetFrameworkVersionGreaterThan4() } } + /// + /// Verifies that when target names are specified they end up in the metaproj. + /// + [Fact] + public void CustomTargetNamesAreInInMetaproj() + { + SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper + (@" + Microsoft Visual Studio Solution File, Format Version 14.00 + # Visual Studio 2015 + Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}"" + EndProject + Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU + {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU + {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU + EndGlobalSection + EndGlobal + "); + + ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null, new List { "One" }); + + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "One", StringComparison.OrdinalIgnoreCase) == 0)); + + instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null, new List { "Two", "Three", "Four" }); + + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Two", StringComparison.OrdinalIgnoreCase) == 0)); + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Three", StringComparison.OrdinalIgnoreCase) == 0)); + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Four", StringComparison.OrdinalIgnoreCase) == 0)); + + instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null, new List { "Build" }); + + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase) == 0)); + + instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null, new List { "Five", "Rebuild" }); + + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Five", StringComparison.OrdinalIgnoreCase) == 0)); + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase) == 0)); + + instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null, new List { "My_Project:Six" }); + + Assert.Equal(1, instances[0].Targets.Count(target => String.Compare(target.Value.Name, "Six", StringComparison.OrdinalIgnoreCase) == 0)); + } + #region Helper Functions /// From aea35d3ad95f4b0c46f46e6b859919fb2ea0f95d Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 6 Jan 2017 10:53:24 -0800 Subject: [PATCH 207/223] Specify ngen architecture for amd64 executables. --- setup/files.swr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/files.swr b/setup/files.swr index 69a155c7ab6..3d312204219 100644 --- a/setup/files.swr +++ b/setup/files.swr @@ -136,8 +136,8 @@ folder InstallDir:\MSBuild\15.0\Bin\zh-Hant file source=$(X86BinPath)zh-Hant\MSBuildTaskHost.resources.dll vs.file.ngen=yes folder InstallDir:\MSBuild\15.0\Bin\amd64 - file source=$(X64BinPath)MSBuild.exe vs.file.ngen=yes - file source=$(X64BinPath)MSBuildTaskHost.exe vs.file.ngen=yes + file source=$(X64BinPath)MSBuild.exe vs.file.ngen=yes vs.file.ngenArchitecture=x64 + file source=$(X64BinPath)MSBuildTaskHost.exe vs.file.ngen=yes vs.file.ngenArchitecture=x64 file source=$(X64BinPath)MSBuild.exe.config file source=$(X64BinPath)MSBuildTaskHost.exe.config From 8ba576d82aeeda456eb561951983b2afc0fc94c8 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 6 Jan 2017 13:37:08 -0800 Subject: [PATCH 208/223] Enable build summary text for more scenarios. (#1516) Always show the Time Elapsed and Build Succeeded text whenever the user specifies the 'summary' console property flag regardless of log verbosity or presence of the ErrorsOnly / WarningsOnly flags. Closes #1513 --- .../Logging/BaseConsoleLogger.cs | 8 +- .../ParallelLogger/ParallelConsoleLogger.cs | 129 +++++++++--------- 2 files changed, 71 insertions(+), 66 deletions(-) diff --git a/src/XMakeBuildEngine/Logging/BaseConsoleLogger.cs b/src/XMakeBuildEngine/Logging/BaseConsoleLogger.cs index 6fe2c83fe7b..41020c0a3c3 100644 --- a/src/XMakeBuildEngine/Logging/BaseConsoleLogger.cs +++ b/src/XMakeBuildEngine/Logging/BaseConsoleLogger.cs @@ -1020,7 +1020,13 @@ public virtual void Initialize(IEventSource eventSource) if (showOnlyWarnings || showOnlyErrors) { - _showSummary = false; + if (!_showSummary.HasValue) + { + // By default don't show the summary when the showOnlyWarnings / showOnlyErrors is specified. + // However, if the user explicitly specified summary or nosummary, use that. + _showSummary = false; + } + this.showPerfSummary = false; } diff --git a/src/XMakeBuildEngine/Logging/ParallelLogger/ParallelConsoleLogger.cs b/src/XMakeBuildEngine/Logging/ParallelLogger/ParallelConsoleLogger.cs index 664ef23c67b..ed799288c92 100644 --- a/src/XMakeBuildEngine/Logging/ParallelLogger/ParallelConsoleLogger.cs +++ b/src/XMakeBuildEngine/Logging/ParallelLogger/ParallelConsoleLogger.cs @@ -237,91 +237,90 @@ public override void BuildStartedHandler(object sender, BuildStartedEventArgs e) /// event arguments public override void BuildFinishedHandler(object sender, BuildFinishedEventArgs e) { - if (!showOnlyErrors && !showOnlyWarnings) + // If for some reason we have deferred messages at the end of the build they should be displayed + // so that the reason why they are still buffered can be determined. + if (!showOnlyErrors && !showOnlyWarnings && _deferredMessages.Count > 0) { - // If for some reason we have deferred messages at the end of the build they should be displayed - // so that the reason why they are still buffered can be determined - if (_deferredMessages.Count > 0) + if (IsVerbosityAtLeast(LoggerVerbosity.Normal)) { - if (IsVerbosityAtLeast(LoggerVerbosity.Normal)) + // Print out all of the deferred messages + WriteLinePrettyFromResource("DeferredMessages"); + foreach (List messageList in _deferredMessages.Values) { - // Print out all of the deferred messages - WriteLinePrettyFromResource("DeferredMessages"); - foreach (List messageList in _deferredMessages.Values) + foreach (BuildMessageEventArgs message in messageList) { - foreach (BuildMessageEventArgs message in messageList) - { - PrintMessage(message, false); - } + PrintMessage(message, false); } } } + } + + // Show the performance summary if the verbosity is diagnostic or the user specifically asked for it + // with a logger parameter. + if (this.showPerfSummary) + { + ShowPerfSummary(); + } - // Show the performance summary iff the verbosity is diagnostic or the user specifically asked for it - // with a logger parameter. - if (this.showPerfSummary) + // Write the "Build Finished" event if verbosity is normal, detailed or diagnostic or the user + // specified to show the summary. + if (IsVerbosityAtLeast(LoggerVerbosity.Normal) || ShowSummary) + { + if (e.Succeeded) { - ShowPerfSummary(); + setColor(ConsoleColor.Green); } - // if verbosity is normal, detailed or diagnostic + // Write the "Build Finished" event. + WriteNewLine(); + WriteLinePretty(e.Message); + resetColor(); + } + + // The decision whether or not to show a summary at this verbosity + // was made during initialization. We just do what we're told. + if (ShowSummary) + { + // We can't display a nice nested summary unless we're at Normal or above, + // since we need to have gotten TargetStarted events, which aren't forwarded otherwise. if (IsVerbosityAtLeast(LoggerVerbosity.Normal)) { - if (e.Succeeded) - { - setColor(ConsoleColor.Green); - } - - // Write the "Build Finished" event. - WriteNewLine(); - WriteLinePretty(e.Message); - resetColor(); + ShowNestedErrorWarningSummary(); } - - // The decision whether or not to show a summary at this verbosity - // was made during initalization. We just do what we're told. - if (ShowSummary) + else { - // We can't display a nice nested summary unless we're at Normal or above, - // since we need to have gotten TargetStarted events, which aren't forwarded otherwise. - if (IsVerbosityAtLeast(LoggerVerbosity.Normal)) - { - ShowNestedErrorWarningSummary(); - - // Emit text like: - // 1 Warning(s) - // 0 Error(s) - // Don't color the line if it's zero. (Per Whidbey behavior.) - if (warningCount > 0) - { - setColor(ConsoleColor.Yellow); - } - WriteLinePrettyFromResource(2, "WarningCount", warningCount); - resetColor(); - - if (errorCount > 0) - { - setColor(ConsoleColor.Red); - } - WriteLinePrettyFromResource(2, "ErrorCount", errorCount); - resetColor(); - } - else - { - ShowFlatErrorWarningSummary(); - } + ShowFlatErrorWarningSummary(); } - // if verbosity is normal, detailed or diagnostic - if (IsVerbosityAtLeast(LoggerVerbosity.Normal)) + // Emit text like: + // 1 Warning(s) + // 0 Error(s) + // Don't color the line if it's zero. (Per Whidbey behavior.) + if (warningCount > 0) { - // The time elapsed is the difference between when the BuildStartedEventArg - // was created and when the BuildFinishedEventArg was created - string timeElapsed = LogFormatter.FormatTimeSpan(e.Timestamp - buildStarted); + setColor(ConsoleColor.Yellow); + } + WriteLinePrettyFromResource(2, "WarningCount", warningCount); + resetColor(); - WriteNewLine(); - WriteLinePrettyFromResource("TimeElapsed", timeElapsed); + if (errorCount > 0) + { + setColor(ConsoleColor.Red); } + WriteLinePrettyFromResource(2, "ErrorCount", errorCount); + resetColor(); + } + + // Show build time if verbosity is normal, detailed or diagnostic or the user specified to + // show the summary. + if (IsVerbosityAtLeast(LoggerVerbosity.Normal) || ShowSummary) + { + // The time elapsed is the difference between when the BuildStartedEventArg + // was created and when the BuildFinishedEventArg was created + string timeElapsed = LogFormatter.FormatTimeSpan(e.Timestamp - buildStarted); + + WriteNewLine(); + WriteLinePrettyFromResource("TimeElapsed", timeElapsed); } ResetConsoleLoggerState(); From 0f2d13b450df02ee66d990253cb84f7fd7fdb85e Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 6 Jan 2017 16:11:39 -0800 Subject: [PATCH 209/223] Enable ngen on multiple architectures for all DLLs (#1519) --- setup/files.swr | 320 ++++++++++++++++++++++++------------------------ 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/setup/files.swr b/setup/files.swr index 3d312204219..e05c1f56d5b 100644 --- a/setup/files.swr +++ b/setup/files.swr @@ -10,18 +10,18 @@ folder InstallDir:\MSBuild\15.0 file source=$(X86BinPath)Microsoft.VisualStudioVersion.v15.Common.props folder InstallDir:\MSBuild\15.0\Bin - file source=$(X86BinPath)Microsoft.Build.Conversion.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Engine.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Framework.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Tasks.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Utilities.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)MSBuild.exe vs.file.ngen=yes + file source=$(X86BinPath)Microsoft.Build.Conversion.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Engine.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Framework.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Tasks.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Utilities.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)MSBuild.exe vs.file.ngenArchitecture=x86 file source=$(X86BinPath)MSBuild.exe.config - file source=$(X86BinPath)MSBuildTaskHost.exe vs.file.ngen=yes + file source=$(X86BinPath)MSBuildTaskHost.exe vs.file.ngenArchitecture=x86 file source=$(X86BinPath)MSBuildTaskHost.exe.config - file source=$(X86BinPath)System.Threading.Tasks.Dataflow.dll vs.file.ngen=yes - file source=$(X86BinPath)System.Collections.Immutable.dll vs.file.ngen=yes + file source=$(X86BinPath)System.Threading.Tasks.Dataflow.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)System.Collections.Immutable.dll vs.file.ngenArchitecture=all file source=$(X86BinPath)Microsoft.Common.CurrentVersion.targets file source=$(X86BinPath)Microsoft.Common.CrossTargeting.targets file source=$(X86BinPath)Microsoft.Common.overridetasks @@ -51,104 +51,104 @@ folder InstallDir:\MSBuild\15.0\Bin\MSBuild file source=$(X86BinPath)Microsoft.Build.CommonTypes.xsd folder InstallDir:\MSBuild\15.0\Bin\cs - file source=$(X86BinPath)cs\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)cs\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)cs\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)cs\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)cs\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)cs\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)cs\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)cs\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)cs\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)cs\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\de - file source=$(X86BinPath)de\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)de\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)de\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)de\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)de\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)de\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)de\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)de\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)de\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)de\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\en - file source=$(X86BinPath)en\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)en\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)en\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)en\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)en\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)en\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)en\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)en\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)en\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)en\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\es - file source=$(X86BinPath)es\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)es\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)es\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)es\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)es\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)es\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)es\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)es\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)es\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)es\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\fr - file source=$(X86BinPath)fr\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)fr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)fr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)fr\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)fr\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)fr\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)fr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)fr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)fr\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)fr\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\it - file source=$(X86BinPath)it\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)it\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)it\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)it\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)it\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)it\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)it\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)it\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)it\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)it\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\ja - file source=$(X86BinPath)ja\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ja\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ja\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ja\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ja\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)ja\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ja\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ja\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ja\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ja\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\ko - file source=$(X86BinPath)ko\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ko\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ko\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ko\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ko\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)ko\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ko\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ko\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ko\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ko\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\pl - file source=$(X86BinPath)pl\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pl\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pl\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pl\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pl\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)pl\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pl\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pl\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pl\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pl\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\pt-BR - file source=$(X86BinPath)pt-BR\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pt-BR\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pt-BR\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pt-BR\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)pt-BR\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)pt-BR\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pt-BR\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pt-BR\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pt-BR\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)pt-BR\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\ru - file source=$(X86BinPath)ru\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ru\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ru\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ru\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)ru\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)ru\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ru\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ru\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ru\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)ru\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\tr - file source=$(X86BinPath)tr\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)tr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)tr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)tr\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)tr\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)tr\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)tr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)tr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)tr\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)tr\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\zh-Hans - file source=$(X86BinPath)zh-Hans\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hans\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hans\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hans\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hans\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)zh-Hans\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hans\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hans\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hans\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hans\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\zh-Hant - file source=$(X86BinPath)zh-Hant\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hant\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hant\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hant\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X86BinPath)zh-Hant\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X86BinPath)zh-Hant\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hant\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hant\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hant\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)zh-Hant\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64 - file source=$(X64BinPath)MSBuild.exe vs.file.ngen=yes vs.file.ngenArchitecture=x64 - file source=$(X64BinPath)MSBuildTaskHost.exe vs.file.ngen=yes vs.file.ngenArchitecture=x64 + file source=$(X64BinPath)MSBuild.exe vs.file.ngenArchitecture=x64 + file source=$(X64BinPath)MSBuildTaskHost.exe vs.file.ngenArchitecture=x64 file source=$(X64BinPath)MSBuild.exe.config file source=$(X64BinPath)MSBuildTaskHost.exe.config - file source=$(X86BinPath)Microsoft.Build.Conversion.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Engine.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Framework.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Tasks.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)Microsoft.Build.Utilities.Core.dll vs.file.ngen=yes - file source=$(X86BinPath)System.Threading.Tasks.Dataflow.dll vs.file.ngen=yes - file source=$(X86BinPath)System.Collections.Immutable.dll vs.file.ngen=yes + file source=$(X86BinPath)Microsoft.Build.Conversion.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Engine.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Framework.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Tasks.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)Microsoft.Build.Utilities.Core.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)System.Threading.Tasks.Dataflow.dll vs.file.ngenArchitecture=all + file source=$(X86BinPath)System.Collections.Immutable.dll vs.file.ngenArchitecture=all file source=$(X86BinPath)Microsoft.Common.CurrentVersion.targets file source=$(X86BinPath)Microsoft.Common.CrossTargeting.targets file source=$(X86BinPath)Microsoft.Common.overridetasks @@ -178,89 +178,89 @@ folder InstallDir:\MSBuild\15.0\Bin\amd64\MSBuild file source=$(X86BinPath)Microsoft.Build.CommonTypes.xsd folder InstallDir:\MSBuild\15.0\Bin\amd64\cs - file source=$(X64BinPath)cs\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)cs\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)cs\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)cs\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)cs\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)cs\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)cs\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)cs\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)cs\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)cs\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\de - file source=$(X64BinPath)de\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)de\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)de\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)de\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)de\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)de\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)de\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)de\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)de\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)de\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\en - file source=$(X64BinPath)en\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)en\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)en\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)en\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)en\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)en\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)en\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)en\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)en\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)en\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\es - file source=$(X64BinPath)es\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)es\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)es\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)es\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)es\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)es\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)es\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)es\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)es\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)es\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\fr - file source=$(X64BinPath)fr\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)fr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)fr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)fr\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)fr\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)fr\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)fr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)fr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)fr\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)fr\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\it - file source=$(X64BinPath)it\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)it\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)it\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)it\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)it\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)it\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)it\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)it\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)it\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)it\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\ja - file source=$(X64BinPath)ja\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ja\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ja\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ja\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ja\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)ja\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ja\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ja\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ja\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ja\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\ko - file source=$(X64BinPath)ko\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ko\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ko\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ko\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ko\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)ko\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ko\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ko\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ko\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ko\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\pl - file source=$(X64BinPath)pl\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pl\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pl\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pl\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pl\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)pl\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pl\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pl\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pl\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pl\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\pt-BR - file source=$(X64BinPath)pt-BR\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pt-BR\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pt-BR\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pt-BR\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)pt-BR\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)pt-BR\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pt-BR\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pt-BR\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pt-BR\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)pt-BR\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\ru - file source=$(X64BinPath)ru\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ru\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ru\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ru\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)ru\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)ru\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ru\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ru\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ru\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)ru\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\tr - file source=$(X64BinPath)tr\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)tr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)tr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)tr\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)tr\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)tr\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)tr\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)tr\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)tr\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)tr\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\zh-Hans - file source=$(X64BinPath)zh-Hans\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hans\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hans\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hans\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hans\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)zh-Hans\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hans\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hans\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hans\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hans\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\MSBuild\15.0\Bin\amd64\zh-Hant - file source=$(X64BinPath)zh-Hant\Microsoft.Build.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hant\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hant\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hant\MSBuild.resources.dll vs.file.ngen=yes - file source=$(X64BinPath)zh-Hant\MSBuildTaskHost.resources.dll vs.file.ngen=yes + file source=$(X64BinPath)zh-Hant\Microsoft.Build.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hant\Microsoft.Build.Tasks.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hant\Microsoft.Build.Utilities.Core.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hant\MSBuild.resources.dll vs.file.ngenArchitecture=all + file source=$(X64BinPath)zh-Hant\MSBuildTaskHost.resources.dll vs.file.ngenArchitecture=all folder InstallDir:\Common7\IDE\CommonExtensions\MSBuild file source=$(SourceDir)Framework\Microsoft.Build.Framework.pkgdef From 767698eef8cf421ad61832113f0274d8b411086a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 6 Jan 2017 16:13:55 -0800 Subject: [PATCH 210/223] ProjectRootElement can reload itself (#1507) * ProjectRootElementCache.Get can not care about whitespacepreservation Some cache callsites (e.g. evaluator loading imports) don't care about the whitespace and they should reuse whatever happens to be in the cache. Currently these callsites are forced to either preserve or not to preserve, which would cause unwanted cache eviction and stale references. * ProjectRootElement can reload itself Resolves #1442 (and potentially #1472) once CPS updates to use Reload * ProjectRootElement cache reloads PREs instead of evicting them --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 7 +- .../Microsoft.Build/Microsoft.Build.cs | 7 +- src/Shared/UnitTests/ObjectModelHelpers.cs | 10 + .../Construction/ProjectRootElement.cs | 111 +++- src/XMakeBuildEngine/Evaluation/Evaluator.cs | 3 +- .../Evaluation/ProjectRootElementCache.cs | 26 +- src/XMakeBuildEngine/Resources/Strings.resx | 17 +- .../ProjectRootElementCache_Tests.cs | 18 +- .../Construction/ProjectRootElement_Tests.cs | 619 ++++++++++++++++-- .../Definition/Project_Tests.cs | 201 ++++++ 10 files changed, 943 insertions(+), 76 deletions(-) diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 5ba0171f72e..1378dbc5ed4 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -311,7 +311,10 @@ internal ProjectRootElement() { } public Microsoft.Build.Construction.ProjectRootElement DeepClone() { throw null; } public static Microsoft.Build.Construction.ProjectRootElement Open(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } - public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, System.Nullable preserveFormatting) { throw null; } + public void Reload(bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } + public void ReloadFrom(string path, bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } + public void ReloadFrom(System.Xml.XmlReader reader, bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } public void Save() { } public void Save(System.IO.TextWriter writer) { } public void Save(string path) { } @@ -319,7 +322,7 @@ public void Save(string path, System.Text.Encoding encoding) { } public void Save(System.Text.Encoding saveEncoding) { } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } - public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, System.Nullable preserveFormatting) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("Name={Name} #Children={Count} Condition={Condition}")] public partial class ProjectTargetElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs index 5a847c6be83..2048eced5a2 100644 --- a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs +++ b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs @@ -311,7 +311,10 @@ internal ProjectRootElement() { } public Microsoft.Build.Construction.ProjectRootElement DeepClone() { throw null; } public static Microsoft.Build.Construction.ProjectRootElement Open(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } - public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, System.Nullable preserveFormatting) { throw null; } + public void Reload(bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } + public void ReloadFrom(string path, bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } + public void ReloadFrom(System.Xml.XmlReader reader, bool throwIfUnsavedChanges=true, System.Nullable preserveFormatting=null) { } public void Save() { } public void Save(System.IO.TextWriter writer) { } public void Save(string path) { } @@ -319,7 +322,7 @@ public void Save(string path, System.Text.Encoding encoding) { } public void Save(System.Text.Encoding saveEncoding) { } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path) { throw null; } public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection) { throw null; } - public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, bool preserveFormatting) { throw null; } + public static Microsoft.Build.Construction.ProjectRootElement TryOpen(string path, Microsoft.Build.Evaluation.ProjectCollection projectCollection, System.Nullable preserveFormatting) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("Name={Name} #Children={Count} Condition={Condition}")] public partial class ProjectTargetElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/src/Shared/UnitTests/ObjectModelHelpers.cs b/src/Shared/UnitTests/ObjectModelHelpers.cs index faad197599c..30184a63eb5 100644 --- a/src/Shared/UnitTests/ObjectModelHelpers.cs +++ b/src/Shared/UnitTests/ObjectModelHelpers.cs @@ -535,6 +535,16 @@ static internal string CreateTempFileOnDiskNoFormat(string fileContents) return projectFilePath; } + internal static ProjectRootElement CreateInMemoryProjectRootElement(string projectContents, ProjectCollection collection = null, bool preserveFormatting = true) + { + var cleanedProject = ObjectModelHelpers.CleanupFileContents(projectContents); + + return ProjectRootElement.Create( + XmlReader.Create(new StringReader(cleanedProject)), + collection ?? new ProjectCollection(), + preserveFormatting); + } + /// /// Create a project in memory. Load up the given XML. /// diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 2af810ef0f3..d58345e6662 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Xml; @@ -263,6 +264,19 @@ private ProjectRootElement(XmlDocumentWithLocation document, ProjectRootElementC ProjectParser.Parse(document, this); } + /// + /// Initialize a ProjectRootElement instance from an existing document. + /// Helper constructor for the > mehtod which needs to check if the document parses + /// + /// + /// Do not make public: we do not wish to expose particular XML API's. + /// + private ProjectRootElement(XmlDocumentWithLocation document) + : base() + { + ProjectParser.Parse(document, this); + } + /// /// Event raised after this project is renamed /// @@ -1085,7 +1099,7 @@ public static ProjectRootElement Open(string path, ProjectCollection projectColl /// Initialize a ProjectRootElement instance by loading from the specified file path. /// Uses the specified project collection and preserves the formatting of the document if specified. /// - public static ProjectRootElement Open(string path, ProjectCollection projectCollection, bool preserveFormatting) + public static ProjectRootElement Open(string path, ProjectCollection projectCollection, bool? preserveFormatting) { ErrorUtilities.VerifyThrowArgumentLength(path, "path"); ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection"); @@ -1142,7 +1156,7 @@ public static ProjectRootElement TryOpen(string path, ProjectCollection projectC /// It is possible for ProjectRootElements to be brought into memory and discarded due to memory pressure. Therefore /// this method returning false does not indicate that it has never been loaded, only that it is not currently in memory. /// - public static ProjectRootElement TryOpen(string path, ProjectCollection projectCollection, bool preserveFormatting) + public static ProjectRootElement TryOpen(string path, ProjectCollection projectCollection, bool? preserveFormatting) { ErrorUtilities.VerifyThrowArgumentLength(path, "path"); ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection"); @@ -1855,6 +1869,84 @@ public ProjectRootElement DeepClone() return (ProjectRootElement)this.DeepClone(this, null); } + /// + /// Reload the existing project root element from its file. + /// An is thrown if the project root element is not associated with any file on disk. + /// + /// See + /// + public void Reload(bool throwIfUnsavedChanges = true, bool? preserveFormatting = null) + { + ErrorUtilities.VerifyThrowInvalidOperation(!string.IsNullOrEmpty(FullPath), "ValueNotSet", $"{nameof(ProjectRootElement)}.{nameof(FullPath)}"); + + ReloadFrom(FullPath, throwIfUnsavedChanges, preserveFormatting); + } + + /// + /// Reload the existing project root element from the given path + /// An is thrown if the path does not exist. + /// + /// See + /// + public void ReloadFrom(string path, bool throwIfUnsavedChanges = true, bool? preserveFormatting = null) + { + ErrorUtilities.VerifyThrowInvalidOperation(File.Exists(path), "FileToReloadFromDoesNotExist", path); + + Func documentProducer = shouldPreserveFormatting => LoadDocument(path, shouldPreserveFormatting); + ReloadFrom(documentProducer, throwIfUnsavedChanges, preserveFormatting); + } + + /// + /// Reload the existing project root element from the given + /// A reload operation completely replaces the state of this object. This operation marks the + /// object as dirty (see for side effects). + /// + /// If the new state has invalid XML or MSBuild syntax, then this method throws an . + /// When this happens, the state of this object does not change. + /// + /// + /// Reader to read from + /// + /// If set to false, the reload operation will discard any unsaved changes. + /// Otherwise, an is thrown when unsaved changes are present. + /// + /// + /// Whether the reload should preserve formatting or not. A null value causes the reload to reuse the existing value. + /// + public void ReloadFrom(XmlReader reader, bool throwIfUnsavedChanges = true, bool? preserveFormatting = null) + { + Func documentProducer = shouldPreserveFormatting => LoadDocument(reader, shouldPreserveFormatting); + ReloadFrom(documentProducer, throwIfUnsavedChanges, preserveFormatting); + } + + private void ReloadFrom(Func documentProducer, bool throwIfUnsavedChanges, bool? preserveFormatting) + { + ThrowIfUnsavedChanges(throwIfUnsavedChanges); + + XmlDocumentWithLocation document = documentProducer(preserveFormatting ?? PreserveFormatting); + + // Reload should only mutate the state if there are no parse errors. + ThrowIfDocumentHasParsingErrors(document); + + // Do not clear the string cache. + // Based on the assumption that Projects are reloaded repeatedly from their file with small increments, + // and thus most strings would get reused + //this.XmlDocument.ClearAnyCachedStrings(); + + this.RemoveAllChildren(); + + ProjectParser.Parse(document, this); + + MarkDirty("Project reloaded", null); + } + + [MethodImpl(MethodImplOptions.NoOptimization)] + private static void ThrowIfDocumentHasParsingErrors(XmlDocumentWithLocation document) + { + // todo: rather than throw away, copy over the parse results + var throwaway = new ProjectRootElement(document); + } + /// /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later. /// Uses the specified project root element cache. @@ -1876,12 +1968,12 @@ internal static ProjectRootElement Create(ProjectRootElementCache projectRootEle /// May throw InvalidProjectFileException. /// internal static ProjectRootElement Open(string path, ProjectRootElementCache projectRootElementCache, bool isExplicitlyLoaded, - bool preserveFormatting) + bool? preserveFormatting) { ErrorUtilities.VerifyThrowInternalRooted(path); ProjectRootElement projectRootElement = projectRootElementCache.Get(path, - preserveFormatting ? s_openLoaderPreserveFormattingDelegate : s_openLoaderDelegate, + preserveFormatting ?? false ? s_openLoaderPreserveFormattingDelegate : s_openLoaderDelegate, isExplicitlyLoaded, preserveFormatting); return projectRootElement; @@ -1917,7 +2009,8 @@ internal static ProjectRootElement OpenProjectOrSolution(string fullPath, IDicti (path, cache) => CreateProjectFromPath(path, globalProperties, toolsVersion, loggingService, cache, buildEventContext, preserveFormatting: false), isExplicitlyLoaded, - preserveFormatting: false); + // don't care about formatting, reuse whatever is there + preserveFormatting: null); return projectRootElement; } @@ -2183,5 +2276,13 @@ private void IncrementVersion() { _version = Interlocked.Increment(ref s_globalVersionCounter); } + + private void ThrowIfUnsavedChanges(bool throwIfUnsavedChanges) + { + if (HasUnsavedChanges && throwIfUnsavedChanges) + { + ErrorUtilities.ThrowInvalidOperation("NoReloadOnUnsavedChanges", null); + } + } } } diff --git a/src/XMakeBuildEngine/Evaluation/Evaluator.cs b/src/XMakeBuildEngine/Evaluation/Evaluator.cs index c1411a730d4..f931aada4f2 100644 --- a/src/XMakeBuildEngine/Evaluation/Evaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/Evaluator.cs @@ -2439,7 +2439,8 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri _buildEventContext, explicitlyLoaded), explicitlyLoaded, - preserveFormatting: false); + // don't care about formatting, reuse whatever is there + preserveFormatting: null); if (duplicateImport) { diff --git a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs index 12f5d25756d..c9b6f57d652 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs @@ -194,7 +194,7 @@ internal ProjectRootElementCache(bool autoReloadFromDisk) /// true to the project was loaded with the formated preserved, otherwise false. /// The ProjectRootElement instance if one exists. Null otherwise. internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openProjectRootElement, bool isExplicitlyLoaded, - bool preserveFormatting) + bool? preserveFormatting) { // Should already have been canonicalized ErrorUtilities.VerifyThrowInternalRooted(projectFile); @@ -204,10 +204,10 @@ internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openP ProjectRootElement projectRootElement; _weakCache.TryGetValue(projectFile, out projectRootElement); - if (projectRootElement != null && projectRootElement.XmlDocument.PreserveWhitespace != preserveFormatting) + if (preserveFormatting != null && projectRootElement != null && projectRootElement.XmlDocument.PreserveWhitespace != preserveFormatting) { - // Cached project doesn't match preserveFormatting setting, so don't use it - projectRootElement = null; + // Cached project doesn't match preserveFormatting setting, so reload it + projectRootElement.Reload(true, preserveFormatting); } if (projectRootElement != null && _autoReloadFromDisk) @@ -218,7 +218,7 @@ internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openP // It's an in-memory project that hasn't been saved yet. if (fileInfo != null) { - bool forgetEntry = false; + bool reloadEntry = false; if (fileInfo.LastWriteTime != projectRootElement.LastWriteTimeWhenRead) { @@ -228,7 +228,7 @@ internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openP // to force a load from disk. There might then exist more than one ProjectRootElement with the same path, // but clients ought not get themselves into such a state - and unless they save them to disk, // it may not be a problem. - forgetEntry = true; + reloadEntry = true; } else if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDCACHECHECKFILECONTENT"))) { @@ -248,16 +248,14 @@ internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openP if (diskContent != cacheContent) { - forgetEntry = true; + reloadEntry = true; } } - if (forgetEntry) + if (reloadEntry) { - ForgetEntry(projectRootElement); - - DebugTraceCache("Out of date dropped from XML cache: ", projectFile); - projectRootElement = null; + DebugTraceCache("Out of date, reloaded: ", projectFile); + projectRootElement.Reload(true, null); } } } @@ -346,14 +344,14 @@ internal void RenameEntry(string oldFullPath, ProjectRootElement projectRootElem /// internal ProjectRootElement TryGet(string projectFile) { - return TryGet(projectFile, preserveFormatting: false); + return TryGet(projectFile, preserveFormatting: null); } /// /// Returns any a ProjectRootElement in the cache with the provided full path, /// otherwise null. /// - internal ProjectRootElement TryGet(string projectFile, bool preserveFormatting) + internal ProjectRootElement TryGet(string projectFile, bool? preserveFormatting) { ProjectRootElement result = Get( projectFile, diff --git a/src/XMakeBuildEngine/Resources/Strings.resx b/src/XMakeBuildEngine/Resources/Strings.resx index 49360a65aba..e6f27d1987a 100644 --- a/src/XMakeBuildEngine/Resources/Strings.resx +++ b/src/XMakeBuildEngine/Resources/Strings.resx @@ -1560,13 +1560,28 @@ Utilization: {0} Average Utilization: {1:###.0} The parameter '{0}' can only be a file name and cannot include a directory. + + + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + + + + + + + + + t1 + + + + + + +"; + /// /// Empty project content /// @@ -1251,16 +1306,519 @@ public void TryOpenWithPreserveFormatting() "; - var collection = new ProjectCollection(); - var projectXml = ProjectRootElement.Create( - XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(project))), - collection, - preserveFormatting: true); + using (var projectFiles = new Helpers.TestProjectWithFiles("", new[] {"build.proj"})) + using (var projectCollection = new ProjectCollection()) + { + var projectFile = projectFiles.CreatedFiles.First(); + + var projectXml = ProjectRootElement.Create( + XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(project))), + projectCollection, + preserveFormatting: true); + + projectXml.Save(projectFile); + + var xml0 = ProjectRootElement.TryOpen(projectXml.FullPath, projectCollection, preserveFormatting: true); + Assert.True(xml0.PreserveFormatting); + + var xml1 = ProjectRootElement.TryOpen(projectXml.FullPath, projectCollection, preserveFormatting: false); + Assert.False(xml1.PreserveFormatting); + + var xml2 = ProjectRootElement.TryOpen(projectXml.FullPath, projectCollection, preserveFormatting: null); + // reuses existing setting + Assert.False(xml2.PreserveFormatting); + + Assert.NotNull(xml0); + + Assert.Same(xml0, xml1); + Assert.Same(xml0, xml2); + } + } + + [Theory] + [InlineData(true, false, false)] + [InlineData(true, true, true)] + [InlineData(false, false, false)] + [InlineData(false, true, true)] + [InlineData(true, null, true)] + [InlineData(false, null, false)] + public void ReloadCanSpecifyPreserveFormatting(bool initialPreserveFormatting, bool? reloadShouldPreserveFormatting, bool expectedFormattingAfterReload) + { + using (var testFiles = new Helpers.TestProjectWithFiles("", new[] { "build.proj" })) + { + var projectFile = testFiles.CreatedFiles.First(); + + var projectElement = ObjectModelHelpers.CreateInMemoryProjectRootElement(SimpleProject, null, initialPreserveFormatting); + projectElement.Save(projectFile); + Assert.Equal(initialPreserveFormatting, projectElement.PreserveFormatting); + + projectElement.Reload(false, reloadShouldPreserveFormatting); + Assert.Equal(expectedFormattingAfterReload, projectElement.PreserveFormatting); + + // reset project to original preserve formatting + projectElement.Reload(false, initialPreserveFormatting); + Assert.Equal(initialPreserveFormatting, projectElement.PreserveFormatting); + + projectElement.ReloadFrom(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(SimpleProject))), false, reloadShouldPreserveFormatting); + Assert.Equal(expectedFormattingAfterReload, projectElement.PreserveFormatting); + + // reset project to original preserve formatting + projectElement.Reload(false, initialPreserveFormatting); + Assert.Equal(initialPreserveFormatting, projectElement.PreserveFormatting); + + projectElement.ReloadFrom(projectFile, false, reloadShouldPreserveFormatting); + Assert.Equal(expectedFormattingAfterReload, projectElement.PreserveFormatting); + } + } + + [Theory] + + // same content should still dirty the project + [InlineData( +SimpleProject, +SimpleProject, +true, false, false)] + + // new comment + [InlineData( +@" + + +

property value

+
+ + + + metadata value + + + +
", +@" + + + +

property value

+
+ + + + + + metadata value + + + +
", +true, false, true)] + + // changed comment + [InlineData( +@" + + + +

property value

+
+ + + + + + metadata value + + + +
", +@" + + + +

property value

+
+ + + + + + metadata value + + + +
", +true, false, true)] + + // deleted comment + [InlineData( +@" + + + +

property value

+
+ + + + + + metadata value + + + +
", +@" + + +

property value

+
+ + + + metadata value + + + +
", +true, false, true)] + + // new comments and changed code + [InlineData( +@" + + +

property value

+
+ + + + metadata value + + + +
", +@" + + + +

property value

+ property value +
+ +
", +true, true, true)] + + // commented out code + [InlineData( +@" + + +

property value

+
+ + + + metadata value + + + +
", +@" + +

property value

+
+ + +
", +true, true, true)] + public void ReloadRespectsNewContents(string initialProjectContents, string changedProjectContents, bool versionChanged, bool msbuildChildrenChanged, bool xmlChanged) + { + Action act = (p, c) => + { + p.ReloadFrom( + XmlReader.Create(new StringReader(c)), + throwIfUnsavedChanges: false); + }; + + AssertReload(initialProjectContents, changedProjectContents, versionChanged, msbuildChildrenChanged, xmlChanged, act); + } + + [Fact] + public void ReloadedStateIsResilientToChangesAndDiskRoundtrip() + { + var initialProjectContents = ObjectModelHelpers.CleanupFileContents( +@" + + + + + + + + metadata value + + + +"); + + var changedProjectContents1 = ObjectModelHelpers.CleanupFileContents( +@" + + + + + + + + + metadata value + + + + +"); + + var changedProjectContents2 = ObjectModelHelpers.CleanupFileContents( +// spurious comment placement issue: https://github.com/Microsoft/msbuild/issues/1503 +@" + + + + + +

v

+
+ + + + + metadata value + + + + +
"); + + using (var testFiles = new Helpers.TestProjectWithFiles("", new []{"build.proj"})) + using (var projectCollection1 = new ProjectCollection()) + using (var projectCollection2 = new ProjectCollection()) + { + var projectPath = testFiles.CreatedFiles.First(); + + var projectElement = ObjectModelHelpers.CreateInMemoryProjectRootElement(initialProjectContents, projectCollection1, preserveFormatting: true); + projectElement.Save(projectPath); + + projectElement.ReloadFrom(XmlReader.Create(new StringReader(changedProjectContents1))); + + VerifyAssertLineByLine(changedProjectContents1, projectElement.RawXml); + + projectElement.AddProperty("P", "v"); + + VerifyAssertLineByLine(changedProjectContents2, projectElement.RawXml); + + projectElement.Save(); + + var projectElement2 = ProjectRootElement.Open(projectPath, projectCollection2, preserveFormatting: true); + + VerifyAssertLineByLine(changedProjectContents2, projectElement2.RawXml); + } + } + + [Fact] + public void ReloadThrowsOnInvalidXmlSyntax() + { + var missingClosingTag = +@" + + +

property value

+
+ + + + metadata value + + + +
"; + + Action act = (p, c) => + { + var exception = + Assert.Throws( + () => + p.ReloadFrom( + XmlReader.Create( + new StringReader(c)), + throwIfUnsavedChanges: false)); + + Assert.Contains(@"The project file could not be loaded. The 'm' start tag on line", exception.Message); + }; + + // reload does not mutate the project element + AssertReload(SimpleProject, missingClosingTag, false, false, false, act); + } + + [Fact] + public void ReloadThrowsForInMemoryProjectsWithoutAPath() + { + Action act = (p, c) => + { + var exception = + Assert.Throws( + () => + p.Reload(throwIfUnsavedChanges: false)); + + Assert.Contains(@"Value not set:", exception.Message); + }; + + // reload does not mutate the project element + AssertReload(SimpleProject, ComplexProject, false, false, false, act); + } + + [Fact] + public void ReloadFromAPathThrowsOnMissingPath() + { + Action act = (p, c) => + { + var fullPath = Path.GetFullPath("foo"); + + var exception = + Assert.Throws( + () => + p.ReloadFrom(fullPath, throwIfUnsavedChanges: false)); - projectXml.Save(FileUtilities.GetTemporaryFile()); + Assert.Contains(@"File to reload from does not exist:", exception.Message); + }; - Assert.NotNull(ProjectRootElement.TryOpen(projectXml.FullPath, collection, preserveFormatting: true)); - Assert.Null(ProjectRootElement.TryOpen(projectXml.FullPath, collection, preserveFormatting: false)); + // reload does not mutate the project element + AssertReload(SimpleProject, ComplexProject, false, false, false, act); + } + + [Fact] + public void ReloadThrowsOnInvalidMsBuildSyntax() + { + var unknownAttribute = +@" + + +

property value

+
+ + + + metadata value + + + +
"; + + Action act = (p, c) => + { + var exception = + Assert.Throws( + () => + p.ReloadFrom( + XmlReader.Create( + new StringReader(c)), + throwIfUnsavedChanges: false)); + + Assert.Contains(@"The attribute ""Foo"" in element is unrecognized", exception.Message); + }; + + // reload does not mutate the project element + AssertReload(SimpleProject, unknownAttribute, false, false, false, act); + } + + [Fact] + public void ReloadThrowsByDefaultIfThereAreUnsavedChanges() + { + Action act = (p, c) => + { + var exception = + Assert.Throws( + () => + p.ReloadFrom( + XmlReader.Create( + new StringReader(c)))); + + Assert.Contains(@"ProjectRootElement can't reload if it contains unsaved changes.", exception.Message); + }; + + // reload does not mutate the project element + AssertReload(SimpleProject, ComplexProject, false, false, false, act); + } + + [Fact] + public void ReloadCanOverwriteUnsavedChanges() + { + Action act = (p, c) => + { + p.ReloadFrom( + XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(c))), + throwIfUnsavedChanges: false); + }; + + AssertReload(SimpleProject, ComplexProject, true, true, true, act); + } + + private void AssertReload( + string initialContents, + string changedContents, + bool versionChanged, + bool msbuildChildrenChanged, + bool xmlChanged, + Action act) + { + var projectElement = ObjectModelHelpers.CreateInMemoryProjectRootElement(initialContents); + + var version = projectElement.Version; + var childrenCount = projectElement.AllChildren.Count(); + var xml = projectElement.RawXml; + + Assert.True(projectElement.HasUnsavedChanges); + act(projectElement, ObjectModelHelpers.CleanupFileContents(changedContents)); + + if (versionChanged) + { + Assert.NotEqual(version, projectElement.Version); + } + else + { + Assert.Equal(version, projectElement.Version); + } + + if (msbuildChildrenChanged) + { + Assert.NotEqual(childrenCount, projectElement.AllChildren.Count()); + } + else + { + Assert.Equal(childrenCount, projectElement.AllChildren.Count()); + } + + + if (xmlChanged) + { + Assert.NotEqual(xml, projectElement.RawXml); + } + else + { + Assert.Equal(xml, projectElement.RawXml); + } + } + + private static string SaveToString(ProjectRootElement project) + { + var writer = new EncodingStringWriter(); + project.Save(writer); + + return writer.ToString(); } /// @@ -1339,49 +1897,16 @@ private void CreateProjectWithEncodingWithoutDeclaration(string projectFullPath, /// private ProjectRootElement CreatePREWithSubstantialContent() { - string content = ObjectModelHelpers.CleanupFileContents( - @" - - -

p1

- q1 -
- - - r1 - - - - - - - s1 - - - - - - - s2 - - - - - - - - t1 - - - - - - -
"); + string content = ObjectModelHelpers.CleanupFileContents(ComplexProject); ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content))); return project; } + + private void VerifyAssertLineByLine(string expected, string actual) + { + Helpers.VerifyAssertLineByLine(expected, actual, false); + } } } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs index d84f8513681..110f56e5a1e 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs @@ -1439,6 +1439,207 @@ public void ImportedXmlModified() File.Delete(path); } } + + /// + /// Adding an import to an existing PRE object and re-evaluating should preserve the initial import PRE object + /// + [Fact] + public void ImportingExistingPREObjectShouldPreserveTheObject() + { + var importProjectContents = ObjectModelHelpers.CleanupFileContents( +@" + + +

p1

+
+ + + + m1 + + + +
"); + + using (var projectFiles = new Helpers.TestProjectWithFiles("", new[] {"import.proj"})) + using (var projectCollection = new ProjectCollection()) + { + var importFile = projectFiles.CreatedFiles.First(); + ProjectRootElement import = + ProjectRootElement.Create( + XmlReader.Create(new StringReader(importProjectContents)), + projectCollection, + // preserve formatting to simulate IDE usage + preserveFormatting: true); + + // puts the import in the PRE cache + import.Save(importFile); + Assert.False(import.HasUnsavedChanges); + + Project project = new Project(projectCollection); + project.Xml.AddImport(importFile); + project.ReevaluateIfNecessary(); + + Assert.Same(import, project.Imports.First().ImportedProject); + } + } + + [Fact] + public void ReloadedImportsMarkProjectAsDirty() + { + var importProjectContents = ObjectModelHelpers.CleanupFileContents( +@" + + +

p1

+
+ + + + m1 + + + +
"); + + var changedImportContents = ObjectModelHelpers.CleanupFileContents( +@" + + +

p2

+
+ + + + m2 + + + +
"); + + Action assertContents = (p, i, m, project) => + { + Assert.Equal(p, project.GetPropertyValue("P")); + Assert.Equal(1, project.GetItems("I").Count); + Assert.Equal(i, project.GetItems("I").First().EvaluatedInclude); + Assert.Equal(m, project.GetItems("I").First().GetMetadataValue("M")); + }; + + using (var projectFiles = new Helpers.TestProjectWithFiles("", new[] {"import.proj"})) + using (var projectCollection = new ProjectCollection()) + { + var importFile = projectFiles.CreatedFiles.First(); + + var import = ProjectRootElement.Create( + XmlReader.Create(new StringReader(importProjectContents)), + projectCollection, + // preserve formatting to simulate IDE usage + preserveFormatting: true); + + // add to cache by saving + import.Save(importFile); + Assert.False(import.HasUnsavedChanges); + + var project = new Project(projectCollection); + project.Xml.AddImport(importFile); + project.ReevaluateIfNecessary(); + + assertContents("p1", "i1", "m1", project); + Assert.False(project.IsDirty); + + import.ReloadFrom(XmlReader.Create(new StringReader(changedImportContents))); + Assert.True(import.HasUnsavedChanges); + + Assert.True(project.IsDirty); + assertContents("p1", "i1", "m1", project); + + project.ReevaluateIfNecessary(); + Assert.False(project.IsDirty); + assertContents("p2", "i2", "m2", project); + + var newProject = new Project(projectCollection); + newProject.Xml.AddImport(importFile); + newProject.ReevaluateIfNecessary(); + assertContents("p2", "i2", "m2", newProject); + + Assert.Same(import, project.Imports.First().ImportedProject); + Assert.Same(import, newProject.Imports.First().ImportedProject); + } + } + + [Fact] + public void ReloadedProjectRootElementMarksProjectAsDirty() + { + var projectContents = ObjectModelHelpers.CleanupFileContents( +@" + + +

p1

+
+ + + + m1 + + + +
"); + + var changedProjectContents = ObjectModelHelpers.CleanupFileContents( +@" + + +

p2

+
+ + + + m2 + + + +
"); + + Action assertContents = (p, i, m, project) => + { + Assert.Equal(p, project.GetPropertyValue("P")); + Assert.Equal(1, project.GetItems("I").Count); + Assert.Equal(i, project.GetItems("I").First().EvaluatedInclude); + Assert.Equal(m, project.GetItems("I").First().GetMetadataValue("M")); + }; + + using (var projectFiles = new Helpers.TestProjectWithFiles("", new[] {"build.proj"})) + using (var projectCollection = new ProjectCollection()) + { + var projectFile = projectFiles.CreatedFiles.First(); + + var projectRootElement = ProjectRootElement.Create( + XmlReader.Create(new StringReader(projectContents)), + projectCollection, + // preserve formatting to simulate IDE usage + preserveFormatting: true); + + // add to cache by saving + projectRootElement.Save(projectFile); + Assert.False(projectRootElement.HasUnsavedChanges); + + var project = new Project(projectRootElement, new Dictionary(), MSBuildConstants.CurrentToolsVersion, projectCollection); + project.ReevaluateIfNecessary(); + + assertContents("p1", "i1", "m1", project); + Assert.False(project.IsDirty); + + projectRootElement.ReloadFrom(XmlReader.Create(new StringReader(changedProjectContents))); + Assert.True(projectRootElement.HasUnsavedChanges); + + Assert.True(project.IsDirty); + assertContents("p1", "i1", "m1", project); + + project.ReevaluateIfNecessary(); + Assert.False(project.IsDirty); + assertContents("p2", "i2", "m2", project); + } + } /// /// To support certain corner cases, it is possible to explicitly mark a Project From 803d46910bfb4b30766f64967c82934f58da0e63 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Fri, 6 Jan 2017 16:40:36 -0800 Subject: [PATCH 211/223] Update System.Collections.Immutable to 1.2.1 Update to match change in Roslyn tools. --- NuGet.Config | 2 +- dir.props | 2 +- src/.nuget/project.json | 2 +- src/XMakeBuildEngine/UnitTestsPublicOM/project.json | 2 +- src/XMakeBuildEngine/project.json | 2 +- src/XMakeTasks/project.json | 2 +- targets/runtimeDependencies/project.json | 3 ++- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index f7d6cea578e..c812dd2d2ca 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -9,7 +9,7 @@ - + diff --git a/dir.props b/dir.props index 276a30aa41c..4eba04a0f70 100644 --- a/dir.props +++ b/dir.props @@ -46,7 +46,7 @@ 1.0.27-prerelease-00927-05 - 2.0.0-beta3 + 2.0.0-rc3-61110-06 2.1.0 0.2.0 1.5.46 diff --git a/src/.nuget/project.json b/src/.nuget/project.json index 047f64f86d0..f776f2f09fc 100644 --- a/src/.nuget/project.json +++ b/src/.nuget/project.json @@ -3,7 +3,7 @@ "xunit.runner.console": "2.1.0", "Nerdbank.GitVersioning": "1.5.46", "NuSpec.ReferenceGenerator": "1.4.2", - "Microsoft.Net.Compilers": "2.0.0-beta3", + "Microsoft.Net.Compilers": "2.0.0-rc3-61110-06", "MicroBuild.Core": "0.2.0", "Microsoft.DotNet.BuildTools.GenAPI": "1.0.0-beta2-00731-01" }, diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json index fae64337d9b..258ad97a8f2 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json @@ -6,7 +6,7 @@ "xunit.assert": "2.1.0", "xunit.abstractions": "2.0.0", "microsoft.xunit.netcore.extensions": "1.0.0-prerelease-00629-09", - "System.Collections.Immutable": "1.2.0" + "System.Collections.Immutable": "1.3.1" }, "frameworks": { "net46": { diff --git a/src/XMakeBuildEngine/project.json b/src/XMakeBuildEngine/project.json index 68205592286..56ab860d339 100644 --- a/src/XMakeBuildEngine/project.json +++ b/src/XMakeBuildEngine/project.json @@ -1,6 +1,6 @@ { "dependencies": { - "System.Collections.Immutable": "1.2.0" + "System.Collections.Immutable": "1.3.1" }, "frameworks": { "net46": { diff --git a/src/XMakeTasks/project.json b/src/XMakeTasks/project.json index d9729553082..66b0290cc5b 100644 --- a/src/XMakeTasks/project.json +++ b/src/XMakeTasks/project.json @@ -1,6 +1,6 @@ { "dependencies": { - "System.Collections.Immutable": "1.2.0" + "System.Collections.Immutable": "1.3.1" }, "frameworks": { "net46": { diff --git a/targets/runtimeDependencies/project.json b/targets/runtimeDependencies/project.json index f8be97054b7..8ca91d9fb61 100644 --- a/targets/runtimeDependencies/project.json +++ b/targets/runtimeDependencies/project.json @@ -10,7 +10,8 @@ "xunit": "2.1.0", "microsoft.xunit.netcore.extensions": "1.0.0-prerelease-00629-09", "System.IO.FileSystem": "4.0.1", - "System.IO.Compression": "4.1.0" + "System.IO.Compression": "4.1.0", + "System.Collections.Immutable": "1.3.1" }, "frameworks": { "net46": { From 1883c56d4d9003c9ea1406315bdc825c3575a453 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 9 Jan 2017 14:40:11 -0600 Subject: [PATCH 212/223] Update System.Security.Cryptography* to 4.3.0 --- src/Utilities/project.json | 2 +- src/XMakeBuildEngine/UnitTestsPublicOM/project.json | 2 +- src/XMakeTasks/project.json | 2 +- targets/runtimeDependencies/project.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Utilities/project.json b/src/Utilities/project.json index a8fa80caf38..ee788ef5409 100644 --- a/src/Utilities/project.json +++ b/src/Utilities/project.json @@ -14,7 +14,7 @@ "System.Reflection.TypeExtensions": "4.1.0", "System.Runtime.Serialization.Primitives": "4.1.1", "System.Runtime.Serialization.Xml": "4.1.1", - "System.Security.Cryptography.X509Certificates": "4.1.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", "System.Threading.Thread": "4.0.0", "System.Xml.XmlDocument": "4.0.1" } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json index 258ad97a8f2..854b278f8d4 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json @@ -23,7 +23,7 @@ "System.Console": "4.0.0", "System.Diagnostics.Process": "4.1.0", "System.Diagnostics.TraceSource": "4.0.0", - "System.Security.Cryptography.X509Certificates": "4.1.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", "System.Threading.Thread": "4.0.0", "System.Threading.ThreadPool": "4.0.10", "System.Xml.XmlDocument": "4.0.1", diff --git a/src/XMakeTasks/project.json b/src/XMakeTasks/project.json index 66b0290cc5b..97ce0f40d01 100644 --- a/src/XMakeTasks/project.json +++ b/src/XMakeTasks/project.json @@ -21,7 +21,7 @@ "System.Resources.Writer": "4.0.0", "System.Runtime.Serialization.Primitives": "4.1.1", "System.Runtime.Serialization.Xml": "4.1.1", - "System.Security.Cryptography.Algorithms" : "4.2.0", + "System.Security.Cryptography.Algorithms" : "4.3.0", "System.Threading.Thread": "4.0.0", "System.Xml.XmlDocument": "4.0.1" } diff --git a/targets/runtimeDependencies/project.json b/targets/runtimeDependencies/project.json index 8ca91d9fb61..b11738a2a6b 100644 --- a/targets/runtimeDependencies/project.json +++ b/targets/runtimeDependencies/project.json @@ -24,7 +24,7 @@ }, "netcoreapp1.0": { "dependencies": { - "System.Security.Cryptography.X509Certificates": "4.1.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", "System.Net.NetworkInformation": "4.1.0", "Microsoft.NETCore": "5.0.1", "Microsoft.NETCore.Portable.Compatibility": "1.0.1", From 7bc04e59df0cec4ebac340a9ad30ef528e8ddd88 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 9 Jan 2017 15:18:43 -0600 Subject: [PATCH 213/223] Update mono csc ref to 2.0.0-rc3-61110-06 --- cibuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuild.sh b/cibuild.sh index a858664738c..50f73db6e77 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -316,7 +316,7 @@ fi # Microsoft.Net.Compilers package is available now, so we can use the latest csc.exe if [ "$host" = "Mono" ]; then - CSC_EXE="$PACKAGES_DIR/microsoft.net.compilers/2.0.0-beta3/tools/csc.exe" + CSC_EXE="$PACKAGES_DIR/microsoft.net.compilers/2.0.0-rc3-61110-06/tools/csc.exe" CSC_ARGS="/p:CscToolExe=csc.exe /p:CscToolPath=`dirname $CSC_EXE` /p:DebugType=portable" fi From 37278eb667747e03a5b17e0794ab72c3b01c9179 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Mon, 9 Jan 2017 13:37:23 -0800 Subject: [PATCH 214/223] Exclude computation skips over illegal file specs (#1524) Resolves #1523 --- src/Shared/FileMatcher.cs | 18 ++-- src/Shared/UnitTests/ObjectModelHelpers.cs | 7 +- .../Definition/ProjectItem_Tests.cs | 90 +++++++++++++++++++ .../Utilities/EngineFileUtilities.cs | 2 +- 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/src/Shared/FileMatcher.cs b/src/Shared/FileMatcher.cs index 493eb13fd80..c19a3660869 100644 --- a/src/Shared/FileMatcher.cs +++ b/src/Shared/FileMatcher.cs @@ -1475,18 +1475,24 @@ static string[] CreateArrayWithSingleItemIfNotExcluded(string filespecUnescaped, { foreach (string excludeSpec in excludeSpecsUnescaped) { - // The FileMatch method always creates a Regex to check if the file matches the pattern - // Creating a Regex is relatively expensive, so we may want to avoid doing so if possible - Result match = FileMatch(excludeSpec, filespecUnescaped); + + // Try a path equality check first to: + // - avoid the expensive regex + // - maintain legacy behaviour where an illegal filespec is treated as a normal string + if (FileUtilities.PathsEqual(filespecUnescaped, excludeSpec)) + { + return new string[0]; + } + + var match = FileMatch(excludeSpec, filespecUnescaped); if (match.isLegalFileSpec && match.isMatch) { - // This file is excluded return new string[0]; } } } - return new string[] { filespecUnescaped }; + return new[] { filespecUnescaped }; } /// @@ -1569,6 +1575,8 @@ DirectoryExists directoryExists resultsToExclude = new HashSet(); } resultsToExclude.Add(excludeSpec); + + continue; } else if (excludeAction == SearchAction.ReturnEmptyList) { diff --git a/src/Shared/UnitTests/ObjectModelHelpers.cs b/src/Shared/UnitTests/ObjectModelHelpers.cs index 30184a63eb5..ca9278f0b1c 100644 --- a/src/Shared/UnitTests/ObjectModelHelpers.cs +++ b/src/Shared/UnitTests/ObjectModelHelpers.cs @@ -139,14 +139,17 @@ internal static void AssertItemEvaluation(string projectContents, string[] input { using (var testProject = new Helpers.TestProjectWithFiles(projectContents, inputFiles)) + using (var collection = new ProjectCollection()) { + var evaluatedItems = new Project(testProject.ProjectFile, new Dictionary(), MSBuildConstants.CurrentToolsVersion, collection).Items.ToList(); + if (expectedMetadataPerItem == null) { - ObjectModelHelpers.AssertItems(expectedInclude, new Project(testProject.ProjectFile).Items.ToList(), expectedDirectMetadata: null, normalizeSlashes: normalizeSlashes); + ObjectModelHelpers.AssertItems(expectedInclude, evaluatedItems, expectedDirectMetadata: null, normalizeSlashes: normalizeSlashes); } else { - ObjectModelHelpers.AssertItems(expectedInclude, new Project(testProject.ProjectFile).Items.ToList(), expectedMetadataPerItem, normalizeSlashes); + ObjectModelHelpers.AssertItems(expectedInclude, evaluatedItems, expectedMetadataPerItem, normalizeSlashes); } } } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs index e4b4039b707..0b1f0f74ca0 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs @@ -642,6 +642,96 @@ public void ExcludeVectorWithWildCards(string projectContents, string includeStr TestIncludeExcludeWithDifferentSlashes(projectContents, includeString, excludeString, inputFiles, expectedInclude); } + [Theory] + [InlineData(ItemWithIncludeAndExclude, + @"**\*", + @"excludes\**.*", + new[] + { + @"a.cs", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + }, + new[] + { + @"a.cs", + "build.proj", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + })] + [InlineData(ItemWithIncludeAndExclude, + @"**\*", + @"excludes\**..\*", + new[] + { + @"a.cs", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + }, + new[] + { + @"a.cs", + "build.proj", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + })] + [InlineData(ItemWithIncludeAndExclude, + @"**\*", + @"**.*", + new[] + { + @"a.cs", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + }, + new[] + { + @"a.cs", + "build.proj", + @"excludes\b.cs", + @"excludes\subdir\c.cs", + })] + [InlineData(ItemWithIncludeAndExclude, + "*;**a", + "**a", + new[] + { + "a", + }, + new[] + { + "a", + "build.proj" + })] + [InlineData(ItemWithIncludeAndExclude, + @"**1;**2", + @"**1", + new[] + { + @"1", + @"2", + @"excludes\1", + @"excludes\2", + @"excludes\subdir\1", + @"excludes\subdir\2", + }, + new[] + { + "**2" + })] + [InlineData(ItemWithIncludeAndExclude, + @":||;||:", + @"||:", + new string[0], + new[] + { + ":||" + })] + public void ExcludeAndIncludeConsideredAsLiteralsWhenFilespecIsIllegal(string projectContents, string includeString, string excludeString, string[] inputFiles, string[] expectedInclude) + { + TestIncludeExclude(projectContents, inputFiles, expectedInclude, includeString, excludeString, normalizeSlashes: true); + } + [Theory] [PlatformSpecific(Xunit.PlatformID.Windows)] [InlineData(ItemWithIncludeAndExclude, diff --git a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs index 4dadf5e8155..e88fbfbcd8d 100644 --- a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs +++ b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs @@ -121,7 +121,7 @@ private static string[] GetFileList // Unescape before handing it to the filesystem. var directoryUnescaped = EscapingUtilities.UnescapeAll(directoryEscaped); var filespecUnescaped = EscapingUtilities.UnescapeAll(filespecEscaped); - var excludeSpecsUnescaped = excludeSpecsEscaped.Where(IsValidExclude).Select(EscapingUtilities.UnescapeAll); + var excludeSpecsUnescaped = excludeSpecsEscaped.Where(IsValidExclude).Select(EscapingUtilities.UnescapeAll).ToList(); // Get the list of actual files which match the filespec. Put // the list into a string array. If the filespec started out From f52cb1426fdca1d650c2018deb34ce50ccfd00b1 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 9 Jan 2017 16:59:14 -0800 Subject: [PATCH 215/223] Ensure BaseIntermediateOutputPath has a trailing slash when set by user (#1528) We used to ensure the trailing slash in common targets but I moved this to common props. This however broke the scenario when a user sets the property since the trailing slash is not ensured and the _CheckForInvalidConfigurationAndPlatform target would then fail. I also introduced a unit test to ensure this doesn't regress again. Closes #1509 --- .../Microsoft.Common.CurrentVersion.targets | 1 + .../Microsoft.Build.Tasks.UnitTests.csproj | 1 + src/XMakeTasks/UnitTests/RegressionTests.cs | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/XMakeTasks/UnitTests/RegressionTests.cs diff --git a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets index 49f35dade6e..55722e85bf8 100644 --- a/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.Common.CurrentVersion.targets @@ -323,6 +323,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. false + $(BaseIntermediateOutputPath)\ $(MSBuildProjectFile).FileListAbsolute.txt false diff --git a/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj b/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj index 94c24e40821..3b792519bea 100644 --- a/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj +++ b/src/XMakeTasks/UnitTests/Microsoft.Build.Tasks.UnitTests.csproj @@ -80,6 +80,7 @@ + diff --git a/src/XMakeTasks/UnitTests/RegressionTests.cs b/src/XMakeTasks/UnitTests/RegressionTests.cs new file mode 100644 index 00000000000..1dcb6966605 --- /dev/null +++ b/src/XMakeTasks/UnitTests/RegressionTests.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Build.Evaluation; +using Microsoft.Build.UnitTests; +using Xunit; + +namespace Microsoft.Build.Tasks.UnitTests +{ + public sealed class RegressionTests + { + /// + /// Verifies that when a user overrides the BaseIntermediateOutputPath that the build still works. + /// + /// This was written because of regression https://github.com/Microsoft/msbuild/issues/1509. + [Fact] + public void OverrideBaseIntermediateOutputPathSucceeds() + { + Project project = ObjectModelHelpers.CreateInMemoryProject($@" + + + + + obj\x86\Debug + + + + + + + "); + + bool result = project.Build(); + + Assert.True(result); + } + } +} \ No newline at end of file From e8b8f2c4c64c2bc7e286ae213288b15addf134bd Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 9 Jan 2017 17:01:45 -0800 Subject: [PATCH 216/223] Implementation of implicit imports during evaluation instead of parsing (#1492) * Implementation of implicit imports during evaluation instead of during parsing of projects. Had to do some hacky stuff in the preprocessor but all of that code is private and we can make it better in the future. Closes #1447 --- ref/net46/Microsoft.Build/Microsoft.Build.cs | 12 +- .../Microsoft.Build/Microsoft.Build.cs | 12 +- src/Shared/XMakeAttributes.cs | 1 - .../Construction/ImplicitImportLocation.cs | 24 ++ .../Construction/ProjectElement.cs | 5 - .../Construction/ProjectElementContainer.cs | 17 +- .../Construction/ProjectImportElement.cs | 47 +++ .../Construction/ProjectRootElement.cs | 73 +++-- src/XMakeBuildEngine/Evaluation/Evaluator.cs | 57 +++- .../Evaluation/Preprocessor.cs | 71 ++++- .../Evaluation/ProjectParser.cs | 67 +---- src/XMakeBuildEngine/Microsoft.Build.csproj | 1 + .../Evaluation/Preprocessor_Tests.cs | 8 +- .../ElementLocationPublic_Tests.cs | 2 +- .../ProjectSdkImplicitImport_Tests.cs | 270 +++++++++++++----- 15 files changed, 446 insertions(+), 221 deletions(-) create mode 100644 src/XMakeBuildEngine/Construction/ImplicitImportLocation.cs diff --git a/ref/net46/Microsoft.Build/Microsoft.Build.cs b/ref/net46/Microsoft.Build/Microsoft.Build.cs index 1378dbc5ed4..450ebba5421 100644 --- a/ref/net46/Microsoft.Build/Microsoft.Build.cs +++ b/ref/net46/Microsoft.Build/Microsoft.Build.cs @@ -14,6 +14,12 @@ protected ElementLocation() { } public override int GetHashCode() { throw null; } public override string ToString() { throw null; } } + public enum ImplicitImportLocation + { + Bottom = 2, + None = 0, + Top = 1, + } [System.Diagnostics.DebuggerDisplayAttribute("ProjectChooseElement (#Children={Count} HasOtherwise={OtherwiseElement != null})")] public partial class ProjectChooseElement : Microsoft.Build.Construction.ProjectElementContainer { @@ -39,7 +45,6 @@ internal ProjectElement() { } public virtual string Condition { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public virtual Microsoft.Build.Construction.ElementLocation ConditionLocation { get { throw null; } } public Microsoft.Build.Construction.ProjectRootElement ContainingProject { get { throw null; } } - public bool IsImplicit { get { throw null; } } public string Label { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public Microsoft.Build.Construction.ElementLocation LabelLocation { get { throw null; } } public Microsoft.Build.Construction.ElementLocation Location { get { throw null; } } @@ -84,8 +89,11 @@ public override void CopyFrom(Microsoft.Build.Construction.ProjectElement elemen public partial class ProjectImportElement : Microsoft.Build.Construction.ProjectElement { internal ProjectImportElement() { } + public Microsoft.Build.Construction.ImplicitImportLocation ImplicitImportLocation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } public string Project { get { throw null; } set { } } public Microsoft.Build.Construction.ElementLocation ProjectLocation { get { throw null; } } + public string Sdk { get { throw null; } set { } } + public Microsoft.Build.Construction.ElementLocation SdkLocation { get { throw null; } } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("#Imports={Count} Condition={Condition} Label={Label}")] @@ -253,6 +261,8 @@ internal ProjectRootElement() { } public System.Collections.Generic.ICollection PropertyGroups { get { throw null; } } public System.Collections.Generic.ICollection PropertyGroupsReversed { get { throw null; } } public string RawXml { get { throw null; } } + public string Sdk { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } + public Microsoft.Build.Construction.ElementLocation SdkLocation { get { throw null; } } public System.Collections.Generic.ICollection Targets { get { throw null; } } public System.DateTime TimeLastChanged { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } } public string ToolsVersion { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } diff --git a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs index 2048eced5a2..4a6a935c779 100644 --- a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs +++ b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs @@ -14,6 +14,12 @@ protected ElementLocation() { } public override int GetHashCode() { throw null; } public override string ToString() { throw null; } } + public enum ImplicitImportLocation + { + Bottom = 2, + None = 0, + Top = 1, + } [System.Diagnostics.DebuggerDisplayAttribute("ProjectChooseElement (#Children={Count} HasOtherwise={OtherwiseElement != null})")] public partial class ProjectChooseElement : Microsoft.Build.Construction.ProjectElementContainer { @@ -39,7 +45,6 @@ internal ProjectElement() { } public virtual string Condition { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public virtual Microsoft.Build.Construction.ElementLocation ConditionLocation { get { throw null; } } public Microsoft.Build.Construction.ProjectRootElement ContainingProject { get { throw null; } } - public bool IsImplicit { get { throw null; } } public string Label { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } public Microsoft.Build.Construction.ElementLocation LabelLocation { get { throw null; } } public Microsoft.Build.Construction.ElementLocation Location { get { throw null; } } @@ -84,8 +89,11 @@ public override void CopyFrom(Microsoft.Build.Construction.ProjectElement elemen public partial class ProjectImportElement : Microsoft.Build.Construction.ProjectElement { internal ProjectImportElement() { } + public Microsoft.Build.Construction.ImplicitImportLocation ImplicitImportLocation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } public string Project { get { throw null; } set { } } public Microsoft.Build.Construction.ElementLocation ProjectLocation { get { throw null; } } + public string Sdk { get { throw null; } set { } } + public Microsoft.Build.Construction.ElementLocation SdkLocation { get { throw null; } } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("#Imports={Count} Condition={Condition} Label={Label}")] @@ -253,6 +261,8 @@ internal ProjectRootElement() { } public System.Collections.Generic.ICollection PropertyGroups { get { throw null; } } public System.Collections.Generic.ICollection PropertyGroupsReversed { get { throw null; } } public string RawXml { get { throw null; } } + public string Sdk { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } + public Microsoft.Build.Construction.ElementLocation SdkLocation { get { throw null; } } public System.Collections.Generic.ICollection Targets { get { throw null; } } public System.DateTime TimeLastChanged { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } } public string ToolsVersion { [System.Diagnostics.DebuggerStepThroughAttribute]get { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute]set { } } diff --git a/src/Shared/XMakeAttributes.cs b/src/Shared/XMakeAttributes.cs index 3df2a54acf8..b34759d7653 100644 --- a/src/Shared/XMakeAttributes.cs +++ b/src/Shared/XMakeAttributes.cs @@ -40,7 +40,6 @@ internal static class XMakeAttributes internal const string taskName = "TaskName"; internal const string continueOnError = "ContinueOnError"; internal const string project = "Project"; - internal const string @implicit = "_Implicit"; internal const string taskParameter = "TaskParameter"; internal const string itemName = "ItemName"; internal const string propertyName = "PropertyName"; diff --git a/src/XMakeBuildEngine/Construction/ImplicitImportLocation.cs b/src/XMakeBuildEngine/Construction/ImplicitImportLocation.cs new file mode 100644 index 00000000000..8f6ad0af683 --- /dev/null +++ b/src/XMakeBuildEngine/Construction/ImplicitImportLocation.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Build.Construction +{ + /// + /// Represents the location of an implicit import. + /// + public enum ImplicitImportLocation + { + /// + /// The import is not implicitly added and is explicitly added in a user-specified location. + /// + None, + /// + /// The import was implicitly added at the top of the project. + /// + Top, + /// + /// The import was implicitly added at the bottom of the project. + /// + Bottom + } +} \ No newline at end of file diff --git a/src/XMakeBuildEngine/Construction/ProjectElement.cs b/src/XMakeBuildEngine/Construction/ProjectElement.cs index 2cd34d3a166..9dc045eee1b 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElement.cs @@ -292,11 +292,6 @@ public ElementLocation Location get { return XmlElement.Location; } } - /// - /// Gets the Implicit state of the element: true if the element was not in the read XML. - /// - public bool IsImplicit => XmlElement.HasAttribute(XMakeAttributes.@implicit); - /// /// Gets the name of the associated element. /// Useful for display in some circumstances. diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index 1212a65c7b5..baf9ffc8338 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -455,11 +455,6 @@ internal void UpdateElementValue(ProjectElement child) /// internal void AddToXml(ProjectElement child) { - if (child.IsImplicit) - { - return; - } - if (child.ExpressedAsAttribute) { // todo children represented as attributes need to be placed in order too @@ -485,7 +480,7 @@ internal void AddToXml(ProjectElement child) // If none is found, then the node being added is inserted as the only node of its kind ProjectElement referenceSibling; - Predicate siblingIsExplicitElement = _ => _.ExpressedAsAttribute == false && _.IsImplicit == false; + Predicate siblingIsExplicitElement = _ => _.ExpressedAsAttribute == false; if (TrySearchLeftSiblings(child.PreviousSibling, siblingIsExplicitElement, out referenceSibling)) { @@ -567,11 +562,6 @@ private string GetElementIndentation(XmlElementWithLocation xmlElement) internal void RemoveFromXml(ProjectElement child) { - if (child.IsImplicit) - { - return; - } - if (child.ExpressedAsAttribute) { XmlElement.RemoveAttribute(child.XmlElement.Name); @@ -630,10 +620,7 @@ private void AddInitialChild(ProjectElement child) _count++; - if (!child.IsImplicit) - { - MarkDirty("Add child element named '{0}'", child.ElementName); - } + MarkDirty("Add child element named '{0}'", child.ElementName); } /// diff --git a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs index 1bf6cfc9269..2095b44ccf3 100644 --- a/src/XMakeBuildEngine/Construction/ProjectImportElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectImportElement.cs @@ -61,6 +61,38 @@ public string Project /// public ElementLocation ProjectLocation => XmlElement.GetAttributeLocation(XMakeAttributes.project); + /// + /// Gets or sets the SDK that contains the import. + /// + public string Sdk + { + get + { + return + FileUtilities.FixFilePath(ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.sdk)); + } + + set + { + ErrorUtilities.VerifyThrowArgumentLength(value, XMakeAttributes.sdk); + + ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.sdk, value); + MarkDirty("Set Import Sdk {0}", value); + } + } + + /// + /// Location of the Sdk attribute + /// + public ElementLocation SdkLocation => XmlElement.GetAttributeLocation(XMakeAttributes.sdk); + + /// + /// Gets the of the import. This indicates if the import was implicitly + /// added because of the attribute and the location where the project was + /// imported. + /// + public ImplicitImportLocation ImplicitImportLocation { get; internal set; } = ImplicitImportLocation.None; + /// /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. /// Validates the project value. @@ -77,6 +109,21 @@ internal static ProjectImportElement CreateDisconnected(string project, ProjectR return import; } + /// + /// Creates an implicit ProjectImportElement as if it was in the project. + /// + /// + internal static ProjectImportElement CreateImplicit(string project, ProjectRootElement containingProject, ImplicitImportLocation implicitImportLocation, string sdkName) + { + ProjectImportElement import = CreateDisconnected(project, containingProject); + + import.ImplicitImportLocation = implicitImportLocation; + + import.Sdk = sdkName; + + return import; + } + /// /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index d58345e6662..8d6910541cc 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -158,11 +158,6 @@ public class ProjectRootElement : ProjectElementContainer /// private BuildEventContext _buildEventContext; - /// - /// Xpath expression that will find any element with the implicit attribute - /// - private static readonly string ImplicitAttributeXpath = $"//*[@{XMakeAttributes.@implicit}]"; - /// /// Initialize a ProjectRootElement instance from a XmlReader. /// May throw InvalidProjectFileException. @@ -668,6 +663,28 @@ public string InitialTargets } } + /// + /// Gets or sets a semicolon delimited list of software development kits (SDK) that the project uses. + /// If a value is specified, an Sdk.props is simplicity imported at the top of the project and an + /// Sdk.targets is simplicity imported at the bottom from the specified SDK. + /// If the value is null or empty, removes the attribute. + /// + public string Sdk + { + [DebuggerStepThrough] + get + { + return ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.sdk); + } + + [DebuggerStepThrough] + set + { + ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, XMakeAttributes.sdk, value); + MarkDirty("Set project Sdk to '{0}'", value); + } + } + /// /// Gets or sets the value of TreatAsLocalProperty. If there is no tag, returns empty string. /// If the value being set is null or empty, removes the attribute. @@ -724,10 +741,8 @@ public string RawXml { using (ProjectWriter projectWriter = new ProjectWriter(stringWriter)) { - var xmlWithNoImplicits = RemoveImplicits(); - - projectWriter.Initialize(xmlWithNoImplicits); - xmlWithNoImplicits.Save(projectWriter); + projectWriter.Initialize(XmlDocument); + XmlDocument.Save(projectWriter); } return stringWriter.ToString(); @@ -862,6 +877,14 @@ public ElementLocation InitialTargetsLocation get { return XmlElement.GetAttributeLocation(XMakeAttributes.initialTargets); } } + /// + /// Location of the Sdk attribute, if any + /// + public ElementLocation SdkLocation + { + get { return XmlElement.GetAttributeLocation(XMakeAttributes.sdk); } + } + /// /// Location of the TreatAsLocalProperty attribute, if any /// @@ -1766,10 +1789,8 @@ public void Save(Encoding saveEncoding) { using (ProjectWriter projectWriter = new ProjectWriter(_projectFileLocation.File, saveEncoding)) { - var xmlWithNoImplicits = RemoveImplicits(); - - projectWriter.Initialize(xmlWithNoImplicits); - xmlWithNoImplicits.Save(projectWriter); + projectWriter.Initialize(XmlDocument); + XmlDocument.Save(projectWriter); } _encoding = saveEncoding; @@ -1798,26 +1819,6 @@ public void Save(Encoding saveEncoding) #endif } - private XmlDocument RemoveImplicits() - { - if (XmlDocument.SelectSingleNode(ImplicitAttributeXpath) == null) - { - return XmlDocument; - } - - var xmlWithNoImplicits = (XmlDocument) XmlDocument.CloneNode(deep: true); - - var implicitElements = - xmlWithNoImplicits.SelectNodes(ImplicitAttributeXpath); - - foreach (XmlNode implicitElement in implicitElements) - { - implicitElement.ParentNode.RemoveChild(implicitElement); - } - - return xmlWithNoImplicits; - } - /// /// Save the project to the file system, if dirty or the path is different. /// Creates any necessary directories. @@ -1851,10 +1852,8 @@ public void Save(TextWriter writer) { using (ProjectWriter projectWriter = new ProjectWriter(writer)) { - var xmlWithNoImplicits = RemoveImplicits(); - - projectWriter.Initialize(xmlWithNoImplicits); - xmlWithNoImplicits.Save(projectWriter); + projectWriter.Initialize(XmlDocument); + XmlDocument.Save(projectWriter); } _versionOnDisk = Version; diff --git a/src/XMakeBuildEngine/Evaluation/Evaluator.cs b/src/XMakeBuildEngine/Evaluation/Evaluator.cs index f931aada4f2..9945f88aeab 100644 --- a/src/XMakeBuildEngine/Evaluation/Evaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/Evaluator.cs @@ -987,6 +987,39 @@ element is ProjectOtherwiseElement DebuggerManager.BakeStates(Path.GetFileNameWithoutExtension(currentProjectOrImport.FullPath)); } #endif + IList implicitImports = new List(); + + if (!String.IsNullOrWhiteSpace(currentProjectOrImport.Sdk)) + { + // SDK imports are added implicitly where they are evaluated at the top and bottom as if they are in the XML + // + foreach (string sdk in currentProjectOrImport.Sdk.Split(';').Select(i => i.Trim())) + { + if (String.IsNullOrWhiteSpace(sdk)) + { + ProjectErrorUtilities.ThrowInvalidProject(currentProjectOrImport.SdkLocation, "InvalidSdkFormat", currentProjectOrImport.Sdk); + } + + int slashIndex = sdk.LastIndexOf("/", StringComparison.Ordinal); + string sdkName = slashIndex > 0 ? sdk.Substring(0, slashIndex) : sdk; + + // TODO: do something other than just ignore the version + + if (sdkName.Contains("/")) + { + ProjectErrorUtilities.ThrowInvalidProject(currentProjectOrImport.SdkLocation, "InvalidSdkFormat", currentProjectOrImport.Sdk); + } + + implicitImports.Add(ProjectImportElement.CreateImplicit("Sdk.props", currentProjectOrImport, ImplicitImportLocation.Top, sdkName)); + + implicitImports.Add(ProjectImportElement.CreateImplicit("Sdk.targets", currentProjectOrImport, ImplicitImportLocation.Bottom, sdkName)); + } + } + + foreach (var import in implicitImports.Where(i => i.ImplicitImportLocation == ImplicitImportLocation.Top)) + { + EvaluateImportElement(currentProjectOrImport.DirectoryPath, import); + } foreach (ProjectElement element in currentProjectOrImport.Children) { @@ -1143,6 +1176,11 @@ child is ProjectItemElement || ErrorUtilities.ThrowInternalError("Unexpected child type"); } + foreach (var import in implicitImports.Where(i => i.ImplicitImportLocation == ImplicitImportLocation.Bottom)) + { + EvaluateImportElement(currentProjectOrImport.DirectoryPath, import); + } + #if FEATURE_MSBUILD_DEBUGGER if (DebuggerManager.DebuggingEnabled) { @@ -2240,7 +2278,14 @@ private List ExpandAndLoadImports(string directoryOfImportin continue; } - var newExpandedImportPath = importElement.Project.Replace(extensionPropertyRefAsString, extensionPathExpanded); + string project = importElement.Project; + if (!String.IsNullOrWhiteSpace(importElement.Sdk)) + { + project = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, importElement.Sdk, "Sdk", project); + } + + + var newExpandedImportPath = project.Replace(extensionPropertyRefAsString, extensionPathExpanded); _loggingService.LogComment(_buildEventContext, MessageImportance.Low, "TryingExtensionsPath", newExpandedImportPath, extensionPathExpanded); List projects; @@ -2307,7 +2352,13 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpressionCondi return LoadImportsResult.ConditionWasFalse; } - return ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, importElement.Project, throwOnFileNotExistsError, out projects); + string project = importElement.Project; + if (!String.IsNullOrWhiteSpace(importElement.Sdk)) + { + project = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, importElement.Sdk, "Sdk", project); + } + + return ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, project, throwOnFileNotExistsError, out projects); } /// @@ -2410,7 +2461,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri { parenthesizedProjectLocation = "[" + _projectRootElement.FullPath + "]"; } - + // TODO: Detect if the duplicate import came from an SDK attribute _loggingService.LogWarning(_buildEventContext, null, new BuildEventFileInfo(importLocationInProject), "DuplicateImport", importFileUnescaped, previouslyImportedAt.Location.LocationString, parenthesizedProjectLocation); duplicateImport = true; } diff --git a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs index 462d81094c9..8734b65fe82 100644 --- a/src/XMakeBuildEngine/Evaluation/Preprocessor.cs +++ b/src/XMakeBuildEngine/Evaluation/Preprocessor.cs @@ -35,17 +35,17 @@ internal class Preprocessor /// /// Project to preprocess /// - private Project _project; + private readonly Project _project; /// /// Table to resolve import tags /// - private Dictionary> _importTable; + private readonly Dictionary> _importTable; /// /// Stack of file paths pushed as we follow imports /// - private Stack _filePaths = new Stack(); + private readonly Stack _filePaths = new Stack(); /// /// Constructor @@ -56,15 +56,15 @@ private Preprocessor(Project project) IList imports = project.Imports; - _importTable = new Dictionary>(imports.Count); + _importTable = new Dictionary>(imports.Count); foreach (ResolvedImport entry in imports) { IList list; - if (!_importTable.TryGetValue(entry.ImportingElement.XmlElement, out list)) + if (!_importTable.TryGetValue(entry.ImportingElement.XmlElement.OuterXml, out list)) { list = new List(); - _importTable[entry.ImportingElement.XmlElement] = list; + _importTable[entry.ImportingElement.XmlElement.OuterXml] = list; } list.Add(entry.ImportedProject); @@ -91,9 +91,44 @@ private XmlDocument Preprocess() { XmlDocument outerDocument = _project.Xml.XmlDocument; - XmlDocument destinationDocument = (XmlDocument)outerDocument.CloneNode(false /* shallow */); + int implicitImportCount = _project.Imports.Count(i => i.ImportingElement.ImplicitImportLocation != ImplicitImportLocation.None); + // At the time of adding this feature, cloning is buggy. The implicit imports are added to the XML document and removed after + // processing. This variable keeps track of the nodes that were added + IList addedNodes = new List(implicitImportCount); + XmlElement documentElement = outerDocument.DocumentElement; - // TODO: Remove Sdk attribute from destination document and put it in a comment (so that if you do a build on a preprocessed file it won't try to import the Sdk imports twice) + if (implicitImportCount > 0 && documentElement != null) + { + // Top implicit imports need to be added in the correct order by adding the first one at the top and each one after the first + // one. This variable keeps track of the last import that was added. + XmlNode lastImplicitImportAdded = null; + + // Add the implicit top imports + // + foreach (var import in _project.Imports.Where(i => i.ImportingElement.ImplicitImportLocation == ImplicitImportLocation.Top)) + { + XmlNode node = outerDocument.ImportNode(import.ImportingElement.XmlElement, false); + if (lastImplicitImportAdded == null) + { + documentElement.InsertBefore(node, documentElement.FirstChild); + lastImplicitImportAdded = node; + } + else + { + documentElement.InsertAfter(node, lastImplicitImportAdded); + } + addedNodes.Add(node); + } + + // Add the implicit bottom imports + // + foreach (var import in _project.Imports.Where(i => i.ImportingElement.ImplicitImportLocation == ImplicitImportLocation.Bottom)) + { + addedNodes.Add(documentElement.InsertAfter(outerDocument.ImportNode(import.ImportingElement.XmlElement, false), documentElement.LastChild)); + } + } + + XmlDocument destinationDocument = (XmlDocument)outerDocument.CloneNode(false /* shallow */); _filePaths.Push(_project.FullPath); @@ -104,6 +139,13 @@ private XmlDocument Preprocess() CloneChildrenResolvingImports(outerDocument, destinationDocument); + // Remove the nodes that were added as implicit imports + // + foreach (XmlNode addedNode in addedNodes) + { + documentElement?.RemoveChild(addedNode); + } + return destinationDocument; } @@ -174,7 +216,7 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) string sdk = importSdk.Length > 0 ? $" {XMakeAttributes.sdk}=\"{importSdk}\"" : String.Empty; IList resolvedList; - if (!_importTable.TryGetValue(child as XmlElement, out resolvedList)) + if (!_importTable.TryGetValue(((XmlElement)child).OuterXml, out resolvedList)) { // Import didn't resolve to anything; just display as a comment and move on string closedImportTag = @@ -192,10 +234,10 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) string importTag = $" "; - if (((XmlElement)child).GetAttribute(XMakeAttributes.@implicit).Length > 0) + if (!String.IsNullOrWhiteSpace(importSdk) && _project.Xml.Sdk.IndexOf(importSdk, StringComparison.OrdinalIgnoreCase) >= 0) { - importTag = - $" Import of \"{importProject.Replace("--", "__")}\" from Sdk \"{importSdk}\" was implied by the {XMakeElements.project} element's {XMakeAttributes.sdk} attribute."; + importTag += + $"\r\n This import was added implicitly because of the {XMakeElements.project} element's {XMakeAttributes.sdk} attribute specified \"{importSdk}\"."; } destination.AppendChild(destinationDocument.CreateComment( @@ -236,6 +278,11 @@ private void CloneChildrenResolvingImports(XmlNode source, XmlNode destination) // Node doesn't need special treatment, clone and append XmlNode clone = destinationDocument.ImportNode(child, false /* shallow */); // ImportNode does a clone but unlike CloneNode it works across XmlDocuments + if (clone.NodeType == XmlNodeType.Element && String.Equals(XMakeElements.project, child.Name, StringComparison.Ordinal) && clone.Attributes?[XMakeAttributes.sdk] != null) + { + clone.Attributes.Remove(clone.Attributes[XMakeAttributes.sdk]); + } + destination.AppendChild(clone); CloneChildrenResolvingImports(child, clone); diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 53b43c2faf3..0e1846855d8 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -47,7 +47,7 @@ internal class ProjectParser /// /// Valid attributes on import element /// - private readonly static string[] s_validAttributesOnImport = new string[] { XMakeAttributes.condition, XMakeAttributes.label, XMakeAttributes.project, XMakeAttributes.sdk, XMakeAttributes.@implicit }; + private readonly static string[] s_validAttributesOnImport = new string[] { XMakeAttributes.condition, XMakeAttributes.label, XMakeAttributes.project, XMakeAttributes.sdk }; /// /// Valid attributes on usingtask element @@ -187,61 +187,6 @@ private void ParseProjectElement(XmlElementWithLocation element) // so we have to set it now _project.SetProjectRootElementFromParser(element, _project); - if (element.HasAttribute(XMakeAttributes.sdk)) - { - - var sdksString = element.GetAttribute(XMakeAttributes.sdk); - - var sdks = sdksString.Contains(";") ? sdksString.Split(';') : new[] {sdksString}; - - foreach (var sdk in sdks) - { - var slashIndex = sdk.LastIndexOf("/", StringComparison.Ordinal); - string sdkName = slashIndex > 0 ? sdk.Substring(0, slashIndex) : sdk; - - // TODO: do something other than just ignore the version - - if (sdkName.Contains("/")) - { - ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.sdk), - "InvalidSdkFormat"); - } - - // TODO: paths should just be Sdk.props/targets; Sdk-aware imports should do the rest of the path. - var initialImportPath = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, - sdkName, "Sdk", "Sdk.props"); - var finalImportPath = Path.Combine(BuildEnvironmentHelper.Instance.MSBuildSDKsPath, - sdkName, "Sdk", "Sdk.targets"); - - // TODO: don't require all SDKs to have both props and targets - // if (File.Exists(initialImportPath)) - { - var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - // TODO: make this - implicitImportElement.SetAttribute(XMakeAttributes.project, - initialImportPath); - implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {sdkName}"); - implicitImportElement.SetAttribute(XMakeAttributes.sdk, sdkName); - - element.PrependChild(implicitImportElement); - } - - // TODO: don't require all SDKs to have both props and targets - // if (File.Exists(finalImportPath)) - { - var implicitImportElement = element.OwnerDocument.CreateElement(XMakeElements.import); - - // TODO: make this - implicitImportElement.SetAttribute(XMakeAttributes.project, - finalImportPath); - implicitImportElement.SetAttribute(XMakeAttributes.@implicit, $"Sdk = {sdkName}"); - implicitImportElement.SetAttribute(XMakeAttributes.sdk, sdkName); - - element.AppendChild(implicitImportElement); - } - } - } ParseProjectRootElementChildren(element); } @@ -573,16 +518,6 @@ private ProjectImportElement ParseProjectImportElement(XmlElementWithLocation el ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); - if (element.HasAttribute(XMakeAttributes.@implicit)) - { - // the implicit attribute is only allowed on Import, but only if MSBuild itself - // put it there. If a user specified it in a project, error just like we would - // when encountering an unknown attribute. - ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute( - element.Location.Line == 0 && element.Location.Column == 0, - element.GetAttributeWithLocation(XMakeAttributes.@implicit)); - } - return new ProjectImportElement(element, parent, _project); } diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index 376f0ac3b1d..9c73dc1246b 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -231,6 +231,7 @@ true + diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs index 71acdfd07e5..9aa3094302f 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Preprocessor_Tests.cs @@ -885,10 +885,11 @@ public void SdkImportsAreInPreprocessedOutput() string expected = ObjectModelHelpers.CleanupFileContents( $@" - + - - + + <_DesignTimeFacadeAssemblies_Names Include="@(_DesignTimeFacadeAssemblies->'%(FileName)')"> + %(_DesignTimeFacadeAssemblies.Identity) + + + <_ReferencePath_Names Include="@(ReferencePath->'%(FileName)')"> + %(ReferencePath.Identity) + + + <_DesignTimeFacadeAssemblies_Names Remove="@(_ReferencePath_Names)"/> + + false false ImplicitlyExpandDesignTimeFacades From 9e6e7dbd1f271fb19a36d0128a474bb469d43801 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 10 Jan 2017 15:40:29 -0600 Subject: [PATCH 218/223] Update nuspecs for #1522 (#1534) These changes were made automatically via `cibuild.cmd --target CoreCLR`, and update the checked-in specs to match the new references. --- .../Microsoft.Build.Tasks.Core.nuspec | 30 +++++++++---------- .../Microsoft.Build.Utilities.Core.nuspec | 30 +++++++++---------- build/NuGetPackages/Microsoft.Build.nuspec | 26 ++++++++-------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/build/NuGetPackages/Microsoft.Build.Tasks.Core.nuspec b/build/NuGetPackages/Microsoft.Build.Tasks.Core.nuspec index b976f8dd625..2fab4e7d59e 100644 --- a/build/NuGetPackages/Microsoft.Build.Tasks.Core.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Tasks.Core.nuspec @@ -20,41 +20,41 @@ - + - + - + - - + + - + - + - + - - + + - - + + - + - - + + diff --git a/build/NuGetPackages/Microsoft.Build.Utilities.Core.nuspec b/build/NuGetPackages/Microsoft.Build.Utilities.Core.nuspec index 96e41e8e025..d7b088150b4 100644 --- a/build/NuGetPackages/Microsoft.Build.Utilities.Core.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Utilities.Core.nuspec @@ -19,33 +19,33 @@ - - + + - + - - + + - + - + - - - - - + + + + + - + - - + + diff --git a/build/NuGetPackages/Microsoft.Build.nuspec b/build/NuGetPackages/Microsoft.Build.nuspec index 0c269f354d0..df413190558 100644 --- a/build/NuGetPackages/Microsoft.Build.nuspec +++ b/build/NuGetPackages/Microsoft.Build.nuspec @@ -18,42 +18,42 @@ - + - + - + - - + + - + - + - + - + - + - + - - + + From b81ac01e05c91d1c8935e2372dc50b328096b35d Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 10 Jan 2017 15:41:18 -0800 Subject: [PATCH 219/223] Clarify rebuild messages (#1530) Will be compiled as -> Will be compiled because --- src/Utilities/Resources/Strings.resx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Utilities/Resources/Strings.resx b/src/Utilities/Resources/Strings.resx index 581f22fb364..fed209eb9af 100644 --- a/src/Utilities/Resources/Strings.resx +++ b/src/Utilities/Resources/Strings.resx @@ -216,19 +216,19 @@ Tracking log {0} is not available. - {0} will be compiled as the tracking log is not available. + {0} will be compiled because the tracking log is not available. - {0} will be compiled as it was not found in the tracking log. + {0} will be compiled because it was not found in the tracking log. - {0} will be compiled as not all outputs are available. + {0} will be compiled because not all outputs are available. - {0} will be compiled as dependency {1} was missing. + {0} will be compiled because dependency {1} was missing. - {0} will be compiled as {1} was modified at {2}. + {0} will be compiled because {1} was modified at {2}. {0} will be compiled. @@ -243,7 +243,7 @@ {0} does not exist; source compilation required. - {0} will be compiled as output {1} does not exist. + {0} will be compiled because output {1} does not exist. Read Tracking Logs: From 08ad22ea14cf33854157e48256dfd3d58f2e77a8 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 10 Jan 2017 17:06:52 -0800 Subject: [PATCH 220/223] Update xlf files from resx (#1537) --- src/Utilities/Resources/xlf/Strings.cs.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.de.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.es.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.fr.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.it.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.ja.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.ko.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.pl.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.pt-BR.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.ru.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.tr.xlf | 36 ++++---- src/Utilities/Resources/xlf/Strings.xlf | 24 ++--- .../Resources/xlf/Strings.zh-Hans.xlf | 36 ++++---- .../Resources/xlf/Strings.zh-Hant.xlf | 36 ++++---- .../Resources/xlf/Strings.cs.xlf | 35 ++++++++ .../Resources/xlf/Strings.de.xlf | 35 ++++++++ .../Resources/xlf/Strings.es.xlf | 35 ++++++++ .../Resources/xlf/Strings.fr.xlf | 35 ++++++++ .../Resources/xlf/Strings.it.xlf | 35 ++++++++ .../Resources/xlf/Strings.ja.xlf | 35 ++++++++ .../Resources/xlf/Strings.ko.xlf | 35 ++++++++ .../Resources/xlf/Strings.pl.xlf | 35 ++++++++ .../Resources/xlf/Strings.pt-BR.xlf | 35 ++++++++ .../Resources/xlf/Strings.ru.xlf | 35 ++++++++ .../Resources/xlf/Strings.tr.xlf | 35 ++++++++ .../Resources/xlf/Strings.xlf | 28 ++++++ .../Resources/xlf/Strings.zh-Hans.xlf | 35 ++++++++ .../Resources/xlf/Strings.zh-Hant.xlf | 35 ++++++++ .../Resources/xlf/Strings.cs.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.de.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.es.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.fr.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.it.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.ja.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.ko.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.pl.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.pt-BR.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.ru.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.tr.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.xlf | 61 ++++++++++++- .../Resources/xlf/Strings.zh-Hans.xlf | 90 ++++++++++++++++++- .../Resources/xlf/Strings.zh-Hant.xlf | 90 ++++++++++++++++++- src/XMakeTasks/Resources/xlf/Strings.cs.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.de.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.es.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.fr.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.it.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.ja.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.ko.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.pl.xlf | 20 +++++ .../Resources/xlf/Strings.pt-BR.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.ru.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.tr.xlf | 20 +++++ src/XMakeTasks/Resources/xlf/Strings.xlf | 16 ++++ .../Resources/xlf/Strings.zh-Hans.xlf | 20 +++++ .../Resources/xlf/Strings.zh-Hant.xlf | 20 +++++ 56 files changed, 2182 insertions(+), 300 deletions(-) diff --git a/src/Utilities/Resources/xlf/Strings.cs.xlf b/src/Utilities/Resources/xlf/Strings.cs.xlf index a89b7917def..c3e42a8dda3 100644 --- a/src/Utilities/Resources/xlf/Strings.cs.xlf +++ b/src/Utilities/Resources/xlf/Strings.cs.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} bude kompilováno, protože protokol sledování není k dispozici. - + {0} will be compiled because the tracking log is not available. + {0} bude kompilováno, protože protokol sledování není k dispozici. + - {0} will be compiled as it was not found in the tracking log. - {0} bude kompilováno, protože nebylo nalezeno v protokolu sledování. - + {0} will be compiled because it was not found in the tracking log. + {0} bude kompilováno, protože nebylo nalezeno v protokolu sledování. + - {0} will be compiled as not all outputs are available. - {0} bude kompilováno, protože nejsou k dispozici všechny výstupy. - + {0} will be compiled because not all outputs are available. + {0} bude kompilováno, protože nejsou k dispozici všechny výstupy. + - {0} will be compiled as dependency {1} was missing. - Zdroj {0} bude zkompilován, protože chyběla závislost {1}. - + {0} will be compiled because dependency {1} was missing. + Zdroj {0} bude zkompilován, protože chyběla závislost {1}. + - {0} will be compiled as {1} was modified at {2}. - Zdroj {0} bude zkompilován, protože závislost {1} byla změněna v {2}. - + {0} will be compiled because {1} was modified at {2}. + Zdroj {0} bude zkompilován, protože závislost {1} byla změněna v {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - Zdroj {0} bude zkompilován, protože neexistuje výstup {1}. - + {0} will be compiled because output {1} does not exist. + Zdroj {0} bude zkompilován, protože neexistuje výstup {1}. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.de.xlf b/src/Utilities/Resources/xlf/Strings.de.xlf index e5d16a590dd..4ffad3058d2 100644 --- a/src/Utilities/Resources/xlf/Strings.de.xlf +++ b/src/Utilities/Resources/xlf/Strings.de.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} wird kompiliert, da das Nachverfolgungsprotokoll nicht verfügbar ist. - + {0} will be compiled because the tracking log is not available. + {0} wird kompiliert, da das Nachverfolgungsprotokoll nicht verfügbar ist. + - {0} will be compiled as it was not found in the tracking log. - {0} wird kompiliert, da sie im Nachverfolgungsprotokoll nicht gefunden wurde. - + {0} will be compiled because it was not found in the tracking log. + {0} wird kompiliert, da sie im Nachverfolgungsprotokoll nicht gefunden wurde. + - {0} will be compiled as not all outputs are available. - {0} wird kompiliert, da nicht alle Ausgaben verfügbar sind. - + {0} will be compiled because not all outputs are available. + {0} wird kompiliert, da nicht alle Ausgaben verfügbar sind. + - {0} will be compiled as dependency {1} was missing. - {0} wird als Abhängigkeit kompiliert {1} war nicht vorhanden. - + {0} will be compiled because dependency {1} was missing. + {0} wird als Abhängigkeit kompiliert {1} war nicht vorhanden. + - {0} will be compiled as {1} was modified at {2}. - {0} wird als {1} kompiliert, wurde geändert bei {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} wird als {1} kompiliert, wurde geändert bei {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} wird als Ausgabe kompiliert {1} ist nicht vorhanden. - + {0} will be compiled because output {1} does not exist. + {0} wird als Ausgabe kompiliert {1} ist nicht vorhanden. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.es.xlf b/src/Utilities/Resources/xlf/Strings.es.xlf index 61167b64e6e..7f4f666c950 100644 --- a/src/Utilities/Resources/xlf/Strings.es.xlf +++ b/src/Utilities/Resources/xlf/Strings.es.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} se compilará porque el registro de seguimiento no está disponible. - + {0} will be compiled because the tracking log is not available. + {0} se compilará porque el registro de seguimiento no está disponible. + - {0} will be compiled as it was not found in the tracking log. - {0} se compilará porque no se encuentra en el registro de seguimiento. - + {0} will be compiled because it was not found in the tracking log. + {0} se compilará porque no se encuentra en el registro de seguimiento. + - {0} will be compiled as not all outputs are available. - {0} se compilará porque no todas las salidas están disponibles. - + {0} will be compiled because not all outputs are available. + {0} se compilará porque no todas las salidas están disponibles. + - {0} will be compiled as dependency {1} was missing. - {0} se compilará porque falta la dependencia {1}. - + {0} will be compiled because dependency {1} was missing. + {0} se compilará porque falta la dependencia {1}. + - {0} will be compiled as {1} was modified at {2}. - {0} se compilará porque {1} se modificó en {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} se compilará porque {1} se modificó en {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} se compilará porque la salida {1} no existe. - + {0} will be compiled because output {1} does not exist. + {0} se compilará porque la salida {1} no existe. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.fr.xlf b/src/Utilities/Resources/xlf/Strings.fr.xlf index a06c6cbb8c8..dcf14f8d845 100644 --- a/src/Utilities/Resources/xlf/Strings.fr.xlf +++ b/src/Utilities/Resources/xlf/Strings.fr.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} sera compilé, car le journal de suivi n'est pas disponible. - + {0} will be compiled because the tracking log is not available. + {0} sera compilé, car le journal de suivi n'est pas disponible. + - {0} will be compiled as it was not found in the tracking log. - {0} sera compilé, car il est introuvable dans le journal de suivi. - + {0} will be compiled because it was not found in the tracking log. + {0} sera compilé, car il est introuvable dans le journal de suivi. + - {0} will be compiled as not all outputs are available. - {0} sera compilé, car les sorties ne sont pas toutes disponibles. - + {0} will be compiled because not all outputs are available. + {0} sera compilé, car les sorties ne sont pas toutes disponibles. + - {0} will be compiled as dependency {1} was missing. - {0} sera compilé puisque la dépendance {1} était manquante. - + {0} will be compiled because dependency {1} was missing. + {0} sera compilé puisque la dépendance {1} était manquante. + - {0} will be compiled as {1} was modified at {2}. - {0} sera compilé puisque {1} a été modifié à {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} sera compilé puisque {1} a été modifié à {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} sera compilé puisque la sortie {1} n'existe pas. - + {0} will be compiled because output {1} does not exist. + {0} sera compilé puisque la sortie {1} n'existe pas. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.it.xlf b/src/Utilities/Resources/xlf/Strings.it.xlf index 2a054a281b3..69c9dee2021 100644 --- a/src/Utilities/Resources/xlf/Strings.it.xlf +++ b/src/Utilities/Resources/xlf/Strings.it.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - Verrà eseguita la compilazione di {0} poiché il log di rilevamento non è disponibile. - + {0} will be compiled because the tracking log is not available. + Verrà eseguita la compilazione di {0} poiché il log di rilevamento non è disponibile. + - {0} will be compiled as it was not found in the tracking log. - Verrà eseguita la compilazione di {0} poiché non presente nel log di rilevamento. - + {0} will be compiled because it was not found in the tracking log. + Verrà eseguita la compilazione di {0} poiché non presente nel log di rilevamento. + - {0} will be compiled as not all outputs are available. - Verrà eseguita la compilazione di {0} poiché non tutti gli output sono disponibili. - + {0} will be compiled because not all outputs are available. + Verrà eseguita la compilazione di {0} poiché non tutti gli output sono disponibili. + - {0} will be compiled as dependency {1} was missing. - Verrà eseguita la compilazione di {0} poiché la dipendenza {1} è mancante. - + {0} will be compiled because dependency {1} was missing. + Verrà eseguita la compilazione di {0} poiché la dipendenza {1} è mancante. + - {0} will be compiled as {1} was modified at {2}. - Verrà eseguita la compilazione di {0} poiché {1} è stato modificato in {2}. - + {0} will be compiled because {1} was modified at {2}. + Verrà eseguita la compilazione di {0} poiché {1} è stato modificato in {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - Verrà eseguita la compilazione di {0} poiché l'output {1} non esiste. - + {0} will be compiled because output {1} does not exist. + Verrà eseguita la compilazione di {0} poiché l'output {1} non esiste. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.ja.xlf b/src/Utilities/Resources/xlf/Strings.ja.xlf index 0e6b611efbf..3d6e62a8042 100644 --- a/src/Utilities/Resources/xlf/Strings.ja.xlf +++ b/src/Utilities/Resources/xlf/Strings.ja.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - 追跡ログが使用できないため {0} はコンパイルされます。 - + {0} will be compiled because the tracking log is not available. + 追跡ログが使用できないため {0} はコンパイルされます。 + - {0} will be compiled as it was not found in the tracking log. - {0} は追跡ログに見つからないためコンパイルされます。 - + {0} will be compiled because it was not found in the tracking log. + {0} は追跡ログに見つからないためコンパイルされます。 + - {0} will be compiled as not all outputs are available. - 使用できない出力があるため {0} はコンパイルされます。 - + {0} will be compiled because not all outputs are available. + 使用できない出力があるため {0} はコンパイルされます。 + - {0} will be compiled as dependency {1} was missing. - 依存関係 {1} がないため、{0} がコンパイルされます。 - + {0} will be compiled because dependency {1} was missing. + 依存関係 {1} がないため、{0} がコンパイルされます。 + - {0} will be compiled as {1} was modified at {2}. - {1} が {2} で変更されたため、{0} がコンパイルされます。 - + {0} will be compiled because {1} was modified at {2}. + {1} が {2} で変更されたため、{0} がコンパイルされます。 + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - 出力 {1} が存在しないため、{0} がコンパイルされます。 - + {0} will be compiled because output {1} does not exist. + 出力 {1} が存在しないため、{0} がコンパイルされます。 + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.ko.xlf b/src/Utilities/Resources/xlf/Strings.ko.xlf index 398fdd9328c..d2bafad02d0 100644 --- a/src/Utilities/Resources/xlf/Strings.ko.xlf +++ b/src/Utilities/Resources/xlf/Strings.ko.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - 추적 로그를 사용할 수 없기 때문에 {0}이(가) 컴파일됩니다. - + {0} will be compiled because the tracking log is not available. + 추적 로그를 사용할 수 없기 때문에 {0}이(가) 컴파일됩니다. + - {0} will be compiled as it was not found in the tracking log. - {0}이(가) 추적 로그에 없기 때문에 컴파일됩니다. - + {0} will be compiled because it was not found in the tracking log. + {0}이(가) 추적 로그에 없기 때문에 컴파일됩니다. + - {0} will be compiled as not all outputs are available. - 일부 출력만 사용할 수 있기 때문에 {0}이(가) 컴파일됩니다. - + {0} will be compiled because not all outputs are available. + 일부 출력만 사용할 수 있기 때문에 {0}이(가) 컴파일됩니다. + - {0} will be compiled as dependency {1} was missing. - {1} 종속성이 없기 때문에 {0}이(가) 컴파일됩니다. - + {0} will be compiled because dependency {1} was missing. + {1} 종속성이 없기 때문에 {0}이(가) 컴파일됩니다. + - {0} will be compiled as {1} was modified at {2}. - {1}이(가) {2}에서 수정되었기 때문에 {0}이(가) 컴파일됩니다. - + {0} will be compiled because {1} was modified at {2}. + {1}이(가) {2}에서 수정되었기 때문에 {0}이(가) 컴파일됩니다. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {1} 출력이 없기 때문에 {0}이(가) 컴파일됩니다. - + {0} will be compiled because output {1} does not exist. + {1} 출력이 없기 때문에 {0}이(가) 컴파일됩니다. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.pl.xlf b/src/Utilities/Resources/xlf/Strings.pl.xlf index 3186097fe75..5cd00da0ac0 100644 --- a/src/Utilities/Resources/xlf/Strings.pl.xlf +++ b/src/Utilities/Resources/xlf/Strings.pl.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - Plik {0} zostanie skompilowany, ponieważ dziennik śledzenia jest niedostępny. - + {0} will be compiled because the tracking log is not available. + Plik {0} zostanie skompilowany, ponieważ dziennik śledzenia jest niedostępny. + - {0} will be compiled as it was not found in the tracking log. - Plik {0} zostanie skompilowany, ponieważ nie odnaleziono go w dzienniku śledzenia. - + {0} will be compiled because it was not found in the tracking log. + Plik {0} zostanie skompilowany, ponieważ nie odnaleziono go w dzienniku śledzenia. + - {0} will be compiled as not all outputs are available. - Plik {0} zostanie skompilowany, ponieważ nie wszystkie dane wyjściowe są dostępne. - + {0} will be compiled because not all outputs are available. + Plik {0} zostanie skompilowany, ponieważ nie wszystkie dane wyjściowe są dostępne. + - {0} will be compiled as dependency {1} was missing. - {0} zostanie skompilowany, ponieważ brakuje zależności {1}. - + {0} will be compiled because dependency {1} was missing. + {0} zostanie skompilowany, ponieważ brakuje zależności {1}. + - {0} will be compiled as {1} was modified at {2}. - {0} zostanie skompilowany, ponieważ {1} został zmodyfikowany w {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} zostanie skompilowany, ponieważ {1} został zmodyfikowany w {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} zostanie skompilowany, ponieważ obiekt wyjściowy {1} nie istnieje. - + {0} will be compiled because output {1} does not exist. + {0} zostanie skompilowany, ponieważ obiekt wyjściowy {1} nie istnieje. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.pt-BR.xlf b/src/Utilities/Resources/xlf/Strings.pt-BR.xlf index 62d2c3bf321..e8704624d3a 100644 --- a/src/Utilities/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Utilities/Resources/xlf/Strings.pt-BR.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} será compilado, pois o log de controle não está disponível. - + {0} will be compiled because the tracking log is not available. + {0} será compilado, pois o log de controle não está disponível. + - {0} will be compiled as it was not found in the tracking log. - {0} será compilado, pois não foi encontrado no log de controle. - + {0} will be compiled because it was not found in the tracking log. + {0} será compilado, pois não foi encontrado no log de controle. + - {0} will be compiled as not all outputs are available. - {0} será compilado, pois nem todas as saídas estão disponíveis. - + {0} will be compiled because not all outputs are available. + {0} será compilado, pois nem todas as saídas estão disponíveis. + - {0} will be compiled as dependency {1} was missing. - {0} será compilado já que a dependência {1} estava ausente. - + {0} will be compiled because dependency {1} was missing. + {0} será compilado já que a dependência {1} estava ausente. + - {0} will be compiled as {1} was modified at {2}. - {0} será compilado já que {1} foi modificado em {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} será compilado já que {1} foi modificado em {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} será compilado já que a saída {1} não existe. - + {0} will be compiled because output {1} does not exist. + {0} será compilado já que a saída {1} não existe. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.ru.xlf b/src/Utilities/Resources/xlf/Strings.ru.xlf index afe332758dd..ff64685f413 100644 --- a/src/Utilities/Resources/xlf/Strings.ru.xlf +++ b/src/Utilities/Resources/xlf/Strings.ru.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - Будет выполнена компиляция {0}, поскольку журнал отслеживания недоступен. - + {0} will be compiled because the tracking log is not available. + Будет выполнена компиляция {0}, поскольку журнал отслеживания недоступен. + - {0} will be compiled as it was not found in the tracking log. - Будет выполнена компиляция {0}, поскольку результаты отсутствуют в журнале отслеживания. - + {0} will be compiled because it was not found in the tracking log. + Будет выполнена компиляция {0}, поскольку результаты отсутствуют в журнале отслеживания. + - {0} will be compiled as not all outputs are available. - Будет выполнена компиляция {0}, поскольку доступны не все выходные данные. - + {0} will be compiled because not all outputs are available. + Будет выполнена компиляция {0}, поскольку доступны не все выходные данные. + - {0} will be compiled as dependency {1} was missing. - Будет выполнена компиляция {0}, поскольку отсутствует зависимость {1}. - + {0} will be compiled because dependency {1} was missing. + Будет выполнена компиляция {0}, поскольку отсутствует зависимость {1}. + - {0} will be compiled as {1} was modified at {2}. - Будет выполнена компиляция {0}, поскольку {1} изменено в {2}. - + {0} will be compiled because {1} was modified at {2}. + Будет выполнена компиляция {0}, поскольку {1} изменено в {2}. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - Будет выполнена компиляция {0}, поскольку выходные данные {1} не существуют. - + {0} will be compiled because output {1} does not exist. + Будет выполнена компиляция {0}, поскольку выходные данные {1} не существуют. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.tr.xlf b/src/Utilities/Resources/xlf/Strings.tr.xlf index bca386c41c0..20d9b3399d9 100644 --- a/src/Utilities/Resources/xlf/Strings.tr.xlf +++ b/src/Utilities/Resources/xlf/Strings.tr.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - İzleme günlüğü kullanılamadığından {0} derlenecek. - + {0} will be compiled because the tracking log is not available. + İzleme günlüğü kullanılamadığından {0} derlenecek. + - {0} will be compiled as it was not found in the tracking log. - İzleme günlüğünde bulunamadığından {0} derlenecek. - + {0} will be compiled because it was not found in the tracking log. + İzleme günlüğünde bulunamadığından {0} derlenecek. + - {0} will be compiled as not all outputs are available. - Tüm çıkışlar kullanılamadığından {0} derlenecek. - + {0} will be compiled because not all outputs are available. + Tüm çıkışlar kullanılamadığından {0} derlenecek. + - {0} will be compiled as dependency {1} was missing. - {1} bağımlılığı eksik olduğundan {0} derlenecek. - + {0} will be compiled because dependency {1} was missing. + {1} bağımlılığı eksik olduğundan {0} derlenecek. + - {0} will be compiled as {1} was modified at {2}. - {1} {2} konumunda değiştirildiğinden {0} derlenecek. - + {0} will be compiled because {1} was modified at {2}. + {1} {2} konumunda değiştirildiğinden {0} derlenecek. + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {1} çıkışı var olmadığından {0} derlenecek. - + {0} will be compiled because output {1} does not exist. + {1} çıkışı var olmadığından {0} derlenecek. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.xlf b/src/Utilities/Resources/xlf/Strings.xlf index f585e9dc314..2ada7b52a09 100644 --- a/src/Utilities/Resources/xlf/Strings.xlf +++ b/src/Utilities/Resources/xlf/Strings.xlf @@ -132,24 +132,24 @@ - {0} will be compiled as the tracking log is not available. - + {0} will be compiled because the tracking log is not available. + - {0} will be compiled as it was not found in the tracking log. - + {0} will be compiled because it was not found in the tracking log. + - {0} will be compiled as not all outputs are available. - + {0} will be compiled because not all outputs are available. + - {0} will be compiled as dependency {1} was missing. - + {0} will be compiled because dependency {1} was missing. + - {0} will be compiled as {1} was modified at {2}. - + {0} will be compiled because {1} was modified at {2}. + {0} will be compiled. @@ -168,8 +168,8 @@ - {0} will be compiled as output {1} does not exist. - + {0} will be compiled because output {1} does not exist. + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.zh-Hans.xlf b/src/Utilities/Resources/xlf/Strings.zh-Hans.xlf index 07bbf34d30d..f8a963cd17a 100644 --- a/src/Utilities/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Utilities/Resources/xlf/Strings.zh-Hans.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - 将编译 {0},因为跟踪日志不可用。 - + {0} will be compiled because the tracking log is not available. + 将编译 {0},因为跟踪日志不可用。 + - {0} will be compiled as it was not found in the tracking log. - 将编译 {0},因为未能在跟踪日志中找到它。 - + {0} will be compiled because it was not found in the tracking log. + 将编译 {0},因为未能在跟踪日志中找到它。 + - {0} will be compiled as not all outputs are available. - 将编译 {0},因为并非所有输出都可用。 - + {0} will be compiled because not all outputs are available. + 将编译 {0},因为并非所有输出都可用。 + - {0} will be compiled as dependency {1} was missing. - 将编译 {0},因为缺少依赖项 {1}。 - + {0} will be compiled because dependency {1} was missing. + 将编译 {0},因为缺少依赖项 {1}。 + - {0} will be compiled as {1} was modified at {2}. - 将编译 {0},因为在 {2} 处修改了 {1}。 - + {0} will be compiled because {1} was modified at {2}. + 将编译 {0},因为在 {2} 处修改了 {1}。 + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - 将编译 {0},因为输出 {1} 不存在。 - + {0} will be compiled because output {1} does not exist. + 将编译 {0},因为输出 {1} 不存在。 + Read Tracking Logs: diff --git a/src/Utilities/Resources/xlf/Strings.zh-Hant.xlf b/src/Utilities/Resources/xlf/Strings.zh-Hant.xlf index fdf60d6ed94..10f790ffd87 100644 --- a/src/Utilities/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Utilities/Resources/xlf/Strings.zh-Hant.xlf @@ -164,29 +164,29 @@ - {0} will be compiled as the tracking log is not available. - {0} 將進行編譯,因為追蹤記錄檔無法使用。 - + {0} will be compiled because the tracking log is not available. + {0} 將進行編譯,因為追蹤記錄檔無法使用。 + - {0} will be compiled as it was not found in the tracking log. - {0} 將進行編譯,因為在追蹤記錄檔中找不到。 - + {0} will be compiled because it was not found in the tracking log. + {0} 將進行編譯,因為在追蹤記錄檔中找不到。 + - {0} will be compiled as not all outputs are available. - {0} 將進行編譯,因為並非所有輸出都可使用。 - + {0} will be compiled because not all outputs are available. + {0} 將進行編譯,因為並非所有輸出都可使用。 + - {0} will be compiled as dependency {1} was missing. - {0} 將進行編譯,因為遺漏相依性 {1}。 - + {0} will be compiled because dependency {1} was missing. + {0} 將進行編譯,因為遺漏相依性 {1}。 + - {0} will be compiled as {1} was modified at {2}. - {0} 將進行編譯,因為 {1} 已於 {2} 修改。 - + {0} will be compiled because {1} was modified at {2}. + {0} 將進行編譯,因為 {1} 已於 {2} 修改。 + {0} will be compiled. @@ -209,9 +209,9 @@ - {0} will be compiled as output {1} does not exist. - {0} 將進行編譯,因為輸出 {1} 不存在。 - + {0} will be compiled because output {1} does not exist. + {0} 將進行編譯,因為輸出 {1} 不存在。 + Read Tracking Logs: diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.cs.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.cs.xlf index 66840ffef07..bf68f11e10f 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.cs.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.cs.xlf @@ -1947,6 +1947,41 @@ Využití: Průměrné využití {0}: {1:###.0} Požadovaná operace potřebuje rozdělit element položky v umístění {0} na jednotlivé elementy, ale {1} dělení elementů položek zakazuje. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.de.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.de.xlf index dbb86a1bed3..aa93ed45d0e 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.de.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.de.xlf @@ -1947,6 +1947,41 @@ Auslastung: {0} Durchschnittliche Auslastung: {1:###.0} Für den angeforderten Vorgang muss das item-Element am Speicherort "{0}" in einzelne Elemente aufgeteilt werden, aber die Aufteilung von item-Elementen ist für "{1}" deaktiviert. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.es.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.es.xlf index db22d7110c3..f5ac9b8be02 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.es.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.es.xlf @@ -1947,6 +1947,41 @@ Utilización: Utilización media de {0}: {1:###.0} La operación solicitada debe dividir el elemento de la ubicación {0} en elementos individuales, pero la división de elementos está deshabilitada con {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.fr.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.fr.xlf index a3e38e68e1e..df1801c87ad 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.fr.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.fr.xlf @@ -1947,6 +1947,41 @@ Utilisation : {0} Utilisation moyenne : {1:###.0} L'opération demandée doit fractionner l'élément item à l'emplacement {0} en éléments individuels. Cependant, le fractionnement de l'élément item est désactivé avec {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.it.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.it.xlf index b754cc560a4..a77556b190b 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.it.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.it.xlf @@ -1947,6 +1947,41 @@ Utilizzo: {0} Utilizzo medio: {1:###.0} L'operazione richiesta deve dividere l'elemento item alla posizione {0} in singoli elementi, ma la suddivisione di elementi item è disabilitata con {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.ja.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.ja.xlf index 5acfe829f34..6ab2c191846 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.ja.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.ja.xlf @@ -1947,6 +1947,41 @@ Utilization: {0} Average Utilization: {1:###.0} 要求操作で、場所 {0} の項目要素を個々の要素に分割する必要がありますが、項目要素の分割は {1} で無効になっています。 + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.ko.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.ko.xlf index 89fa63cda64..69f9b705dd5 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.ko.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.ko.xlf @@ -1947,6 +1947,41 @@ Utilization: {0} Average Utilization: {1:###.0} 요청된 작업을 수행하려면 {0} 위치에서 항목 요소를 개별 요소로 분할해야 하지만 {1}에서 항목 요소 분할을 사용할 수 없습니다. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.pl.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.pl.xlf index 321928ef397..ac2ad30982d 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.pl.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.pl.xlf @@ -1947,6 +1947,41 @@ Wykorzystanie: Średnie wykorzystanie {0}: {1:###.0} Żądana operacja musi podzielić element item w lokalizacji {0} na pojedyncze elementy, ale dzielenie elementu item zostało wyłączone przy użyciu opcji {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.pt-BR.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.pt-BR.xlf index a16857ed120..9162e5c5476 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.pt-BR.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.pt-BR.xlf @@ -1947,6 +1947,41 @@ Utilização: {0} Utilização Média: {1:###.0} A operação solicitada precisa dividir o elemento do item no local {0} em elementos individuais, mas a divisão de elemento de item está desabilitada com {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.ru.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.ru.xlf index 1311dd3b1f6..9e1ece2ccd7 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.ru.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.ru.xlf @@ -1947,6 +1947,41 @@ Utilization: {0} Average Utilization: {1:###.0} Запрошенной операции необходимо разделить элемент в расположении "{0}" на отдельные элементы, но разделение элемента отключено при помощи {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.tr.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.tr.xlf index 787a0a9969a..4055bc3048d 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.tr.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.tr.xlf @@ -1947,6 +1947,41 @@ Kullanım: {0} Ortalama Kullanım: {1:###.0} İstenen işlemin item öğesini {0} konumunda ayrı öğelere bölmesi gerekiyor ancak item öğesini bölme {1} ile devre dışı bırakılmış. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.xlf index bd6c5cf756a..a3a342e0bba 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.xlf @@ -1577,6 +1577,34 @@ Utilization: {0} Average Utilization: {1:###.0} The requested operation needs to split the item element at location {0} into individual elements but item element splitting is disabled with {1}. + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hans.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hans.xlf index 1ad67d7128d..5d96bcaea20 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hans.xlf @@ -1947,6 +1947,41 @@ Utilization: {0} Average Utilization: {1:###.0} 请求的操作需要将 {0} 处的项元素拆分为单个元素,但 {1} 禁用了项元素拆分。 + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hant.xlf b/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hant.xlf index 7ddc358df21..a26bd42ac2f 100644 --- a/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/XMakeBuildEngine/Resources/xlf/Strings.zh-Hant.xlf @@ -1947,6 +1947,41 @@ Utilization: {0} Average Utilization: {1:###.0} 要求的作業需要將位於 {0} 的項目元素分割成個體元素,但 {1} 停用了分割項目元素。 + + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + MSB4229: The value "{0}" is not valid for an Sdk specification. The attribute should be a semicolon-delimited list of Sdk-name/minimum-version pairs, separated by a forward slash. + {StrBegin="MSB4229: "} + + + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + MSB4801: The task factory "{0}" could not be loaded because this version of MSBuild does not support it. + {StrBegin="MSB4801: "} + + + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + MSB4802: The "{0}" task could not be instantiated from "{1}". This version of MSBuild does not support {2}. + {StrBegin="MSB4802: "} + + + The parameter '{0}' can only be a file name and cannot include a directory. + The parameter '{0}' can only be a file name and cannot include a directory. + + + + MSB4229: File to reload from does not exist: {0} + MSB4229: File to reload from does not exist: {0} + {StrBegin="MSB4229: "} + + + MSB4230: Value not set: {0} + MSB4230: Value not set: {0} + {StrBegin="MSB4230: "} + + + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + MSB4231: ProjectRootElement can't reload if it contains unsaved changes. + {StrBegin="MSB4231: "} + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.cs.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.cs.xlf index c98731638cf..a21d99fb006 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.cs.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.cs.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Všechna práva vyhrazena. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Syntaxe: MSBuild.exe [možnosti] [soubor projektu] + Syntaxe: MSBuild.exe [možnosti] [soubor projektu] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Všechna práva vyhrazena. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Popis: Sestaví určené cíle v souboru projektu. Pokud + Popis: Sestaví určené cíle v souboru projektu. Pokud není zadaný soubor projektu, nástroj MSBuild vyhledá v aktuálním pracovním adresáři soubor s příponou, která končí řetězcem proj, a použije tento soubor. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Všechna práva vyhrazena. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.de.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.de.xlf index e76afa9e5fd..2ef478c0c12 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.de.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.de.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Syntax: MSBuild.exe [Optionen] [Projektdatei] + Syntax: MSBuild.exe [Optionen] [Projektdatei] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Beschreibung: Erstellt die angegebenen Ziele in der Projektdatei. Wenn + Beschreibung: Erstellt die angegebenen Ziele in der Projektdatei. Wenn keine Projektdatei angegeben ist, wird das aktuelle Arbeitsverzeichnis von MSBuild nach einer Datei durchsucht, die eine Dateierweiterung besitzt, die auf "proj" endet. Diese Datei wird dann verwendet. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.es.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.es.xlf index 771fa77865d..72e10542008 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.es.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.es.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Todos los derechos reservados. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Sintaxis: MSBuild.exe [opciones] [archivo de proyecto] + Sintaxis: MSBuild.exe [opciones] [archivo de proyecto] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Todos los derechos reservados. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Descripción: Crea los destinos especificados en el archivo del proyecto. Si + Descripción: Crea los destinos especificados en el archivo del proyecto. Si no se especifica un archivo de proyecto, MSBuild busca en el directorio de trabajo actual un archivo con una extensión de archivo que termine en "proj" y usa ese archivo. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Todos los derechos reservados. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.fr.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.fr.xlf index 4370321f054..c8da9a5c765 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.fr.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.fr.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Tous droits réservés. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Syntaxe : MSBuild.exe [options] [fichier projet] + Syntaxe : MSBuild.exe [options] [fichier projet] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Tous droits réservés. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Description : Génère les cibles spécifiées dans le fichier projet. Si + Description : Génère les cibles spécifiées dans le fichier projet. Si aucun fichier projet n'est spécifié, MSBuild recherche dans le répertoire de travail actuel un fichier dont l'extension se termine par "proj" et utilise ce dernier. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Tous droits réservés. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.it.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.it.xlf index 940f4415524..0e6911413c7 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.it.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.it.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Tutti i diritti sono riservati. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Sintassi: MSBuild.exe [opzioni] [file di progetto] + Sintassi: MSBuild.exe [opzioni] [file di progetto] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Tutti i diritti sono riservati. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Descrizione: compila le destinazioni specificate nel file di progetto. Se + Descrizione: compila le destinazioni specificate nel file di progetto. Se non viene specificato un file di progetto, MSBuild esegue la ricerca di un file con estensione che termina con "proj" nella directory di lavoro corrente e verrà usato tale file. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Tutti i diritti sono riservati. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.ja.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.ja.xlf index 43baf5296a0..0bec7ffc259 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.ja.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.ja.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation.All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - 構文: MSBuild.exe [オプション] [プロジェクト ファイル] + 構文: MSBuild.exe [オプション] [プロジェクト ファイル] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation.All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - 説明: プロジェクト ファイル内の指定したターゲットをビルドします。 + 説明: プロジェクト ファイル内の指定したターゲットをビルドします。 プロジェクト ファイルを指定しなかった場合、MSBuild は現在の作業ディレクトリの中から "proj" で終わるファイル拡張子を検索し、そのファイルを使用します。 @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation.All rights reserved. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.ko.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.ko.xlf index 5d87199b357..f9d1e0fe8a2 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.ko.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.ko.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - 구문: MSBuild.exe [options] [project file] + 구문: MSBuild.exe [options] [project file] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - 설명: 지정한 대상을 프로젝트 파일에 빌드합니다. 프로젝트 + 설명: 지정한 대상을 프로젝트 파일에 빌드합니다. 프로젝트 파일을 지정하지 않으면 MSBuild는 현재 작업 디렉터리에서 파일 확장명이 "proj"로 끝나는 파일을 찾아서 사용합니다. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. All rights reserved. {0}({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.pl.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.pl.xlf index a0c5d6b9c2c..78d67576487 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.pl.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.pl.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Wszelkie prawa zastrzeżone. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Składnia: MSBuild.exe [opcje] [plik projektu] + Składnia: MSBuild.exe [opcje] [plik projektu] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Wszelkie prawa zastrzeżone. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Opis: Kompiluje określone elementy docelowe w pliku projektu. Jeśli + Opis: Kompiluje określone elementy docelowe w pliku projektu. Jeśli nie określono pliku projektu, program MSBuild wyszukuje w bieżącym katalogu roboczym plik, którego rozszerzenie kończy się na „proj”, i używa tego pliku. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Wszelkie prawa zastrzeżone. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.pt-BR.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.pt-BR.xlf index c87b8f60dd4..0088aed04ad 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.pt-BR.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.pt-BR.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. Todos os direitos reservados. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Sintaxe: MSBuild.exe [opções] [arquivo do projeto] + Sintaxe: MSBuild.exe [opções] [arquivo do projeto] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. Todos os direitos reservados. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Descrição: Compila os destinos especificados no arquivo de projeto. Se + Descrição: Compila os destinos especificados no arquivo de projeto. Se não houver arquivo de projeto especificado, o MSBuild pesquisa no diretório de trabalho atual um arquivo que contenha uma extensão de arquivo que termine em "proj" e usa esse arquivo. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. Todos os direitos reservados. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.ru.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.ru.xlf index d8df998fe84..c582bd6a87c 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.ru.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.ru.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Синтаксис: MSBuild.exe [параметры] [файл проекта] + Синтаксис: MSBuild.exe [параметры] [файл проекта] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Описание: собирает указанные целевые объекты в файле проекта. Если + Описание: собирает указанные целевые объекты в файле проекта. Если файл проекта не указан, MSBuild ищет текущий рабочий каталог для файла, который имеет расширение , заканчивающееся на "proj", и использует этот файл. @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. All rights reserved. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.tr.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.tr.xlf index e90e0db5ee1..8216e502161 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.tr.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.tr.xlf @@ -49,9 +49,9 @@ Telif Hakkı (C) Microsoft Corporation. Tüm hakları saklıdır. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - Sözdizimi: MSBuild.exe [seçenekler] [proje dosyası] + Sözdizimi: MSBuild.exe [seçenekler] [proje dosyası] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Telif Hakkı (C) Microsoft Corporation. Tüm hakları saklıdır. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - Açıklama: Proje dosyasında belirtilen hedefleri oluşturur. Eğer + Açıklama: Proje dosyasında belirtilen hedefleri oluşturur. Eğer bir proje dosyası belirtilmezse MSBuild geçerli çalışma dizininde dosya uzantısının sonu "proj" olan bir dosyayı arar ve bu dosyayı kullanır. @@ -1181,6 +1183,86 @@ Telif Hakkı (C) Microsoft Corporation. Tüm hakları saklıdır. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.xlf index 9953a0db8f8..d8a718fb82f 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.xlf @@ -41,7 +41,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] LOCALIZATION: The following should not be localized: @@ -56,7 +56,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. LOCALIZATION: The following should not be localized: @@ -882,6 +884,61 @@ Copyright (C) Microsoft Corporation. All rights reserved. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hans.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hans.xlf index 159514bf7fd..15944df411f 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hans.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - 语法: MSBuild.exe [选项] [项目文件] + 语法: MSBuild.exe [选项] [项目文件] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation. All rights reserved. Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - 描述: 在项目文件中生成指定的目标。如果 + 描述: 在项目文件中生成指定的目标。如果 未指定项目文件,MSBuild 将搜索 当前工作目录来查找文件 扩展名以“proj”结尾的文件并使用该文件。 @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation. All rights reserved. {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hant.xlf b/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hant.xlf index 4ffc73dc871..fd9e759c4c0 100644 --- a/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/XMakeCommandLine/Resources/xlf/Strings.zh-Hant.xlf @@ -49,9 +49,9 @@ Copyright (C) Microsoft Corporation.著作權所有,並保留一切權利。 LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" and "MSBuild" should not be localized. - Syntax: MSBuild.exe [options] [project file] + Syntax: MSBuild.exe [options] [project file | directory] - 語法: MSBuild.exe [options] [專案檔] + 語法: MSBuild.exe [options] [專案檔] LOCALIZATION: The following should not be localized: @@ -66,9 +66,11 @@ Copyright (C) Microsoft Corporation.著作權所有,並保留一切權利。 Description: Builds the specified targets in the project file. If a project file is not specified, MSBuild searches the current working directory for a file that has a file - extension that ends in "proj" and uses that file. + extension that ends in "proj" and uses that file. If + a directory is specified, MSBuild searches that + directory for a project file. - 描述: 在專案檔中建置指定的目標。若 + 描述: 在專案檔中建置指定的目標。若 未指定專案檔,MSBuild 會在目前的工作目錄 搜尋副檔名以 "proj" 結尾的檔案, 並使用該檔案。 @@ -1180,6 +1182,86 @@ Copyright (C) Microsoft Corporation.著作權所有,並保留一切權利。 {0} ({1},{2}) A file location to be embedded in a string. + + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + MSBUILD : error MSB1050: Specify which project or solution file to use because the folder "{0}" contains more than one project or solution file. + + {StrBegin="MSBUILD : error MSB1050: "}UE: If no project or solution file is explicitly specified on the MSBuild.exe command-line, then the engine searches for a + project or solution file in the current directory by looking for *.*PROJ and *.SLN. If more than one file is found that matches this wildcard, we + fire this error. + LOCALIZATION: The prefix "MSB1050 : error MSBxxxx:" should not be localized. + + + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + /warnaserror[:code[;code2]] + List of warning codes to treats as errors. Use a semicolon + or a comma to separate multiple warning codes. To treat all + warnings as errors use the switch with no values. + (Short form: /err[:c;[c2]]) + + Example: + /warnaserror:MSB4130 + + When a warning is treated as an error the target will + continue to execute as if it was a warning but the overall + build will fail. + + + LOCALIZATION: "/warnaserror" and "/err" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + /warnasmessage[:code[;code2]] + List of warning codes to treats as low importance + messages. Use a semicolon or a comma to separate + multiple warning codes. + (Short form: /nowarn[:c;[c2]]) + + Example: + /warnasmessage:MSB3026 + + + LOCALIZATION: "/warnasmessage" and "/nowarn" should not be localized. + LOCALIZATION: None of the lines should be longer than a standard width console window, eg 80 chars. + + + + MSBUILD : error MSB1049: The {0} parameter must be specified + MSBUILD : error MSB1049: The {0} parameter must be specified + {StrBegin="MSBUILD : error MSB1049: "} + + + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + MSBUILD : error MSB1051: Specify one or more warning codes to treat as low importance messages when using the /warnasmessage switch. + + {StrBegin="MSBUILD : error MSB1051: "} + UE: This happens if the user does something like "msbuild.exe /warnasmessage:" without any codes. + LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.cs.xlf b/src/XMakeTasks/Resources/xlf/Strings.cs.xlf index 826ac31fc34..efc7db55607 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.cs.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.cs.xlf @@ -2979,6 +2979,26 @@ MSB3891: V souboru projektu jste zadali jak položku {0}, tak i {1}. Zvolte buď jednu, nebo druhou. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.de.xlf b/src/XMakeTasks/Resources/xlf/Strings.de.xlf index 93850ae5cf7..b379015fbc5 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.de.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.de.xlf @@ -2979,6 +2979,26 @@ MSB3891: "{0}" und "{1}" wurden in der Projektdatei angegeben. Verwenden Sie nur einen dieser Werte. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.es.xlf b/src/XMakeTasks/Resources/xlf/Strings.es.xlf index 0321d203e13..1ebaae93c01 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.es.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.es.xlf @@ -2979,6 +2979,26 @@ MSB3891: Se especificó "{0}" y "{1}" en el archivo de proyecto. Elija solo uno de los dos. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.fr.xlf b/src/XMakeTasks/Resources/xlf/Strings.fr.xlf index 50f62408db6..8b465ddce99 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.fr.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.fr.xlf @@ -2979,6 +2979,26 @@ MSB3891: "{0}" et "{1}" ont été spécifiés dans le fichier projet. Choisissez l'un ou l'autre. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.it.xlf b/src/XMakeTasks/Resources/xlf/Strings.it.xlf index c6387f84468..de201f435b0 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.it.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.it.xlf @@ -2979,6 +2979,26 @@ MSB3891: nel file di progetto sono stati specificati sia "{0}" che "{1}". Sceglierne uno. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.ja.xlf b/src/XMakeTasks/Resources/xlf/Strings.ja.xlf index 46ea0876fae..b7fdf90fb57 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.ja.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.ja.xlf @@ -2979,6 +2979,26 @@ MSB3891: "{0}" と "{1}" の両方がプロジェクト ファイルで指定されました。いずれか 1 つを選択してください。 + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.ko.xlf b/src/XMakeTasks/Resources/xlf/Strings.ko.xlf index 20d0768e595..09f943134da 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.ko.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.ko.xlf @@ -2979,6 +2979,26 @@ MSB3891: 프로젝트 파일에서 "{0}" 및 "{1}"을(를) 모두 지정했습니다. 둘 중 하나만 선택하세요. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.pl.xlf b/src/XMakeTasks/Resources/xlf/Strings.pl.xlf index c215286b03a..4aa275c3c16 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.pl.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.pl.xlf @@ -2979,6 +2979,26 @@ MSB3891: W pliku projektu określono elementy „{0}” i „{1}”. Wybierz jeden z nich. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.pt-BR.xlf b/src/XMakeTasks/Resources/xlf/Strings.pt-BR.xlf index 101dfa45b25..d9fc42f2abe 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.pt-BR.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.pt-BR.xlf @@ -2979,6 +2979,26 @@ MSB3891: "{0}" e "{1}" foram especificados no arquivo do projeto. Escolha um ou outro. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.ru.xlf b/src/XMakeTasks/Resources/xlf/Strings.ru.xlf index 7ce2c29b84e..64e68dbd5dc 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.ru.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.ru.xlf @@ -2979,6 +2979,26 @@ MSB3891: в файле проекта указан как "{0}", так и "{1}". Укажите только один из них. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.tr.xlf b/src/XMakeTasks/Resources/xlf/Strings.tr.xlf index 86304c10d6c..e65a82f29ff 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.tr.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.tr.xlf @@ -2979,6 +2979,26 @@ MSB3891: Proje dosyasında hem "{0}" hem de "{1}" belirtilmiş. Lütfen yalnızca birini seçin. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.xlf b/src/XMakeTasks/Resources/xlf/Strings.xlf index d73917931fb..66de4490c48 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.xlf @@ -2391,6 +2391,22 @@ MSB3891: Both "{0}" and "{1}" were specified in the project file. Please choose one or the other. + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.zh-Hans.xlf b/src/XMakeTasks/Resources/xlf/Strings.zh-Hans.xlf index 0af5a42e429..60926e0d153 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.zh-Hans.xlf @@ -2979,6 +2979,26 @@ MSB3891: 项目文件中同时指定了“{0}”和“{1}”。请任选其一。 + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file diff --git a/src/XMakeTasks/Resources/xlf/Strings.zh-Hant.xlf b/src/XMakeTasks/Resources/xlf/Strings.zh-Hant.xlf index f8aeed9fd35..719e6d5467a 100644 --- a/src/XMakeTasks/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/XMakeTasks/Resources/xlf/Strings.zh-Hant.xlf @@ -2979,6 +2979,26 @@ MSB3891: 專案檔中已同時指定 "{0}" 和 "{1}"。請選擇使用其中一個。 + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + The property "{0}" in the telemetry event data property list "{1}" is malformed. Please only pass in a semicolon-delimited list of constant string values separated by "=", e.g., "Property1=Value1;Property2=Value2". + + + + (No message specified) + (No message specified) + + \ No newline at end of file From 941b8caee2c69426d5a5628d64fe4fae7b02f87e Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 12 Jan 2017 11:11:40 -0800 Subject: [PATCH 221/223] Update projects that should be generating reference assembly sources (#1553) * Update projects so they'll generate reference assembly sources * Update reference assembly sources --- .../Microsoft.Build.Framework.cs | 16 ++++++++++++++++ .../Microsoft.Build.Framework.cs | 15 +++++++++++++++ src/Framework/Microsoft.Build.Framework.csproj | 1 + src/OrcasEngine/OrcasEngine.csproj | 1 + src/XMakeConversion/XMakeConversion.csproj | 1 + 5 files changed, 34 insertions(+) diff --git a/ref/net46/Microsoft.Build.Framework/Microsoft.Build.Framework.cs b/ref/net46/Microsoft.Build.Framework/Microsoft.Build.Framework.cs index 040e25825ab..2d769c07130 100644 --- a/ref/net46/Microsoft.Build.Framework/Microsoft.Build.Framework.cs +++ b/ref/net46/Microsoft.Build.Framework/Microsoft.Build.Framework.cs @@ -184,6 +184,10 @@ public partial interface IBuildEngine4 : Microsoft.Build.Framework.IBuildEngine, void RegisterTaskObject(object key, object obj, Microsoft.Build.Framework.RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection); object UnregisterTaskObject(object key, Microsoft.Build.Framework.RegisteredTaskObjectLifetime lifetime); } + public partial interface IBuildEngine5 : Microsoft.Build.Framework.IBuildEngine, Microsoft.Build.Framework.IBuildEngine2, Microsoft.Build.Framework.IBuildEngine3, Microsoft.Build.Framework.IBuildEngine4 + { + void LogTelemetry(string eventName, System.Collections.Generic.IDictionary properties); + } public partial interface ICancelableTask : Microsoft.Build.Framework.ITask { void Cancel(); @@ -209,6 +213,10 @@ public partial interface IEventSource event Microsoft.Build.Framework.TaskStartedEventHandler TaskStarted; event Microsoft.Build.Framework.BuildWarningEventHandler WarningRaised; } + public partial interface IEventSource2 : Microsoft.Build.Framework.IEventSource + { + event Microsoft.Build.Framework.TelemetryEventHandler TelemetryLogged; + } public partial interface IForwardingLogger : Microsoft.Build.Framework.ILogger, Microsoft.Build.Framework.INodeLogger { Microsoft.Build.Framework.IEventRedirector BuildEventRedirector { get; set; } @@ -439,6 +447,13 @@ public TaskStartedEventArgs(string message, string helpKeyword, string projectFi public string TaskName { get { throw null; } } } public delegate void TaskStartedEventHandler(object sender, Microsoft.Build.Framework.TaskStartedEventArgs e); + public sealed partial class TelemetryEventArgs : Microsoft.Build.Framework.BuildEventArgs + { + public TelemetryEventArgs() { } + public string EventName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + } + public delegate void TelemetryEventHandler(object sender, Microsoft.Build.Framework.TelemetryEventArgs e); } namespace Microsoft.Build.Framework.XamlTypes { @@ -537,6 +552,7 @@ public DataSource() { } public string MSBuildTarget { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public string PersistedName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public string Persistence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PersistenceStyle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public Microsoft.Build.Framework.XamlTypes.DefaultValueSourceLocation SourceOfDefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public string SourceType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public void BeginInit() { } diff --git a/ref/netstandard1.3/Microsoft.Build.Framework/Microsoft.Build.Framework.cs b/ref/netstandard1.3/Microsoft.Build.Framework/Microsoft.Build.Framework.cs index f0a9bf372f4..a7851bba7b1 100644 --- a/ref/netstandard1.3/Microsoft.Build.Framework/Microsoft.Build.Framework.cs +++ b/ref/netstandard1.3/Microsoft.Build.Framework/Microsoft.Build.Framework.cs @@ -184,6 +184,10 @@ public partial interface IBuildEngine4 : Microsoft.Build.Framework.IBuildEngine, void RegisterTaskObject(object key, object obj, Microsoft.Build.Framework.RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection); object UnregisterTaskObject(object key, Microsoft.Build.Framework.RegisteredTaskObjectLifetime lifetime); } + public partial interface IBuildEngine5 : Microsoft.Build.Framework.IBuildEngine, Microsoft.Build.Framework.IBuildEngine2, Microsoft.Build.Framework.IBuildEngine3, Microsoft.Build.Framework.IBuildEngine4 + { + void LogTelemetry(string eventName, System.Collections.Generic.IDictionary properties); + } public partial interface ICancelableTask : Microsoft.Build.Framework.ITask { void Cancel(); @@ -209,6 +213,10 @@ public partial interface IEventSource event Microsoft.Build.Framework.TaskStartedEventHandler TaskStarted; event Microsoft.Build.Framework.BuildWarningEventHandler WarningRaised; } + public partial interface IEventSource2 : Microsoft.Build.Framework.IEventSource + { + event Microsoft.Build.Framework.TelemetryEventHandler TelemetryLogged; + } public partial interface IForwardingLogger : Microsoft.Build.Framework.ILogger, Microsoft.Build.Framework.INodeLogger { Microsoft.Build.Framework.IEventRedirector BuildEventRedirector { get; set; } @@ -436,4 +444,11 @@ public TaskStartedEventArgs(string message, string helpKeyword, string projectFi public string TaskName { get { throw null; } } } public delegate void TaskStartedEventHandler(object sender, Microsoft.Build.Framework.TaskStartedEventArgs e); + public sealed partial class TelemetryEventArgs : Microsoft.Build.Framework.BuildEventArgs + { + public TelemetryEventArgs() { } + public string EventName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + } + public delegate void TelemetryEventHandler(object sender, Microsoft.Build.Framework.TelemetryEventArgs e); } diff --git a/src/Framework/Microsoft.Build.Framework.csproj b/src/Framework/Microsoft.Build.Framework.csproj index ee1e259f3be..9847686c117 100644 --- a/src/Framework/Microsoft.Build.Framework.csproj +++ b/src/Framework/Microsoft.Build.Framework.csproj @@ -10,6 +10,7 @@ true true true + true diff --git a/src/OrcasEngine/OrcasEngine.csproj b/src/OrcasEngine/OrcasEngine.csproj index e9628326772..777338af025 100644 --- a/src/OrcasEngine/OrcasEngine.csproj +++ b/src/OrcasEngine/OrcasEngine.csproj @@ -10,6 +10,7 @@ Microsoft.Build.Engine Microsoft.Build.Engine $(NoWarn);618 + true diff --git a/src/XMakeConversion/XMakeConversion.csproj b/src/XMakeConversion/XMakeConversion.csproj index dd2b8f022e4..3e221046257 100644 --- a/src/XMakeConversion/XMakeConversion.csproj +++ b/src/XMakeConversion/XMakeConversion.csproj @@ -9,6 +9,7 @@ Properties Microsoft.Build.Conversion.Core Microsoft.Build.Conversion.Core + true From 8ab953a40ed5489d190555cab636dcf8e700892e Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 12 Jan 2017 17:35:48 -0600 Subject: [PATCH 222/223] Binplace System.Collections.Immutable to Output (#1538) This file is required by the VSIX builder, and was placed in Output as part of the transitive dependencies of Microsoft.Build.Tasks.CodeAnalysis, but more recent versions don't have that dependency, so it wasn't getting placed. Added a workaround to ensure that Immutable appears in the folder. --- src/XMakeBuildEngine/Microsoft.Build.csproj | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index 9c73dc1246b..55442ebd6e0 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -767,4 +767,20 @@ --> - \ No newline at end of file + + + + + true + + + + From 9654902b70e22eccc8105efdac5060c7d7adaa1a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Thu, 12 Jan 2017 16:39:15 -0800 Subject: [PATCH 223/223] Cache IsMono call (#1536) * Cache IsMono call VS has potentially expensive TypeResolve events, so cache IsMono * IsMono = false under Visual Studio * Propagate dependencies of BuildEnvironmentHelper into test project * Replace static constructor with static lazy Can't use static constructor because BuildEnvironmentHelper calls back into NativeMethodsShared, so the type is null :( * Replace Lazy with code NativeMethodsShared's source is compiled into MsbuildTaskHost which is .net3.5 and does not know about Lazy :( Also, did not use the static nested class singleton pattern to prevent weird null reference exception in case the BuildEnvironmentHelper starts calling into IsMono --- src/Shared/NativeMethodsShared.cs | 19 ++++++++++++++++++- ...Microsoft.Build.Engine.OM.UnitTests.csproj | 6 ++++++ .../UnitTestsPublicOM/project.json | 3 ++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Shared/NativeMethodsShared.cs b/src/Shared/NativeMethodsShared.cs index 01ae40cfa39..d7f7e163c1e 100644 --- a/src/Shared/NativeMethodsShared.cs +++ b/src/Shared/NativeMethodsShared.cs @@ -494,6 +494,10 @@ internal static bool IsUnix } } + private static readonly object IsMonoLock = new object(); + + private static bool? _isMono; + /// /// Gets a flag indicating if we are running under MONO /// @@ -501,7 +505,20 @@ internal static bool IsMono { get { - return Type.GetType("Mono.Runtime") != null; + if (_isMono != null) return _isMono.Value; + + lock (IsMonoLock) + { + if (_isMono == null) + { + // There could be potentially expensive TypeResolve events, so cache IsMono. + // Also, VS does not host Mono runtimes, so turn IsMono off when msbuild is running under VS + _isMono = !BuildEnvironmentHelper.Instance.RunningInVisualStudio && + Type.GetType("Mono.Runtime") != null; + } + } + + return _isMono.Value; } } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj index 88d73037777..f82f7b73afd 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Microsoft.Build.Engine.OM.UnitTests.csproj @@ -52,9 +52,15 @@ true + + VisualStudioLocationHelper.cs + true + + BuildEnvironmentHelper.cs + true diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json index 854b278f8d4..9247f20f7ae 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/project.json +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/project.json @@ -11,7 +11,8 @@ "frameworks": { "net46": { "dependencies": { - "xunit.runner.visualstudio": "2.1.0" + "xunit.runner.visualstudio": "2.1.0", + "Microsoft.VisualStudio.Setup.Configuration.Interop": "1.2.304-preview5" } }, "netstandard1.3": {
/// Called only by the parser to tell the ProjectRootElement its backing XmlElement and its own parent project (itself) /// This can't be done during construction, as it hasn't loaded the document at that point and it doesn't have a 'this' pointer either. diff --git a/src/XMakeBuildEngine/Construction/ProjectItemElement.cs b/src/XMakeBuildEngine/Construction/ProjectItemElement.cs index ae6e3dea683..ecbd18879a8 100644 --- a/src/XMakeBuildEngine/Construction/ProjectItemElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectItemElement.cs @@ -460,5 +460,10 @@ protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return owner.CreateItemElement(this.ItemType, this.Include); } + + /// + /// Do not clone attributes which can be metadata. The corresponding expressed as attribute project elements are responsible for adding their attribute + /// + protected override bool ShouldCloneXmlAttribute(XmlAttribute attribute) => !ProjectMetadataElement.AttributeNameIsValidMetadataName(attribute.LocalName); } } diff --git a/src/XMakeBuildEngine/Construction/ProjectMetadataElement.cs b/src/XMakeBuildEngine/Construction/ProjectMetadataElement.cs index b29fde7e6da..0a5b3b7cf00 100644 --- a/src/XMakeBuildEngine/Construction/ProjectMetadataElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectMetadataElement.cs @@ -131,17 +131,22 @@ internal void ChangeName(string newName) internal static void ValidateValidMetadataAsAttributeName(string name, string parentName, IElementLocation parentLocation) { - bool isKnownAttribute; - bool isValidMetadataNameInAttribute; - - ProjectParser.CheckMetadataAsAttributeName(name, out isKnownAttribute, out isValidMetadataNameInAttribute); - - if (isKnownAttribute || !isValidMetadataNameInAttribute) + if (!AttributeNameIsValidMetadataName(name)) { ProjectErrorUtilities.ThrowInvalidProject(parentLocation, "InvalidMetadataAsAttribute", name, parentName); } } + internal static bool AttributeNameIsValidMetadataName(string name) + { + bool isReservedAttributeName; + bool isValidMetadataNameInAttribute; + + ProjectParser.CheckMetadataAsAttributeName(name, out isReservedAttributeName, out isValidMetadataNameInAttribute); + + return !isReservedAttributeName && isValidMetadataNameInAttribute; + } + /// /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. diff --git a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs index 28c9880e342..e8137266667 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectParser.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectParser.cs @@ -393,11 +393,11 @@ private ProjectItemElement ParseProjectItemElement(XmlElementWithLocation elemen return item; } - internal static void CheckMetadataAsAttributeName(string name, out bool isKnownAttribute, out bool isValidMetadataNameInAttribute) + internal static void CheckMetadataAsAttributeName(string name, out bool isReservedAttributeName, out bool isValidMetadataNameInAttribute) { if (!XmlUtilities.IsValidElementName(name)) { - isKnownAttribute = false; + isReservedAttributeName = false; isValidMetadataNameInAttribute = false; return; } @@ -408,13 +408,13 @@ internal static void CheckMetadataAsAttributeName(string name, out bool isKnownA // error instead of unexpected behavior if (name == s_knownAttributesOnItem[i]) { - isKnownAttribute = true; + isReservedAttributeName = true; isValidMetadataNameInAttribute = false; return; } else if (name.Equals(s_knownAttributesOnItem[i], StringComparison.OrdinalIgnoreCase)) { - isKnownAttribute = false; + isReservedAttributeName = false; isValidMetadataNameInAttribute = false; return; } @@ -423,7 +423,7 @@ internal static void CheckMetadataAsAttributeName(string name, out bool isKnownA // Reserve attributes starting with underscores in case we need to add more built-in attributes later if (name[0] == '_') { - isKnownAttribute = false; + isReservedAttributeName = false; isValidMetadataNameInAttribute = false; return; } @@ -431,12 +431,12 @@ internal static void CheckMetadataAsAttributeName(string name, out bool isKnownA if (FileUtilities.ItemSpecModifiers.IsItemSpecModifier(name) || XMakeElements.IllegalItemPropertyNames[name] != null) { - isKnownAttribute = false; + isReservedAttributeName = false; isValidMetadataNameInAttribute = false; return; } - isKnownAttribute = false; + isReservedAttributeName = false; isValidMetadataNameInAttribute = true; } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs index 8dbae355a7c..20f6bd6add7 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/ProjectRootElement_Tests.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; #if FEATURE_SECURITY_PRINCIPAL_WINDOWS @@ -1203,6 +1204,42 @@ public void DeepCloneWithProjectExtensionsElementOfXml() ValidateDeepCloneAndCopyFrom(pre); } + /// + /// Tests DeepClone and CopyFrom when there is metadata expressed as attributes + /// + [Fact] + public void DeepCloneWithMetadataAsAttributes() + { + var project = +@" + + + + + + + + +

val

+
+ + + +
+ + v2 + + + + + + "; + + var pre = ProjectRootElement.Create(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(project)))); + + ValidateDeepCloneAndCopyFrom(pre); + } + /// /// Test helper for validating that DeepClone and CopyFrom work as advertised. /// From 59da91fabe68aa52a856d7dbc9a3a9fecdb6d31a Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 8 Nov 2016 16:43:55 -0600 Subject: [PATCH 059/223] Keep BuildEventContext.SubmissionId in serialization (#1324) Fixes #651, which was occurring because the serialized SubmissionId returned from the remote node didn't match the saved SubmissionId, so it wasn't marked as complete in BuildManager.OnProjectFinished. Since there was an incomplete submission, the build never finished. --- src/Shared/NodePacketTranslator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared/NodePacketTranslator.cs b/src/Shared/NodePacketTranslator.cs index 59345726ba1..96bc18f6a58 100644 --- a/src/Shared/NodePacketTranslator.cs +++ b/src/Shared/NodePacketTranslator.cs @@ -1318,7 +1318,7 @@ public static void TranslateBuildEventContext(INodePacketTranslator translator, projectContextId = context.ProjectContextId; taskId = context.TaskId; projectInstanceId = context.ProjectInstanceId; - submissionId = context.ProjectInstanceId; + submissionId = context.SubmissionId; } translator.Translate(ref nodeId); From 762e7211ed4c998adaf0444b26887418fd13e0d8 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 9 Nov 2016 09:40:08 -0800 Subject: [PATCH 060/223] Whitespace tests for adding siblings (#1326) --- .../WhiteSpacePreservation_Tests.cs | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs index 480010dba0f..2b612dcc3a4 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs @@ -259,6 +259,158 @@ public void AddFirstChildInExistingParent(string projectContents, string updated (pe, p) => { pe.ItemGroups.ElementAt(1).AddItem("i2", "b"); }); } + [Theory] + [InlineData( +@" + + + +", + +@" + + + + +")] + + [InlineData( +@" + + + + +", + +@" + + + + + +")] + + [InlineData( +@" + + + + +", + +@" + + + + + + +")] + + [InlineData( +@" + + + + + +", + +@" + + + + + + + +")] + // AddItem ends up calling InsertAfterChild + public void AddChildWithExistingSiblingsViaAddItem(string projectContents, string updatedProject) + { + AssertWhiteSpacePreservation(projectContents, updatedProject, + (pe, p) => { pe.ItemGroups.First().AddItem("i2", "b"); }); + } + + [Theory] + [InlineData( +@" + + + +", + +@" + + + + +")] + + [InlineData( +@" + + + + +", + +@" + + + + + +")] + + [InlineData( +@" + + + + +", + +@" + + + + + + +")] + + [InlineData( +@" + + + + + +", + +@" + + + + + + + +")] + public void AddChildWithExistingSiblingsViaInsertBeforeChild(string projectContents, string updatedProject) + { + AssertWhiteSpacePreservation(projectContents, updatedProject, + (pe, p) => + { + var itemGroup = pe.ItemGroups.First(); + var existingItemElement = itemGroup.FirstChild; + var newItemElement = itemGroup.ContainingProject.CreateItemElement("i2", "b"); + + itemGroup.InsertBeforeChild(newItemElement, existingItemElement); + }); + } + private void AssertWhiteSpacePreservation(string projectContents, string updatedProject, Action act) { From 1725ae141aefab2c9cf39955aa82bce84f92caff Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 11 Nov 2016 10:45:23 -0800 Subject: [PATCH 061/223] GetItemProvenance should not unescape input (#1332) ItemSpec users control unescaping. This resolves #1106 Also fixes various issues with slash normalization which got exposed by the fix for #1106: - slashes are normalized only when the string is a path - checking whether a string is a valid path uses a union of Windows and !Windows characters, based on: #781 (comment) - Re-implement Path.GetFileName so it works with potentially malformed paths. - Normalize the slashes before normalizing the path. Otherwise .Net's implementation of GetFullPath does not work. --- src/Shared/FileUtilities.cs | 75 +++++---- src/XMakeBuildEngine/Evaluation/ItemSpec.cs | 4 +- .../LazyItemEvaluator.IncludeOperation.cs | 5 +- .../Definition/ProjectItem_Tests.cs | 47 ++++-- .../Definition/Project_Tests.cs | 147 ++++++++++++++++-- .../Utilities/EngineFileUtilities.cs | 15 +- 6 files changed, 223 insertions(+), 70 deletions(-) diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs index ba93bfd3bb0..9a5638ca3c3 100644 --- a/src/Shared/FileUtilities.cs +++ b/src/Shared/FileUtilities.cs @@ -55,6 +55,35 @@ internal static void ClearCacheDirectoryPath() // TODO: assumption on file system case sensitivity: https://github.com/Microsoft/msbuild/issues/781 internal static readonly StringComparison PathComparison = StringComparison.OrdinalIgnoreCase; + /// + /// Copied from https://github.com/dotnet/corefx/blob/056715ff70e14712419d82d51c8c50c54b9ea795/src/Common/src/System/IO/PathInternal.Windows.cs#L61 + /// MSBuild should support the union of invalid path chars across the supported OSes, so builds can have the same behaviour crossplatform: https://github.com/Microsoft/msbuild/issues/781#issuecomment-243942514 + /// + + internal static char[] InvalidPathChars => new char[] + { + '|', '\0', + (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, + (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, + (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, + (char)31 + }; + + /// + /// Copied from https://github.com/dotnet/corefx/blob/387cf98c410bdca8fd195b28cbe53af578698f94/src/System.Runtime.Extensions/src/System/IO/Path.Windows.cs#L18 + /// MSBuild should support the union of invalid path chars across the supported OSes, so builds can have the same behaviour crossplatform: https://github.com/Microsoft/msbuild/issues/781#issuecomment-243942514 + /// + internal static char[] InvalidFileNameChars => new char[] + { + '\"', '<', '>', '|', '\0', + (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, + (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, + (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, + (char)31, ':', '*', '?', '\\', '/' + }; + + private static readonly char[] Slashes = { '/', '\\' }; + /// /// Retrieves the MSBuild runtime cache directory /// @@ -379,7 +408,7 @@ internal static string MaybeAdjustFilePath(string value) // have no slashes. if (NativeMethodsShared.IsWindows || string.IsNullOrEmpty(value) || value.StartsWith("$(") || value.StartsWith("@(") || value.StartsWith("\\\\") || - value.IndexOfAny(new[] { '/', '\\' }) == -1) + value.IndexOfAny(Slashes) == -1) { return value; } @@ -551,7 +580,6 @@ internal static string GetFullPathNoThrow(string path) /// internal static bool ComparePathsNoThrow(string first, string second, string currentDirectory) { - // perf: try comparing the bare strings first if (string.Equals(first, second, PathComparison)) { @@ -571,46 +599,37 @@ internal static bool ComparePathsNoThrow(string first, string second, string cur ///
internal static string NormalizePathForComparisonNoThrow(string path, string currentDirectory) { - return GetFullPathNoThrow(path, currentDirectory).NormalizeForPathComparison(); - } - - /// - /// A variation of Path.GetFullPath that will return the input value - /// instead of throwing any IO exception. - /// Useful to get a better path for an error message, without the risk of throwing - /// if the error message was itself caused by the path being invalid! - /// - internal static string GetFullPathNoThrow(string fileSpec, string currentDirectory) - { - var fullPath = fileSpec; - // file is invalid, return early to avoid triggering an exception - if (IsInvalidPath(fullPath)) + if (PathIsInvalid(path)) { - return fullPath; + return path; } - try - { - fullPath = GetFullPath(fileSpec, currentDirectory); - } - catch (Exception ex) when (ExceptionHandling.IsIoRelatedException(ex)) - { - } + var normalizedPath = path.NormalizeForPathComparison(); + var fullPath = GetFullPathNoThrow(Path.Combine(currentDirectory, normalizedPath)); return fullPath; } - private static bool IsInvalidPath(string path) + private static bool PathIsInvalid(string path) { - if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0) + if (path.IndexOfAny(InvalidPathChars) >= 0) { return true; } - var filename = Path.GetFileName(path); + var filename = GetFileName(path); - return filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0; + return filename.IndexOfAny(InvalidFileNameChars) >= 0; + } + + // Path.GetFileName does not react well to malformed filenames. + // For example, Path.GetFileName("a/b/foo:bar") returns bar instead of foo:bar + // It also throws exceptions on illegal path characters + private static string GetFileName(string path) + { + var lastDirectorySeparator = path.LastIndexOfAny(Slashes); + return lastDirectorySeparator >= 0 ? path.Substring(lastDirectorySeparator + 1) : path; } /// diff --git a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs index d6ca4b4a0e4..9d8485cf1be 100644 --- a/src/XMakeBuildEngine/Evaluation/ItemSpec.cs +++ b/src/XMakeBuildEngine/Evaluation/ItemSpec.cs @@ -91,7 +91,7 @@ private IEnumerable BuildItemFragments(IElementLocation itemSpecLo var containsRealWildcards = FileMatcher.HasWildcards(splitEscaped); // '*' is an illegal character to have in a filename. - // todo file-system assumption on legal path characters: https://github.com/Microsoft/msbuild/issues/781 + // todo: file-system assumption on legal path characters: https://github.com/Microsoft/msbuild/issues/781 if (containsEscapedWildcards && containsRealWildcards) { @@ -208,7 +208,7 @@ protected ItemFragment(string itemSpecFragment, string projectPath) : this( itemSpecFragment, projectPath, - new Lazy>(() => EngineFileUtilities.GetMatchTester(itemSpecFragment, projectPath))) + new Lazy>(() => EngineFileUtilities.GetFileSpecMatchTester(itemSpecFragment, projectPath))) { } diff --git a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs index 6e460298a08..b9f0ec7677d 100644 --- a/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs +++ b/src/XMakeBuildEngine/Evaluation/LazyItemEvaluator.IncludeOperation.cs @@ -7,6 +7,7 @@ using Microsoft.Build.Construction; using System.Collections.Immutable; using Microsoft.Build.Internal; +using Microsoft.Build.Shared; namespace Microsoft.Build.Evaluation { @@ -54,7 +55,7 @@ protected override ICollection SelectItems(ImmutableList.Builder li if (excludePatterns.Any()) { - excludeTester = new Lazy>(() => EngineFileUtilities.GetMatchTester(excludePatterns, _rootDirectory)); + excludeTester = new Lazy>(() => EngineFileUtilities.GetFileSpecMatchTester(excludePatterns, _rootDirectory)); } } @@ -84,7 +85,7 @@ protected override ICollection SelectItems(ImmutableList.Builder li string value = ((ValueFragment)fragment).ItemSpecFragment; if (excludeTester == null || - !excludeTester.Value(value)) + !excludeTester.Value(EscapingUtilities.UnescapeAll(value))) { var item = _itemFactory.CreateItem(value, value, _itemElement.ContainingProject.FullPath); itemsToAdd.Add(item); diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs index 1b32700a958..eeac9eaa0ba 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs @@ -479,32 +479,26 @@ public void ExcludeVectorWithIncludeVector() "b", new string[0], new[] { "a" })] - //// items as strings: escaped include matches non-escaped exclude + // items as strings: escaped include matches non-escaped exclude [InlineData(ItemWithIncludeAndExclude, "%61", "a", new string[0], new string[0])] - //// items as strings: non-escaped include matches escaped exclude + // items as strings: non-escaped include matches escaped exclude [InlineData(ItemWithIncludeAndExclude, "a", "%61", new string[0], new string[0])] - // items as strings: include with escaped wildcard and non-escaped wildcard matches exclude with escaped wildcard and non-escaped wildcard. Both are treated as values and not as globs - [InlineData(ItemWithIncludeAndExclude, - @"**/a%2Axb", - @"**/a%2Axb", - new string[0], - new string[0])] // items as files: non-escaped wildcard include matches escaped non-wildcard character [InlineData(ItemWithIncludeAndExclude, "a?b", "a%40b", new[] { "acb", "a@b" }, new[] { "acb" })] - // items as files: non-escaped non-wildcard include matches escaped non-wildcard character - [InlineData(ItemWithIncludeAndExclude, + // items as files: non-escaped non-wildcard include matches escaped non-wildcard character + [InlineData(ItemWithIncludeAndExclude, "acb;a@b", "a%40b", new string[0], @@ -521,16 +515,16 @@ public void ExcludeVectorWithIncludeVector() "a%40?b", new[] { "a@b", "a@ab", "a@bb" }, new[] { "a@b" })] - // items as files: non-escaped recursive wildcard include matches escaped recursive wildcard exclude - [InlineData(ItemWithIncludeAndExclude, + // items as files: non-escaped recursive wildcard include matches escaped recursive wildcard exclude + [InlineData(ItemWithIncludeAndExclude, @"**\a*b", @"**\a*%78b", new[] { "aab", "aaxb", @"dir\abb", @"dir\abxb" }, new[] { "aab", @"dir\abb" })] // items as files: include with non-escaped glob does not match exclude with escaped wildcard character. - // The exclude is treated as a literal and only matches against non-glob include fragments (i.e., against values and item references). %2A is * + // The exclude is treated as a literal, not a glob, and therefore should not match the input files [InlineData(ItemWithIncludeAndExclude, - @"**\a*b;**\a%2Axb", + @"**\a*b", @"**\a%2Axb", new[] { "aab", "aaxb", @"dir\abb", @"dir\abxb" }, new[] { "aab", "aaxb", @"dir\abb", @"dir\abxb" })] @@ -539,6 +533,31 @@ public void IncludeExcludeWithEscapedCharacters(string projectContents, string i TestIncludeExcludeWithDifferentSlashes(projectContents, includeString, excludeString, inputFiles, expectedInclude); } + [Theory] + // items as strings: include with both escaped and unescaped glob should be treated as literal and therefore not match against files as a glob + [InlineData(ItemWithIncludeAndExclude, + @"**\a%2Axb", + @"foo", + new[] { "aab", "aaxb", @"dir\abb", @"dir\abxb" }, + new[] { @"**\a*xb" })] + // Include with both escaped and unescaped glob does not match exclude with escaped wildcard character which has a different slash orientation + // The presence of the escaped and unescaped glob should make things behave as strings-which-are-not-paths and not as strings-which-are-paths + [InlineData(ItemWithIncludeAndExclude, + @"**\a%2Axb", + @"**/a%2Axb", + new string[0], + new[] { @"**\a*xb" })] + // Slashes are not normalized when contents is not a path + [InlineData(ItemWithIncludeAndExclude, + @"a/b/foo::||bar;a/b/foo::||bar/;a/b/foo::||bar\;a/b\foo::||bar", + @"a/b/foo::||bar", + new string[0], + new [] { "a/b/foo::||bar/", @"a/b/foo::||bar\", @"a/b\foo::||bar" })] + public void IncludeExcludeWithNonPathContents(string projectContents, string includeString, string excludeString, string[] inputFiles, string[] expectedInclude) + { + TestIncludeExclude(projectContents, inputFiles, expectedInclude, includeString, excludeString, normalizeSlashes: false); + } + [Theory] [InlineData(ItemWithIncludeAndExclude, "a.*", diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs index 1656e6fe064..d84f8513681 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/Project_Tests.cs @@ -3099,28 +3099,143 @@ public void GetItemProvenancePathMatchingShouldBeCaseInsensitive() AssertProvenanceResult(expected, project, "A"); } - [Fact] - public void GetItemProvenanceShouldWorkWithEscapedCharacters() + + public static IEnumerable GetItemProvenanceShouldWorkWithEscapedCharactersTestData { - var project = + get + { + var projectTemplate = @" - - - + + + - - "; + "; - var expected = new ProvenanceResultTupleList - { - Tuple.Create("A", Operation.Include, Provenance.StringLiteral | Provenance.Glob, 3), - Tuple.Create("A", Operation.Update, Provenance.StringLiteral | Provenance.Glob, 3), - Tuple.Create("A", Operation.Remove, Provenance.StringLiteral | Provenance.Glob, 3) - }; + yield return new object[] + { + // the itemspec for the include, update, and remove + string.Format(projectTemplate, "a;%61;*%61*"), + // the string argument sent to GetItemProvenance + "a", + // the expected GetItemProvenance result + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.StringLiteral | Provenance.Glob, 3), + Tuple.Create("A", Operation.Update, Provenance.StringLiteral | Provenance.Glob, 3), + Tuple.Create("A", Operation.Remove, Provenance.StringLiteral | Provenance.Glob, 3) + } + }; - AssertProvenanceResult(expected, project, "a"); - AssertProvenanceResult(expected, project, "%61"); + yield return new object[] + { + string.Format(projectTemplate, "a;%61;*%61*"), + "%61", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "%61b%63"), + "abc", + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.StringLiteral, 1), + Tuple.Create("A", Operation.Update, Provenance.StringLiteral, 1), + Tuple.Create("A", Operation.Remove, Provenance.StringLiteral, 1) + } + }; + + yield return new object[] + { + string.Format(projectTemplate, "%61b%63"), + "ab%63", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "a?c"), + "ab%63", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "a?c"), + "a%62c", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "a?%63"), + "abc", + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.Glob, 1), + Tuple.Create("A", Operation.Update, Provenance.Glob, 1), + Tuple.Create("A", Operation.Remove, Provenance.Glob, 1) + } + }; + + yield return new object[] + { + string.Format(projectTemplate, "a?%63"), + "ab%63", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "a?%63"), + "a%62c", + new ProvenanceResultTupleList() + }; + + yield return new object[] + { + string.Format(projectTemplate, "a*c"), + "a%62c", + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.Glob, 1), + Tuple.Create("A", Operation.Update, Provenance.Glob, 1), + Tuple.Create("A", Operation.Remove, Provenance.Glob, 1) + } + }; + + yield return new object[] + { + string.Format(projectTemplate, "a*%63"), + "abcdefc", + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.Glob, 1), + Tuple.Create("A", Operation.Update, Provenance.Glob, 1), + Tuple.Create("A", Operation.Remove, Provenance.Glob, 1) + } + }; + + yield return new object[] + { + string.Format(projectTemplate, "a*%63"), + "a%62%61c", + new ProvenanceResultTupleList + { + Tuple.Create("A", Operation.Include, Provenance.Glob, 1), + Tuple.Create("A", Operation.Update, Provenance.Glob, 1), + Tuple.Create("A", Operation.Remove, Provenance.Glob, 1) + } + }; + } + } + [Theory] + [MemberData(nameof(GetItemProvenanceShouldWorkWithEscapedCharactersTestData))] + public void GetItemProvenanceShouldWorkWithEscapedCharacters(string project, string provenanceArgument, ProvenanceResultTupleList expectedProvenance) + { + AssertProvenanceResult(expectedProvenance, project, provenanceArgument); } [Fact] diff --git a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs index 6e61defca2a..4dadf5e8155 100644 --- a/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs +++ b/src/XMakeBuildEngine/Utilities/EngineFileUtilities.cs @@ -172,17 +172,18 @@ private static bool IsValidExclude(string exclude) } /// Returns a Func that will return true IFF its argument matches any of the specified filespecs - /// Assumes inputs may be escaped, so it unescapes them - internal static Func GetMatchTester(IList filespecsEscaped, string currentDirectory) + /// Assumes filespec may be escaped, so it unescapes it + /// The returned function makes no escaping assumptions or escaping operations. Its callers should control escaping. + internal static Func GetFileSpecMatchTester(IList filespecsEscaped, string currentDirectory) { var matchers = filespecsEscaped - .Select(fs => new Lazy>(() => GetMatchTester(fs, currentDirectory))) + .Select(fs => new Lazy>(() => GetFileSpecMatchTester(fs, currentDirectory))) .ToList(); return file => matchers.Any(m => m.Value(file)); } - internal static Func GetMatchTester(string filespec, string currentDirectory) + internal static Func GetFileSpecMatchTester(string filespec, string currentDirectory) { var unescapedSpec = EscapingUtilities.UnescapeAll(filespec); Regex regex = null; @@ -209,15 +210,13 @@ internal static Func GetMatchTester(string filespec, string curren return file => { - var unescapedFile = EscapingUtilities.UnescapeAll(file); - // check if there is a regex matching the file if (regex != null) { - return regex.IsMatch(unescapedFile); + return regex.IsMatch(file); } - return FileUtilities.ComparePathsNoThrow(unescapedSpec, unescapedFile, currentDirectory); + return FileUtilities.ComparePathsNoThrow(unescapedSpec, file, currentDirectory); }; } } From cb8c727a898e4439a3cd18f329504e436b0b7c00 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 11 Nov 2016 14:02:37 -0800 Subject: [PATCH 062/223] Remove "Extensions" folder from MSBuildExtensionsPath (#1336) This only applies for "app local" MSBuild. Our NuGet package does not have the Extensions folder and the dotnet CLI is already setting this so property. Closes #1335 --- src/XMakeBuildEngine/Resources/Constants.cs | 1 - src/XMakeBuildEngine/Utilities/Utilities.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/XMakeBuildEngine/Resources/Constants.cs b/src/XMakeBuildEngine/Resources/Constants.cs index 19d692e8d82..e39816cbbb1 100644 --- a/src/XMakeBuildEngine/Resources/Constants.cs +++ b/src/XMakeBuildEngine/Resources/Constants.cs @@ -44,7 +44,6 @@ internal static class ReservedPropertyNames internal const string buildNodeCount = "MSBuildNodeCount"; internal const string lastTaskResult = "MSBuildLastTaskResult"; internal const string extensionsPathSuffix = "MSBuild"; - internal const string appLocalExtensionsPathSuffix = "Extensions"; internal const string userExtensionsPathSuffix = "Microsoft\\MSBuild"; internal const string programFiles32 = "MSBuildProgramFiles32"; internal const string localAppData = "LocalAppData"; diff --git a/src/XMakeBuildEngine/Utilities/Utilities.cs b/src/XMakeBuildEngine/Utilities/Utilities.cs index 378c6d15de0..17d1aa3794a 100644 --- a/src/XMakeBuildEngine/Utilities/Utilities.cs +++ b/src/XMakeBuildEngine/Utilities/Utilities.cs @@ -459,7 +459,7 @@ internal static PropertyDictionary GetEnvironmentProper // environment or as a global property. #if !FEATURE_INSTALLED_MSBUILD - string extensionsPath = Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, ReservedPropertyNames.appLocalExtensionsPathSuffix); + string extensionsPath = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; string extensionsPath32 = extensionsPath; #else // "MSBuildExtensionsPath32". This points to whatever the value of "Program Files (x86)" environment variable is; From bad71ddbf273798939f79df33de397c9b297818d Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 15 Nov 2016 15:22:13 -0800 Subject: [PATCH 063/223] Remove /validate switch from help on .NET Core (#1348) The switch is #ifdef'd out in our list of possible switches but not the help. I skimmed the other switches in help and /validate looks like the only one we missed. Closes #1342 --- src/XMakeCommandLine/XMake.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index 6563ebc49ee..e039d48f342 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -3121,7 +3121,9 @@ private static void ShowHelpMessage() Console.WriteLine(AssemblyResources.GetString("HelpMessage_18_DistributedLoggerSwitch")); Console.WriteLine(AssemblyResources.GetString("HelpMessage_21_DistributedFileLoggerSwitch")); Console.WriteLine(AssemblyResources.GetString("HelpMessage_11_LoggerSwitch")); +#if FEATURE_XML_SCHEMA_VALIDATION Console.WriteLine(AssemblyResources.GetString("HelpMessage_15_ValidateSwitch")); +#endif Console.WriteLine(AssemblyResources.GetString("HelpMessage_19_IgnoreProjectExtensionsSwitch")); #if FEATURE_NODE_REUSE Console.WriteLine(AssemblyResources.GetString("HelpMessage_24_NodeReuse")); From 63cf735deb821969cb096056c0c429c78cc76fbb Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 15 Nov 2016 15:51:48 -0800 Subject: [PATCH 064/223] Only use RtlMoveMemory on Full Framework (#1343) RtlMoveMemory is not available on Nano Server, so the runtime check introduced in 60a585c isn't quite right: Nano Server is Windows but doesn't have this API exposed. Introduce a new feature flag for RtlMoveMemory, used only when building for Full Framework. For Mono and .NET Core builds, use the simpler (and I guess slower? Would like to see a benchmark) Environment.GetEnvironmentVariables codepath. Related to #1233. --- dir.props | 1 + src/Shared/CommunicationsUtilities.cs | 105 +++++++++++++------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/dir.props b/dir.props index ee345a0bce3..24261777c86 100644 --- a/dir.props +++ b/dir.props @@ -309,6 +309,7 @@ $(DefineConstants);FEATURE_RESGEN $(DefineConstants);FEATURE_RESOURCE_EXPOSURE $(DefineConstants);FEATURE_RESX_RESOURCE_READER + $(DefineConstants);FEATURE_RTLMOVEMEMORY $(DefineConstants);FEATURE_RUN_EXE_IN_TESTS $(DefineConstants);FEATURE_SECURITY_PERMISSIONS $(DefineConstants);FEATURE_SECURITY_PRINCIPAL_WINDOWS diff --git a/src/Shared/CommunicationsUtilities.cs b/src/Shared/CommunicationsUtilities.cs index e813a1fe387..1b4795c1e20 100644 --- a/src/Shared/CommunicationsUtilities.cs +++ b/src/Shared/CommunicationsUtilities.cs @@ -147,6 +147,7 @@ private static int FileVersionHash [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] internal static unsafe extern bool FreeEnvironmentStrings(char* pStrings); +#if FEATURE_RTLMOVEMEMORY /// /// Move a block of chars /// @@ -202,6 +203,7 @@ internal unsafe static char[] GetEnvironmentCharArray() return block; } +#endif /// /// Copied from the BCL implementation to eliminate some expensive security asserts. @@ -212,77 +214,74 @@ internal static Dictionary GetEnvironmentVariables() { Dictionary table = new Dictionary(200, StringComparer.OrdinalIgnoreCase); // Razzle has 150 environment variables - if (NativeMethodsShared.IsWindows) +#if FEATURE_RTLMOVEMEMORY + char[] block = GetEnvironmentCharArray(); + + // Copy strings out, parsing into pairs and inserting into the table. + // The first few environment variable entries start with an '='! + // The current working directory of every drive (except for those drives + // you haven't cd'ed into in your DOS window) are stored in the + // environment block (as =C:=pwd) and the program's exit code is + // as well (=ExitCode=00000000) Skip all that start with =. + // Read docs about Environment Blocks on MSDN's CreateProcess page. + + // Format for GetEnvironmentStrings is: + // (=HiddenVar=value\0 | Variable=value\0)* \0 + // See the description of Environment Blocks in MSDN's + // CreateProcess page (null-terminated array of null-terminated strings). + // Note the =HiddenVar's aren't always at the beginning. + for (int i = 0; i < block.Length; i++) { - char[] block = GetEnvironmentCharArray(); + int startKey = i; - // Copy strings out, parsing into pairs and inserting into the table. - // The first few environment variable entries start with an '='! - // The current working directory of every drive (except for those drives - // you haven't cd'ed into in your DOS window) are stored in the - // environment block (as =C:=pwd) and the program's exit code is - // as well (=ExitCode=00000000) Skip all that start with =. - // Read docs about Environment Blocks on MSDN's CreateProcess page. + // Skip to key + // On some old OS, the environment block can be corrupted. + // Some lines will not have '=', so we need to check for '\0'. + while (block[i] != '=' && block[i] != '\0') + { + i++; + } - // Format for GetEnvironmentStrings is: - // (=HiddenVar=value\0 | Variable=value\0)* \0 - // See the description of Environment Blocks in MSDN's - // CreateProcess page (null-terminated array of null-terminated strings). - // Note the =HiddenVar's aren't always at the beginning. - for (int i = 0; i < block.Length; i++) + if (block[i] == '\0') { - int startKey = i; + continue; + } - // Skip to key - // On some old OS, the environment block can be corrupted. - // Some lines will not have '=', so we need to check for '\0'. - while (block[i] != '=' && block[i] != '\0') + // Skip over environment variables starting with '=' + if (i - startKey == 0) + { + while (block[i] != 0) { i++; } - if (block[i] == '\0') - { - continue; - } + continue; + } - // Skip over environment variables starting with '=' - if (i - startKey == 0) - { - while (block[i] != 0) - { - i++; - } + string key = new string(block, startKey, i - startKey); + i++; - continue; - } + // skip over '=' + int startValue = i; - string key = new string(block, startKey, i - startKey); + while (block[i] != 0) + { + // Read to end of this entry i++; + } - // skip over '=' - int startValue = i; - - while (block[i] != 0) - { - // Read to end of this entry - i++; - } - - string value = new string(block, startValue, i - startValue); + string value = new string(block, startValue, i - startValue); - // skip over 0 handled by for loop's i++ - table[key] = value; - } + // skip over 0 handled by for loop's i++ + table[key] = value; } - else +#else + var vars = Environment.GetEnvironmentVariables(); + foreach (var key in vars.Keys) { - var vars = Environment.GetEnvironmentVariables(); - foreach (var key in vars.Keys) - { - table[(string)key] = (string)vars[key]; - } + table[(string)key] = (string)vars[key]; } +#endif return table; } From 56348d526d79b4cd406f5c762d60c9f3c5464058 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Tue, 8 Nov 2016 22:13:15 -0800 Subject: [PATCH 065/223] Add WriteOnlyWhenDifferent to WriteLinesToFile Add option to not write the file when the file would not have changed (preserves the timestamp). --- .../Microsoft.Build.Tasks.Core.cs | 1 + src/XMakeTasks/FileIO/WriteLinesToFile.cs | 62 ++++++++++------ src/XMakeTasks/Resources/Strings.resx | 8 ++ .../UnitTests/ReadLinesFromFile_Tests.cs | 73 +++++++++++++++++++ 4 files changed, 121 insertions(+), 23 deletions(-) diff --git a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs index 4a847d796d7..5f96c40fadd 100644 --- a/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs +++ b/ref/net46/Microsoft.Build.Tasks.Core/Microsoft.Build.Tasks.Core.cs @@ -1177,6 +1177,7 @@ public WriteLinesToFile() { } public Microsoft.Build.Framework.ITaskItem File { get { throw null; } set { } } public Microsoft.Build.Framework.ITaskItem[] Lines { get { throw null; } set { } } public bool Overwrite { get { throw null; } set { } } + public bool WriteOnlyWhenDifferent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public override bool Execute() { throw null; } } public partial class XamlTaskFactory : Microsoft.Build.Framework.ITaskFactory diff --git a/src/XMakeTasks/FileIO/WriteLinesToFile.cs b/src/XMakeTasks/FileIO/WriteLinesToFile.cs index c434b5fb18b..88de0ef1b6e 100644 --- a/src/XMakeTasks/FileIO/WriteLinesToFile.cs +++ b/src/XMakeTasks/FileIO/WriteLinesToFile.cs @@ -4,12 +4,7 @@ using System; using System.IO; using System.Text; -using System.Diagnostics; -using System.Collections; -using System.Globalization; - using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; using Microsoft.Build.Shared; namespace Microsoft.Build.Tasks @@ -24,6 +19,9 @@ public class WriteLinesToFile : TaskExtension private bool _overwrite = false; private string _encoding = null; + // Default encoding taken from System.IO.WriteAllText() + private static readonly Encoding s_defaultEncoding = new UTF8Encoding(false, true); + /// /// File to write lines to. /// @@ -61,6 +59,13 @@ public string Encoding set { _encoding = value; } } + /// + /// If true, the target file specified, if it exists, will be read first to compare against + /// what the task would have written. If identical, the file is not written to disk and the + /// timestamp will be preserved. + /// + public bool WriteOnlyWhenDifferent { get; set; } + /// /// Execute the task. @@ -83,12 +88,12 @@ public override bool Execute() } } - Encoding encode = null; + Encoding encoding = s_defaultEncoding; if (_encoding != null) { try { - encode = System.Text.Encoding.GetEncoding(_encoding); + encoding = System.Text.Encoding.GetEncoding(_encoding); } catch (ArgumentException) { @@ -97,7 +102,6 @@ public override bool Execute() } } - try { if (Overwrite) @@ -110,29 +114,41 @@ public override bool Execute() } else { - // Passing a null encoding, or Encoding.Default, to WriteAllText or AppendAllText - // is not the same as calling the overload that does not take encoding! - // Encoding.Default is based on the current codepage, the overload without encoding is UTF8-without-BOM. - if (encode == null) + string contentsAsString = null; + + try + { + // When WriteOnlyWhenDifferent is set, read the file and if they're the same return. + if (WriteOnlyWhenDifferent && FileUtilities.FileExistsNoThrow(File.ItemSpec)) + { + var existingContents = System.IO.File.ReadAllText(File.ItemSpec); + if (existingContents.Length == buffer.Length) + { + contentsAsString = buffer.ToString(); + if (existingContents.Equals(contentsAsString)) + { + Log.LogMessageFromResources(MessageImportance.Low, "WriteLinesToFile.SkippingUnchangedFile", File.ItemSpec); + return true; + } + } + } + } + catch (IOException) { - System.IO.File.WriteAllText(File.ItemSpec, buffer.ToString()); + Log.LogMessageFromResources(MessageImportance.Low, "WriteLinesToFile.ErrorReadingFile", File.ItemSpec); } - else + + if (contentsAsString == null) { - System.IO.File.WriteAllText(File.ItemSpec, buffer.ToString(), encode); + contentsAsString = buffer.ToString(); } + + System.IO.File.WriteAllText(File.ItemSpec, contentsAsString, encoding); } } else { - if (encode == null) - { - System.IO.File.AppendAllText(File.ItemSpec, buffer.ToString()); - } - else - { - System.IO.File.AppendAllText(File.ItemSpec, buffer.ToString(), encode); - } + System.IO.File.AppendAllText(File.ItemSpec, buffer.ToString(), encoding); } } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) diff --git a/src/XMakeTasks/Resources/Strings.resx b/src/XMakeTasks/Resources/Strings.resx index 0daa5f8c5c1..46b08ab913e 100644 --- a/src/XMakeTasks/Resources/Strings.resx +++ b/src/XMakeTasks/Resources/Strings.resx @@ -2085,6 +2085,14 @@ MSB3491: Could not write lines to file "{0}". {1} {StrBegin="MSB3491: "} + + MSB3492: Could not read existing file "{0}" to determine whether its contents are up to date. Overwriting it. + {StrBegin="MSB3491: "} + + + MSB3493: + {StrBegin="Skipping write to file "{0}" because content would not change."} + + + + + + + + + + + + + + + Reference to a package + + + + + + + + + + + Assets to include from this reference + + + + + + + Assets to exclude from this reference + + + + + + + Assets that are private in this reference + + + + + + + + + Version of dependency + + + + + + + @@ -1466,6 +1511,7 @@ elementFormDefault="qualified"> + From 79618b926ec77e3eb5ca0a118d920570f3695a25 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 16 Nov 2016 10:29:42 -0800 Subject: [PATCH 069/223] Make SerializedException robust to load errors (#1337) `GetTypeInfo().Assembly` seems to produce bogus results at least some of the time (noticed especially for XmlException). Since exceptions are serialized by including the exception's type and assembly, and then deserialized by reflecting over that assembly to find the type's constructor, this could cause an unhandled exception if the assembly couldn't be loaded. This change wraps the attempt to find the constructor to make it robust to file-not-found errors--if the assembly can't be loaded, simply use the preexisting FormattedError fallback case. Fixes #1246. --- src/Shared/NodePacketTranslator.cs | 42 ++++++++++++++++++------------ 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/Shared/NodePacketTranslator.cs b/src/Shared/NodePacketTranslator.cs index 96bc18f6a58..80dfdda8f66 100644 --- a/src/Shared/NodePacketTranslator.cs +++ b/src/Shared/NodePacketTranslator.cs @@ -18,6 +18,7 @@ using Microsoft.Build.Collections; using Microsoft.Build.Execution; using Microsoft.Build.Framework; +using Microsoft.Build.Internal; using Microsoft.Build.Shared; using System.Globalization; using System.Reflection; @@ -1396,35 +1397,44 @@ public static SerializedException FromException(Exception ex) public static Exception ToException(SerializedException serializedException) { - var typeLoader = new TypeLoader((t, o) => true); - - LoadedType loadedExceptionType = typeLoader.Load(serializedException.TypeFullName, serializedException.ExceptionAssembly); - Type exceptionType = loadedExceptionType.Type; - Exception innerException = null; if (serializedException.InnerException != null) { innerException = ToException(serializedException.InnerException); } - Type[] parameterTypes; - object[] constructorParameters; - if (innerException == null) + ConstructorInfo constructor = null; + object[] constructorParameters = null; + + try { - parameterTypes = new[] { typeof(string) }; - constructorParameters = new object[] { serializedException.Message }; + var typeLoader = new TypeLoader((t, o) => true); + + LoadedType loadedExceptionType = typeLoader.Load(serializedException.TypeFullName, serializedException.ExceptionAssembly); + Type exceptionType = loadedExceptionType.Type; + + Type[] parameterTypes; + if (innerException == null) + { + parameterTypes = new[] { typeof(string) }; + constructorParameters = new object[] { serializedException.Message }; + } + else + { + parameterTypes = new[] { typeof(string), typeof(Exception) }; + constructorParameters = new object[] { serializedException.Message, innerException }; + } + + constructor = exceptionType.GetConstructor(parameterTypes); } - else + catch (FileLoadException e) { - parameterTypes = new[] { typeof(string), typeof(Exception) }; - constructorParameters = new object[] { serializedException.Message, innerException }; + CommunicationsUtilities.Trace($"Exception while attempting to deserialize an exception of type \"{serializedException.TypeFullName}\". Could not load from \"{serializedException.ExceptionAssembly.AssemblyLocation}\": {e}"); } - ConstructorInfo constructor = exceptionType.GetConstructor(parameterTypes); if (constructor == null) { - // Couldn't find appropriate constructor. Fall back to creating an exception - // that will look the same as the original one when ToString() is called + CommunicationsUtilities.Trace($"Could not find a constructor to deserialize an exception of type \"{serializedException.TypeFullName}\". Falling back to an exception that will look the same."); return new FormattedException(serializedException.ExceptionToString); } From b3fc7d0201e297d2e882e3d86b1f21920db2a6a8 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 17 Nov 2016 16:55:29 -0800 Subject: [PATCH 070/223] Avoid result caching in Visual Studio (#1351) Resolves the worst UI behavior of #1308 by avoiding the slow synchronous operations when hosted by devenv.exe. --- .../BuildRequestEngine/BuildRequestEngine.cs | 112 +++++++++++------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs b/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs index 9b0076eb3d7..783dce0b727 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs @@ -825,61 +825,81 @@ private void EvaluateRequestStates() /// /// Check the amount of memory we are using and, if we exceed the threshold, unload cacheable items. /// + /// + /// Since this causes synchronous I/O and a stop-the-world GC, it can be very expensive. If + /// something other than build results is taking up the bulk of the memory space, it may not + /// free any space. That's caused customer reports of VS hangs resulting from build requests + /// that are very slow because something in VS is taking all of the memory, but every + /// project build is slowed down by this codepath. To mitigate this, don't perform these + /// checks in devenv.exe. On the command line, 32-bit MSBuild may still need to cache build + /// results on very large builds, but build results are much more likely to be the bulk of + /// memory usage there. + /// [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.GC.Collect", Justification = "We're trying to get rid of memory because we're running low, so we need to collect NOW in order to free it up ASAP")] private void CheckMemoryUsage() { - if (NativeMethodsShared.IsWindows) + if (!NativeMethodsShared.IsWindows || BuildEnvironmentHelper.Instance.RunningInVisualStudio) + { + /// Since this causes synchronous I/O and a stop-the-world GC, it can be very expensive. If + /// something other than build results is taking up the bulk of the memory space, it may not + /// free any space. That's caused customer reports of VS hangs resulting from build requests + /// that are very slow because something in VS is taking all of the memory, but every + /// project build is slowed down by this codepath. To mitigate this, don't perform these + /// checks in devenv.exe. On the command line, 32-bit MSBuild may still need to cache build + /// results on very large builds, but build results are much more likely to be the bulk of + /// memory usage there. + return; + } + + // Jeffrey Richter suggests that when the memory load in the system exceeds 80% it is a good + // idea to start finding ways to unload unnecessary data to prevent memory starvation. We use this metric in + // our calculations below. + NativeMethodsShared.MemoryStatus memoryStatus = NativeMethodsShared.GetMemoryStatus(); + if (memoryStatus != null) { - // Jeffrey Richter suggests that when the memory load in the system exceeds 80% it is a good - // idea to start finding ways to unload unnecessary data to prevent memory starvation. We use this metric in - // our calculations below. - NativeMethodsShared.MemoryStatus memoryStatus = NativeMethodsShared.GetMemoryStatus(); - if (memoryStatus != null) + try { - try + // The minimum limit must be no more than 80% of the virtual memory limit to reduce the chances of a single unfortunately + // large project resulting in allocations which exceed available VM space between calls to this function. This situation + // is more likely on 32-bit machines where VM space is only 2 gigs. + ulong memoryUseLimit = Convert.ToUInt64(memoryStatus.TotalVirtual * 0.8); + + // See how much memory we are using and compart that to our limit. + ulong memoryInUse = memoryStatus.TotalVirtual - memoryStatus.AvailableVirtual; + while ((memoryInUse > memoryUseLimit) || _debugForceCaching) { - // The minimum limit must be no more than 80% of the virtual memory limit to reduce the chances of a single unfortunately - // large project resulting in allocations which exceed available VM space between calls to this function. This situation - // is more likely on 32-bit machines where VM space is only 2 gigs. - ulong memoryUseLimit = Convert.ToUInt64(memoryStatus.TotalVirtual * 0.8); - - // See how much memory we are using and compart that to our limit. - ulong memoryInUse = memoryStatus.TotalVirtual - memoryStatus.AvailableVirtual; - while ((memoryInUse > memoryUseLimit) || _debugForceCaching) + TraceEngine( + "Memory usage at {0}, limit is {1}. Caching configurations and results cache and collecting.", + memoryInUse, + memoryUseLimit); + IResultsCache resultsCache = + _componentHost.GetComponent(BuildComponentType.ResultsCache) as IResultsCache; + + resultsCache.WriteResultsToDisk(); + if (_configCache.WriteConfigurationsToDisk()) { - TraceEngine( - "Memory usage at {0}, limit is {1}. Caching configurations and results cache and collecting.", - memoryInUse, - memoryUseLimit); - IResultsCache resultsCache = - _componentHost.GetComponent(BuildComponentType.ResultsCache) as IResultsCache; - - resultsCache.WriteResultsToDisk(); - if (_configCache.WriteConfigurationsToDisk()) - { - // We have to collect here because WriteConfigurationsToDisk only collects 10% of the configurations. It is entirely possible - // that those 10% don't constitute enough collected memory to reduce our usage below the threshold. The only way to know is to - // force the collection then re-test the memory usage. We repeat until we have reduced our use below the threshold or - // we failed to write any more configurations to disk. - GC.Collect(); - } - else - { - break; - } - - memoryStatus = NativeMethodsShared.GetMemoryStatus(); - memoryInUse = memoryStatus.TotalVirtual - memoryStatus.AvailableVirtual; - TraceEngine("Memory usage now at {0}", memoryInUse); + // We have to collect here because WriteConfigurationsToDisk only collects 10% of the configurations. It is entirely possible + // that those 10% don't constitute enough collected memory to reduce our usage below the threshold. The only way to know is to + // force the collection then re-test the memory usage. We repeat until we have reduced our use below the threshold or + // we failed to write any more configurations to disk. + GC.Collect(); } + else + { + break; + } + + memoryStatus = NativeMethodsShared.GetMemoryStatus(); + memoryInUse = memoryStatus.TotalVirtual - memoryStatus.AvailableVirtual; + TraceEngine("Memory usage now at {0}", memoryInUse); } - catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) - { - _nodeLoggingContext.LogFatalBuildError( - new BuildEventFileInfo(Microsoft.Build.Construction.ElementLocation.EmptyLocation), - e); - throw new BuildAbortedException(e.Message, e); - } + } + catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) + { + _nodeLoggingContext.LogFatalBuildError( + new BuildEventFileInfo(Microsoft.Build.Construction.ElementLocation.EmptyLocation), + e); + throw new BuildAbortedException(e.Message, e); } } } From c8aeb005edae4f7c83f340f1734464b8aeee98d0 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Fri, 18 Nov 2016 08:22:21 -0800 Subject: [PATCH 071/223] Clean up nuspecs so they don't change during build (#1338) * Add latest xml namespace * Fix casing to be consistent and to align with NUGET PACK * Reorder some elements that get changed in NUGET PACK * Align with NuSpecReferenceGenerator --- .../Microsoft.Build.Conversion.Core.nuspec | 6 +++--- .../Microsoft.Build.Engine.nuspec | 8 ++++---- .../Microsoft.Build.Framework.nuspec | 6 +++--- .../Microsoft.Build.Runtime.nuspec | 14 +++++++------- .../Microsoft.Build.Tasks.Core.nuspec | 8 ++++---- .../Microsoft.Build.Utilities.Core.nuspec | 8 ++++---- build/NuGetPackages/Microsoft.Build.nuspec | 10 +++++----- dir.props | 2 +- src/MSBuild.sln | 19 ++++++++++++------- src/XMakeBuildEngine/project.json | 2 +- 10 files changed, 44 insertions(+), 39 deletions(-) diff --git a/build/NuGetPackages/Microsoft.Build.Conversion.Core.nuspec b/build/NuGetPackages/Microsoft.Build.Conversion.Core.nuspec index dac998d3ff8..38580e4a379 100644 --- a/build/NuGetPackages/Microsoft.Build.Conversion.Core.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Conversion.Core.nuspec @@ -1,5 +1,5 @@  - + $id$ $version$ @@ -11,10 +11,10 @@ $projectUrl$ $iconUrl$ This package contains the $id$ assembly which contains logic for converting projects. NOTE: This assembly is deprecated. - MSBuild Copyright © Microsoft Corporation + MSBuild - + diff --git a/build/NuGetPackages/Microsoft.Build.Engine.nuspec b/build/NuGetPackages/Microsoft.Build.Engine.nuspec index eccc574e542..01057738ef9 100644 --- a/build/NuGetPackages/Microsoft.Build.Engine.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Engine.nuspec @@ -1,5 +1,5 @@  - + $id$ $version$ @@ -11,15 +11,15 @@ $projectUrl$ $iconUrl$ This package contains the $id$ assembly which contains the legacy compatibility shim for the MSBuild engine. NOTE: This assembly is deprecated. - MSBuild Copyright © Microsoft Corporation + MSBuild - + - + diff --git a/build/NuGetPackages/Microsoft.Build.Framework.nuspec b/build/NuGetPackages/Microsoft.Build.Framework.nuspec index 36d52348fc5..fc2e3388ce9 100644 --- a/build/NuGetPackages/Microsoft.Build.Framework.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Framework.nuspec @@ -1,5 +1,5 @@  - + $id$ $version$ @@ -11,10 +11,10 @@ $projectUrl$ $iconUrl$ This package contains the $id$ assembly which is a common assembly used by other MSBuild assemblies. - MSBuild Copyright © Microsoft Corporation + MSBuild - + diff --git a/build/NuGetPackages/Microsoft.Build.Runtime.nuspec b/build/NuGetPackages/Microsoft.Build.Runtime.nuspec index 51f95324896..67f2f319a06 100644 --- a/build/NuGetPackages/Microsoft.Build.Runtime.nuspec +++ b/build/NuGetPackages/Microsoft.Build.Runtime.nuspec @@ -1,5 +1,5 @@  - + $id$ $version$ @@ -11,25 +11,25 @@ $projectUrl$ $iconUrl$ This package contains the runtime of MSBuild. Reference this package only if your application needs to load projects or execute in-process builds. - MSBuild Copyright © Microsoft Corporation - - - + MSBuild - + - + + + + - netstandard$(TargetFrameworkVersion.TrimStart('v')) + .NETStandard$(TargetFrameworkVersion.TrimStart('v')) diff --git a/src/MSBuild.sln b/src/MSBuild.sln index f571f1ac270..f527bbf621a 100644 --- a/src/MSBuild.sln +++ b/src/MSBuild.sln @@ -48,13 +48,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PortableTask", "..\Samples\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCoreCompileTest", "..\Samples\NetCoreCompileTest\NetCoreCompileTest.csproj", "{11B5D53E-90E4-4BD5-9883-B5921F7DE854}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{144F834D-9344-42E1-919D-4D1951F3E281}" - ProjectSection(SolutionItems) = preProject - nuget\Microsoft.Build.Framework.nuspec = nuget\Microsoft.Build.Framework.nuspec - nuget\Microsoft.Build.Tasks.Core.nuspec = nuget\Microsoft.Build.Tasks.Core.nuspec - nuget\Microsoft.Build.Utilities.Core.nuspec = nuget\Microsoft.Build.Utilities.Core.nuspec - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSBuildTaskHost", "XMakeCommandLine\MSBuildTaskHost\MSBuildTaskHost.csproj", "{53733ECF-0D81-43DA-B602-2AE9417F614F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dependency", "..\Samples\Dependency\Dependency.csproj", "{9EAE36C3-50CD-49A6-9CA2-94649125DCD1}" @@ -67,6 +60,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrcasEngine", "OrcasEngine\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XMakeConversion", "XMakeConversion\XMakeConversion.csproj", "{5274C277-F122-4A44-B7A0-00A1B3F39803}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGetPackages", "NuGetPackages", "{B3A6667F-80C1-4264-874B-60AF572F641F}" + ProjectSection(SolutionItems) = preProject + ..\build\NuGetPackages\CreateNuGetPackages.proj = ..\build\NuGetPackages\CreateNuGetPackages.proj + ..\build\NuGetPackages\Microsoft.Build.Conversion.Core.nuspec = ..\build\NuGetPackages\Microsoft.Build.Conversion.Core.nuspec + ..\build\NuGetPackages\Microsoft.Build.Engine.nuspec = ..\build\NuGetPackages\Microsoft.Build.Engine.nuspec + ..\build\NuGetPackages\Microsoft.Build.Framework.nuspec = ..\build\NuGetPackages\Microsoft.Build.Framework.nuspec + ..\build\NuGetPackages\Microsoft.Build.nuspec = ..\build\NuGetPackages\Microsoft.Build.nuspec + ..\build\NuGetPackages\Microsoft.Build.Runtime.nuspec = ..\build\NuGetPackages\Microsoft.Build.Runtime.nuspec + ..\build\NuGetPackages\Microsoft.Build.Tasks.Core.nuspec = ..\build\NuGetPackages\Microsoft.Build.Tasks.Core.nuspec + ..\build\NuGetPackages\Microsoft.Build.Utilities.Core.nuspec = ..\build\NuGetPackages\Microsoft.Build.Utilities.Core.nuspec + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/XMakeBuildEngine/project.json b/src/XMakeBuildEngine/project.json index 6b29065a381..68205592286 100644 --- a/src/XMakeBuildEngine/project.json +++ b/src/XMakeBuildEngine/project.json @@ -25,7 +25,7 @@ "System.Runtime.Loader": "4.0.0", "System.Runtime.Serialization.Primitives": "4.1.1", "System.Threading.Tasks.Dataflow": "4.6.0", - "system.Threading.Thread": "4.0.0", + "System.Threading.Thread": "4.0.0", "System.Threading.ThreadPool": "4.0.10", "System.Xml.XmlDocument": "4.0.1", "System.Xml.XPath.XmlDocument": "4.0.1" From 9d9aca3de6237692c3788df1ca9559212270d612 Mon Sep 17 00:00:00 2001 From: Jeff Greene Date: Fri, 18 Nov 2016 16:37:43 -0800 Subject: [PATCH 072/223] Guard against null ref when a Glob exclude fails to match any files (#1349) --- src/Shared/FileMatcher.cs | 7 +++++-- .../Definition/ProjectItem_Tests.cs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Shared/FileMatcher.cs b/src/Shared/FileMatcher.cs index 5c2347d8b0b..493eb13fd80 100644 --- a/src/Shared/FileMatcher.cs +++ b/src/Shared/FileMatcher.cs @@ -722,9 +722,12 @@ Dictionary> searchesToExcludeInSubdirs filesToExclude = new HashSet(); foreach (var excludeStep in excludeNextSteps) { - foreach (var file in excludeStep.Files) + if (excludeStep.Files != null) { - filesToExclude.Add(file); + foreach (var file in excludeStep.Files) + { + filesToExclude.Add(file); + } } } } diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs index eeac9eaa0ba..e4b4039b707 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Definition/ProjectItem_Tests.cs @@ -621,6 +621,22 @@ public void IncludeExcludeWithNonPathContents(string projectContents, string inc @"a\foo", "build.proj" })] + [InlineData(ItemWithIncludeAndExclude, + @"**\*", + @"a\af*\*", + new[] + { + @"a\foo", + @"a\a\foo", + @"a\b\foo", + }, + new[] + { + @"a\a\foo", + @"a\b\foo", + @"a\foo", + "build.proj" + })] public void ExcludeVectorWithWildCards(string projectContents, string includeString, string excludeString, string[] inputFiles, string[] expectedInclude) { TestIncludeExcludeWithDifferentSlashes(projectContents, includeString, excludeString, inputFiles, expectedInclude); From 14114bfd3911750aa4880ca016380a89aadae3aa Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 21 Nov 2016 09:39:07 -0800 Subject: [PATCH 073/223] Update ref assembly source and fix some warnings (#1361) ShouldCloneXmlAttribute() method BuildRequestEngine.cs(843,17): warning CS1587: XML comment is not placed on a valid language element FileUtilities.cs(575): warning CS1574: XML comment has cref attribute 'GetFullPathNoThrow(string, string)' that could not be resolved FileUtilities.cs(597): warning CS1574: XML comment has cref attribute 'GetFullPathNoThrow(string, string)' that could not be resolved --- .../Microsoft.Build/Microsoft.Build.cs | 2 ++ src/Shared/FileUtilities.cs | 4 ++-- .../BuildRequestEngine/BuildRequestEngine.cs | 16 ++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs index 9b000a08d65..19ae83b1aed 100644 --- a/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs +++ b/ref/netstandard1.3/Microsoft.Build/Microsoft.Build.cs @@ -49,6 +49,7 @@ internal ProjectElement() { } protected internal virtual Microsoft.Build.Construction.ProjectElement Clone(Microsoft.Build.Construction.ProjectRootElement factory) { throw null; } public virtual void CopyFrom(Microsoft.Build.Construction.ProjectElement element) { } protected abstract Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner); + protected virtual bool ShouldCloneXmlAttribute(System.Xml.XmlAttribute attribute) { throw null; } } public abstract partial class ProjectElementContainer : Microsoft.Build.Construction.ProjectElement { @@ -148,6 +149,7 @@ internal ProjectItemElement() { } public Microsoft.Build.Construction.ProjectMetadataElement AddMetadata(string name, string unevaluatedValue, bool expressAsAttribute) { throw null; } public override void CopyFrom(Microsoft.Build.Construction.ProjectElement element) { } protected override Microsoft.Build.Construction.ProjectElement CreateNewInstance(Microsoft.Build.Construction.ProjectRootElement owner) { throw null; } + protected override bool ShouldCloneXmlAttribute(System.Xml.XmlAttribute attribute) { throw null; } } [System.Diagnostics.DebuggerDisplayAttribute("#Items={Count} Condition={Condition} Label={Label}")] public partial class ProjectItemGroupElement : Microsoft.Build.Construction.ProjectElementContainer diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs index 9a5638ca3c3..4dbb517ab7e 100644 --- a/src/Shared/FileUtilities.cs +++ b/src/Shared/FileUtilities.cs @@ -572,7 +572,7 @@ internal static string GetFullPathNoThrow(string path) /// /// Compare if two paths, relative to the given currentDirectory are equal. - /// Does not throw IO exceptions. See + /// Does not throw IO exceptions. See /// /// /// @@ -594,7 +594,7 @@ internal static bool ComparePathsNoThrow(string first, string second, string cur /// /// Normalizes a path for path comparison - /// Does not throw IO exceptions. See + /// Does not throw IO exceptions. See /// /// internal static string NormalizePathForComparisonNoThrow(string path, string currentDirectory) diff --git a/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs b/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs index 783dce0b727..b817c3d3fa8 100644 --- a/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs +++ b/src/XMakeBuildEngine/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs @@ -840,14 +840,14 @@ private void CheckMemoryUsage() { if (!NativeMethodsShared.IsWindows || BuildEnvironmentHelper.Instance.RunningInVisualStudio) { - /// Since this causes synchronous I/O and a stop-the-world GC, it can be very expensive. If - /// something other than build results is taking up the bulk of the memory space, it may not - /// free any space. That's caused customer reports of VS hangs resulting from build requests - /// that are very slow because something in VS is taking all of the memory, but every - /// project build is slowed down by this codepath. To mitigate this, don't perform these - /// checks in devenv.exe. On the command line, 32-bit MSBuild may still need to cache build - /// results on very large builds, but build results are much more likely to be the bulk of - /// memory usage there. + // Since this causes synchronous I/O and a stop-the-world GC, it can be very expensive. If + // something other than build results is taking up the bulk of the memory space, it may not + // free any space. That's caused customer reports of VS hangs resulting from build requests + // that are very slow because something in VS is taking all of the memory, but every + // project build is slowed down by this codepath. To mitigate this, don't perform these + // checks in devenv.exe. On the command line, 32-bit MSBuild may still need to cache build + // results on very large builds, but build results are much more likely to be the bulk of + // memory usage there. return; } From 55f8ebfb61d9aa32ede512e686fd731e35f6baf3 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 21 Nov 2016 09:54:29 -0800 Subject: [PATCH 074/223] Enable Exec_Tests.Timeout (#1362) The issue was fixed by #886. This is a revert of 2b3d4f1 with the expected exit code updated for cross-platform. Closes #434 --- src/XMakeTasks/UnitTests/Exec_Tests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/XMakeTasks/UnitTests/Exec_Tests.cs b/src/XMakeTasks/UnitTests/Exec_Tests.cs index b74ff03da3f..128b1b9311a 100644 --- a/src/XMakeTasks/UnitTests/Exec_Tests.cs +++ b/src/XMakeTasks/UnitTests/Exec_Tests.cs @@ -88,15 +88,17 @@ public void ExitCodeCausesFailure() } [Fact] - [PlatformSpecific(PlatformID.Windows)] // TODO: https://github.com/Microsoft/msbuild/issues/434 public void Timeout() { + // On non-Windows the exit code of a killed process is SIGTERM (143) + int expectedExitCode = NativeMethodsShared.IsWindows ? -1 : 143; + Exec exec = PrepareExec(NativeMethodsShared.IsWindows ? ":foo \n goto foo" : "while true; do sleep 1; done"); exec.Timeout = 5; bool result = exec.Execute(); Assert.Equal(false, result); - Assert.Equal(-1, exec.ExitCode); + Assert.Equal(expectedExitCode, exec.ExitCode); ((MockEngine)exec.BuildEngine).AssertLogContains("MSB5002"); Assert.Equal(1, ((MockEngine)exec.BuildEngine).Warnings); From 3af198d045bbb3d62e8d219ff0b9f7c61ef73ab1 Mon Sep 17 00:00:00 2001 From: Nick Guerrera Date: Mon, 21 Nov 2016 13:08:50 -0800 Subject: [PATCH 075/223] Specify build as default target for cross-targeting projects (#1365) Fixes #1364 --- src/XMakeTasks/Microsoft.Common.CrossTargeting.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeTasks/Microsoft.Common.CrossTargeting.targets b/src/XMakeTasks/Microsoft.Common.CrossTargeting.targets index 80dd72c3988..d4ede1aa369 100644 --- a/src/XMakeTasks/Microsoft.Common.CrossTargeting.targets +++ b/src/XMakeTasks/Microsoft.Common.CrossTargeting.targets @@ -10,7 +10,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. *********************************************************************************************** --> - + true From 4b6125bc51e383e887929c5d1061e74ccf68ba95 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Mon, 21 Nov 2016 13:32:48 -0800 Subject: [PATCH 076/223] Enable CancelledBuildWithDelay20 (#1368) This test shouldn't be as flaky because I fixed killing process in 9bcc0028f211b6198f8514ae4a7e7f823dba18ce --- src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs index dfdadd786c7..d37f27e5d6d 100644 --- a/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/BackEnd/BuildManager_Tests.cs @@ -1433,7 +1433,7 @@ public void CancelledBuild() /// A canceled build which waits for the task to get started before canceling. Because it is a 2.0 task, we should /// wait until the task finishes normally (cancellation not supported.) /// - [Fact(Skip= "https://github.com/Microsoft/msbuild/issues/696")] + [Fact] public void CancelledBuildWithDelay20() { if (FrameworkLocationHelper.PathToDotNetFrameworkV20 != null) From 92a49a7c6c65cd9e75b6bdb4c50228121dada718 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 22 Nov 2016 07:22:19 -0800 Subject: [PATCH 077/223] Property function for EnsureTrailingSlash() (#1376) Closes #1302 --- .../Evaluation/IntrinsicFunctions.cs | 11 ++++++++++ .../UnitTests/Evaluation/Expander_Tests.cs | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index 885267a310c..a64777400f3 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -364,6 +364,17 @@ internal static bool DoesTaskHostExist(string runtime, string architecture) return false; } + /// + /// If the given path doesn't have a trailing slash then add one. + /// If the path is an empty string, does not modify it. + /// + /// The path to check. + /// The specified path with a trailing slash. + internal static string EnsureTrailingSlash(string path) + { + return FileUtilities.EnsureTrailingSlash(path); + } + public static string GetCurrentExecutableDirectory() { return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs index 9d5218fbbb8..c37a39fc4a8 100644 --- a/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/Expander_Tests.cs @@ -3361,5 +3361,27 @@ public void Medley() ); } } + + [Fact] + public void PropertyFunctionEnsureTrailingSlash() + { + string path = Path.Combine("foo", "bar"); + + PropertyDictionary pg = new PropertyDictionary(); + + pg.Set(ProjectPropertyInstance.Create("SomeProperty", path)); + + Expander expander = new Expander(pg); + + // Verify a constant expands properly + string result = expander.ExpandIntoStringLeaveEscaped($"$([MSBuild]::EnsureTrailingSlash('{path}'))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); + + Assert.Equal(path + Path.DirectorySeparatorChar, result); + + // Verify that a property expands properly + result = expander.ExpandIntoStringLeaveEscaped("$([MSBuild]::EnsureTrailingSlash($(SomeProperty)))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); + + Assert.Equal(path + Path.DirectorySeparatorChar, result); + } } } From 7a1e89ffc8a1dd7dfdeeb5a31982605d1ce321c1 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 22 Nov 2016 07:22:52 -0800 Subject: [PATCH 078/223] Print out prompt and process ID when waiting for a debugger to attach. (#1370) If MSBUILDDEBUGONSTART=2 you will now see: ``` Waiting for debugger to attach (PID 21552). Press enter to continue... ``` Closes #1118 --- src/XMakeCommandLine/XMake.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/XMakeCommandLine/XMake.cs b/src/XMakeCommandLine/XMake.cs index e039d48f342..ed2b35e3fc4 100644 --- a/src/XMakeCommandLine/XMake.cs +++ b/src/XMakeCommandLine/XMake.cs @@ -491,6 +491,7 @@ string [] commandLine #endif case "2": // Sometimes easier to attach rather than deal with JIT prompt + Console.WriteLine($"Waiting for debugger to attach (PID {Process.GetCurrentProcess().Id}). Press enter to continue..."); Console.ReadLine(); break; } From 6b8573009626ee00e73e5cd47b0d1be1b5b9174c Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 11 Nov 2016 17:20:53 -0600 Subject: [PATCH 079/223] Expose MSBuildToolsPath intrinsics for all bitness The previous implementation of MSBuildToolsPath32/64 was wrong when run from amd64 MSBuild: it would return the 64-bit path in the 32 property and an entirely wrong `bin/amd64/amd64` in the 64 property. Expose new intrinsics to get the correct values from all bitnesses. --- .../Evaluation/IntrinsicFunctions.cs | 12 +++++++++++- src/XMakeCommandLine/app.amd64.config | 8 +++----- src/XMakeCommandLine/app.config | 8 +++----- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs index a64777400f3..2072fb6c73f 100644 --- a/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs +++ b/src/XMakeBuildEngine/Evaluation/IntrinsicFunctions.cs @@ -375,11 +375,21 @@ internal static string EnsureTrailingSlash(string path) return FileUtilities.EnsureTrailingSlash(path); } - public static string GetCurrentExecutableDirectory() + public static string GetCurrentToolsDirectory() { return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; } + public static string GetToolsDirectory32() + { + return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32; + } + + public static string GetToolsDirectory64() + { + return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64; + } + public static string GetVsInstallRoot() { return BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory; diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index 407e027afa9..aecc3fe8bc9 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -57,11 +57,9 @@ - - - - - + + + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index 0a873072866..5d92a6fdb1d 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -51,11 +51,9 @@ - - - - - + + + From 8786ab3832777819f6b909e70d5bfb6d9ea89997 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 11 Nov 2016 17:19:24 -0600 Subject: [PATCH 080/223] Unescape properties defined in toolset This enables removing the workaround for #704 in the app.config file that arose because the v14-and-earlier registry-defined toolsets gave unescaped paths (including the parens in `Program Files (x86)`) but reading them from an app.config did not. --- src/XMakeBuildEngine/Definition/ToolsetReader.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/XMakeBuildEngine/Definition/ToolsetReader.cs b/src/XMakeBuildEngine/Definition/ToolsetReader.cs index f70cd4b749e..fe2124f6b2b 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetReader.cs @@ -631,7 +631,7 @@ private void EvaluateAndSetProperty(ToolsetPropertyDefinition property, Property { if (0 == String.Compare(property.Name, ReservedPropertyNames.toolsPath, StringComparison.OrdinalIgnoreCase)) { - toolsPath = ExpandPropertyLeaveEscaped(property, expander); + toolsPath = ExpandPropertyUnescaped(property, expander); toolsPath = ExpandRelativePathsRelativeToExeLocation(toolsPath); if (accumulateProperties) @@ -646,7 +646,7 @@ private void EvaluateAndSetProperty(ToolsetPropertyDefinition property, Property } else if (0 == String.Compare(property.Name, ReservedPropertyNames.binPath, StringComparison.OrdinalIgnoreCase)) { - binPath = ExpandPropertyLeaveEscaped(property, expander); + binPath = ExpandPropertyUnescaped(property, expander); binPath = ExpandRelativePathsRelativeToExeLocation(binPath); if (accumulateProperties) @@ -668,7 +668,7 @@ private void EvaluateAndSetProperty(ToolsetPropertyDefinition property, Property else { // It's an arbitrary property - property.Value = ExpandPropertyLeaveEscaped(property, expander); + property.Value = ExpandPropertyUnescaped(property, expander); SetProperty(property, properties, globalProperties); @@ -688,11 +688,11 @@ private void EvaluateAndSetProperty(ToolsetPropertyDefinition property, Property /// Expands the given unexpanded property expression using the properties in the /// given expander. /// - private string ExpandPropertyLeaveEscaped(ToolsetPropertyDefinition property, Expander expander) + private string ExpandPropertyUnescaped(ToolsetPropertyDefinition property, Expander expander) { try { - return expander.ExpandIntoStringLeaveEscaped(property.Value, ExpanderOptions.ExpandProperties, property.Source); + return expander.ExpandIntoStringAndUnescape(property.Value, ExpanderOptions.ExpandProperties, property.Source); } catch (InvalidProjectFileException ex) { From 60e78ab98d1d55f907b383015b6b6af111a70902 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 10 Nov 2016 18:05:17 -0600 Subject: [PATCH 081/223] Deploy Roslyn from full-framework package manually On .NET Core, we resolve assets from the Microsoft.Net.Compilers.netcore package and deploy them to the Roslyn subfolder. But the equivalent package for Full Framework doesn't include all the right assets, so we deploy from its tools directory instead. However, this only makes sense when deploying for Full Framework--otherwise we'll expand an empty property to just /, causing copy errors. --- targets/BootStrapMSBuild.proj | 16 +++++------ targets/DeployDependencies.proj | 51 ++++++++++++++++----------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/targets/BootStrapMSBuild.proj b/targets/BootStrapMSBuild.proj index ed732c6fe2b..7b4d2ce87dd 100644 --- a/targets/BootStrapMSBuild.proj +++ b/targets/BootStrapMSBuild.proj @@ -46,13 +46,13 @@ - - - + + + - - - + + + @@ -74,7 +74,7 @@ + DestinationFiles="@(FreshlyBuiltProjects -> '$(BootstrapDestination)$(TargetMSBuildToolsVersion)\Bin\%(RecursiveDir)%(Filename)%(Extension)')" /> @@ -104,4 +104,4 @@ - \ No newline at end of file + diff --git a/targets/DeployDependencies.proj b/targets/DeployDependencies.proj index 156c9fece67..56cf0be3b1e 100644 --- a/targets/DeployDependencies.proj +++ b/targets/DeployDependencies.proj @@ -3,24 +3,24 @@ - - + - + + DestinationFolder="$(DeploymentDir)\Roslyn" + SkipUnchangedFiles="true" /> + DestinationFolder="$(TestDeploymentDir)\Roslyn" + SkipUnchangedFiles="true" /> - + @@ -85,48 +85,47 @@ $(MSBuildThisFileDirectory)runtimeDependencies\project.json $(MSBuildThisFileDirectory)runtimeDependencies\project.lock.json - $(DnuRestoreCommand) "$(RuntimeProjectJson)" - $(RuntimeSystem)-$(RuntimeArchitecture) + + + $(MSBuildThisFileDirectory)runtimeDependencies\project.lock.json + $(DeploymentDir) + $(TestDeploymentDir) + + + - + Outputs="@(RuntimeProjectJson->'%(LockFile)')"> + - + + Outputs="%(RuntimeProjectJson.DestinationFolder)\dummy"> - - - - - From 1598a5001cc49a1242d15fccee56cc68cf05a162 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 11 Nov 2016 10:23:50 -0600 Subject: [PATCH 082/223] Deploy Roslyn to subfolder on .NET Core --- targets/DeployDependencies.proj | 7 ++++++- targets/roslyn/project.json | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 targets/roslyn/project.json diff --git a/targets/DeployDependencies.proj b/targets/DeployDependencies.proj index 56cf0be3b1e..36af3d1b640 100644 --- a/targets/DeployDependencies.proj +++ b/targets/DeployDependencies.proj @@ -94,12 +94,17 @@ $(DeploymentDir) $(TestDeploymentDir) + + $(MSBuildThisFileDirectory)roslyn\project.lock.json + $(DeploymentDir)\Roslyn + $(TestDeploymentDir)\Roslyn + - + diff --git a/targets/roslyn/project.json b/targets/roslyn/project.json new file mode 100644 index 00000000000..89528e0547e --- /dev/null +++ b/targets/roslyn/project.json @@ -0,0 +1,26 @@ +{ + "runtimes": { + "win7-x86": {}, + "win7-x64": {}, + "osx.10.10-x64": {}, + "ubuntu.14.04-x64": {}, + "ubuntu.16.04-x64": {} + }, + "dependencies": {}, + "frameworks": { + "net46": { + "dependencies": {} + }, + "netcoreapp1.0": { + "dependencies": { + "Microsoft.Net.Compilers.NetCore": "1.3.2", + "Microsoft.Net.Compilers.Targets.NetCore": "0.1.5-dev", + }, + "imports": [ + "portable-net451+win81", + "dnxcore50", + "netstandard1.6" + ] + } + } +} From b277dd8c4b01f553f2396b913ded4d983f6e3189 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 15 Nov 2016 18:47:00 -0800 Subject: [PATCH 083/223] Introduce RoslynTargetsPath to toolset This allows defining the Roslyn path in one place to be either * The only copy of the Roslyn assemblies on Full framework (a child of the 32-bit MSBuild folder), or * The only copy of the Roslyn assemblies on .NET Core (a child of the only MSBuild folder). Includes a reference in our unit test app.config. --- src/Shared/UnitTests/App.config | 1 + src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs | 3 +++ src/XMakeCommandLine/app.amd64.config | 2 ++ src/XMakeCommandLine/app.config | 2 ++ src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets | 2 +- src/XMakeTasks/Microsoft.Common.tasks | 6 +++--- src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets | 2 +- 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Shared/UnitTests/App.config b/src/Shared/UnitTests/App.config index 03a15d5e8a9..d6407124ae2 100644 --- a/src/Shared/UnitTests/App.config +++ b/src/Shared/UnitTests/App.config @@ -46,6 +46,7 @@ + \ No newline at end of file diff --git a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs index 80c63045c07..a243c13c3e0 100644 --- a/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs +++ b/src/XMakeBuildEngine/Definition/ToolsetLocalReader.cs @@ -57,6 +57,9 @@ protected override IEnumerable ToolsVersions protected override IEnumerable GetPropertyDefinitions(string toolsVersion) { yield return new ToolsetPropertyDefinition(MSBuildConstants.ToolsPath, BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, _sourceLocation); + yield return new ToolsetPropertyDefinition("RoslynTargetsPath", + System.IO.Path.Combine(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, "Roslyn"), + _sourceLocation); } protected override IEnumerable GetSubToolsetPropertyDefinitions(string toolsVersion, string subToolsetVersion) diff --git a/src/XMakeCommandLine/app.amd64.config b/src/XMakeCommandLine/app.amd64.config index aecc3fe8bc9..85bba4f3c67 100644 --- a/src/XMakeCommandLine/app.amd64.config +++ b/src/XMakeCommandLine/app.amd64.config @@ -74,6 +74,8 @@ + + diff --git a/src/XMakeCommandLine/app.config b/src/XMakeCommandLine/app.config index 5d92a6fdb1d..4c5f10ad678 100644 --- a/src/XMakeCommandLine/app.config +++ b/src/XMakeCommandLine/app.config @@ -68,6 +68,8 @@ + + diff --git a/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets b/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets index 84ddc431cea..e79edeab986 100644 --- a/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.CSharp.CurrentVersion.targets @@ -315,7 +315,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. - Microsoft.CSharp.Core.targets + $(RoslynTargetsPath)\Microsoft.CSharp.Core.targets diff --git a/src/XMakeTasks/Microsoft.Common.tasks b/src/XMakeTasks/Microsoft.Common.tasks index 9339d8db499..d284df7336a 100644 --- a/src/XMakeTasks/Microsoft.Common.tasks +++ b/src/XMakeTasks/Microsoft.Common.tasks @@ -169,8 +169,8 @@ - - - + + + diff --git a/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets b/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets index 2119f41506f..0b4680542d5 100644 --- a/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets +++ b/src/XMakeTasks/Microsoft.VisualBasic.CurrentVersion.targets @@ -315,7 +315,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. - Microsoft.VisualBasic.Core.targets + $(RoslynTargetsPath)\Microsoft.VisualBasic.Core.targets From 9344078e531d3a077f26751c39bdc4db58cd97e9 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 21 Nov 2016 11:01:10 -0600 Subject: [PATCH 084/223] Update README for xplat primacy --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e7f05793adc..9b2e5997fb2 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,18 @@ The Microsoft Build Engine is a platform for building applications. This engine, For more information on MSBuild, see the [MSDN documentation](https://msdn.microsoft.com/en-us/library/dd393574%28v=vs.140%29.aspx). ### Build Status -Full framework build from `master` (stable, inserted into Visual Studio builds): -[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_master_Windows_NT_Desktop)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_master_Windows_NT_Desktop) -The `xplat` branch is soon to be merged back upstream. Follow the [The Great Merge](https://github.com/Microsoft/msbuild/milestone/6) milestone for progress. +The current development branch is `xplat`. It builds for .NET Core and the full desktop .NET framework. | Runtime\OS | Windows | Ubuntu 14.04 | Ubuntu 16.04 |Mac OS X| |:------|:------:|:------:|:------:|:------:| | **Full Framework** |[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_Desktop)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_Desktop)| N/A | N/A | N/A | |**.NET Core**|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Windows_NT_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Windows_NT_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu14.04_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu14.04_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_Ubuntu16.04_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_Ubuntu16.04_CoreCLR)|[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_xplat_OSX_CoreCLR)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_xplat_OSX_CoreCLR)| +Full-framework-only build from `master` (deprecated): +[![Build Status](https://ci.dot.net/buildStatus/icon?job=Microsoft_msbuild/master/innerloop_master_Windows_NT_Desktop)](https://ci.dot.net/job/Microsoft_msbuild/job/master/job/innerloop_master_Windows_NT_Desktop) + + [![Join the chat at https://gitter.im/Microsoft/msbuild](https://badges.gitter.im/Microsoft/msbuild.svg)](https://gitter.im/Microsoft/msbuild?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Check out what we're working on using our Waffle board!](https://badge.waffle.io/Microsoft/msbuild.svg?label=In+Progress&title=waffle+board)](http://waffle.io/Microsoft/msbuild) From 7f9e127ebae5e263621fb213d1b1586dc6c27f0b Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 21 Nov 2016 11:49:40 -0600 Subject: [PATCH 085/223] Remove Waffle badge We're currently using GitHub native Projects instead of Waffle for boards. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 9b2e5997fb2..9487c491c3c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ Full-framework-only build from `master` (deprecated): [![Join the chat at https://gitter.im/Microsoft/msbuild](https://badges.gitter.im/Microsoft/msbuild.svg)](https://gitter.im/Microsoft/msbuild?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Check out what we're working on using our Waffle board!](https://badge.waffle.io/Microsoft/msbuild.svg?label=In+Progress&title=waffle+board)](http://waffle.io/Microsoft/msbuild) ### Source code From d7127616c48e0337e65874b230e16eb6734fb5ad Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 21 Nov 2016 11:51:57 -0600 Subject: [PATCH 086/223] Simplify clone-and-build instructions Personally, I always use `cibuild` to restore the required packages for MSBuild, so telling other people to do that. --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9487c491c3c..67f9c9ab943 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ Full-framework-only build from `master` (deprecated): * Clone the sources: `git clone https://github.com/Microsoft/msbuild.git` ### Building -## Building MSBuild in VS 2015 -For the full supported experience, you will need to have Visual Studio 2015. You can open the solution in Visual Studio 2013, but you will encounter issues building with the provided scripts. +## Building MSBuild with VS 2015 +For the full supported experience, you will need to have Visual Studio 2015. You can open the solution in Visual Studio 2017 RC, but you will encounter issues building with the provided scripts. To get started on **Visual Studio 2015**: @@ -33,8 +33,7 @@ To get started on **Visual Studio 2015**: - _Universal Windows App Development Tools_ - _Tools and Windows SDK 10.0.10240_ 2. Clone the source code (see above). -3. (on the `xplat` branch only) Initialize tools the first time: `init-tools.cmd` -4. Restore NuGet packages: `msbuild /t:BulkRestoreNugetPackages build.proj` +3. Build the code using the `cibuild.cmd` script. 5. Open src/MSBuild.sln solution in Visual Studio 2015. ## Building MSBuild in Unix (Mac & Linux) From a1e9dcdd10e5063e6f2bd547404fd55d2ec7f159 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 22 Nov 2016 09:39:17 -0800 Subject: [PATCH 087/223] Alter TEMP folder when running in CI (#1373) * Alter TEMP folder when running in CI for non-Windows --- cibuild.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cibuild.sh b/cibuild.sh index 8d013325211..8c79b372e4f 100755 --- a/cibuild.sh +++ b/cibuild.sh @@ -24,6 +24,10 @@ setHome() then export HOME=$HOME_DEFAULT mkdir -p $HOME_DEFAULT + + # Use a different temp directory in CI so that hopefully things are a little more stable + export TMPDIR=$TEMP_DEFAULT + mkdir -p $TEMP_DEFAULT fi } @@ -134,6 +138,7 @@ TOOLS_DIR="$THIS_SCRIPT_PATH/Tools" MSBUILD_DOWNLOAD_URL="https://github.com/Microsoft/msbuild/releases/download/mono-hosted-msbuild-v0.2/mono_msbuild_bootstrap_5e01f07.zip" MSBUILD_ZIP="$PACKAGES_DIR/msbuild.zip" HOME_DEFAULT="$WORKSPACE/msbuild-CI-home" +TEMP_DEFAULT="$WORKSPACE/tmp" PROJECT_FILE_ARG='"'"$THIS_SCRIPT_PATH/build.proj"'"' BOOTSTRAP_FILE_ARG='"'"$THIS_SCRIPT_PATH/targets/BootStrapMSBuild.proj"'"' From 97dddbba5ec1b865121b6ec9901d4a95f698306a Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 14 Apr 2016 15:50:05 -0400 Subject: [PATCH 088/223] $(MSBuildRuntimeType): Add 'Mono' to the existing set of values .. .. Full and Core. --- src/XMakeBuildEngine/Evaluation/Evaluator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/XMakeBuildEngine/Evaluation/Evaluator.cs b/src/XMakeBuildEngine/Evaluation/Evaluator.cs index b85b0daa4a7..e95bd8ca63e 100644 --- a/src/XMakeBuildEngine/Evaluation/Evaluator.cs +++ b/src/XMakeBuildEngine/Evaluation/Evaluator.cs @@ -1392,6 +1392,9 @@ private ICollection

AddBuiltInProperties() #if RUNTIME_TYPE_NETCORE builtInProperties.Add(SetBuiltInProperty(ReservedPropertyNames.msbuildRuntimeType, "Core")); +#elif MONO + builtInProperties.Add(SetBuiltInProperty(ReservedPropertyNames.msbuildRuntimeType, + NativeMethodsShared.IsMono ? "Mono" : "Full")); #else builtInProperties.Add(SetBuiltInProperty(ReservedPropertyNames.msbuildRuntimeType, "Full")); #endif From 54807125711d8d2ac215b2ff6b7eac103ac274fd Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 22 Nov 2016 11:08:08 -0800 Subject: [PATCH 089/223] Mimic Full Framework string quoting (#1369) * Mimic Full Framework string quoting CodeDom is not available on .net core, so copy over its string quoting implementation. Ideally, all this code should be replaced with crossplatform Roselyn Fixes #1294 --- .../UnitTests/WriteCodeFragment_Tests.cs | 80 +++++++ src/XMakeTasks/WriteCodeFragment.cs | 217 +++++++++++++++++- 2 files changed, 293 insertions(+), 4 deletions(-) diff --git a/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs b/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs index de0ed66306c..69345ca6caf 100644 --- a/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs +++ b/src/XMakeTasks/UnitTests/WriteCodeFragment_Tests.cs @@ -429,6 +429,86 @@ public void OneAttributeTwoPositionalParams() File.Delete(task.OutputFile.ItemSpec); } + public static string EscapedLineSeparator => NativeMethodsShared.IsWindows ? "\\r\\n" : "\\n"; + + ///

+ /// Multi line argument values should cause a verbatim string to be used + /// + [Fact] + public void MultilineAttributeCSharp() + { + var lines = new[] { "line 1", "line 2", "line 3" }; + var multilineString = String.Join(Environment.NewLine, lines); + + WriteCodeFragment task = new WriteCodeFragment(); + MockEngine engine = new MockEngine(true); + task.BuildEngine = engine; + TaskItem attribute = new TaskItem("System.Reflection.AssemblyDescriptionAttribute"); + attribute.SetMetadata("_Parameter1", multilineString); + attribute.SetMetadata("Description", multilineString); + task.AssemblyAttributes = new TaskItem[] { attribute }; + task.Language = "c#"; + task.OutputDirectory = new TaskItem(Path.GetTempPath()); + bool result = task.Execute(); + + Assert.Equal(true, result); + + string content = File.ReadAllText(task.OutputFile.ItemSpec); + Console.WriteLine(content); + + var csMultilineString = lines.Aggregate((l1, l2) => l1 + EscapedLineSeparator + l2); + CheckContentCSharp(content, $"[assembly: System.Reflection.AssemblyDescriptionAttribute(\"{csMultilineString}\", Description=\"{csMultilineString}\")]"); + + File.Delete(task.OutputFile.ItemSpec); + } + + private static readonly string VBCarriageReturn = "Global.Microsoft.VisualBasic.ChrW(13)"; + private static readonly string VBLineFeed = "Global.Microsoft.VisualBasic.ChrW(10)"; + private static readonly string WindowsNewLine = $"{VBCarriageReturn}&{VBLineFeed}"; + + public static readonly string VBLineSeparator = +#if FEATURE_CODEDOM + WindowsNewLine; +#else + NativeMethodsShared.IsWindows + ? WindowsNewLine + : VBLineFeed; +#endif + + /// + /// Multi line argument values should cause a verbatim string to be used + /// + [Fact] + public void MultilineAttributeVB() + { + var lines = new []{ "line 1", "line 2", "line 3" }; + var multilineString = String.Join(Environment.NewLine, lines); + + WriteCodeFragment task = new WriteCodeFragment(); + MockEngine engine = new MockEngine(true); + task.BuildEngine = engine; + TaskItem attribute = new TaskItem("System.Reflection.AssemblyDescriptionAttribute"); + attribute.SetMetadata("_Parameter1", multilineString); + attribute.SetMetadata("Description", multilineString); + task.AssemblyAttributes = new TaskItem[] { attribute }; + task.Language = "visualbasic"; + task.OutputDirectory = new TaskItem(Path.GetTempPath()); + bool result = task.Execute(); + + Assert.Equal(true, result); + + string content = File.ReadAllText(task.OutputFile.ItemSpec); + Console.WriteLine(content); + + var vbMultilineString = lines + .Select(l => $"\"{l}\"") + .Aggregate((l1, l2) => $"{l1}&{VBLineSeparator}&{l2}"); + + CheckContentVB(content, $""); + + File.Delete(task.OutputFile.ItemSpec); + } + /// /// Some attributes only allow positional constructor arguments. /// To set those, use metadata names like "_Parameter1", "_Parameter2" etc. diff --git a/src/XMakeTasks/WriteCodeFragment.cs b/src/XMakeTasks/WriteCodeFragment.cs index 31ce45a5470..5e817079192 100644 --- a/src/XMakeTasks/WriteCodeFragment.cs +++ b/src/XMakeTasks/WriteCodeFragment.cs @@ -303,7 +303,7 @@ private string GenerateCodeCoreClr(out string extension) foreach (ITaskItem attributeItem in AssemblyAttributes) { - string args = GetAttributeArguments(attributeItem, "="); + string args = GetAttributeArguments(attributeItem, "=", QuoteSnippetStringCSharp); if (args == null) return null; code.AppendLine(string.Format($"[assembly: {attributeItem.ItemSpec}({args})]")); @@ -326,7 +326,7 @@ private string GenerateCodeCoreClr(out string extension) foreach (ITaskItem attributeItem in AssemblyAttributes) { - string args = GetAttributeArguments(attributeItem, ":="); + string args = GetAttributeArguments(attributeItem, ":=", QuoteSnippetStringVisualBasic); if (args == null) return null; code.AppendLine(string.Format($"")); @@ -343,7 +343,7 @@ private string GenerateCodeCoreClr(out string extension) return haveGeneratedContent ? code.ToString() : string.Empty; } - private string GetAttributeArguments(ITaskItem attributeItem, string namedArgumentString) + private string GetAttributeArguments(ITaskItem attributeItem, string namedArgumentString, Func quoteString) { // Some attributes only allow positional constructor arguments, or the user may just prefer them. // To set those, use metadata names like "_Parameter1", "_Parameter2" etc. @@ -357,7 +357,7 @@ private string GetAttributeArguments(ITaskItem attributeItem, string namedArgume foreach (DictionaryEntry entry in customMetadata) { string name = (string) entry.Key; - string value = entry.Value is string ? $@"""{entry.Value}""" : entry.Value.ToString(); + string value = entry.Value is string ? quoteString(entry.Value.ToString()) : entry.Value.ToString(); if (name.StartsWith("_Parameter", StringComparison.OrdinalIgnoreCase)) { @@ -404,5 +404,214 @@ private string GetAttributeArguments(ITaskItem attributeItem, string namedArgume return string.Join(", ", orderedParameters.Union(namedParameters).Where(p => !string.IsNullOrWhiteSpace(p))); } + + private const int MaxLineLength = 80; + + // copied from Microsoft.CSharp.CSharpCodeProvider + private string QuoteSnippetStringCSharp(string value) + { + // If the string is short, use C style quoting (e.g "\r\n") + // Also do it if it is too long to fit in one line + // If the string contains '\0', verbatim style won't work. + if (value.Length < 256 || value.Length > 1500 || (value.IndexOf('\0') != -1)) + return QuoteSnippetStringCStyle(value); + + // Otherwise, use 'verbatim' style quoting (e.g. @"foo") + return QuoteSnippetStringVerbatimStyle(value); + } + + // copied from Microsoft.CSharp.CSharpCodeProvider + private string QuoteSnippetStringCStyle(string value) + { + StringBuilder b = new StringBuilder(value.Length + 5); + + b.Append("\""); + + int i = 0; + while (i < value.Length) + { + switch (value[i]) + { + case '\r': + b.Append("\\r"); + break; + case '\t': + b.Append("\\t"); + break; + case '\"': + b.Append("\\\""); + break; + case '\'': + b.Append("\\\'"); + break; + case '\\': + b.Append("\\\\"); + break; + case '\0': + b.Append("\\0"); + break; + case '\n': + b.Append("\\n"); + break; + case '\u2028': + case '\u2029': + b.Append("\\n"); + break; + + default: + b.Append(value[i]); + break; + } + + if (i > 0 && i%MaxLineLength == 0) + { + // + // If current character is a high surrogate and the following + // character is a low surrogate, don't break them. + // Otherwise when we write the string to a file, we might lose + // the characters. + // + if (Char.IsHighSurrogate(value[i]) + && (i < value.Length - 1) + && Char.IsLowSurrogate(value[i + 1])) + { + b.Append(value[++i]); + } + + b.Append("\" +"); + b.Append(Environment.NewLine); + b.Append('\"'); + } + ++i; + } + + b.Append("\""); + + return b.ToString(); + } + + // copied from Microsoft.CSharp.CSharpCodeProvider + private string QuoteSnippetStringVerbatimStyle(string value) + { + StringBuilder b = new StringBuilder(value.Length + 5); + + b.Append("@\""); + + for (int i = 0; i < value.Length; i++) + { + if (value[i] == '\"') + b.Append("\"\""); + else + b.Append(value[i]); + } + + b.Append("\""); + + return b.ToString(); + } + + // copied from Microsoft.VisualBasic.VBCodeProvider + private string QuoteSnippetStringVisualBasic(string value) + { + StringBuilder b = new StringBuilder(value.Length + 5); + + bool fInDoubleQuotes = true; + + b.Append("\""); + + int i = 0; + while (i < value.Length) + { + char ch = value[i]; + switch (ch) + { + case '\"': + // These are the inward sloping quotes used by default in some cultures like CHS. + // VBC.EXE does a mapping ANSI that results in it treating these as syntactically equivalent to a + // regular double quote. + case '\u201C': + case '\u201D': + case '\uFF02': + EnsureInDoubleQuotes(ref fInDoubleQuotes, b); + b.Append(ch); + b.Append(ch); + break; + case '\r': + EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b); + if (i < value.Length - 1 && value[i + 1] == '\n') + { + b.Append("&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10)"); + i++; + } + else + { + b.Append("&Global.Microsoft.VisualBasic.ChrW(13)"); + } + break; + case '\t': + EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b); + b.Append("&Global.Microsoft.VisualBasic.ChrW(9)"); + break; + case '\0': + EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b); + b.Append("&Global.Microsoft.VisualBasic.ChrW(0)"); + break; + case '\n': + case '\u2028': + case '\u2029': + EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b); + b.Append("&Global.Microsoft.VisualBasic.ChrW(10)"); + break; + default: + EnsureInDoubleQuotes(ref fInDoubleQuotes, b); + b.Append(value[i]); + break; + } + + if (i > 0 && i%MaxLineLength == 0) + { + // + // If current character is a high surrogate and the following + // character is a low surrogate, don't break them. + // Otherwise when we write the string to a file, we might lose + // the characters. + // + if (Char.IsHighSurrogate(value[i]) + && (i < value.Length - 1) + && Char.IsLowSurrogate(value[i + 1])) + { + b.Append(value[++i]); + } + + if (fInDoubleQuotes) + b.Append("\""); + fInDoubleQuotes = true; + + b.Append("& _ "); + b.Append(Environment.NewLine); + b.Append('\"'); + } + ++i; + } + + if (fInDoubleQuotes) + b.Append("\""); + + return b.ToString(); + } + + private void EnsureNotInDoubleQuotes(ref bool fInDoubleQuotes, StringBuilder b) + { + if (!fInDoubleQuotes) return; + b.Append("\""); + fInDoubleQuotes = false; + } + + private void EnsureInDoubleQuotes(ref bool fInDoubleQuotes, StringBuilder b) + { + if (fInDoubleQuotes) return; + b.Append("&\""); + fInDoubleQuotes = true; + } } } From be8ee861d0d02c5d613bab5f49110aa86fbe8ac9 Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Tue, 22 Nov 2016 12:01:10 -0800 Subject: [PATCH 090/223] Fix issue with xml file line ending normalization (#1378) Background: * Previous implementation on Full Framework used XmlTextReader(path). This contained an issue with certain characters (#985) and was fixed by using streams (#1004). #1004 also changed from XmlTextReader to XmlReader. * XmlReader contains logic to normalize line endings. Internally, it sets the Normalize property to true and replaces (some? all?) \r\n with \n. This change switches implementation to use XmlTextReader. This class sets the internal Normalize to false and does not replace \r\n with \n. This fixes #1340. However, .NET Core does not ship with XmlTextReader, only XmlReader. #1340 still exists for .NET Core. --- .../Construction/ProjectElementContainer.cs | 4 +- .../Construction/ProjectRootElement.cs | 18 +-- .../XmlDocumentWithLocation.cs | 9 +- .../Evaluation/ProjectRootElementCache.cs | 10 +- src/XMakeBuildEngine/Microsoft.Build.csproj | 1 + .../WhiteSpacePreservation_Tests.cs | 99 ++++++++++++++--- .../Xml/XmlReaderExtension.cs | 104 ++++++++++++++++++ 7 files changed, 201 insertions(+), 44 deletions(-) create mode 100644 src/XMakeBuildEngine/Xml/XmlReaderExtension.cs diff --git a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs index 0243ad217bf..1cbaed63205 100644 --- a/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs +++ b/src/XMakeBuildEngine/Construction/ProjectElementContainer.cs @@ -530,8 +530,8 @@ internal void AddToXml(ProjectElement child) var parentIndentation = GetElementIndentation(XmlElement); - var leadingWhitespaceNode = XmlDocument.CreateWhitespace("\n" + parentIndentation + DEFAULT_INDENT); - var trailingWhiteSpaceNode = XmlDocument.CreateWhitespace("\n" + parentIndentation); + var leadingWhitespaceNode = XmlDocument.CreateWhitespace(Environment.NewLine + parentIndentation + DEFAULT_INDENT); + var trailingWhiteSpaceNode = XmlDocument.CreateWhitespace(Environment.NewLine + parentIndentation); XmlElement.InsertBefore(leadingWhitespaceNode, child.XmlElement); XmlElement.InsertAfter(trailingWhiteSpaceNode, child.XmlElement); diff --git a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs index 58a2cb655f2..9d9761a8b21 100644 --- a/src/XMakeBuildEngine/Construction/ProjectRootElement.cs +++ b/src/XMakeBuildEngine/Construction/ProjectRootElement.cs @@ -17,6 +17,7 @@ using Microsoft.Build.Evaluation; using Microsoft.Build.Framework; using Microsoft.Build.Shared; +using Microsoft.Build.Internal; #if (!STANDALONEBUILD) using Microsoft.Internal.Performance; #if MSBUILDENABLEVSPROFILING @@ -195,7 +196,7 @@ private ProjectRootElement(ProjectRootElementCache projectRootElementCache, NewP XmlReaderSettings xrs = new XmlReaderSettings(); xrs.DtdProcessing = DtdProcessing.Ignore; - + var emptyProjectFile = string.Format(EmptyProjectFileContent, (projectFileOptions & NewProjectFileOptions.IncludeXmlDeclaration) != 0 ? EmptyProjectFileXmlDeclaration : string.Empty, (projectFileOptions & NewProjectFileOptions.IncludeToolsVersion) != 0 ? EmptyProjectFileToolsVersion : string.Empty, @@ -2038,19 +2039,10 @@ private XmlDocumentWithLocation LoadDocument(string fullPath, bool preserveForma string beginProjectLoad = String.Format(CultureInfo.CurrentCulture, "Load Project {0} From File - Start", fullPath); DataCollection.CommentMarkProfile(8806, beginProjectLoad); #endif - - XmlReaderSettings dtdSettings = new XmlReaderSettings(); - dtdSettings.DtdProcessing = DtdProcessing.Ignore; - - using (var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read)) - using (var stream2 = new StreamReader(stream, Encoding.UTF8, true)) - using (XmlReader xtr = XmlReader.Create(stream2, dtdSettings)) + using (var xtr = XmlReaderExtension.Create(fullPath)) { - // Start the reader so it has an idea of what the encoding is. - xtr.Read(); - var encoding = xtr.GetAttribute("encoding"); - _encoding = !string.IsNullOrEmpty(encoding) ? Encoding.GetEncoding(encoding) : stream2.CurrentEncoding; - document.Load(xtr); + _encoding = xtr.Encoding; + document.Load(xtr.Reader); } document.FullPath = fullPath; diff --git a/src/XMakeBuildEngine/ElementLocation/XmlDocumentWithLocation.cs b/src/XMakeBuildEngine/ElementLocation/XmlDocumentWithLocation.cs index 5b4a59cb3bc..4d16e3040e2 100644 --- a/src/XMakeBuildEngine/ElementLocation/XmlDocumentWithLocation.cs +++ b/src/XMakeBuildEngine/ElementLocation/XmlDocumentWithLocation.cs @@ -170,14 +170,9 @@ public override void Load(string fullPath) _fullPath = fullPath; - // For security purposes we need to disable DTD processing when loading an XML file - XmlReaderSettings rs = new XmlReaderSettings(); - rs.DtdProcessing = DtdProcessing.Ignore; - - using (var stream = new StreamReader(fullPath)) - using(XmlReader xmlReader = XmlReader.Create(stream, rs)) + using(var xtr = XmlReaderExtension.Create(fullPath)) { - this.Load(xmlReader); + this.Load(xtr.Reader); } } #endif diff --git a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs index a9c877448b7..7c751cd74b9 100644 --- a/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs +++ b/src/XMakeBuildEngine/Evaluation/ProjectRootElementCache.cs @@ -19,7 +19,7 @@ using System.Diagnostics; using System.Globalization; using Microsoft.Build.BackEnd; - +using Microsoft.Build.Internal; using OutOfProcNode = Microsoft.Build.Execution.OutOfProcNode; namespace Microsoft.Build.Evaluation @@ -238,13 +238,9 @@ internal ProjectRootElement Get(string projectFile, OpenProjectRootElement openP XmlDocument document = new XmlDocument(); document.PreserveWhitespace = projectRootElement.XmlDocument.PreserveWhitespace; - XmlReaderSettings dtdSettings = new XmlReaderSettings(); - dtdSettings.DtdProcessing = DtdProcessing.Ignore; - - using (var stream = new FileStream(projectRootElement.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read)) - using (XmlReader xtr = XmlReader.Create(stream, dtdSettings)) + using (var xtr = XmlReaderExtension.Create(projectRootElement.FullPath)) { - document.Load(xtr); + document.Load(xtr.Reader); } string diskContent = document.OuterXml; diff --git a/src/XMakeBuildEngine/Microsoft.Build.csproj b/src/XMakeBuildEngine/Microsoft.Build.csproj index c42f2e705b0..bfe246912b2 100644 --- a/src/XMakeBuildEngine/Microsoft.Build.csproj +++ b/src/XMakeBuildEngine/Microsoft.Build.csproj @@ -595,6 +595,7 @@ true + SharedUtilities\AssemblyLoadInfo.cs true diff --git a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs index 2b612dcc3a4..9e78e394ee8 100644 --- a/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs +++ b/src/XMakeBuildEngine/UnitTestsPublicOM/Construction/WhiteSpacePreservation_Tests.cs @@ -7,12 +7,14 @@ using System; using System.IO; -using System.Xml; using Microsoft.Build.Construction; using Xunit; using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; using Microsoft.Build.Evaluation; +using Microsoft.Build.Shared; namespace Microsoft.Build.UnitTests.OM.Construction @@ -411,32 +413,99 @@ public void AddChildWithExistingSiblingsViaInsertBeforeChild(string projectConte }); } - private void AssertWhiteSpacePreservation(string projectContents, string updatedProject, - Action act) + [Fact] + public void VerifySaveProjectContainsCorrectLineEndings() { - var projectElement = - ProjectRootElement.Create( - XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(projectContents))), - ProjectCollection.GlobalProjectCollection, - true); + var project = @" + + + - act(projectElement, project); + + +"; + string expected = @" + + + - var writer = new StringWriter(); - project.Save(writer); + + + + +"; + // Use existing test to add a sibling and verify the output is as expected (including comments) + AddChildWithExistingSiblingsViaInsertBeforeChild(project, expected); + } + + private void AssertWhiteSpacePreservation(string projectContents, string updatedProject, + Action act) + { + // Note: This test will write the project file to disk rather than using in-memory streams. + // Using streams can cause issues with CRLF characters being replaced by LF going in to + // ProjectRootElement. Saving to disk mimics the real-world behavior so we can specifically + // test issues with CRLF characters being normalized. Related issue: #1340 + var file = FileUtilities.GetTemporaryFile(); + var expected = ObjectModelHelpers.CleanupFileContents(updatedProject); + string actual; + + try + { + // Write the projectConents to disk and load it + File.WriteAllText(file, ObjectModelHelpers.CleanupFileContents(projectContents)); + var projectElement = ProjectRootElement.Open(file, ProjectCollection.GlobalProjectCollection, true); + var project = new Project(projectElement); + + act(projectElement, project); + + // Write the project to a UTF8 string writer to compare against + var writer = new EncodingStringWriter(); + project.Save(writer); + actual = writer.ToString(); + } + finally + { + FileUtilities.DeleteNoThrow(file); + } VerifyAssertLineByLine(expected, actual); + +#if FEATURE_XMLTEXTREADER + VerifyLineEndings(actual); +#endif } private void VerifyAssertLineByLine(string expected, string actual) { Helpers.VerifyAssertLineByLine(expected, actual, false); } + + /// + /// Ensure that all line-endings in the save result are correct for the current OS + /// + /// Project file contents after save. + private void VerifyLineEndings(string projectResults) + { + if (Environment.NewLine.Length == 2) + { + // Windows, ensure that \n doesn't exist by itself + var crlfCount = Regex.Matches(projectResults, @"\r\n", RegexOptions.Multiline).Count; + var nlCount = Regex.Matches(projectResults, @"\n").Count; + + // Compare number of \r\n to number of \n, they should be equal. + Assert.Equal(crlfCount, nlCount); + } + else + { + // Ensure we did not add \r\n + Assert.Equal(0, Regex.Matches(projectResults, @"\r\n", RegexOptions.Multiline).Count); + } + } } } diff --git a/src/XMakeBuildEngine/Xml/XmlReaderExtension.cs b/src/XMakeBuildEngine/Xml/XmlReaderExtension.cs new file mode 100644 index 00000000000..7323378947c --- /dev/null +++ b/src/XMakeBuildEngine/Xml/XmlReaderExtension.cs @@ -0,0 +1,104 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Xml; + +namespace Microsoft.Build.Internal +{ + /// + /// Disposable helper class to wrap XmlReader / XmlTextReader functionality. + /// + internal class XmlReaderExtension : IDisposable + { + /// + /// Creates an XmlReaderExtension with handle to an XmlReader. + /// + /// Path to the file on disk. + /// Disposable XmlReaderExtenion object. + internal static XmlReaderExtension Create(string filePath) + { + return new XmlReaderExtension(filePath); + } + + private readonly Encoding _encoding; + private readonly Stream _stream; + private readonly StreamReader _streamReader; + + private XmlReaderExtension(string file) + { + try + { + _stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); + _streamReader = new StreamReader(_stream, Encoding.UTF8, true); + Reader = GetXmlReader(_streamReader, out _encoding); + + // Override detected encoding if xml encoding attribute is specified + var encodingAttribute = Reader.GetAttribute("encoding"); + _encoding = !string.IsNullOrEmpty(encodingAttribute) + ? Encoding.GetEncoding(encodingAttribute) + : _encoding; + } + catch + { + // GetXmlReader calls Read() to get Encoding and can throw. If it does, close + // the streams as needed. + Dispose(); + throw; + } + } + + internal XmlReader Reader { get; } + + internal Encoding Encoding => _encoding; + + public void Dispose() + { + Reader?.Dispose(); + _streamReader?.Dispose(); + _stream?.Dispose(); + } + + private static XmlReader GetXmlReader(StreamReader input, out Encoding encoding) + { +#if FEATURE_XMLTEXTREADER + var reader = new XmlTextReader(input) { DtdProcessing = DtdProcessing.Ignore }; + + reader.Read(); + encoding = input.CurrentEncoding; + + return reader; +#else + var xr = XmlReader.Create(input, new XmlReaderSettings {DtdProcessing = DtdProcessing.Ignore}); + + // Set Normalization = false if possible. Without this, certain line endings will be normalized + // with \n (specifically in XML comments). Does not throw if if type or property is not found. + // This issue does not apply to XmlTextReader (above) which is not shipped with .NET Core yet. + + // NOTE: This doesn't work in .NET Core. + //var xmlReaderType = typeof(XmlReader).GetTypeInfo().Assembly.GetType("System.Xml.XmlTextReaderImpl"); + + //// Works in full framework, not in .NET Core + //var normalization = xmlReaderType?.GetProperty("Normalization", BindingFlags.Instance | BindingFlags.NonPublic); + //normalization?.SetValue(xr, false); + + //// Set _normalize = false, and _ps.eolNormalized = true + //var normalizationMember = xmlReaderType?.GetField("_normalize", BindingFlags.Instance | BindingFlags.NonPublic); + //normalizationMember?.SetValue(xr, false); + + //var psField = xmlReaderType.GetField("_ps", BindingFlags.Instance | BindingFlags.NonPublic); + //var ps = psField.GetValue(xr); + + //var eolField = ps.GetType().GetField("eolNormalized", BindingFlags.Instance | BindingFlags.NonPublic); + //eolField.SetValue(ps, true); + + xr.Read(); + encoding = input.CurrentEncoding; + + return xr; +#endif + } + } +} From 0d8015abaf713e7bc8b9033b52a524b5f58dc92b Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 22 Nov 2016 12:01:46 -0800 Subject: [PATCH 091/223] Signing specific loc targets use DependsOnTargets (#1383) Because AfterTargets does not guarantee that the target will be executed after its AfterTargets, but DependsOnTargets does. --- src/UpdateLocalizedResources.targets | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/UpdateLocalizedResources.targets b/src/UpdateLocalizedResources.targets index e0061114f26..ad6cb56bc02 100644 --- a/src/UpdateLocalizedResources.targets +++ b/src/UpdateLocalizedResources.targets @@ -111,7 +111,7 @@ --> From fbba93c46c3603d4eef64cbfe5aaf86a8e6b2e88 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 22 Nov 2016 12:03:03 -0800 Subject: [PATCH 092/223] Compare strong names only when both assemblies are strong named (#1374) * Compare strong names only when both assemblies are strong named Fixes #1314 --- src/XMakeTasks/NativeMethods.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/XMakeTasks/NativeMethods.cs b/src/XMakeTasks/NativeMethods.cs index 686243abf1b..78edfb81a46 100644 --- a/src/XMakeTasks/NativeMethods.cs +++ b/src/XMakeTasks/NativeMethods.cs @@ -1171,14 +1171,9 @@ internal static void CompareAssemblyIdentity( // Based on coreclr baseassemblyspec.cpp (https://github.com/dotnet/coreclr/blob/4cf8a6b082d9bb1789facd996d8265d3908757b2/src/vm/baseassemblyspec.cpp#L330) private static bool RefMatchesDef(AssemblyName @ref, AssemblyName def) { - var refPkt = @ref.GetPublicKeyToken(); - bool refStrongNamed = refPkt != null && refPkt.Length != 0; - if (refStrongNamed) + if (IsStrongNamed(@ref)) { - var defPkt = def.GetPublicKeyToken(); - bool defStrongNamed = defPkt != null && defPkt.Length != 0; - - return CompareRefToDef(@ref, def); + return IsStrongNamed(def) && CompareRefToDef(@ref, def); } else { @@ -1186,6 +1181,13 @@ private static bool RefMatchesDef(AssemblyName @ref, AssemblyName def) } } + // Based on coreclr baseassemblyspec.inl (https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/baseassemblyspec.inl#L679-L683) + private static bool IsStrongNamed(AssemblyName assembly) + { + var refPkt = assembly.GetPublicKeyToken(); + return refPkt != null && refPkt.Length != 0; + } + // Based on https://github.com/dotnet/coreclr/blob/4cf8a6b082d9bb1789facd996d8265d3908757b2/src/vm/baseassemblyspec.cpp#L241 private static bool CompareRefToDef(AssemblyName @ref, AssemblyName def) { From ad50a5356f1be61a6ac2e740a6a1c10618112ec4 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 1 Apr 2016 11:40:09 -0400 Subject: [PATCH 093/223] Enable Binary serialization for Mono builds also. This enables resgen caches. Also mark Microsoft.Build.UnitTests.GenerateResource*_Tests.InProc.PropertyErrors.StateFileUnwritable as windows only. This test creates a read-only (removes the write permission) state file and then expects the task to fail while trying to write to such a file. But the code[1] (`GenerateResource.WriteStateFile -> ResGenDependencies.SerializeCache -> StateFileBase.SerializeCache`) that does this, deletes the file before writing to it. - On Unix, it is legal to delete such a file. So, subsequently trying to write to that path succeeds and the test fails - IIUC, trying to delete or write to this read-only fails on windows, thus satisfying the test. 1. https://github.com/Microsoft/msbuild/blob/xplat/src/XMakeTasks/StateFileBase.cs#L40 --- dir.props | 2 +- src/XMakeBuildEngine/BackEnd/Shared/BuildAbortedException.cs | 2 ++ src/XMakeBuildEngine/Errors/InternalLoggerException.cs | 2 ++ src/XMakeBuildEngine/Errors/InvalidProjectFileException.cs | 2 ++ .../Errors/InvalidToolsetDefinitionException.cs | 2 ++ src/XMakeTasks/UnitTests/GenerateResourceOutOfProc_Tests.cs | 2 +- src/XMakeTasks/UnitTests/GenerateResource_Tests.cs | 1 + 7 files changed, 11 insertions(+), 2 deletions(-) diff --git a/dir.props b/dir.props index 407c0c2ffda..3dd4a197d90 100644 --- a/dir.props +++ b/dir.props @@ -272,7 +272,7 @@ $(DefineConstants);FEATURE_ASSEMBLY_LOCATION $(DefineConstants);FEATURE_ASSEMBLYNAME_CULTUREINFO $(DefineConstants);FEATURE_ASSEMBLYNAME_CLONE - $(DefineConstants);FEATURE_BINARY_SERIALIZATION + $(DefineConstants);FEATURE_BINARY_SERIALIZATION $(DefineConstants);FEATURE_COM_INTEROP $(DefineConstants);FEATURE_COMPILE_IN_TESTS $(DefineConstants);FEATURE_CONSOLE_BUFFERWIDTH diff --git a/src/XMakeBuildEngine/BackEnd/Shared/BuildAbortedException.cs b/src/XMakeBuildEngine/BackEnd/Shared/BuildAbortedException.cs index ee481f15766..6172227bd5b 100644 --- a/src/XMakeBuildEngine/BackEnd/Shared/BuildAbortedException.cs +++ b/src/XMakeBuildEngine/BackEnd/Shared/BuildAbortedException.cs @@ -96,7 +96,9 @@ public string ErrorCode /// ISerializable method which we must override since Exception implements this interface /// If we ever add new members to this class, we'll need to update this. /// +#if FEATURE_SECURITY_PERMISSIONS [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] +#endif override public void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/XMakeBuildEngine/Errors/InternalLoggerException.cs b/src/XMakeBuildEngine/Errors/InternalLoggerException.cs index 3d8a6604b6a..4d3493e51e6 100644 --- a/src/XMakeBuildEngine/Errors/InternalLoggerException.cs +++ b/src/XMakeBuildEngine/Errors/InternalLoggerException.cs @@ -126,7 +126,9 @@ private InternalLoggerException(SerializationInfo info, StreamingContext context ///
/// /// +#if FEATURE_SECURITY_PERMISSIONS [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] +#endif override public void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/XMakeBuildEngine/Errors/InvalidProjectFileException.cs b/src/XMakeBuildEngine/Errors/InvalidProjectFileException.cs index 555f234de20..e43b6982574 100644 --- a/src/XMakeBuildEngine/Errors/InvalidProjectFileException.cs +++ b/src/XMakeBuildEngine/Errors/InvalidProjectFileException.cs @@ -108,7 +108,9 @@ private InvalidProjectFileException(SerializationInfo info, StreamingContext con ///