Sujay Kulkarni Sujay Kulkarni -4 years ago 217
C++ Question

How to set SAFESEH linker option using MSBuild command line

I am trying to build my C++ project created in VS2008 and upgraded to VS2013 using MSBuild.
I am referencing 3 third party dlls.
In the project settings I'm using /SAFESEH:NO. With this setting when I build my project in Visual Studio, it successfully builds.
An issue arises when I build the same project using MSBuild, error as follows:

error LNK2026: module unsafe for SAFESEH image


Build command:
"C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe" TI.sln /t:ReBuild /p:configuration=Release /p:Platform="Win32" /p:ToolVersion="12.0" /p:SAFESEH="NO"


Please suggest me a solution

Answer Source

/SAFESEH:NO shown in the project settings is very different from passing an msbuild property named SAFESEH and set it to "NO": /SAFESEH is a linker command line option and there is no direct relation to msbuild properties. Instead in an msbuild project file the linker options are specified in the ItemDefinitionGroup called Link so if you open the file in a text editor you'll see something like

<ItemDefinitionGroup>
  <Link>
    <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
  </Link>
</ItemDefinitionGroup>

Now if your project doesn't build without SAFESEH truned off, I don't see why you wouldn't permanently configure it that way in the project settings. It also has the benefit it'll build from VS and command line without additional configuration.

If for some reason you cannot do that there are a couple of options. First one is basically the same as my answer to the question on how to set compiler options via the command line: create a file, say c:\nosafeseh.props, containing

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemDefinitionGroup>
    <Link>
      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
    </Link>
  </ItemDefinitionGroup>
</Project>

then put it to use by calling

msbuild TI.sln /p:ForceImportBeforeCppTargets=c:\nosafeseh.props

Another option is to 'translate' a property into the ItemDefinitionGroup entry. Open the project file using a text editor and add these lines, in the same location where VS would put the linker options, ususally right before the line with '':

<ItemDefinitionGroup>
  <Link>
    <ImageHasSafeExceptionHandlers Conditon="'$(SafeSeh)'!='">$(SafeSeh)</ImageHasSafeExceptionHandlers>
  </Link>
</ItemDefinitionGroup>

This sets the value of ImageHasSafeExceptionHandlers to the value of the property named SafeSeh (this is an arbitrary name, you can select whatever you want), and only if that property is defined and has a value. So, to set it to false, you'd call

msbuild TI.sln /p:SafeSeh=False
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download