Visual Studio ignores UseDebugLibraries from .props - visual-studio

I have the following .props file, generated with CMake (but this does not seem to be a CMake problem):
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
</Project>
I have another .props file, next to this one in the .vcxproj, but it is correctly merged when i open it in Visual Studio, they look like this in the project file:
<ImportGroup Label="PropertySheets">
<Import Project="other_props_file_that_works.props;does_not_work.props" Condition="exists('other_props_file_that_works.props;does_not_work.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
Not really relevant, but the props are added like this in the CMakeLists.txt:
set_property(TARGET "${PROJECT_NAME}" PROPERTY VS_USER_PROPS ${USE_DEBUG_LIBARIES_PROPS_FILE_PATH} APPEND)

Related

Can't set property via .props file

I'm trying to change project's property via .props file. I created 2 files:
Directory.build.props
<Project>
<PropertyGroup Label="Globals">
<ForceImportBeforeCppProps>$(MsbuildThisFileDirectory)\MyProps.props</ForceImportBeforeCppProps>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
</Project>
And
MyProps.props
<Project>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
</PropertyGroup>
</Project>
Both properties WindowsTargetPlatformVersion and PlatformToolset are successfully applied, but not the PreferredToolArchitecture. Could you please tell me, where I'm wrong? How to set it properly? I', using Visual Studio 2019
I also found, that this works if I delete PreferredToolArchitecture property from the .vcxproj file. Why it can't override it?
'Directory.build.props' is imported early, before the main body of the project file. The ForceImportBeforeCppProps property instructs that your 'MyProps.props' file should be imported early.
The PreferredToolArchitecture property in the .vcxproj is overriding your definition.
Move your property overrides to a 'Directory.build.targets' file.

MSBuild reexpand property

I use some custom props file like this (my_super_props.props)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<TargetOsName>linux</TargetOsName>
<RemoteGeneratedFilesDir>$(RemoteIntDir)generated_files/</RemoteGeneratedFilesDir>
</PropertyGroup>
<ItemGroup />
</Project>
VS generates vcxproj file for me like this (piece)
.....
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x86'">
<Import Project="my_super_props.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x86'">
<RemoteIntDir>$(RemoteProjectDir)/obj/$(PlatformTarget)/$(TargetOsName)/$(Configuration)/</RemoteIntDir>
</PropertyGroup>
.....
Inside Microsoft.Cpp.props - $(RemoteIntDir) already defined like this
<RemoteIntDir Condition="'$(RemoteIntDir)' == ''">$(RemoteProjectDir)/obj/$(Platform)/$(Configuration)/</RemoteIntDir>
So Inside my Targets i'ev got wrong value of $(RemoteGeneratedFilesDir)
for exmaple
my_proj/obj/x86/debug/generated_files
instead of
my_proj/obj/x86/linux/debug/generated_files
because properties expands at declaration time,
but i can't declare $(RemoteIntDir) earlier, cos it depends of $(TargetOsName)
So I must somehow reexpand $(RemoteGeneratedFilesDir) before targets start - but i don't know how ??
PS
$(RemoteIntDir) - filled with Visual Studio project configuraion UI Dialog, so i even can't change order of properties declaration/props imports and etc
Your requirements are in a mess and there are no default properties RemoteProjectDir,RemoteGeneratedFilesDir,RemoteIntDir on system Microsoft.Cpp.props file. So it is quite strange due to your description.
I have added
<RemoteIntDir Condition="'$(RemoteIntDir)' == ''">$(RemoteProjectDir)/obj/$(Platform)/$(Configuration)/</RemoteIntDir>
.....
into my Microsoft.Cpp.props file to keep the same MSBuild environment as yours.
I have two questions.
my_proj/obj/x86/linux/debug/generated_files, is your current build configuration is linux? And why did you have two similar configuration linux and debug under it?
Also, is it my_proj/obj/x86/linux/generated_files?
In this situation, I have trusted your description, and assume it is my_proj/obj/x86/linux/debug/generated_files.
Besides, the changed $(Configuration) will act on the whole msbuild files including Microsoft.Cpp.props system files and vcxproj file.
One
If your current build configuration is debug and Platform is x86, you should try to change your my_super_props.props file like this:
<RemoteGeneratedFilesDir>$(RemoteProjectDir)/obj/$(Platform)/$(TargetOsName)/$(Configuration)/generated_files/</RemoteGeneratedFilesDir>
Two
If your build configuration is linux(to create it, you have to enter Build top menu under VS IDE-->Configuration Manager-->click New under the Project Configuration then input linux under it)
First, you have to add these under your current vcxproj file:
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='linux|x86'">
<Import Project="my_super_props.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='linux|x86'">
<RemoteIntDir>$(RemoteProjectDir)/obj/$(PlatformTarget)/$(TargetOsName)/debug/</RemoteIntDir>
</PropertyGroup>
Second, modify your my_super_props.props file:
<RemoteGeneratedFilesDir>$(RemoteProjectDir)/obj/$(Platform)/$(TargetOsName)/debug/generated_files/</RemoteGeneratedFilesDir>
Rebuild the project:

Msbuild : Error: The OutputPath property is not set for this project

