Is there any way to set the ANDROID_NDK_HOME environment variable from within Visual Studio in the project/solution properties? - windows

I'm setting up build and release process for a project that does some Windows and Android development through Visual Studio 2013 (though some projects still have to have 2012 configs). I'd like for the developers to be able to stay within Visual Studio and not have to jump out to System Properties to change their environment variables in order to test another version of the NDK/SDK.
In the property sheets there's a setting that allows you to define a User Macro and expose it as an environment variable. I've followed the instructions from here (Visual Studio Property Pages Environment Variables) however it doesn't appear to be working (at least not for doing Android stuff).
We tried setting the User Macro in the property sheet for the project as well as "Microsoft.cpp.Android.User" but still get the same error when building:
1>------ Build started: Project: libstuff, Configuration: Release Android ------
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\Microsoft.Cpp.Android.Targets(570,5): error : Could not find the Android NDK, check that your ANDROID_NDK_ROOT path is correct!
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\Microsoft.Cpp.Android.Targets(570,5): error : It's currently: '<unset>'
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\Microsoft.Cpp.Android.Targets(570,5): error : The NDK can be downloaded at this URL:
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\Microsoft.Cpp.Android.Targets(570,5): error : http://developer.android.com/sdk/ndk/index.html
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
We also tried a pre build event where we set the environment variable from the command line via a "set" with no luck.
Any thoughts on why this might not be working? Is the build order different when doing Android stuff that would cause the environment variables to be set and exposed after the Microsoft.Cpp.Android.Targets is called?
UPDATE *
A small update on this.
We've been able to narrow this down to an issue with MSBuild and how it loads properties.
If you don't want to set the ANDROID_NDK_ROOT and ANDROID_SDK_ROOT you can create a user macro to set those values.
Those are:
$(AndroidNdkDir) and $(AndroidsdkDir)
When MSBuild tries to execute any android build targets it loads two files.
The first is: C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\vs-android.EnvVars.props
That is where AndroidNdkDir, AndroidSdkDir, and other android properties are set.
The second file depends on the android platform you're on. For example this is the file it's loading for us: C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Android\PlatformToolsets\arm-linux-androideabi-4.8
In that file all the Gcc properties are set.
For some reason the AndroidNdkDir property that was set in the first file is not set. I don't see any settings in the Import tag in MSBuild that controls how/if other properties are inherited. Could this be some order of operation thing?

