How do I compile a single source file within an MSVC project from the command line? - visual-studio

I'm about to start doing some benchmarking/testing of our builds, and I'd like to drive the whole thing from a command line. I am aware of DevEnv but am not convinced it can do what I want.
If I could have a single file built within a single project, I'd be happy.
Can this be done?

The magical incantation is as follows. Note that this has only been tested with VS 2010 - I have heard this is the first version of Visual Studio with this capability:
The Incantation
<msbuild> <project> <settings> <file>
Where
msbuild is a path to MSBuild.exe. Usually this should be set up for you by the VS2010 bat file so the right one will end up in your PATH, but if not I found one at C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe
project is the path to the vcxproj file within which your source file resides.
settings include the following:
/p:Configuration="Debug" // or whatever your Configuration is
/p:Platform=x64 // or x86
/t:ClCompile // to specify specifically you're looking to compile the file
file is actually another setting:
/p:SelectedFiles="path_to_file"
Notes
For <project> I had to specify a project (vcxproj) file instead of a solution (sln) file. The sln I would have used has multiple projects within it, so there would have been extra work to go that route anyhow (if it can even be done).
For the /p:Platform=x64 setting, there are several environment variables that pivot on what platform you are targeting (x64 v. x86) so make sure you set those up properly via Visual Studio's vcvarsall.bat.
Regarding path_to_file in the SelectedFiles parameter, this path must be the path as specified in the project file. If the path does not match the path used in the project file to reference the source, it doesn't seem to work.

Related

Setting Environment variable in Visual studio C++project

I realize that similar questions were posted earlier but I need slightly different solution.
I have VS2012 C++ project A.vcxproj,that has debug1 configuration( platform x64) , and it builds corresponding .exe. It also uses a dll from other VS2012 C project B.vcxproj from a path that must be added to the environment variables. A.vcxproj.user file has following text
<LocalDebuggerEnvironment>PATH=%PATH%;C:\Program Files\libsndfile\bin;..\..\lib\simulink\;$(LocalDebuggerEnvironment) </LocalDebuggerEnvironment>
I need to add this setting automatically to the "A"project with following constraints
I cannot export user file as it as "per user", so cannot upload to our SCM system where other users can download it.
I tried adding code in main function, something like
_putenv("PATH = ....\lib\simulink");
but this does not work, as before the main file is compiled, it needs to search for the dll from specified path, which it dosn't .
Can anyone suggest a easy, portable fix , that i could distribute to all users through SCM, along with the project file.
I have also tried following:
--Created batch file setpath.bat with following content
#ECHO %PATH% set PATH = %PATH%;C:\Program Files\libsndfile\bin;C:\dev\lib\simulink
-- added to A.vcxproj settings->build event->Pre-build->Command line
call C:\setpath.bat
and I don't see the added paths under vS op window. neither does the VS User file gets the change, and running the project complains for missing dll error.
--I tried to execute the batch file in
A.vcxproj settings->
Custom build step->Execute before "Run"
and still no result.
I guess the solution needs to add needed path to current environment variable for the time VS project is "run".
Thanks
sedy
added to A.vcxproj settings-> Build Events ->Pre-Build event
call setdllpath.bat
where the file contains the following:
#ECHO %PATH%
set COMSPEC = "%VCINSTALLDIR%\vcvarsall.bat" amd64
setx PATH "C:\Program Files\libsndfile\bin;..\..\lib\simulink"
#ECHO %PATH%
So, once I build the Project, close Visual studio and open it again, and run the files wiithin project, it picks up dll correctly.
Contents in *.vcxproj.user, *.vcxproj.user or *.props use the same xml schema so can be easily exchanged or included.
First if usefull you can add UserMacros to define the path to your libraries.
Like bellow for the following two variable
PYTHONHOME=$(USERPROFILE)\AppData\Local\Programs\Python\Python37
PYTHONPATH=$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages
Edit the .vcxproj adding inside <Project>:
<Project .... >
...
<PropertyGroup Label="UserMacros">
<PYTHONHOME>$(USERPROFILE)\AppData\Local\Programs\Python\Python37</PYTHONHOME>
<PYTHONPATH>$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages;</PYTHONPATH> </PropertyGroup>
...
</Project>
After you can add inside your build configuration, the following to set the $(Path) variable.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<LocalDebuggerEnvironment>Path=$(Path);$(PYTHONHOME);$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages;$(PYTHONHOME)\Scripts;$(PYTHONHOME);</LocalDebuggerEnvironment>

Visual Studio Custom Build Default Directory Incorrect

My Visual Studio 2013 Custom Build Tool step is failing because the directory in which the step is being executed is not the directory where the project file is (which was by default the case up until recently). I can patch it by adding a cd command to the start of the step to change to the project directory but I was wondering if anyone could tell me
how this directory path is set
how to change it.
The build always assumes the project directory as 'base' directory.
This gives msbuild a set location (Builds to bin\debug is a subfolder off 'Base', reference hint paths and a lot more besides).
I would just change the execute of your tool to be reference based (i.e ....\tool.exe or similar) or make use of the path environment variables ($(OutDir),$(TargetPath),$(ProjectPath),$(TargetDir) etc).
Another option that I make use of is to have a batch file called 'post.bat' that has the necessary steps to execute a custom tool. This is then placed in the project folder and added to the project as an artefact.
Without knowing exactly where your custom tool resides relative to the project (or solution) or what the 'working directory' requirements of the custom tool are I cannot suggest more.

