We are working with some huge Visual Studio 2010 solutions with a great many static library projects shared between the two. After building either of these solutions the other solution will complain that many (but not all) of the projects are out of date, though actually building naturally does next to nothing and is almost instant.
After following the steps on this question on debugging MSBuild project dependencies I can see many lines of the following messages indicating that the projects are considered out of date because of a "different evaluation fingerprint":
[8444] Project not up to date because the last build has different evaluation fingerprint.
[8444] devenv.exe Information: 0 :
[8444] Project not up to date because the last build has different evaluation fingerprint.
[8444] devenv.exe Information: 0 :
I have come up completely blank while trying to find out what an MSBuild evaluation fingerprint is, where they come from, or what could cause them to be off like this.
Creating new project files is a non-starter given their shear size, the complexity of their configuration requirements, and the lack of enough time in our schedule for cleaning up small annoyances like this.
What are MSBuild evaluation fingerprints and how are they determined?
I assume you are using C++?
The issue is that the solution directory which was used to build the project is saved to to "*.lastbuildstate" file.
It's just a plain text file which look like:
#v4.0:v100:false
Debug|Win32|C:\MyPath\ToSolution\|
The second line is used as project evaluation fingerprint.
First line consist of following information (see line 246 in Microsoft.CppBuild.targets)
#$(TargetFrameworkVersion):$(PlatformToolSet):$(EnableManagedIncrementalBuild)
Second line (see line 38 in Microsoft.CppBuild.targets)
$(Configuration)|$(Platform)|$(SolutionDir)|
Microsoft.CppBuild.targets can be found at %ProgramFiles (x86)%\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets
Maybe its possible to modify / extend the MSBuild scripts not to use the SolutionDir in the lastbuildstate file.
Related
Been trying to set up configuration-specific variants of resource .resw files in my project, so I could have have different resource string values in Debug and in Release (and in other configurations).
There are standard facilities in VS to have files conditionally included or excluded from build depending on selected Configuration. I have set up file properties to be Content=Yes and Excluded From Build=No for a file that must be included in a configuration, and the other way around for the other file.
The variants appear as expected in the IDE - only one matching current configuration is active, and another one is shown with Content=False in the Properties view, and with a red icon in the files list. The vcxproj also contains correct PRIResource nodes for .resw files with DeploymentContent and ExcludedFromBuild set:
<ItemGroup>
<PRIResource Include="Debug\Strings.resw">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
<DeploymentContent...
Building this project however fails with a message
error PRI277: 0xdef00532 - Conflicting values for resource 'resw
name/resource name'
Examining intermediate files reveals that both .resw variants are listed in resources.resfiles that is then fed into MakePri.exe . The ExcludedFromBuild setting appears to be ignored.
How would I get this to work? Is there a special way to control the inclusion of resw files? Maybe a different approach to having string variants altogether?
There are apparently "qualifiers" for organizing resource variants, and a naming scheme (https://learn.microsoft.com/en-us/windows/uwp/app-resources/tailor-resources-lang-scale-contrast). There is even a "Configuration" qualifier, though it is not entirely clear which configuration that is, and where at run time I am supposed to take an identifier to select a resource variant I want.
Adding this as an answer for the sake of completeness, as this is relevant and might even be useful to someone. But I am not happy with project configuration concerns being displaced to runtime, with unneeded and possibly sensitive values being added to the package. So I decided to force-emulate ExcludedFromBuild and am picking and copying the single .resw variant I need into build via a Custom Build Step. Shout out to whoever is responsible for this awkward mess at Microsoft.
Is it possible to have CMake-QT generate individual .obj files during AUTOMOC thus allowing for Whole Program Optimization during link time?
If yes - how?
TLDR - Pseudologic:
CMAKE_AUTOMOC ON => [mocs_compilation.obj != (moc_a.obj moc_b.obj)] => linker(one_instead_of_many.obj)? dependency missing : no dependency missing
Situation
When I set CMAKE_AUTOMOC ON in a Project, a file named mocs_compilation.cpp is created in the <project_name>_autogen folder which includes the AUTOMOCed files and thus creates one object instead of several individual files.
Why I think it is important?
Using Link Time Code Generation/Whole Program Optimization in Visual Studio 2015 our build (with custom moc-generation steps and individual .boj files) works without problems - possibly getting rid of unnecessary .obj files thus even eliminating a dependency to an extra LIB/DLL.
PS: By the way I really think there should be a cmake-qt tag if anyone cares to create one.
Seems it is a general issue with CMake:
https://gitlab.kitware.com/cmake/cmake/issues/17277
I want to be able to change my feature file from outside visual studio and have the updated feature file picked up, for subsequent test execution, without compilation of my test project. Is it possible to do this? Can someone help to specify the exact steps needed to do this? I am using MsTest.
Here are the steps I followed, but I get the message "No tests to execute." every time:
Change Test Project file (.csproj) as mentioned here
Build the Test DLL from Visual Studio
Kept the feature file in a folder FeatureFiles, under the Test release folder
Changed the feature file in Notepad
Used the Specflow generate all command, to regenerate the tests:
Specflow generateall TestProject.csproj /force /verbose
Create the report:
mstest /testcontainer:Test.Dll /resultsfile:TestResult.trx
A similar question was asked earlier, and I am following the same steps as mentioned by Marcus there.
Update
Here is what I would like to do. Considering the following .feature file:
Feature: Score Calculation
As a player
I want the system to calculate my total score
So that I know my performance
Scenario: Another beginners game
Given a new bowling game
When I roll the following series: 2,7,3,4,1,1,5,1,1,1,1,1,1,1,1,1,1,1,5,1
Then my total score should be 40
In the above feature file, I would like to change the data series of numbers and change the total score and run the same test again to check if it runs fine and I get a correct score
If you only want to change the data for a test, then go with a CSV file that you save inside your VS project. Then in a Given statement open that file, parse it and save it to the ScenarioContext.Current object for use in subsequent steps.
I can't see how what you want is possible. SpecFlow generates unit test classes from the feature file. These unit test classes MUST be compiled before they can be run, the same as ANY code change.
You are getting a 'no tests to execute' because you are still running against the old version of the dll, which doesn't contain any tests because you have not rebuilt it with the new code that specflow has generated.
From what is stated in the linked question it seems they are saying that some changes may be able to be run without recompiling, but honestly I cannot see how that is possible, and even if some feature file changes were possible I imagine that the solution would be specific to certain unit test frameworks and unsupported.
EDIT
When I look at the generated feature.cs file you have this:
[Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
[Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Another beginners game")]
[Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("FeatureTitle", "Score Calculation")]
public virtual void AnotherBeginnersGame()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Another beginners game", ((string[])(null)));
#line 5
this.ScenarioSetup(scenarioInfo);
#line 6
testRunner.Given("a new bowling game", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
#line 7
testRunner.When("I roll the following series: 2,7,3,4,1,1,5,1,1,1,1,1,1,1,1,1,1,1,5,1", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 8
testRunner.Then("my total score should be 40", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line hidden
this.ScenarioCleanup();
}
As you can see this contains your actual list of values and expected result in the code
This surely implies that you can't change the feature file and have the test update without recompiling, as otherwise any changes to the cs file will not be reflected in the actual dll that you are running.
Sadly, a project that I have been working on lately has a large amount of copy-and-paste code, even within single files. Are there any tools or techniques that can detect duplication or near-duplication within a single file? I have Beyond Compare 3 and it works well for comparing separate files, but I am at a loss for comparing single files.
Thanks in advance.
Edit:
Thanks for all the great tools! I'll definitely check them out.
This project is an ASP.NET/C# project, but I work with a variety of languages including Java; I'm interested in what tools are best (for any language) to remove duplication.
Check out Atomiq. It finds code that is duplicate that is prime for extracting to one location.
http://www.getatomiq.com/
If you're using Eclipse, you can use the copy paste detector (CPD) https://olex.openlogic.com/packages/cpd.
You don't say what language you are using, which is going to affect what tools you can use.
For Python there is CloneDigger. It also supports Java but I have not tried that. It can find code duplication both with a single file and between files, and gives you the result as a diff-like report in HTML.
See SD CloneDR, a tool for detecting copy-paste-edit code within and across multiple files. It detects exact copyies, copies that have been reformatted, and near-miss copies with different identifiers, literals, and even different seqeunces of statements.
The CloneDR handles many languages, including Java (1.4,1.5,1.6) and C# especially up to C#4.0. You can see sample clone detection reports at the website, also including one for C#.
Resharper does this automagically - it suggests when it thinks code should be extracted into a method, and will do the extraction for you
Check out PMD , once you have configured it (which is tad simple) you can run its copy paste detector to find duplicate code.
One with some Office skills can do following sequence in 1 minute:
use ordinary formatter to unify the code style, preferably without line wrapping
feed the code text into Microsoft Excel as a single column
search and replace all dual spaces with single one and do other replacements
sort column
At this point the keywords for duplicates will be already well detected. But to go further
add comparator formula to 2nd column and counter to 3rd
copy and paste values again, sort and see the most repetitive lines
There is an analysis tool, called Simian, which I haven't yet tried. Supposedly it can be run on any kind of text and point out duplicated items. It can be used via a command line interface.
Another option similar to those above, but with a different tool chain: https://www.npmjs.com/package/jscpd
So the directory layout would look like:
Visual Studio 2008\
Projects\
MyCompany.MySolution\
Models\
Models.Tests\
Services\
Services.Tests\
UI\
etc..
rather than
Visual Studio 2008\
Projects\
MyCompany.MySolution\
MyCompany.MySolution.Models\
MyCompany.MySolution.Models.Tests\
MyCompany.MySolution.Services\
MyCompany.MySolution.Services.Tests\
MyCompany.MySolution.UI\
etc..
The namespace for each project would of course be MyCompany.MySolution.MyProject.
The question was generated by concern over maximum character path limit of 260. It seems better to me to do whatever I can to be able to freely name my projects and solutions; however, I don't want to run into an unforeseen mess.
If you run up the character path limit, you have to do something and you have to get creative. In this case, it is reasonable to alter the filename to a less-than ideal convention. Demoting the project names from including the complete namespace to merely the project name seems reasonable. Otherwise, consider using acronyms whenever you can. This approach will help a bunch.