5

According to Microsoft's Exec Task, it runs the specified program or command by using the specified arguments:

Command - Required String parameter.

The command(s) to run. These can be system commands, such as attrib, or an executable, such as program.exe, runprogram.bat, or setup.msi.

This parameter can contain multiple lines of commands. Alternatively, you can put multiple commands in a batch file and run it by using this parameter.

We are currently using a CustomBuild like the following:

<CustomBuild Condition="'$(Platform)'=='Win32'" Include="rdrand.asm">
    <Message>Building and assembling rdrand.asm</Message>
    <Command>ml.exe /c /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo"$(IntDir)rdrand-x86.obj" "%(FullPath)"</Command>
    <Outputs>$(IntDir)\rdrand-x86.obj;%(Outputs)</Outputs>
 </CustomBuild>

We want to switch to NASM and an Exec Task because it provides a single set of sources for Windows and Linux. It also allows us to provide ASM for Windows phones and tablets when appropriate, like PMULL and PMULL2. If NASM is not available, then we will use the standby C/C++ implementation.

Note: we don't want the user to do anything. We don't want them to select something, and we don't want them setting defines. Asking the user to do something means we have to field user questions. We want things to "just work" for users; F5 under Visual Studio should "just work" as far as the user is concerned.

My first question is, is Exec Task the right tool for the job? My scond question is, how can we determine if nasm.exe is available from within MSBuild? Here, "available" means its on-path so we can call it.

jww
  • 97,681
  • 90
  • 411
  • 885

1 Answers1

5

Hard to tell with certainty whether Exec is the right tool but it's definitely the way to call external programs so it's perfectly usable here I guess.

Here, "available" means its on-path so we can call it.

Better make sure it can be called (as in, not missing dependencies and not 64bit on a 32bit machine for example), not just whether it's found. Standard way of doing this: just try to run it:

<Target Name="CheckNasmIsCallable">
  <!-- Redirect standard output to avoid clutter, IgnoreExitCode
       as this is just a check so should not lead to actual errors. -->
  <Exec Command="nasm.exe -h > NUL" IgnoreExitCode="True">
    <Output TaskParameter="ExitCode" PropertyName="NasmExitCode" />
  </Exec>
</Target>

<Target Name="WantsToRunNasm" DependsOnTargets="CheckNasmIsCallable">
  <Message Text="Nasm found" Condition="'$(NasmExitCode)' == '0'" />
  <Message Text="Nasm not found" Condition="'$(NasmExitCode)' != '0'" />
</Target>
stijn
  • 34,664
  • 13
  • 111
  • 163
  • Thanks @stijn. Its going to take me a few days to test it and get back with an accept. And sorry to ask if its the right tool. After spending three days on that simple makefile dependency, I wanted to ensure I was not going down another rabbit hole. – jww Nov 15 '16 at 12:53