Detect MSVC version in GYP - c++

I'm trying to detect a msvc version during node-gyp configure in my binding.gyp file.
Basically, I want to be able to link against particular 3rdparty library based on Visual C++ version:
['OS=="win"' and 'toolset="vc12"' , {
'libraries': [
"opencv/lib/vc12/opencv_world300.lib"
],
}],
['OS=="win"' and 'toolset="vc11"' , {
'libraries': [
"opencv/lib/vc11/opencv_world300.lib"
],
}],
['OS=="win"' and 'toolset="vc10"' , {
'libraries': [
"opencv/lib/vc10/opencv_world300.lib"
],
}]
Unfortunately, neither toolset, nor _toolset or even $(TOOLSET) variables are defined in GYP.
I wasn't able to find such variable in GYP documentation. Is it possible at all?

I couldn't figure out from the docs that how to check for toolset version, but only found the top-level settings: https://chromium.googlesource.com/external/gyp/+/master/docs/UserDocumentation.md#Skeleton-of-a-typical-executable-target-in-a-gyp-file.
However, #saper on GitHub figured it out using MSVS_VERSION instead:
['OS=="win"' and 'MSVS_VERSION=="2013"' , {
'libraries': [
"opencv/lib/vc12/opencv_world300.lib"
],
}],
['OS=="win"' and 'MSVS_VERSION=="2012"' , {
'libraries': [
"opencv/lib/vc11/opencv_world300.lib"
],
}],
['OS=="win"' and 'MSVS_VERSION=="2010"' , {
'libraries': [
"opencv/lib/vc10/opencv_world300.lib"
],
}]
(nit: in your example, although toolset token is not identified by gyp, = should be replaced with ==)
Example: https://github.com/saper/node-sass/blob/c7e9cf0f0e0098e8316bd41722fc2edf4a835d9f/src/libsass.gyp#L91-L94.
Limitation 1:
Unfortunately, these conditions are not emitted in the .targets or .vcxproj files (such as this), but it will emit the .vcxproj after post-processing the conditions separate for the given version of MSVS and hence renders the .vcxproj file incompatible with newer/older versions of VCR.
However, the MSVS version can by overridden for gyp in multiple ways, for instance, using environment variable:
In CMD:
SET GYP_MSVS_VERSION=2012
Or in PowerShell:
$env:GYP_MSVS_VERSION=2015
It can also be passed as a command line argument:
node_modules/.bin/node-gyp build --msvs_version=2012
If both env-var and command line argument are present, CLI arg will take the precedence.
This CLI argument can be supplied to npm task, for example, to enforce the constraint for all the Windows consumers of your package to use specific version of MSVCR otherwise error.
and since so forth..
Limitation 2:
From CLI arg, there is no way to specify minimum MSVS version no such flag as: --min-msvs-version.
Limitation 3:
In case of multiple version of MSBUILD installed, node-gyp's MSBUILD discovery (at present) will ignore the preferred/required version of toolset by .vcxproj, but will give precedence to the one in PATH. In this case, you may get errors, for instance if you are using C99/C++1[1/4/7] features only offered by VS2015. To remedy this situation:
either reset PATH to the desired version MSBuild bin directory.
instead of node-gyp build or rebuild, use node-gyp configure followed by "%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild" build/binding.sln /p:Configuration=Release (or from posh, it would become: &"${env:ProgramFiles(x86)}\MSBuild\14.0\Bin\MSBuild" build\binding.sln /p:Configuration=Release)
by sending a Pull Request for node-gyp and pangyp to fix the toolset-version-aware MSBUILD discovery, if your Windows Registry skills are not as rusty as mine. :)

Related

vcpkg does not use registry defined in `vcpkg-configuration.json`

