warning MSB8012 : make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile) - visual-studio-2010

I am getting the following error when building my code.
C:\Program Files
(x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(990,5):
warning MSB8012:
TargetPath(E:\Study\FWIF\demola\ext-libs\libcommoncpp2-1.6.0\w32\Debug\ccgnu2.dll)
does not match the Linker's OutputFile property value
g\CapeCommon14.dll). This may cause your project to build incorrectly.
To correct this, please make sure that $(OutDir), $(TargetName) and
$(TargetExt) property values match the value specified in
%(Link.OutputFile).
I hope that some one will know what to do.

Did you upgrade a project to Visual Studio 2010 from a previous version? If so, this is a well-known issue.
Visual Studio 2010 C++ Project Upgrade Guide
http://blogs.msdn.com/b/vcblog/archive/2010/03/02/visual-studio-2010-c-project-upgrade-guide.aspx
Warnings during upgrade
Here are some of the common warnings that you may run into during conversion:
1) Linker output directory
One of the warnings you may see when upgrading you applications is MSB8012: $(TargetPath) and Linker’s OutputFile property value does not match:
MSB8012: $(TargetExt) ('.dll') does not match the Linker's OutputFile property value 'C:\foo\Debug\MFCActiveX.ocx' ('.ocx') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetExt) property value matches the value specified in %(Link.OutputFile).
MSB8012: $(TargetPath) ('C:\foo\Debug\MFCActiveX.dll') does not match the Linker's OutputFile property value 'C:\foo\Debug\MFCActiveX.ocx' ('C:\foo\Debug\MFCActiveX.ocx') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Link.OutputFile is the value defined at Linker -> General -> Output File on the property page. By default, its value is $(OutDir)$(TargetName)$(TargetExt), which is the same as the value of $(TargetPath). When we convert an application from a previous version, however, there is not an easy way for conversion to parse Link.OutputFile to figure out what exactly the values are for $(TargetName) and $(TargetExt), as different customers may have formatted them in different ways. To work around that, we decided to preserve the value of Linker.OutputFile during conversion. After conversion, $(TargetName) will default to $(ProjectName). $(TargetExt) will default to the default extension for the application type: .dll for Dynamic Library, .lib for Static Library and .exe for Application. Link.OutputFile value will be preserved. Warning MSB8012 will be issued in the conversion log if Link.OutputFile and $(TargetPath) are not the same. You will get the same warnings when building the application.
$(OutDir), $(TargetName) and $(TargetExt) are exposed on the "General" property page, as "Output Directory", "Target Name", "Target Extension", respectively. You can manually change the values of these properties so that you no longer get the warning.
If your project produces Import Library (Linker -> Advanced -> Import Library), you may need to change the Output folder of the Import Library as well after conversion if the Linker output directory is not the default output directory. Otherwise, the generated import lib maybe in a different directory than the linker output.
Debugging.Command is set to default $(TargetPath) after conversion. You may need to make changes so that the right executable will be launched upon F5 (Debugging) or Ctrl + F5 (Start without debugging).

See also here Stackoverflow MSB8012.
What worked for me when converting a VS2008 C++ project to VS2012: right click the project in solution explorer, select properties, in the pop-up: configuration properties, linker, general. Select Output file on the right, this gives a drop-down, select inherent from parent or project defaults. Click apply. This gives the default linker setting: $(OutDir)$(TargetName)$(TargetExt). Re-build the project and the warning should no longer appear.

The same problem occured to me for debug DLLs, that I wanted to have a trailing "D" in the basename. For example, foo.dll (Release) but fooD.dll (Debug). When you refine the output name in the Linker settings of the Debug-Configuration -- the ugly MSB8012 warning occurs.
The only solution that works with Visual-Studio 2010 seems to be a Postbuild-Event for the Debug-Configuration:
#echo off
echo Copying $(OutDir)$(TargetName)$(TargetExt) as $(TargetName)D$(TargetExt)
copy /Y $(OutDir)$(TargetName)$(TargetExt) $(OutDir)$(TargetName)D$(TargetExt)

I had the scenario where my executable name was different than the project name AND I wanted it to build the executable/dll to a different location than where the project was located.
1)Change the default project name to be different.
General->TargetName
< my executable name>
2) Output to a different location where I want the executable to build.
General->OutputDirectory
< my new location goes here >
3) Update the Linker settings.
Linker->General
new value: $(OutDir)$(TargetName)$(TargetExt)
This takes on the new settings from 1 and 2.

I obtained the same error after converting from old project to VS 2010.
To fix this I created empty project of the same type (e.g. .dll, .lib, .exe).
Then I copied its default values in Project Propeties to my project for Output Directory, Intermediate directory and Output File