What is the default location for MSBuild logs?

I am using Visual Studio Express 2012. Where is the location of the log file? I have searched in the folder where my solution and projects are stored, but cannot find any .log file.
This is the configuration for logging:
Log file from Visual Studio is only supported for C++ projects. You just have to work with the output window for others.
See this similar thread: VS2010: minimal build log in output and detailed log in log file
And in case you happen to do this for a C++ project, the file is at:
... build log in the intermediate files directory
... The path and name of the build log is represented by the MSBuild macro
expression, $(IntDir)\$(MSBuildProjectName).log.
Use build output instead of logging to file. Instead of copy/paste, simply click somewhere in the output and press CTRL + S to save. Visual Studio will prompt you for a location (tested with Visual Studio 2017, but I'm assuming this works in earlier versions too).
The msdn documentation is pretty clear about this (And you ain't gonna like it!):
https://msdn.microsoft.com/en-us/library/jj651643.aspx
Where it says:
To create a build log file for a managed-code project On the menu bar,
choose Build, Build Solution.
In the Output window, highlight the
information from the build, and then copy it to the Clipboard.
Open a
text editor, such as Notepad, paste the information into the file, and
then save it.
While it's true that VS doesn't allow this directly, it is still possible to build with MSBuild "inside" VS2015 and get both the build window output and the log file, as follows: (Arguably this is a bit of a hack.)
In your VS Managed solution, add a new project (Let's call it 'Make').
a. The project type you want is Visual C++/NMake project.
Define the MSBuild commands you need on the command line (see below).
Change the solution configuration to build the NMake project instead of the normal managed projects.
This will create a project that has Build, Rebuild, and Clean command lines where you can execute MSBuild directly. For example:
Rebuild: MSBuild.exe /ds /v:diag /property:Configuration=Debug ..\BuildTest\BuildTest.csproj /t:Clean,Build
Build: MSBuild.exe /ds /v:diag /property:Configuration=Debug ..\BuildTest\BuildTest.csproj /t:Build
Clean: MSBuild.exe /ds /v:diag /property:Configuration=Debug ..\BuildTest\BuildTest.csproj /t:Clean
You can also specify multiple MSBuild.EXE command lines in order to build multiple projects. For the usual build-the-entire-solution outcome you can target only the final end assemblies and let the dependency graph generate the individual targets.
This will produce a .log file, where NAME is the name of the NMake project you used. In the example above, the log would be make.log.
A working example is available on GitHub:
https://github.com/bitblitz/VS_MsbuildExample
(Tested with VS2015)
Note that building individual projects directly will still build with the normal VS behavior, but you can build the full solution inside VS and get the build logs.

Force VS2010 to keep the build output path absolute

We want to have our build server send the output of each build to
C:\Projects\{project name}\build\{build configuration}\.
To accomplish this, I set the Build Output path property for my projects to that in Visual Studio 2010, and build locally to make sure everything works. When I do so, visual studio changes the path to a relative one, for example ..\..\build\Debug.
Since the project directory is not the same on the build server (we use TeamCity, so the project url there is something like C:\BuildAgent\work\9358A92GF92), the output doesn't end up where we want it.
How do I make Visual Studio not change the build output paths to relative paths?
You cannot convince the IDE to make it absolute. Possible solutions:
Use a post-build event to xcopy the build output
It won't make the path relative if the output directory is on another drive. You could use the SUBST command to map a drive letter like z: to a folder on c: and fool the IDE that way
Run msbuild.exe directly on the build machine. Use the /p command line option to force the OutDir property to another value.
Solution 3 is probably best since you can make it specific to the build machine without tinkering with the project files and make the devs' lives difficult. The command should look similar to this:
msbuild /p:outdir=c:\mumble\ projectOrSolutionFileName
Beware that the output directory name must end with a trailing backslash
You can not convince IDE to use absolute path, but you can change the Project file:
<OutputPath>C:\Dir1\Dir2</OutputPath>
Your IDE will still show relative path but it will store the absolute path.
Works for me with Visual studio 2010 Sp1

Is there a way to extract info from vs project, eg cl.exe command line

Since I write a command line program to check cpp files, and it need lib path and include path of those cpp files.
How can I get the include and lib path info from visual studio project? Our project uses property sheets to make up those information.
It is made up from 3 distinct sources:
Tools + Options, Projects and Solutions, VC++ Directories. In turn built up from several registry keys
the settings in your .vsprops project property sheets
the settings in your .vcproj project
The first part is the hardest, you can get it by running vc\vsvarsall.bat. The .vsprops and .vcproj files are XML, easy to parse.
If you just want to find out what the command line should look like then you can get it from the buildlog.htm file, produced when building from the IDE. Or you could use vcbuild.exe on the command line to build your project from the .vcproj file. Or you could build using devenv.exe /build.
Check out the Visual Studio project files - they're typically only XML files, so you should be able to extract out whatever you need from those, really. Just a matter of understanding and parsing your XML contents in the project file, really.

Resources