Project settings changes with VS2010

Project settings changes with VS2010

Rate This
  • Comments 36

Hi, I am Andreea Isac, a developer on the Visual C++ team at Microsoft. I would like to present you a summary of all project settings that are stored in a different manner or place with Visual Studio 2010, compared with previous VS releases.

 

MSBuild syntax

If you explore your project files on disk, you will notice that our default project extension changed from .vcproj to .vcxproj. The file extension for property sheets changed from .vsprops to .props and that their content format changed to msbuild syntax. As Marian Luparu explains in this blog post, moving to the msbuild syntax is a big step forward for VC build system. It provides to C++ developers with an open, extensible and customizable architecture, enriched with cool features (like better diagnostics).

 

Custom build rules

Custom build rules are no longer implemented solely via .rules files, but through a triplet of files .props/.targets/.xml.  VS2010 automatically converts any rules files that your projects reference into their corresponding .props/.targets/.xml. We plan to publish a separate blog post about custom build rules, but until then let me briefly describe the three files. Since property pages are data driven in VS2010 (as explained in this post), the xml file supports the property page UI of the custom build rule and defines at the same time the task that will be invoked during build. The “.props file contains the default values for the properties defined in the xml file. The targets file defines the build behavior of the custom build rule. Custom build rules information is better structured in three distinct components (a property sheet, an inline task and a property page) and integrates more seamlessly with project system and build features.

 

Filters

If you inspect the content of the project file you will see how the filters information is no longer defined there. They exist now in a complementary file, located at the same level as the project file on disk, always having the following format for the name: [ProjectName].vcxproj.filters. Thus, the build information is separated from the solution explorer display information and incremental build will not be affected by an exclusive-UI settings change.

 

Project dependencies

Until Orcas, we used to define project dependencies only in the solution file and project references in the project file. Also, the project dependencies in some cases were implying a reference implicitly for e.g. a solution dependency between executable and library project would automatically pass the dependency to the link command line (not being more than a project reference defined at the solution level). With VS2010, we stopped supporting project dependencies defining implicit references and we also introduced a new way of defining project dependencies at the project level. Since a project reference and a project dependency are close concepts, both applying to a project, it made sense to have them represented together, in a consistent way, in the project file. As you will see in the snippets below, the only difference between a project reference definition and a project dependency definition consists in metadata that defines the output assembly inclusion/exclusion into/from the main project link command line.

Although we did not remove the “Project Dependencies” dialog, we recommend defining new project dependencies via the “Framework and References” dialog. You need to set the “Reference Assembly Output” property in the property page UI to false for a project dependency and to true for a project reference.

 

Because we recommend this pattern going forward, the conversion to VS2010 is also converting the project dependency information defined at solution level into project reference information defined at project level. What we have defined in the Orcas solution file after adding DependencyProject.vcproj as dependency for MainProject.vcproj (via ProjectàProject Dependencies… menu):

 

MySolution.sln:

Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DependencyProject", "DependencyProject\DependencyProject.vcproj", "{AD3B5768-7679-4CEC-B4A7-3AD056B3632C}"

EndProject

Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MainProject", "MainProject\MainProject.vcproj", "{BA6A25FC-401B-4F6F-BAF0-083708C6502A}"

                ProjectSection(ProjectDependencies) = postProject

                                {AD3B5768-7679-4CEC-B4A7-3AD056B3632C} = {AD3B5768-7679-4CEC-B4A7-3AD056B3632C}

                EndProjectSection

EndProject

 

It looks in the VS2010 project file like this:

 

MainProject.vcxproj:

  <ItemGroup>

    <ProjectReference Include="..\DependencyProject\DependencyProject.vcxproj">

      <Project>{ad3b5768-7679-4cec-b4a7-3ad056b3632c}</Project>

      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

    </ProjectReference>

  </ItemGroup>

 

The project name and GUID are information taken from the Orcas solution file. ReferenceOutputAssembly metadata is used to control whether the assembly pointed by the referenced project will be included or not into the command line of the compiler, during the build of the main project. Since we converted a relationship of “dependency” (as we call it in Orcas), which means only build order, we set the ReferenceOutputAssembly metadata to false.

 

To demonstrate the difference between converting an Orcas project dependency and an Orcas project reference, consider the following example of a referenced project added in Orcas via Project Properties - Framework and References.