Goto Project->Properties->Configuration Properties -> Linker->General section
Specify 'Output File' as $(OutDir)$(TargetName)$(TargetExt)

I managed to fix a similar issue by editing the vcxproj file manually.
The OutDir and TargetName settings were at the bottom of the project file.
...
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(OUTPUT_DIRECTORY)\</OutDir>
<IntDir>$(ProjectDir)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
</Project>
Moving the block above the ClCompile block solved the issue.

I solved this by comparing the project to a very similar project that was working properly. All of the settings in the project properties matched but I found the following extra lines in the vcxproj file of the malfunctioning project:
<Lib>
<OutputFile>.\MCtlDrvX.lib</OutputFile>
</Lib>
I deleted them and the message went away and the output went to the directory specified in the project settings.

Related

How does VS 2019 select for which .asm file to create a listing file

I have a standard (?) project (vcxproj) with multiple .asm files in Visual Studio 2019 Community 16.6.
In Configuration properties->MASM I have not set anything
Still the .lst file is created for the project. So, there must be some "hidden" defaults somewhere. However, even if I set them explicitly - there is no setting as to for which .asm file the listing file should be created.
I could not find anything as to the default implicit behavior / explicit behavior of choice of one .asm file over another. Logically, it would be the file containing the entry point in x86-32bit "end main", but that's not the case. Also, is there a way to generate .lst next to the .obj file for all .asm files in a given project.
right for me:
Open Project ,
Create a file (*).asm AND write code
Go to Property of Project: ( note platform for correct in first line - for me: WIN32 )
Go to Microsoft Macro Assembler - Listing file - set Yes(/Sg) Enable Assembly Generated Code Listing
and set $(ProjectName).lst in Assembled Code Listing File
Go to property of file (*).asm do the same thing as above...
Thanks for watch

How does Visual Studio know my project is up to date so it can skip running MSBuild?