I'm trying to use a modified version of imgui through vcpkg.
I've created a git repository to be used for the registry (https://github.com/altschuler/vcpkg-custom-ports), and copied over the imgui port configuration, and made the changes I needed (following guides like this and this).
However, vcpkg seems to ignore the entry for the custom repo in vcpkg-configuration.json, it simply doesn't load anything from it (I know because I tried changing the repository url to something that doesn't exist). If I set the default-repository to my custom one it does load stuff, but then all the packages I want from the builtin registry obviously fail to install.
Note: the reason I need a custom port for imgui is that I need to compile some definitions (basically just do target_compile_definitions in its CMakeLists). If you know of an easier way to do that I'm all ears.
vcpkg-configuration.json:
{
"registries": [
{
"kind": "git",
"baseline": "e3b33f3a548f20ba06b2959aa3701bd50ece0638",
"repository": "https://github.com/altschuler/vcpkg-custom-ports.git",
"packages": ["imgui"]
}
]
}
vcpkg.json:
{
"name": "tester",
"version-string": "0.1.0",
"dependencies": [
"lager",
"sdl2",
{
"name": "imgui",
"features": ["docking-experimental", "sdl2-binding", "opengl3-binding"]
},
"immer",
"cereal",
"rxcpp",
"range-v3",
"glew",
"boost"
]
}
Try setting an environment variable
VCPKG_FEATURE_FLAGS=manifests,binarycaching,registries
AFAIK, some features are not enabled by default. Seems that manifests are automatically enabled, so vcpkg.json gets picked up, but perhaps "registries" are not enabled by default. (Disregard "binarycaching", if you don't use it).
This is what is working for me.

Why default build tasks in vs code runs in powershell instead of the default terminal selected? [duplicate]

When I woke up this morning and launched VSCode my default terminal on launch, and when running tasks is now powershell, instead of Git Bash. I am on windows. I have tried changing the settings.json to no avail. Is there something I'm missing?
{
"workbench.startupEditor": "newUntitledFile",
"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe",
"[javascript]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"aws.samcli.location": "C:\\Users\\king\\AppData\\Roaming\\npm\\sam.exe",
"typescript.updateImportsOnFileMove.enabled": "always",
"[html]": {
"editor.defaultFormatter": "vscode.html-language-features"
},
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"javascript.updateImportsOnFileMove.enabled": "always",
"explorer.confirmDragAndDrop": false,
"diffEditor.maxComputationTime": 0,
"extensions.ignoreRecommendations": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.renderControlCharacters": true,
"[jsonc]": {
"editor.quickSuggestions": {
"strings": true
},
"editor.suggest.insertMode": "replace"
},
"window.zoomLevel": 0,
"editor.accessibilitySupport": "off",
"workbench.editor.untitled.hint": "hidden",
"terminal.integrated.defaultProfile.windows": "Git Bash",
"terminal.external.windowsExec": "C:\\Program Files\\Git\\bin\\bash.exe",
"terminal.explorerKind": "external",
"terminal.integrated.automationShell.linux": ""
}
I found this related SO post making the default powershell, but I didn't see anything that was incorrect about my setting...especially because my goal is the opposite- to stop Powershell!
Update: Version v1.60.0 had a bug. Upgrade to v1.60.1 or higher for a fix.
The bug manifested in the following symptoms:
The Open in Integrated Terminal shortcut-menu command in the Explorer pane's shortcut always uses the built-in default shell (PowerShell on Windows), ignoring the configured one.
The same goes for running tasks (with or without a separate terminal.integrated.automationShell.* setting).
Also, if a given folder or workspace happened to have an integrated terminal open when quitting Visual Studio Code, the shell that is launched when the integrated terminal automatically reopens the next time is again the built-in default shell, not the configured one. By contrast, if reopening doesn't auto-open the integrated terminal, opening it manually does respect the configured default shell, and so does manually creating another shell instance later.
See GitHub issue #132150
The following information turned out to be unrelated to the bug, but is hopefully still useful general information about Visual Studio Code's recent change in how shells for the integrated terminal are configured:
Migrating from the legacy default shell settings to shell profiles:
Recently, the "terminal.integrated.shell.*" and "terminal.integrated.shellArgs.*" settings were deprecated and replaced with a more flexible model that allows defining multiple shells to select from, via so-called shell profiles, optionally defined in setting "terminal.integrated.profiles.*", with an associated mandatory "terminal.integrated.defaultProfile.*" setting referencing the name of the profile to use by default - which may be an explicitly defined custom profile or one of the built-in, platform-appropriate default profiles.
Note: * in the setting names above represents the appropriate platform identifier, namely windows, linux, or osx (macOS).
As of v1.60.1, if legacy "terminal.integrated.shell.*" settings are also present, the new settings take precedence (even though the tooltip when editing "terminal.integrated.shell.*" in settings.json suggests that this change is yet to come).
In the absence of both settings, Visual Studio Code's built-in default shell is used, which on Windows is PowerShell,[1] and on Unix-like platforms the user's default shell, as specified in the SHELL environment variable.
Recent Visual Studio Code versions, starting before v1.60 - seemingly as one-time opportunity - displayed a prompt offering to migrate the deprecated settings to the new ones.
Accepting the migration results in the following:
Creation of setting "terminal.integrated.shell.*" containing a custom shell profile derived from the values of legacy settings "terminal.integrated.shell.*" and, if present, "terminal.integrated.shellArgs.*"; that custom profile's name has the suffix (migrated)
Creation of setting terminal.integrated.defaultProfile.* whose value is the migrated profile's name, making it the default shell.
Removal of legacy settings "terminal.integrated.shell.*" and "terminal.integrated.shellArgs.*"
If you decline the migration, you can later effectively perform it by re-choosing the default shell, as described below.
Note: The new "terminal.integrated.defaultProfile.*" setting that is created in the process then effectively overrides the legacy "terminal.integrated.shell.*" and "terminal.integrated.shellArgs.*" settings, but the latter won't be removed automatically. To avoid confusion, it's best to remove them from settings.json manually.
Choose the default shell profile to use in order to (re)specify the default shell:
Click on the down-arrow part of the shell-selector icon () on the right side of the integrated terminal, select Select Default Profile, which presents a list of the defined profiles to select the default from - in the absence of explicitly defined profiles, standard profiles are offered (see below).
This translates into a terminal.integrated.defaultProfile.* setting in settings.json, whose value is the name of the chosen shell profile - which may be the name of a built-in profile or one of the ones explicitly defined in "terminal.integrated.profiles.*"
Note: This shell is by default also used for tasks (defined in tasks.json), but that can be overridden with a "terminal.integrated.automationShell.*" setting pointing to the executable of an alternative shell.
Optionally, in your settings.json file, you may create a platform-appropriate terminal.integrated.profiles.* setting with shell profiles of interest:
Note: Even if your settings.json contains no (platform-appropriate) "terminal.integrated.profiles.*" setting, Visual Studio code has built-in standard profiles it knows of and offers them for selection when choosing the default shell.
These standard profiles are a mix of shells that come with the host platform as well as some that Visual Studio detects dynamically on a given system, such as Git Bash on Windows.
To create the standard profiles explicitly, do the following:
Note: You may choose to do this in order to customize the standard profiles. However, if your intent is merely to add custom profiles - see this answer for an example - it isn't necessary to create the standard profiles inside the "terminal.integrated.profiles.*" setting, because Visual Studio Code knows about them even if not explicitly defined.
Via File > Preferences > Settings (Ctrl-,), search for profiles and click on Edit in settings.json below the platform-appropriate Terminal > Integrated > Profiles > * setting; this will open settings.json for editing, with the standard profiles added; simply saving the file is sufficient.
Note: If the "terminal.integrated.profiles.*" setting shown doesn't contain the expected, platform-appropriate standard profiles, a setting by that name may already be present; to force creation of the standard profiles, remove or comment out the existing setting and save the file, then try again.
On Windows, you'll end up with something like the following:
"terminal.integrated.profiles.windows": {
"PowerShell": {
"source": "PowerShell",
"icon": "terminal-powershell"
},
"Command Prompt": {
"path": [
"${env:windir}\\Sysnative\\cmd.exe",
"${env:windir}\\System32\\cmd.exe"
],
"args": [],
"icon": "terminal-cmd"
},
"Git Bash": {
"source": "Git Bash"
}
}
The answer you link to in your question, which provides an overview of the various types of shells used in Visual Studio Code, has been updated to reflect the information about the new shell profiles.
[1] Note: If a PowerShell (Core) v6+ installation is found, it takes precedence over the built-in Windows PowerShell version.
Edit:1
Note: Now this bug has been fixed by VSCode. Just update your VSCode to the latest version. (17-Sep-2021)
I have a temporary solution.
First paste this code in settings.json and save
"terminal.integrated.defaultProfile.windows": "Git Bash",
"terminal.integrated.profiles.windows": {
"C:\\Program Files\\Git\\bin\\bash.exe": {
"path": "",
"args": []
}
},
Before closing VSCode select Output instead of Terminal
Now you can open VSCode
After VSCode is loaded, you need to click on Terminal. After this you will now see bash.
Select output before whenever you close VSCode.
Reference: VSCode is suddenly defaulting to PowerShell for integrated terminal instead of $Bash in Windows
Note: This is not an solution. I shared this because maybe it can save you from getting disappointed.
This is my first post, if there is any mistake please let me know so that I can correct it.
You can always download and install previous releases from the official website https://code.visualstudio.com/updates/v1_59 (currently at the top).
As version 1.60 was bugged, v1.59 is a good candidate.
Disable automatic updates
Explained here.
Open User Settings File > Preferences > Settings.
Add "update.mode": "none" to your settings.
Install older version
Afterwards you can just overwrite current version with the installation of downloaded version.
Note: Wait for next version to fix it, so remember you had automatic update disabled!
I have same problem but I try run command prompt. I fix it by adding to ...\Code\User\settings.json
"terminal.integrated.automationShell.windows": "cmd.exe",
This could be related to issue 138999 which will add a mitigation/enhancement to VSCode 1.70 (July 2022) with PR 154290 and commit 91b82c0
increase barrier for available profiles to be ready
Wait up to 20 seconds for profiles to be ready so it's assured that we know the actual default terminal before launching the first terminal.
This isn't expected to ever take this long.
For VSCode with synchronized user settings, the profile might take more time than expected to fully load, hence the advantage of that workaround.
Simply replaced the CMD by Git Bash :-) in the settings.json
"terminal.integrated.profiles.windows": {
"PowerShell": {
"source": "PowerShell",
"icon": "terminal-powershell"
},
"Command Prompt": {
"path": [
//"${env:windir}\\Sysnative\\cmd.exe",
//"${env:windir}\\System32\\cmd.exe"
"C:\\PrivateProgramms\\Git\\bin\\bash.exe"
],
"args": [],
"icon": "terminal-cmd"
},
"Git Bash": {
"source": "Git Bash"
//"path": [ "C:\\PrivateProgramms\\Git\\bin\\bash.exe" ],
//"args": [],
//"icon": "terminal-cmd"
}
},
"terminal.integrated.defaultProfile.windows": "Command Prompt"