In the Orcas project we would have:

 

MainProject.vcproj:

               <References>

                                <ProjectReference

                                                ReferencedProjectIdentifier="{C0F77507-0B6F-41AC-A576-2D462FED270E}"

                                                RelativePathToProject=".\ReferenceProject\ReferenceProject.vcproj"

                                />

                </References>

 

 

And in the VS2010 project we convert to:

 

MainProject.vcxproj:

<ItemGroup>

    <ProjectReference Include="..\ReferenceProject\ReferenceProject.vcxproj">

      <Project>{c0f77507-0b6f-41ac-a576-2d462fed270e}</Project>

      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>

      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>

    </ProjectReference>

  </ItemGroup>

 

The end result of the above is both projects DependencyProject and ReferenceProject showing up in the Framework and References window. In VS2008, only ReferenceProject would show up.

 

Note, that if you need to go back to VS2008 for a quick experiment, your project does have such dependencies and you are not using your source control for this, changing the converted solution header section with the VS2008 version will result into losing all your P2P information.

 

VC Directories

We also implemented VC directories differently with VS2010. They are no longer found in Tools à Options à Project and Solutions, but in the property pages of a loaded project. The data support behind the UI consists of user property sheets that are normally imported by any project from [LocalAppData]\Microsoft\MSBuild\v4.0. You can control the VC Directories settings by customizing what user property sheets to be imported in your projects and this way you can define per project or global VC Directories settings. This brings again consistency with msbuild syntax (to have a property sheet instead of an ini file), more flexibility in setting up multiple projects on the same machine (instead of having a rigid per user /per machine environment) and better source control experience with enlistments across different machines (instead of always changing the machine specific settings). Brian Tyler explains thoroughly this change and its benefits in this blog post.

 

Additional reference search paths

A change that is tied with VC directories is that assembly search paths (from Property Pages à Framework and References à Additional reference search paths) is now part of the VC directories section, in the property pages of a loaded project. It makes sense to have all the paths defining the build environment defined in the same place.

 

Source control information

Another settings location change that happens with conversion to VS2010 is project source control information for mssccprj.scc hint file based providers (like Visual Source Safe). Since the project file extension changed to .vcxproj, source control providers may not able to track this new extension and create mssccprj.scc hint files for it. This change does not apply for solution source control information (because the .sln extension remained the same), or for any other types of files except the project file.

 

An example is, in VS2008, if the source control provider is able to write a mssccprj.scc file and persist there the project bindings (which is the default case for the vcproj files), the mssccprj.scc file would look like this:

 

Mssccprj.scc:

SCC = This is a Source Code Control file

[MyProject.vcproj]

SCC_Aux_Path = "\\SCCServer\SCCDatabase"

SCC_Project_Name = "$/MyProject.root/MyProject/MyProject", IQAAAAAA

 

VS2008 will then be able to use the binding from this provider-generated file, and the vcproj project file will only contain “SAK” triggers:

 

MyProject.vcproj:

                SccProjectName="SAK"

                SccAuxPath="SAK"

                SccLocalPath="SAK"

                SccProvider="SAK"

 

By default VS2010 does not find the mssccprj.scc file and the project file will contain the following source control information:

 

MyProject.vcxproj:

    <SccProjectName>"$/MyProject.root/MyProject/MyProject", IQAAAAAA </SccProjectName>

    <SccAuxPath></SccAuxPath>

    <SccLocalPath>.</SccLocalPath>

    <SccProvider>MSSCCI:Microsoft Visual SourceSafe</SccProvider>

 

SccAuxPath value wasn’t migrated into the new project file because usually this property stores user specific information. This is migrated into the solution suo file.

 

Note that the recognized project extensions might be settable in the source control provider UI, e.g. for SourceSafe the project extension can be added in SourceSafe Explorer/Tools/Options/File Types/CreateSccFiles list.

Let us know if you have any questions.

 

Andreea Isac

Software Developer Engineer