I have a custom MSBuild target included in my C++ project that produces a data file in the $(OutDir) folder for each item of a given item type. I have the item type hooked up with a property page schema so you can select it on files in the solution explorer and my target declares input and outputs so incremental builds work. I have also added my target to the $(BuildDependsOn) property so it is automatically evaluated during the Build target Visual Studio invokes.
Everything seems to work except for one thing: If I delete one of my output data files in the $(OutDir) and then build Visual Studio does nothing and says my project is up to date. If I delete the exe file the project produces or touch the modified time of one of the MSBuild scripts Visual Studio re-evaluates the targts and finds the output file is missing, causing it to be re-built using my target.
From the MSBuild diagnostic logging it seems like Visual Studio is internally maintaining some list of output files and input files that it checks to avoid evaluating the MSBuild script at all. How do I add my output files to this list?
MsBuild/VS indeed have a mechanism to determine what is up-to-date with respect to the input files, it revolves around an executable tracker.exe which scans .tlog files to figure out what a project's output files are. There might be more to it, and if you look around on the internet you can probably get more info about this.
But the thing is you don't really need to understand every single detail of it: you can find a simple usage example for it when inspecting how the built-in CustomBuildStep works and apply that to your case. I'll briefly explain how I got to this because I think it might be useful for you as well in dealing with msbuild questions like these.
If you add
<ItemDefinitionGroup>
<CustomBuildStep>
<Command>echo foo > $(OutDir)\foo.txt</Command>
<Outputs>$(OutDir)\foo.txt</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
either manually or via the project's property pages for Custom Build Step you'll see the beahviour is eactly what you need: if foo.txt is deleted a build will start, while a build is marked up-to-date if it is not (well, and when the rest of the outputs are also up-to-date).
Hence the key is to do what CustomBuildStep does under the hood, and figuring that out is just a matter of using your tool of choice to search all occurrences of CustomBuildStep in all files under C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120 (adjust path for platform/VS version used).
This leads us to Microsoft.CppCommon.Targets where the target named CustomBuildStep (mind you, that's the same name as the entry in the ItemDefinitionGroup above) invokes the actual CustomBuildStep command. It also has this particularily interesting bit:
<!-- Appended tlog to track custom build events -->
<WriteLinesToFile Encoding="Unicode"
File="$(TLogLocation)$(ProjectName).write.1u.tlog"
Lines="#(CustomBuildStep->'^%(Identity)');#(CustomBuildStep->MetaData('Outputs')->FullPath()->Distinct())"/>
So this writes the path of the Outputs to a .tlog file in the directory used by the tracker and makes it work as desired. Also see here for more information about the format.
tl;dr Use WriteLinesToFile to append full paths of your targets' outputs to a file like $(TLogLocation)$(ProjectName).write.1u.tlog. I'm saying like because write.tlog, write.u.tlog etc also work.
Visual Studio uses something called Visual Studio Common Project System (CPS) (https://github.com/Microsoft/VSProjectSystem) (VS 2017)
to manage projects, including build process.
Within CPS anything that implements IBuildUpToDateCheckProvider interface can be used
as a 'UpToDateChecker' for a project.
'UpToDateChecker' is invoked before invoking MsBuild. Its main purpose is to determine whether or not invoke MsBuild to build project, or to mark project as 'Up To Date' and skip msbuild all along.
This 'UpToDateChecker' is exactly what prints into diagnostic build output:
1>------ Up-To-Date check: Project: "ProjectName", Configuration:
Debug x86 ------ Project is not up-to-date: build input 'header.h' was
modified after build output 'a.out'. Input time: 12/27/2018 4:43:08
PM, Output time: 1/1/0001 2:00:00 AM
As for C++ Projects, for VS 2017 its default 'UpToDateChecker' is VCProjectBuildUpToDateCheck
( Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.dll ).
As starter, it looks into tlogs directory ( usually something like Debug\x86\.tlog) for these files:
.lastbuildstate
unsuccessfulbuild
all '.read..tlog' - input files, marked as 'build input' in diagnostic build output
all '.write..tlog' - output files, marked as 'build output' in diagnostic build output
There's actually more checks, but most fails occur when checking these 4 types
The original question here relates to C++ projects, but for anyone finding this while searching for information about modern (SDK-style) C#/VB/F# projects, you can customise Visual Studio's fast up-to-date check as described in this document:
https://github.com/dotnet/project-system/blob/master/docs/up-to-date-check.md
In a nutshell, you specify inputs and outputs as items:
UpToDateCheckInput — Describes an input file that MSBuild would not otherwise know about
UpToDateCheckBuilt — Describes an output file that MSBuild would not otherwise know about
It can be very helpful to increase the diagnostic logging level for the up-to-date check via this setting:
You can find out why a project is being rebuilt by enabling the verbosity of the fast up to date checker in the registry key:
New-ItemProperty `
-Name U2DCheckVerbosity `
-PropertyType DWORD -Value 1 `
-Path HKCU:\Software\Microsoft\VisualStudio\14.0\General -Force
You should be able to see in the build log messages like
Project 'Caliburn.Micro.Silverlight.Extensions' is not up to date. Project item 'C:\dev\projects\Caliburn.Micro.Silverlight.Extensions\NavigationBootstrapperSample.cs.pp' has 'Copy to Output Directory' attribute set to 'Copy always'.
[1] https://blogs.msdn.microsoft.com/kirillosenkov/2014/08/04/how-to-investigate-rebuilding-in-visual-studio-when-nothing-has-changed/
To enable logging for old-style projects (i.e. non-SDK-style projects, common in the .NET Framework era):
Open a "Developer Command Prompt" for the particular version of Visual Studio you are using.
Enter command:
vsregedit set "%cd%" HKCU General U2DCheckVerbosity dword 1
The message Set value for U2DCheckVerbosity should be displayed.
Run the same command with a 0 instead of a 1 to disable this logging.
More information at: https://github.com/dotnet/project-system/blob/main/docs/up-to-date-check.md#net-framework-projects

Output Path and MSBuild

I have a solution with 9 projects. All references in each project have their CopyLocal property set to False.
When I build it from VS, none of these referenced binaries are copyed to the output build directory. Similarly, when I build using msbuild, I only see the project binaries and no references.
However, when I specify an output path in the msbuild command, some references are copied and I don't know why? Is there some setting I am forgetting to set? Has anyone seen this before?
When you build your application without setting the OutDir property, the files are copied to the path specified in project properties (Build\Output path). After this, there is another step that copies the referenced project output (*.dll file) to the OutDir of your application (*.exe). But if you set CopyLocal to false, this last step doesn't happen. Like this:
ProjectEXE\OutDir = c:\a\bin
ProjectDLL\OutDir = c:\b\bin
Pay attention to the fact that the two OutDir are different (and differently specified in your projects properties).
But when you set the OutDir using the command-prompt, you are setting both OutDir parameters to the same path. Still there is no final copy of the DLL to the same directory of your application, except for the fact that it is the same location you built the DLL and EXE first time. Like this:
msbuild yourSolution.sln /p:OutDir="c:\a\bin\"
ProjectEXE\OutDir = c:\a\bin
ProjectDLL\OutDir = c:\a\bin

Missing header files for VTK

I installed Visual Studio 2010, Qt and Cmake. I configured them. Then I wanted to test by an example code. However, the program cannot find the header files. I searched on the internet and found that there might be a problem with the PATH.
Then, I followed this way that results in failure:
I wrote each folder name separately by putting semicolon between them to
Project > Properties > C/C++ > General > Additional Include Directories.
In this way, program found the header files but it gave me an error LNK1104. I think it happened because the Path for file name expands to more than 260 characters. I learned that from this site.
I tried to find one folder that I can write to PATH. I think it's lib file. But I could not find it.
what should I do to fix this problem?
Setting two values in visual studio will remove this error.
Go to Properties of the project -> C/C++ -> All Options -> Set the correct value for "Additional Options".
Go to Properties of the project -> Linker -> Input -> Set correct the value for "Additional Dependencies".
If you create the project using CMake, then these values will be setup automatically.

Copying Visual Studio project file(s) to output directory during build

When I build a Visual Studio project, the executable is written to the output directory specified in the projects Property Page.
I have a project that has some extra files (e.g., .ini file) that are used by the program.
How can I configure the project to copy the file to the output directory so that when the program runs, it has a copy of the other file in its CWD?
I checked the Property Page of the file and there was nothing useful other than an option to exclude it from the build (which is disabled), and the custom-build-tool command is empty (plus it is a plain-text file that does not need any processing).
For copying a files to the output directory in Visual Studio 2003 you could use Post-Build event:
Right click on the project->Properties
Common Properties->Build Events
Set Post-Build Event Command Line to:
xcopy /y $(ProjectDir)my_file.ini $(ProjectDir)$(OutDir)
OK and build!
Please try select the file in Solution Explorer. Then you should be able to see its properties in Properties window (press F4 if it is not visible). You will find there two properties:
"Build Action" and
"Copy to Output Directory"
Set "Build Action" to "Content", and then - select an appropriate value for "Copy to Output Directory" setting.
File properties window with "Build Action" and "Copy to Output Directory" settings
If the way above doesn't work for you, please read this post "Copy to output directory issue with .inf file". And have a look at this one then "Visual Studio: default build action for non-default file-types"
While I was searching the file’s Property Page for a build-action field, I had a thought: set the custom build step to copy the file (manually). This turned out to be easier than I thought. I had figured it would require using cmd or other external executable (xcopy, robocopy, etc.), but that is not necessary.
I set the Custom Build Step as follows:
Command Line : copy $(InputFileName) $(OutDir)
Description : Copying foobar...
Outputs : $(InputFileName)
Setting the outputs field (correctly) was critical in order to prevent VS from always thinking the project is out of date and requiring to be rebuilt (I’m not certain if it needs to be prefixed with $(OutDir)\).
It is reflected in the Output window as such:
Copying foobar...
1 file(s) copied.
Compiling resources...
Linking...
For VS 2017 the command Dmitry Pavlov posted would be the following:
xcopy /y "$(ProjectDir)my_file.ini" "$(OutDir)"
Quotes are important in case there are spaces in the path to the project directory.
Expanding on Synetech's answer.
In VS2019 right click the file you want to copy in the Solution Explorer and select Properties. Then under General >> Item Type change to Copy File then hit Apply.
You now should have UI fields in the Properties Page for Destination etc.
In case this helps anyone, I needed to copy the output dll of the project i was building into another project.
xcopy /y "$(ProjectDir)$(OutDir)$(TargetName)$(TargetExt)"
"C:\Application\MyApplicationName\bin\x86\Debug"
/y = overwrite file if already exists
$(ProjectDir) = location on your machine where the project lives
$(OutDir) = is where your current build setup outputs the build
$(TargetName) = What the project being built is set to be called. Ex: XXX of XXX.dll
$(TargetExt) = the extension of the build Ex: .dll of XXX.dll
"C:/..../x86/Debug" is the location to copy to.
You need the extra $(OutDir). Otherwise, in the rebuild/clean step it will throw away your source.
CommandLine : copy "$(SolutionDir)last-script.js" "$(TargetDir)Debug"
Outputs : $(TargetDir)Debug\last-script.js
Improving Synetech
answer :
In VS 2013 C++ project Command Line : copy %(Identity) $(OutDir) Description : Copying foobar... Outputs : %(Identity)
It works , But it leads to circular dependency , i.e. it will be executed each time you demand increamental build, no meter it has been already copied.
To solve this , you can add that item at target folder, change path to $(OutDir), and use that in first added item as Output. Drawback - two items with similar name are in solution.
Also usefull xcopy with /d /y parameters in postbuild - copy only if target file date is older.
You could also after the unload the project (Right click on the project >> Unload Project) add the following inside an existent <ItemGroup> tag:
<Content Include="..\..\Config\db.config">
<Link>Config\db.config</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
In this case it will grab the db.config file from 2 folders up and put it in the output folder(by default bin/Debug) after creating a Config folder with the db.config file inside

Resources