I am currently trying to decouple a project and I am getting the following error
The OutputPath property is not set for project 'MyProj.vcxpro j'.
Please check to make sure that you have specified a valid combination
of Configuration and Platform for this project. Configuration=''
Platform='x64'. You may be seeing this message because you a re
trying to build a project without a solution file, and have specified
a non-default Configuration or Platform that doesn't exist for this
project. [D:\Test\MyProj.vcxproj]
I added this to my project but it is not helping
<PropertyGroup Label="Globals">
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<TargetName>MyProj</TargetName>
<ResolveExportedSymbols>true</ResolveExportedSymbols>
<ProjectGuid>{xxxxx-xxxx-xxxx-xxx}</ProjectGuid>
<UsePrecompiledHeader>true</UsePrecompiledHeader>
<OutputPath>D:\MyOutput\out\</OutputPath>
</PropertyGroup>
Any suggestions ?
Please use this:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<TargetName>MyProj</TargetName>
<ResolveExportedSymbols>true</ResolveExportedSymbols>
<ProjectGuid>{xxxxx-xxxx-xxxx-xxx}</ProjectGuid>
<OutputPath>D:\MyOutput\out\</OutputPath>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
.....
</ClCompile>
</ItemDefinitionGroup>
.....
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
Then, delete any output folder like Debug and then rebuild again.

ToolsVersion in Visual Studio 2019

I am doing the migration of several projects from VS2010 to VS2019. Those projects have Tools Version 4 in their vcxprojs:
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Target VS is VS2019 v16.5.0, MSBuild version is 16.5.0.12403, so I am trying to set ToolsVersion to 16.5:
<Project DefaultTargets="Build" ToolsVersion="16.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
But it seems that MSBuild doesn't like it:
1>Building with tools version "Current".
1>Project file contains ToolsVersion="16.5". 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="Current".
Despite builds are anyway successful, I care about this message. What can be wrong here?
UPD:
Providing simplified example of structure of projects:
common props:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShouldUnsetParentConfigurationAndPlatform>false</ShouldUnsetParentConfigurationAndPlatform>
</PropertyGroup>
<PropertyGroup Label="Globals">
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<DotNetFrameworkVersion>v4.0</DotNetFrameworkVersion>
</PropertyGroup>
<!-- Other common variables-->
</Project>
cpp props:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup>
<TargetExt>.dll</TargetExt>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="common.props" />
<-- compiler, linker settings and so on -->
</Project>
Real project:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectName>my_name</ProjectName>
<ProjectGuid>{my_guid}</ProjectGuid>
<RootNamespace>my_ns</RootNamespace>
<Keyword>my_keyword</Keyword>
</PropertyGroup>
<Import Project="cpp.props" />
<-- configurations (Release, Debug, x64/Win32 and so on -->
<-- project-specific compiler/linker settings -->
<-- items: cpp, heanders and so on -->
<-- references -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Project file contains ToolsVersion="16.5". This toolset may be unknown
or missing
To solve this issue, you should do some updates.
Suggestion
1), right-click on the project on VS2019 IDE-->Retarget Projects and target this project to the Windows 10 SDK version and choose upgrade to v142.
2), Right-click your project on VS2019 IDE-->unload project-->Edit (project name).vcxproj-->change ToolsVersion="4.0" to ToolsVersion="Current"--> then reload your project
3) Right-click on your project-->Properties-->Configuration Properties-->General-->change Platform Toolset to Visual Studio 2019 v142.
----------------Update 1-----------
First of all, ToolVersion is related to the version of MSBuild that is included in the Visual Studio edition like. And in general, we do not use 16.5 in VS2019. See this link. And actually, In VS2019, the ToolVersion is set to Current.
VS2019-->Current, VS2017-->15.0,VS2015-->14.0
You cannot include a specific small version number.
This is my test result with your sample in my side and it seems that it is just like a warning:
It means that it cannot specify the Illegal toolversion 16.5.
Solution
1) Just as I said before, change toolversion to Current in Realproject.vcxproj.
2) delete the toolversion xml node in Realproject.vcxproj and in VS2019, it will automatically recognize toolversion without adding it manually.
To prove it, you can create a new VS2019 c++ project and I am sure that you cannot find toolversion node in xxxx.vcxproj file.
Then try my solution into every projects and I am sure when you finish it, the info will not appear again.

Can I use a property sheet to generate project configurations?

I'm trying to avoid hard coding settings into my .vcxproj files. I'd like to edit a single file, i.e. inherited property sheets (.props), to change my settings. This works great for compiler and linker settings. I also use this technique for all my dependent libraries like boost, zlib, for appending the include path and the libpath.
I'd like to take this a step farther and create the list of configurations in one property sheet.
Is this possible. I keep getting a error.
proj1.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="configurations.props"/>
<PropertyGroup Label="Globals">
<ProjectGuid>{36327322-B9FA-4D71-1111-E94F5BB55D57}</ProjectGuid>
<RootNamespace>Proj1</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
configurations.props
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="DebugUnicode|Win32">
<Configuration>DebugUnicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
</Project>
proj1.vcxproj : error : Project "proj1" does not contain any
configuration. The project cannot be loaded.
So is this possible?
Sorry, that is a bug I reported in VS 2010 Beta 2, but a fix didn't make RTM.
Link to Connect bug report

Resources