VC Project System and Build Team

 

  • P.S.

    I get the following warning on building:

    warning MSB8012: TargetPath(...) does not match the Linker's OutputFile property value (...). 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).

    how can i fix this?

  • @mg: similar question has been raised in another blog, this is what I have replied, hope it will be helpful to you:

    Friday, February 19, 2010 11:54 AM by Li Shao

    # re: Visual Studio 2010 Release Candidate Is Now Available For Download

    @Emil Persson: This warning was introduced to workaround a limitation that we have when converting applications from previous version of Visual Studio.

    As you may know, 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 $(TargetPath). When we convert application from previous versions, however, it is pretty hard for us to parse Link.OutputFile to figure out what exactly are the the values for $(TargetName) and $(TargetExt),as different customers may format them in different ways. To work around that, we have decided to have conversion preserve the value of Linker.OutputFile. $(TargetName) will be default to $(ProjectName). $(TargetExt) will be default to the default extension for the application type: .dll for Dynamic Library, .lib for Static Library and .exe for Application. Warning MSB8012 will be issued if Link.OutputFile and $(TargetPath) are not the same in the conversion log. You will get the same warnings when building the application.

    $(OutDir), $(TargetPath) 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.

    In your particular case, it looks like your $(OutDir) is F:\FrameworkTest4 instead of F:\FrameworkTest4\Release, you can change the "Output Directory" value to "F:\FrameworkTest4" and that should eliminate the warning. It should take care of the issue you are seeing with lauching exe as now the value of $(TargetPath), which corresponding to $(OutDir)$(TargetName)$(TargetExt) is 'F:\FrameworkTest4\FrameworkTest4.exe'

    Li Shao, Project and Build Team

  • @Andreea Isac

    > If you convert the solution containing the main and the dependency projects, your converted main project will contain the dependency. If you convert the solution containing only the main project, the converted main project won't contain the dependency.

    > If you convert them both and you pick the small solution first, make sure to overwrite the common project when the second solution conversion asks for it. If you convert the big solution first, do not allow project overwrite when the small solution will convert.

    No matter which way you do it, the MainProject.vcxproj file will be wrong for one of the solutions.  Either it will contain a dependency that will prevent the small project from compiling at all or it will be missing the dependency that allows the big project to compile in the proper order.

    My solution was to rip out all of the "ProjectReference" entries out of all of my .vcxproj files, and readd them (using

    "Project -> Project Dependencies") to the solutions.  Essentially, I had to undo all of the work VS2010 did in the conversion just to make this work again.

  • @Matt Houser

    > What happens if you have a project that has a dependency set, but that project is not in the current solution?  Will the compiler attempt to find the project and build it?

    From what I've seen, having one project that includes another project that is not in the solution is fatal.  You won't be able to compile your solution at all.  You'll just get Error MSB8006.

    If this is a problem for you, you can revert to the VS2008 way of doing things (see my previous post).

    Of course, someone from Microsoft might have a better way to handle this.

  • @ Matt Houser

    If your project has a dependency (or reference) set to another project that is not a member of your current solution it will be ignored. You will not see the dependency/reference either in "Project Dependencies" nor "Framework and References" dialogs. Also the solution build or the main project build will ignore to build any dependency/reference that is not part of the current solution. This behavior is different in the VS command prompt, msbuild will detect and will build the depndency/reference.

  • @ Dale Nichols

    Dale, I am not able to reproduce the MSB8006 when building a project depending or referencing another project which is not included in the current solution. What I see is that any dependency/reference that is not part of the current solution is simply ignored by the solution build and by the main project build.

    Maybe there is some other detail in your scenario that causes MSB8006?

  • Li Shao, thank you for the clarifications about the Link.OutputFile problem.

    It works now for me by setting TargetPath, TargetExt and OutDir in all our projects correctly, as you suggested. (although it takes much more time to convert the projects)

    Maybe you should consider removing Link.OutputFile from the user interface. It is now just confusing for old VS-users.

    A resume:

    Our Solution is a commercial 3D-CAD-Application with OpenGL as 3D-Runtime and .NET 3.51 with WPF as User-Interface. (Its a great combination and we really like WPF as the best user-interface-framework on the market.)

    It took more than one hour to correctly convert our medium size VS2008-Solution containing approx. 500.000 lines of code in 3 projects of native c++, 2 projects of c++/cli and 5 c# projects with .NET 3.5 and WPF - Framework to the VS2010 MSBUILD-Format.

    Sadly, I still could not get all our post-build scripts to work and I could not set the .NET - Framework from 4.0 to 3.5 in the c++/cli-projects. Why is there not a GUI-Option for .NET in c++/cli? Setting TargetFrameworkVersion manually with v3.5 gave me linker errors (e.g. with managedh.obj).

    The result was, that I had C# Projects with .NET 3.5-framework-dependencies with references to .NET 4 c++/cli - projects and nothing worked after switching all projects to .NET 4 manually. This should really be fixed in the final release!

    Intellisense is now worse for us, since C++/CLI - support is gone. We can not upgrade until it is available again.

    Btw:

    The Visual Studio 2010 - WPF - GUI is faster than expected. Its comparable to VS2008.

  • P.S.

    the build and runtime performance of our application in VS2010 is about the same as the speed in VS2008. (at least, there is no regression). I only needed to change approx. 5 lines in our native c++ - codebase that were incompatible with VS2010.

    But there may be a bug with post-build scripts (regression from VS2008):

    When a post-build script modifies the build-output (e.g. by resigning an assembly), the compiler should not ask for a rebuild on the next Debug/Run-command.

    At the moment, VS2010 always asks for a rebuild when I press F5, without any changes made by myself.

  • The Link.OutputFile issue is extremely frustrating to us since we have 711 project files that we'll have to modify by hand as our debug targets all have "D" appended to the project name.

    I've also noticed that a project that sets its output directory to "$(ConfigurationName)Static\" that inherits a property sheet with an output directory of "$(ConfigurationName)\" and an Intermediate directory of "$(OutDir)\Intermed", the intermediate files all end up in, for example, Debug\Intermed while the final targets correctly end up in DebugStatic.

    Finally, I don't know if this issue is a "you're lucky it ever worked", but since at least VC6, we've indicated additional static libraries by adding them to a Folder/Filter in the project instead of using the annoying to use Additional Libraries linker option.

    It seemed to work in Beta2 (at least from a devenv /build perspective), but in the RC it doesn't seem to work from the command line or from the IDE.

    If this configuration is no longer supported, is there a way to retain the behavior or do we have to migrate to Additional Libraries?

  • @mg. Thank you for your feedback of your VS2010 experience. UI retargeting for C# application is, unfortunately, not supported in this release due to resource reasons. I will have a post coming up including information on how to retarget your applications. On the other hand, what is the error you are seeing after switching everything to 4.0 framework?

    The up to date issue you are seeing most likely is caused by files that are missing in the disk but listed in the project file. I will address that in my next post as well.

    @Michael, I am not able to repro your issues with OutDir and Intermediate directory. If you have a repro, please open a connect bug.

    Yes, we do support adding files that are included in the project to their respective tools. They should be available in the final RTM build.

    Li Shao, Project and Build Team

  • @Andreea Isac

    > Dale, I am not able to reproduce the MSB8006 ... Maybe there is some other detail in your scenario that causes MSB8006?

    That would be really nice if it were true, but the only difference I've found between projects that work and ones that don't is the ProjectReference section. Connect issue 534334 contains an example that demonstrates the problem -- at least on my computer.

    Hmm, now that I think about it, I've only tried the ProjectReferences after an upgrade from VS2008.  I haven't tried adding them by hand (using the menu option you described).  Perhaps that works differently.  I'll check.

  • I've done further research on my problem, and it appears that HP computers define the environment variable:

      PLATFORM=HPD

    and that MSBuild uses the PLATFORM environment variable for some purpose.  It isn't clear whether these uses are related or not.  I'll update 534334 with this information

  • Removing the PLATFORM environment variable fixed the MSB8006 error, but even after that the upgraded VS2010 solutions are not equivalent to the pre-upgrade VS2008 solutions.

    In particular, under VS2010 using this feature, there is an extra link-time dependency between the two DLLS, and it is looking for the dependent DLL someplace rather weird (in the Debug directory of the other project).

  • I notice that when converting from VS2008, the project dependencies have been converted to references.

    However as I'm building for 32 and 64 bit outputs, all four configurations now reference the same 32bit debug library; so my release build has debug in it and my 64bit builds fail to link.

    Am I missing a step somewhere?

    I have tried reapplying the reference manually but get the same result.

  • Hi Simon, sorry for the delay. The referencing project should reference the output file of the referenced project, which is platform/Configuration specific. If you like, you can send me the project files before and after conversion and I will be happy to take a look. My email is lishao AT Microsoft.com.

    Li Shao, Project and Build Team

Page 2 of 3 (36 items) 123