Build a Visual Studio C++ project using the Command Line - c++

I''ve written this batch script to build a Visual Studio C++ project using the Command Line:
pushd C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\
VsDevCmd.bat
pushd F:\Master_Copy2\embedded\IFV-170\visualC12
Msbuild.exe DSP1_Emu.vcxproj
The script changes to C:\Program Files (x86)\ ... directory, runs the VsDevCmd.bat, and then don't complete the commands, and I don't know what's wrong.
Note: When I run these commands one by one in a Command window it runs properly and builds the project.
Edit: #roalz pointed out that I should use Call with the batch file VsDevCmd.bat, and this solved the problem.

I think you need to use the call batch command to call VsDevCmd.bat from inside your batch file.
"The CALL command will launch a new batch file context along with any specified parameters. When the end of the second batch file is reached (or if EXIT is used), control will return to just after the initial CALL statement."
Please see the reference here
Another suggestion is to enclose paths containing spaces inside double quotes, i.e.
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\"

Related

How to override compile command of Visual Studio 2017 Community [duplicate]

This question already has answers here:
How to use Clang compiler with MSBuild?
(3 answers)
Closed 5 years ago.
I would like to override the default Visual Studio C++ compiler with a simple shell script. What I want is to capture the arguments, such as file name, and create some statistics. However I want to override the compilation process completely - that is, I want to call the original compilation from my shell script.
I googled but all I found was how to have pre-build and post-build scripts that execute within a project. That's not what I want.
I want to change this globally. How can I do it?
For a standard C++ project file compilation is done by invoking the MsBuild Target named ClCompile. Note there's also an MsBuild Item named ClCompile which lists the actual C++ source files used, this can be readily seen by opening your .vcxproj in a text editor. Consequently this ClCompile Item is used in the ClCompile Target, where it gets passed to the CL Task which in turn will invoke cl.exe, the actual compiler executable. This code for this can be found in the Microsoft.CppCommon.targets file for the toolset you use, for a default install of VS2017 community on a 64bit machine that is C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets.
Any of those 3 could be overridden with a custom version however as you figured already just replacing cl.exe on disk isn't the best idea.
But CL can use any executable simply by overriding the CLToolExe and CLToolPath properties. Practically: open your .vcxproj file and add
<PropertyGroup>
<CLToolExe>mycl.exe</CLToolExe>
<CLToolPath>c:\path\to\mycompilerstub\</CLToolPath>
</PropertyGroup>
all the way at the end, after the line importing Microsoft.Cpp.targets; mycl.exe will be called instead of cl.exe. If you want the same effect globally on your machine, you'll put that PropertyGroup in a seperate msbuild file and save it in for example C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Platforms\x64\ImportAfter\MyCustomImport.targets. Any targets file in that directory will be imported automatically.
As an alternative you could override the ClCompile target or the CL task. That's more involved though, e.g. for ClCompile you'd start by copying the whole implementation found in Microsoft.CppCommon.targets and then add whatever logic you need. Advantage is you have direct access to e.g. source files etc without having to parse a command line. For example this would override ClCompile and print source files and pass them to a custom executable:
<Target Name="ClCompile"
Condition="'#(ClCompile)' != ''"
DependsOnTargets="SelectClCompile">
<Message Text="All the sources = #(ClCompile)"/>
<Exec Command="mycustom.exe #(ClCompile)" />
... <!--rest of implementation copied from Microsoft.CppCommon.targets goes here-->
</Target>
Again, this needs to be put at the end of your project file or in the ImportAfter directory for global overriding.

Start windows batch from C++ CreateProcess has different behavior

