[CMake] Visual Studio 10 default property sheets

David Hunter davidhunter22 at gmail.com
Wed Dec 7 18:59:09 EST 2011


I'm not sure if this has been discussed much within the CMake developer
community but I wanted to give some thoughts on the use of Visual Sudio
property sheets and some suggestion for CMake. As far as I know this is
only relevant to Visual Studio 10 and hence MSBuild. I am not familiar with
older versions of VS. Sorry if this a bit long winded or it falls into the
"bleeding obvious" category. I did look around and couldn't find any
discussion like this online.

So first an overview of property sheets in VS10/MSBuild skip this if you
are in the know.

For those not to familiar with property sheets you can consider them to be
collections of compiler/linker flags and other build related information.
Physically property sheets are just MSBuild XML files which get included
into the main Visaul Studio project file, the .vcxproj file, which is also
an MSBuild XML file. To a certain degree you can consider one of Visual
Studio functions to be a glorified editor of MSBuild XML files.

When you create a project in Visual Studio you have to select what type of
project it is, for instance a standard DLL, aka shared library, project.
When you do this the project file that VS produces will automatically
includes certain property sheets that Microsoft supplies with MSBuild.
These files can be found in something like "C:\Program Files
(x86)\MSBuild\Microsoft.Cpp\v4.0" and have names like
"Microsoft.Cl.Common.props". The is also a sub directory called "Platforms"
which contains directories like "Win32" and "x64". These correspond
directly to the "Platform" you see in VS. These directories contain further
MSBuild predefined platform specific property sheets like
"Microsoft.Cpp.Win32.props"

Property sheets can be inherited what this means is that a property sheet
can inherit a set of compiler flags from a parent sheet and can override or
extend them if it wants to. This is the key to the usefulness of property
sheets. If you look in the "Property Manager" screen in VS of a standard
DLL project you should see something like the following property sheets
being inherited for a 32 bit windows build

Microsoft.Cpp.Win32.user
Windows Dynamic Link Library
Multi-byte Character Support
Core Windows Libraries

Sheets higher up inherit and can override sheets lower down the list. The
bottom three correspond to MSBuild supplied property sheets in the MSBuild
install directories mentioned earlier. Sadly I haven't found a way in the
VS GUI of finding out the actual file name and path of the property sheet
but you can normally guess it. The "Microsoft.Cpp.Win32.user" property
sheet which is normally somewhere like
"AppData\Local\Microsoft\MSBuild\v4.0" in your user id allows you to store
user specific build overrides which is generally a bad idea.

When you right click on a project in VS solution explorer ( or other
equivalent method ) you can look at the properties of that project,
including all the compiler/linker flags. Items that are in bold font are
defined directly in the property sheet you are looking at while non bold
indicates a value that has been inherited. For some compiler flags like the
include path it makes sense to inherit the value from your parent property
sheet and extend it. In this case you'll see something like
"%(AdditionIncludeDirectories)" in the value which is a macro value
representing the value of this field inherited from the parent sheet.

A very key portion of the property sheet you can see in VS GUI is the
"General" page under "Configuration Properties". At the bottom of this
screen is a section called "Project Defaults" which looks something like

Configuration Type                            Dynamic Library (.dll)
Use of MFC                                     Use Standard Windows
Libraries
Use of ATL                                       Not using ATL
Character Set                                   Use Multi Byte Character Set
Common Language Runtime Support  No Common Language Runtime Support
Whole Program Optimization              No Whole Program Optimization

The above are not really compiler flags directly but define which MSBuild
supplied property sheets to inherit. In other words they effect compiler
flags used in your build by changing what property sheets you inherit from.
So if you change the "Character set" from multi byte to Unicode you will
see in the property manager that you now inherit from a sheet called
"Unicode Support" rather than "Multi-byte Character set". This may change
many compiler/linker flags/defines etc...

Note the situation is a little more complicated as you can define certain
MSBuild XML elements before you inherit the MSBuild supplied property
sheets which influence what flags they set. A good exmple of this is the
<UseDebugLibraries>true<UseDebugLibraries> which amongst many other things
makes the build process link to the debug versions "MDd" of the MS runtime
libraries rather than the optimized/release ones.

End of overview

So what was the point of this ramble through property sheets. My assertion
is that at present, probably for historic reasons, CMake does not allow you
to completely control what MSBuild supplied property sheets you inherit and
often ends up setting specific compiler flags that the MSBuild supplied
property sheets would have set anyway if the correct ones had been
inherited. In general I believe the ethos is to use the, presumably
consistent and correct, set of flags the MSBuild supplied property sheets
give you and only specifically override these flags if you really have a
reason.

In CMake you can control this, at least in 2.8.6, to a certain degree. Most
of the action happens in
cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues. In this
memeber function you can see XML being written out like
"<CharacterSet>Unicode</CharacterSet>" which makes MSBuild inherit the
"Unicode" property sheet rather than the default "Multi-Byte" one. In this
case you can trigger this by adding the define "-D_UNICODE" to your Cmake
input file. This is probably a side effect that many are not aware of and
the result might be a lot more than just adding "-D_UNICODE" to you compile
line as the property sheet may do many things. Note this
http://www.cmake.org/pipermail/cmake/2011-June/045002.html concerning an
extension to this particular element.
In the case of MFC a magic "CMAKE_MFC_FLAG" variable is used, there is no
equivalent magic flag for ATL or CLR. Note CLR was the origional reason I
looked at all this. Locally I added the following code for another magic
flag
    const char* clrFlag =
this->Target->GetMakefile()->GetDefinition("CMAKE_CLR_FLAG");
    if(clrFlag)
      {
      this->WriteString("<CLRSupport>true</CLRSupport>\n", 2);
      }
This causes the "CLR" property sheet to be inherited which would fix the
relatively often asked question how do I get CMake to build C++/CLI code.

So my question about all of this is should CMake have a consistent way to
influence what property sheets you inherit from and if so how? If this was
done one related, and possibly harder, issue would be to remove the
explicit setting of the many flags the inherited property sheets now set
for you, for instance the "/MDd" flag mentioned earlier. How could you tell
if the inherited flags are the same as the ones the CMake explicitly set in
all configurations?

So, I am happy to volunteer to do some of this work but wanted to know,
being a CMake internals newbie, what the experts thought. Is is worth doing
or if not why not, or is someone already doing this? What would be the best
approach? How much do people care about consistency of flags between CMake
releases? All thoughts welcomed.

David


-- 
M +1 917 545-0240
Skype davidhunter22
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20111207/0ad111ea/attachment.htm>


More information about the CMake mailing list