After doing some more research is seems like the answer to this is that it cannot currently be done. I found this bullet point on the VS-Android plugin TODO list (https://code.google.com/p/vs-android/wiki/TODO_List)
Ability to override environment variables for SDK/NDK/Ant/JDK on a
per-project basis in property sheets.

Related

Visual Studio: How can I find corresponding CLI command for a GUI build operation?

I've been a linux/make guy and recently I'm learning to build UE5 engine from VS 2022. I need to figure out a CLI way to build it.
For example, I right click on one of the modules (not sure if it's the most proper name) and choose 'Build' then the build will start. I want to automate the procedure using CLI.
How can I find the corresponding CLI command for this manual operation?
I don't have access to the Unreal Engine source code and I don't know if Epic has done anything highly unconventional.
From your start menu launch the "Developer Command Prompt for VS2022". This is a shortcut file for launching the Windows command line with a batch file run to set up the PATH and other environment variables for the Visual Studio development tools.
Visual Studio project files (.csproj for C# and .vcxproj for C++ for example) are MSBuild files. (MSBuild was inspired by Ant, if that helps.)
Solution files (.sln) are a completely different format but MSBuild can build a solution file.
From the screenshot in the question I can see that the solution is UE5 which will be UE5.sln. I can also see that you want to build a C++ project. I'm guessing the project may be named BenchmarkTest (BenchmarkTest.vcxproj)?
MSBuild has a notion of targets. A target always has a name and it groups a set of tasks to be performed. (It's like a makefile rule in some respects but it's not the same.)
Solutions and projects created with Visual Studio support some standard targets. The 'Build', 'Rebuild', and 'Clean' menu items map directly to some of these targets.
Visual Studio solutions and projects support Configurations and Platforms. The standard Configurations are Debug and Release. The screenshot shows a non-standard configuration of Develop. The screenshot also shows a platform of Win64.
In the Developer Command Prompt, msbuild should be in the PATH. Try the following command:
msbuild --version
To build the solution with the default target (which is 'build') and the default configuration and platform:
msbuild UE5.sln
To run a 'clean':
msbuild UE5.sln -target:clean
The target switch can be shortened to -t.
The configuration and platform are passed as properties using the -property switch. The short form is -p. Multiple property switches can be provided and multiple properties, delimited by ';', can be provided in one property switch.
msbuild UE5.sln -t:rebuild -p:Configuration=Develop -p:Platform=Win64
or
msbuild UE5.sln -t:rebuild -p:Configuration=Develop;Platform=Win64
To build the BenchmarkTest project, specify the project file:
msbuild BenchmarkTest.vcxproj -t:build -p:Configuration=Develop;Platform=Win64

MSBuild ignoring publish profile configuration

I'm trying to publish a bunch of web services and a web site via command line using MSBuild. When I publish, the web services publish successfully but my web site does n't upon checking the logs, I've realized that msbuild is ignoring the build configurations in the specified publish profile and is using the default configurations i.e. Debug|AnyCpu. I've roamed around SO and the internet and found some articles but none worked for me.
Other SO article
I would like to be able to make MSBuild understand that I am trying to publish via the publishprofile. I tested the publish profile and visual studio and was able to execute a publish.
Here is my msbuild command
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MsBuild.exe "PATH_TO_PROJECT\PROJECT.csproj" /nodeReuse:false /nologo /p:PublishProfile="FolderProfile" /p:DeployOnBuild=True
Logs
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at
"C:\Program Files
(x86)\MSBuild\4.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets
(34,37)" does not exist in the project, and will be ignored. The
target "_CollectPdbFiles" listed in an AfterTargets attribute at
"C:\Program Files
(x86)\MSBuild\4.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets
(34,70)" does not exist in the project, and will be ignored. The
target "_CollectMdbFiles" listed in a BeforeTargets attribute at
"C:\Program Files
(x86)\MSBuild\4.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets
(41,38)" does not exist in the project, and will be ignored. The
target "_CopyMdbFiles" listed in an AfterTargets attribute at
"C:\Program Files
(x86)\MSBuild\4.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets
(41,71)" does not exist in the project, and will be ignored. Project
"C:\Git\DXT\DXT.UI.WEB.APP.DEVICES\Dxt.Web\Dxt.Web.csproj" on node 1
(default targets).
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(609,5):
error : The OutputPath property is not set for project
'Dxt.Web.csproj'. Please check to make sure that you have specified a
valid combination of Configuration and Platform for this project.
Configuration='Debug' Platform='AnyCPU'. You may be seeing this
message because you are trying to build a project without a solution
file, and have specified a non-default Configuration or Platform that
doesn't exist for this project.
[C:\Git\DXT\DXT.UI.WEB.APP.DEVICES\Dxt.Web\Dxt.Web.csproj] Done
Building Project
"C:\Git\DXT\DXT.UI.WEB.APP.DEVICES\Dxt.Web\Dxt.Web.csproj" (default
targets) -- FAILED.
Build FAILED.
"C:\Git\DXT\DXT.UI.WEB.APP.DEVICES\Dxt.Web\Dxt.Web.csproj" (default
target) (1) -> (_CheckForInvalidConfigurationAndPlatform target) ->
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(609,5):
error : The OutputPath property is not set for project
'Dxt.Web.csproj'. Please check to make sure that you have specified a
valid combination of Configuration and Platform for this project.
Configuration='Debug' Platform='AnyCPU'. You may be seeing this
message because you are trying to build a project without a solution
file, and have specified a non-default Configuration or Platform that
doesn't exist for this project.
[C:\Git\DXT\DXT.UI.WEB.APP.DEVICES\Dxt.Web\Dxt.Web.csproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.09
I tried supplying a specific configuration to avoid the Debug|AnyCpu combo but encountered errors since the website has a custom Configuration called Release.Custom and depends on projects that do not have that configuration.
Any help is much appreciated.
If anyone encounters this, I was able to fix my error by changing the value of the Configuration tag to my custom BuildConfiguration i.e. "Release.Custom". It's very stupid considering I've spent a day on this.

How does Visual Studio know my project is up to date so it can skip running MSBuild?

I have a custom MSBuild target included in my C++ project that produces a data file in the $(OutDir) folder for each item of a given item type. I have the item type hooked up with a property page schema so you can select it on files in the solution explorer and my target declares input and outputs so incremental builds work. I have also added my target to the $(BuildDependsOn) property so it is automatically evaluated during the Build target Visual Studio invokes.
Everything seems to work except for one thing: If I delete one of my output data files in the $(OutDir) and then build Visual Studio does nothing and says my project is up to date. If I delete the exe file the project produces or touch the modified time of one of the MSBuild scripts Visual Studio re-evaluates the targts and finds the output file is missing, causing it to be re-built using my target.
From the MSBuild diagnostic logging it seems like Visual Studio is internally maintaining some list of output files and input files that it checks to avoid evaluating the MSBuild script at all. How do I add my output files to this list?
MsBuild/VS indeed have a mechanism to determine what is up-to-date with respect to the input files, it revolves around an executable tracker.exe which scans .tlog files to figure out what a project's output files are. There might be more to it, and if you look around on the internet you can probably get more info about this.
But the thing is you don't really need to understand every single detail of it: you can find a simple usage example for it when inspecting how the built-in CustomBuildStep works and apply that to your case. I'll briefly explain how I got to this because I think it might be useful for you as well in dealing with msbuild questions like these.
If you add
<ItemDefinitionGroup>
<CustomBuildStep>
<Command>echo foo > $(OutDir)\foo.txt</Command>
<Outputs>$(OutDir)\foo.txt</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
either manually or via the project's property pages for Custom Build Step you'll see the beahviour is eactly what you need: if foo.txt is deleted a build will start, while a build is marked up-to-date if it is not (well, and when the rest of the outputs are also up-to-date).
Hence the key is to do what CustomBuildStep does under the hood, and figuring that out is just a matter of using your tool of choice to search all occurrences of CustomBuildStep in all files under C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120 (adjust path for platform/VS version used).
This leads us to Microsoft.CppCommon.Targets where the target named CustomBuildStep (mind you, that's the same name as the entry in the ItemDefinitionGroup above) invokes the actual CustomBuildStep command. It also has this particularily interesting bit:
<!-- Appended tlog to track custom build events -->
<WriteLinesToFile Encoding="Unicode"
File="$(TLogLocation)$(ProjectName).write.1u.tlog"
Lines="#(CustomBuildStep->'^%(Identity)');#(CustomBuildStep->MetaData('Outputs')->FullPath()->Distinct())"/>
So this writes the path of the Outputs to a .tlog file in the directory used by the tracker and makes it work as desired. Also see here for more information about the format.
tl;dr Use WriteLinesToFile to append full paths of your targets' outputs to a file like $(TLogLocation)$(ProjectName).write.1u.tlog. I'm saying like because write.tlog, write.u.tlog etc also work.
Visual Studio uses something called Visual Studio Common Project System (CPS) (https://github.com/Microsoft/VSProjectSystem) (VS 2017)
to manage projects, including build process.
Within CPS anything that implements IBuildUpToDateCheckProvider interface can be used
as a 'UpToDateChecker' for a project.
'UpToDateChecker' is invoked before invoking MsBuild. Its main purpose is to determine whether or not invoke MsBuild to build project, or to mark project as 'Up To Date' and skip msbuild all along.
This 'UpToDateChecker' is exactly what prints into diagnostic build output:
1>------ Up-To-Date check: Project: "ProjectName", Configuration:
Debug x86 ------ Project is not up-to-date: build input 'header.h' was
modified after build output 'a.out'. Input time: 12/27/2018 4:43:08
PM, Output time: 1/1/0001 2:00:00 AM
As for C++ Projects, for VS 2017 its default 'UpToDateChecker' is VCProjectBuildUpToDateCheck
( Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.dll ).
As starter, it looks into tlogs directory ( usually something like Debug\x86\.tlog) for these files:
.lastbuildstate
unsuccessfulbuild
all '.read..tlog' - input files, marked as 'build input' in diagnostic build output
all '.write..tlog' - output files, marked as 'build output' in diagnostic build output
There's actually more checks, but most fails occur when checking these 4 types
The original question here relates to C++ projects, but for anyone finding this while searching for information about modern (SDK-style) C#/VB/F# projects, you can customise Visual Studio's fast up-to-date check as described in this document:
https://github.com/dotnet/project-system/blob/master/docs/up-to-date-check.md
In a nutshell, you specify inputs and outputs as items:
UpToDateCheckInput — Describes an input file that MSBuild would not otherwise know about
UpToDateCheckBuilt — Describes an output file that MSBuild would not otherwise know about
It can be very helpful to increase the diagnostic logging level for the up-to-date check via this setting:
You can find out why a project is being rebuilt by enabling the verbosity of the fast up to date checker in the registry key:
New-ItemProperty `
-Name U2DCheckVerbosity `
-PropertyType DWORD -Value 1 `
-Path HKCU:\Software\Microsoft\VisualStudio\14.0\General -Force
You should be able to see in the build log messages like
Project 'Caliburn.Micro.Silverlight.Extensions' is not up to date. Project item 'C:\dev\projects\Caliburn.Micro.Silverlight.Extensions\NavigationBootstrapperSample.cs.pp' has 'Copy to Output Directory' attribute set to 'Copy always'.
[1] https://blogs.msdn.microsoft.com/kirillosenkov/2014/08/04/how-to-investigate-rebuilding-in-visual-studio-when-nothing-has-changed/
To enable logging for old-style projects (i.e. non-SDK-style projects, common in the .NET Framework era):
Open a "Developer Command Prompt" for the particular version of Visual Studio you are using.
Enter command:
vsregedit set "%cd%" HKCU General U2DCheckVerbosity dword 1
The message Set value for U2DCheckVerbosity should be displayed.
Run the same command with a 0 instead of a 1 to disable this logging.
More information at: https://github.com/dotnet/project-system/blob/main/docs/up-to-date-check.md#net-framework-projects

How Do I Trigger A Post-Build Event In Visual Studio Community 2013?

I right-clicked on my C++ project - Properties - Configuration Properties - Build Events - Post-Build Event and set the command line to calc.
I now do Build - Rebuild Solution and although I get this in the Output pane Calculator never launches.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
I even tried Configuration Properties - Custom Build Step - General and set the command line to notepad and Execute After to CoreBuild but nothing happened on Rebuild Solution either.
NB: My Post-Build event is actually a copy command but since that isn't working I wanted to break it down to something simpler.
I inherited this project and it had several configurations in it (ANSI Debug/Release and Unicode Debug/Release).
Since I am only targeting Unicode I manually removed those sections from the sln and vcxproj files.
With this in mind, it then became clearer that Visual Studio was showing different options for different configurations.
After switching to the All Configurations options and deleting from the other sections I could make calc run.
xcopy still failed for a while as $(TargetPath) didn't resolve correctly when the OuputFile option had been changed in the Linker to suffix "_Debug" for the debug config.
It all seems to work now.

The TypeScript Compiler was given no files for compilation, so it will skip compiling

When i am trying to Build my default JavaScript project(BlankApp Apache Cordova) in Visual Studio 2015 preview am getting following error.
The TypeScript Compiler was given no files for compilation, so it will skip compiling.
Steps Taken in visual studio 2015 preview:
File -> New -> Project -> Apache Cordova apps(under Javascript templates).
Run the default project with Android Emulator.
Getting the following error.
Warning 2 The TypeScript Compiler was given no files for compilation, so it will skip compiling. C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript\Microsoft.TypeScript.targets 97 5 BlankCordovaApp4
This is a known issue in the CTP3 release. It sounds like you've created a JS-based project, and have not added any TypeScript files, and so of course there are no .ts (aka TypeScript) files passed to the compiler. Ideally the compiler wouldn't be run at all, but the warning is harmless, and everything else should otherwise be working.
You need to make sure that at least one of your TypeScript files is marked with the TypeScriptCompile build action.
If you click on the file and check the properties window in Visual Studio you will see the build action - it may be that they are all set to some other action.
Option 1:
Take Project offline, edit project, remove the following lines:
<Import
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props"
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')"/>
and
<Import
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets"
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets')"
/>
Option 2:
Change "AddTypeScriptReferencePath": true to false in Webessentials-Settings.json
It seems that there is no type script file available to compile. add a blank type script file under script folder and then compile, it should work.
This warning was driving me nuts with ASP.NET 5 (asp.net core 1). If you double click the warning you open the Microsoft.TypeScript.targets file. Delete the line with CompileTypeScript and the warning goes away. I'm assuming this prevents TypeScript from compiling normally, which is fine by me as I don't want it anyway.
<PropertyGroup>
<CompileDependsOn>
CompileTypeScript; <--- delete this line
$(CompileDependsOn);
</CompileDependsOn>
I had the same issue.
Mine was due to missing system variable to nodejs. Check your visual studio output. If it is not recognizing “node” command, add system variable.
Computer->right click-> properties -> advanced system settings -> Environment Variable
Check “path” under user variables and system variables
Add the nodejs path to it. Ie: C:\Program Files (x86)\nodejs

Resources