Nuget error during build

I grabbed this repo CommandLIneParser
and opened it in Visual Studio 2017. Build fails because Nuget fails. In the nuget package manager I see messages like this:
Dependency '"CommandLine": {
"target": "project"
}' has invalid version specification.
What does that mean and how can I resolve it?
Second problem (may be caused by the first). During build I get this error:
Error occurred while restoring NuGet packages: Invalid restore input.
UAP projects must contain exactly one target framework. Input files:
C:\Users\Jerry\Source\Repos\commandline\tests\CommandLine.Tests\CommandLine.Tests.csproj,
C:\Users\Jerry\Source\Repos\commandline\tests\CommandLine.Tests\project.json.
but both projects do, in fact, target the same framework (.net 4.5, in this case). So I'm guessing that the error message means something else?
Update:
Now that I'm looking at the two files in the error message, I'm getting a clue:
CommandLine.Tests.csproj has:
<TargetFrameworks>netstandard1.5;net40;net45</TargetFrameworks>
project.json has:
"testRunner": "xunit",
"frameworks": {
"netcoreapp1.0": {
"buildOptions": {
"define": [ "PLATFORM_DOTNET", "SKIP_FSHARP" ],
"keyFile": "../../CommandLine.snk"
},
So I see the mismatch. But that just leaves me with the somewhat-rhetorical question: "How did the last version ever build?"

Configuring DUB to use 64-bit compiler

How do I configure DUB to compile my application as 64-bit executable? Here's my dub.json:
{
"name": "dvulkanbase",
"targetType": "executable",
"description": "Vulkan boilerplate",
"authors": ["Myself"],
"homepage": "http://something",
"license": "MIT"
}
I tried adding this line to dub.json:
"dflags-dmd": ["-m64"]
but then dub build outputted:
## Warning for package dvulkanbase ##
The following compiler flags have been specified in the package description
file. They are handled by DUB and direct use in packages is discouraged.
Alternatively, you can set the DFLAGS environment variable to pass custom flags
to the compiler, or use one of the suggestions below:
-m64: Use --arch=x86/--arch=x86_64/--arch=x86_mscoff to specify the target architecture
Performing "debug" build using dmd for x86.
So I tried replacing the line with:
"dflags-dmd": ["--arch=x86_64"]
but got this error:
Error: unrecognized switch '--arch=x86_64'
I'm on Windows 10, have DMD 2.074.0 and Visual Studio 2015 and 2017 installed.
I am pretty sure (correct me if I am wrong) that you did not configure DMD properly for the 64bit environment.
Have a look at http://dlang.org/dmd-windows.html#environment . - The key information there is that you need to set LINKCMD64 variable correctly. Example: set LINKCMD64=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\link.exe
Then you instruct the DMD compiler (with the -m64 option) to compile the D code and use Microsoft's linker to generate 64bit executable.
Finally, you will need to modify your JSON or SDL DUB file to contain proper environment settings. ( Have a look at https://code.dlang.org/package-format?lang=json#target-types )
If you do not specify the environment in the DUB file, you will have to explicitly provide it in your dub build. Example: dub build --arch=x86_64

Turning off "Language Service Disabled" error message in VS2017

We are getting the following "Error" message in our MVC web application in Visual studio 2017 Enterprise.
The language service is disabled for project 'C:\Work\Blackhawk
Platform\Platform-DEV-Branch\BlackhawkViewer\BlackhawkViewer.csproj'
because it included a large number of .js files. Consider excluding
files using the 'exclude' section of a 'tsconfig.json' file.
I have tried turning off the Language service in the options but this does not turn the message off:
This is a rather large web application. Is there a way to turn this message off without disabling any files in the tsconfig.json file as it suggests?
To solve this issue do the following:
Create file in root directory of your project and call it tsconfig.json
Add this:
{
"compilerOptions": {
"allowJs": true,
"noEmit": true,
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
},
"include": [
"scripts"
],
"exclude": [
],
"typeAcquisition": {
"enable": true
}
}
Please have a look at the below two links for tsconfig.json explanation, because you may still need to change it according to your setup. This is the only way that worked for me. I hope that will help.
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
https://developercommunity.visualstudio.com/content/problem/8148/javascript-intellisense-not-working.html
This helped me. You can have a try.
Go to Tools -> Options -> Text Editor -> JavaScript/TypeScript -> Language Service -> General
and uncheck the box: "Enable the new JavaScript language service.
I have found a solution for this problem.
I reset my userData using:
devenv.exe /resetuserdata
Since doing this the JavaScript settings seem to have persisted and I no longer get the language service error above.
TAKE NOTE: This will reset all your user data and customisations.
In My case I just disable TypeScript support on Visual Studio:
Tools > Extensions and Updates > TypeScript for Microsoft Visual Studio > Disable
After that, just restart Visual Studio, and you are good to go.
Hope this will help,
I had the same problem after migrating Ionic 1 project from VS2015 to VS2017, first I executed git clean -fxd as sugested above and added this content into tsconfig.json in my ionic project.
{
"compilerOptions": {
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "es5"
},
"exclude": [
"node_modules",
"www",
"bower_components"
]
}
I solved this problem with following solution:
When you have a JavaScript file that is included in the project.csproj file but isn't in the project folder, this error occurred.
For example I have a .csproj file like below:
<ItemGroup>
<Content Include="Scripts\Test.js" />
</ItemGroup>
The Test.js is included in the .csproj file, but it isn't in the Scripts folder:
Delete the <Content Include="Scripts\Test.js" /> line from the .csproj file and rebuild your project
Solution that worked for me:
Go to C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE>.
Open command prompt as admin in current folder
Ran devenv /Setup
Ran devenv /ResetSkipPkgs
For me is helping the next solution. I've create a tsconfig.json file in root of the my project with "disableSizeLimit": "true" option.
So, my tsconfig.json file is:
{
"compilerOptions": {
"disableSizeLimit": "true"
},
"exclude": []
}
If none of suggested methods worked, try:
npm install -g typescript#latest
and then
Install the latest version of TypeScript for Visual Studio on Get TypeScript.