Environment: windows 10, VS2013.
I have a C++ app, using Poco framework (Poco 1.7.6) and I need to launch some batch files. It works without problem, but for a particular script, and I can't figure out the reason.
This particular script is as follows (let's call it buildMySolution.bat):
set BUILD_DIR=%~dp0
call "C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
msbuild /p:Platform=%~1 /p:Configuration=%~2 %BUILD_DIR%\Mysolution.sln
As you can see the batch file simply compiles a VS2013 solution. Needless to say that this simple batch works perfectly well if launched from command line.
The problem is that this batch is in drive D: (in D:\DevRoot\build\MySolution) and when launched from my app (in D:\ drive as well), I get a "cannot find the path" on the second line.
I tried several modifications in the batch: like forcing C: or cd /D C: ... it can go to C: but not further, it refuses to cd to the directory containing vcvarsall.bat (again, I know the path is correct as the very same script executes fine from command line). It has however no problem coming back to initial directory through a cd /D %BUILD_DIR%.
To launch the script from my C++ app, I use this:
Poco::ProcessHandle handleBuild = Poco::Process::launch(path_to_script, argsBuild);
handleBuild.wait();
The Poco launch is just a thin wrapper around CreateProcessA(), I don't see anything special in their code (Poco Process.cpp).
I tried as well to specify the working directory to be the directory containing vcvarsall.bat, but then CreateProcess fails.
I just found a solution: I changed the line (in the batch buildMySolution.bat):
call "C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
to:
call C:\PROGRA~2\micros~1.0\vc\vcvarsall.bat
Believe it or not: using DOS names and removing quotes makes it work!!!
Bug or feature, I'm not sure...

MSBuild - Cannot open include file (despite listed in the INCLUDE list )

I am probably missing something obvious - but I have been stuck for a while on this issue. I am compiling a Visual Studio project on the command line using MSBuild. Basically like this:
CALL vcvars32.bat
MSBuild myproject.sln /m /t:rebuild /p:Configuration=Release /verbosity:m
But this gives me an error: fatal error C1083: Cannot open include file 'winsock.h': No such file or directory
But if I check the environment variable INCLUDEafter the vcvars32.bat call the directory containing 'winsock.h' is in the list - so I definitely have this file in the SDK.
In addition if I change verbosity of MSBuild to detailed I can see the full compile command used. If I copy that and run it in the console the same cpp file compiles without any problem.
Any idea whats different inside the MSBuild context ?
Solved it, adding /p:useenv=true make MSBuild use the INCLUDE environment variable.
( Still a bit unsure why that had to be done though, since I can't recall having needed that earlier for command line builds. )

Compilation issue with '.cu file'

I am trying compile a ".cu" file on Windows 8 but getting the following error:
nvcc fatal: Can not find compiler 'cl.exe' in PATH
I tried adding "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin" in PATH variable but it did not help. Any solution/suggestions?
Instead of manually modifying the PATH environment variable, you can execute a batch script "vsvars32.bat" located in "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools" directory. This script sets all the environment variables correctly.

Visual Studio 2012 error MSB3073

I'm trying to upgrade just my IDE, not the compiler yet, from Visual studio 2010 to 2012. I keep getting
Error 9 error MSB3073: The command ""C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Tools\..\IDE\devenv" mdlibs.sln /Build "Release|x64"" exited with code 1. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.MakeFile.Targets 38 lib_mdlibs (Visual Studio 2008)
It directs me to this code
<Target Name="Build"
DependsOnTargets="PrepareForNMakeBuild;ResolveReferences;GetTargetPath"
Returns="$(NMakeManagedOutput)">
<VCMessage Code="MSB8005" Type="Warning" Arguments="NMakeBuildCommandLine"
Condition="'$(NMakeBuildCommandLine)'==''"/>
<Exec Command="$(NMakeBuildCommandLine)"
Condition="'$(NMakeBuildCommandLine)'!=''"/>
</Target>
Specifically the second last line
I have no idea how to deal with this! I've tried a few things but nothing so far has worked
When I build just lib_mdlibs it says
The operation could not be completed
1>
1> Use:
1> devenv [solutionfile | projectfile | anyfile.ext] [switches]
1>
1> The first argument for devenv is usually a solution file or project file.
1> You can also use any other file as the first argument if you want to have the
1> file open automatically in an editor. When you enter a project file, the IDE
1> looks for an .sln file with the same base name as the project file in the
1> parent directory for the project file. If no such .sln file exists, then the
1> IDE looks for a single .sln file that references the project. If no such single
1> .sln file exists, then the IDE creates an unsaved solution with a default .sln
1> file name that has the same base name as the project file.
I thought maybe it was my Command line Build which is
"$(VS110COMNTOOLS)..\IDE\devenv" mdlibs.sln /Build "$(Configuration)|$(Platform)"
But I've tried changing it a couple of time and nothing really helps
I tried opening the just the mdlibs solution in vs2012 and building that, but when I try to build it I get a pop up that says the project file ' ' has been renamed or is no longer in the solution
Or if I try to build any of the individual projects in mdlibs.sln it says cannot perform requested action because a build is already in progress, even if I had just opened the solution
Any suggestions? Any help at all would be greatly appreciated I'm completely stuck
This is most probably because vc11 vcvars get setup as default. Go to VS2010 -> VS Tools -> VS Command Prompt (2010) & then execute your command there.
If above works, execute the 2010 vcvars.bat from the command prompt before executing devenv.exe or msbuild.exe.