Initial commit
This commit is contained in:
5
server/node_modules/buildcheck/.eslintrc.js
generated
vendored
Normal file
5
server/node_modules/buildcheck/.eslintrc.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: '@mscdex/eslint-config',
|
||||
};
|
||||
88
server/node_modules/buildcheck/.github/workflows/ci.yml
generated
vendored
Normal file
88
server/node_modules/buildcheck/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
tests-linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-macos-intel:
|
||||
runs-on: macos-15-intel
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-macos-arm:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-windows-2022:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
27
server/node_modules/buildcheck/.github/workflows/lint.yml
generated
vendored
Normal file
27
server/node_modules/buildcheck/.github/workflows/lint.yml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
NODE_VERSION: 22.x
|
||||
|
||||
jobs:
|
||||
lint-js:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install ESLint + ESLint configs/plugins
|
||||
run: npm install --only=dev
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
3
server/node_modules/buildcheck/.npmignore
generated
vendored
Normal file
3
server/node_modules/buildcheck/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.eslintcache
|
||||
**/node_modules/**
|
||||
/package-lock.json
|
||||
19
server/node_modules/buildcheck/LICENSE
generated
vendored
Normal file
19
server/node_modules/buildcheck/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright Brian White. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
106
server/node_modules/buildcheck/README.md
generated
vendored
Normal file
106
server/node_modules/buildcheck/README.md
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
# Description
|
||||
|
||||
Build environment checking for [node.js](http://nodejs.org/).
|
||||
|
||||
This allows for autoconf-like functionality for node addons/build scripts.
|
||||
|
||||
**Note:** Obsolete and/or exotic build environments or platforms not supported
|
||||
by node.js are not supported.
|
||||
|
||||
## Requirements
|
||||
|
||||
* [node.js](http://nodejs.org/) -- v10.0.0 or newer
|
||||
* Supported compilers:
|
||||
* gcc
|
||||
* clang
|
||||
* MSVC 2013+ and Windows SDK 8.1+
|
||||
|
||||
## Installation
|
||||
|
||||
npm install buildcheck
|
||||
|
||||
## Examples
|
||||
|
||||
### Check if a C function exists
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
const BuildEnvironment = require('buildcheck');
|
||||
|
||||
const buildEnv = new BuildEnvironment();
|
||||
|
||||
console.log(buildEnv.checkFunction('c', 'preadv2'));
|
||||
```
|
||||
|
||||
### Check if a C header is usable
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
const BuildEnvironment = require('buildcheck');
|
||||
|
||||
const buildEnv = new BuildEnvironment();
|
||||
|
||||
console.log(buildEnv.checkHeader('c', 'linux/io_uring.h'));
|
||||
```
|
||||
|
||||
### Try to compile some C code
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
const BuildEnvironment = require('buildcheck');
|
||||
|
||||
const buildEnv = new BuildEnvironment();
|
||||
|
||||
// Should be a successful compile
|
||||
console.log(buildEnv.tryCompile('c', 'int main() { return 0; }'));
|
||||
|
||||
// Should be a failed compile
|
||||
console.log(buildEnv.tryCompile('c', 'int main() { return z; }'));
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Exports
|
||||
|
||||
The exported value is `BuildEnvironment`, the main class for dealing with a build environment.
|
||||
|
||||
### BuildEnvironment
|
||||
|
||||
#### Methods
|
||||
|
||||
* **(constructor)**([< _object_ >config]) - Creates and returns a new BuildEnvironment instance. `config` may contain:
|
||||
|
||||
* **compilerC** - _string_ - C compiler command to use. *Note: this is ignored on Windows.* **Default:** `process.env.CC` or `'cc'`
|
||||
|
||||
* **compilerCXX** - _string_ - C++ compiler command to use. *Note: this is ignored on Windows.* **Default:** `process.env.CXX` or `'c++'`
|
||||
|
||||
* **msvs_version** - _mixed_ - A string or number containing the year of the Visual Studio compiler to use. *Note: this is for Windows only.* **Default:** newest version installed
|
||||
|
||||
* **checkDeclared**(< _string_ >lang, < _string_ >symbolName[, < _object_ >options]) - _boolean_ - Checks if a symbol `symbolName` is declared where `lang` is either `'c'` or `'c++'`. Returns `true` if symbol exists, `false` otherwise. `options` may contain:
|
||||
|
||||
* **headers** - _array_ - A list of headers to try when checking if the symbol is declared. `checkFunction()` will always first try without a library. If not supplied, a default list of common (platform-specific) headers will be used.
|
||||
|
||||
* **searchLibs** - _array_ - A list of library names (without the `'-l'` prefix) to try when checking if the symbol is declared. `checkDeclared()` will always first try without a library.
|
||||
|
||||
* **checkFunction**(< _string_ >lang, < _string_ >functionName[, < _object_ >options]) - _boolean_ - Checks if a function `functionName` exists and is linkable where `lang` is either `'c'` or `'c++'`. Returns `true` if function exists, `false` otherwise. `options` may contain:
|
||||
|
||||
* **searchLibs** - _array_ - A list of library names (without the `'-l'` prefix) to try when checking for this function. `checkFunction()` will always first try without a library.
|
||||
|
||||
* **checkFeature**(< _string_ >featureName) - _mixed_ - Executes a special test for a "feature" and returns the result. Supported values for `featureName`:
|
||||
|
||||
* `'strerror_r'` - Returns an object containing:
|
||||
|
||||
* `declared` - _boolean_ - Whether `strerror_r()` is declared
|
||||
|
||||
* `returnsCharPtr` - _boolean_ - If `strerror_r()` is declared, whether it returns `char*` (a GNU extension) or not.
|
||||
|
||||
* **checkHeader**(< _string_ >lang, < _string_ >headerName) - _boolean_ - Checks if the header `headerName` exists and is usable where `lang` is either `'c'` or `'c++'`. Returns `true` if the header exists and is usable, `false` otherwise.
|
||||
|
||||
* **defines**([< _string_ >lang[, < _boolean_ >rendered]]) - _array_ - Returns a list of features, functions, headers, and symbols known to be defined by this build environment instance. `lang` is either `'c'` or `'c++'` If `lang` is not set, defines for both `'c'` and `'c++'` will be returned. If `rendered` is `true` (defaults to `false`), autoconf-style defines (e.g. "HAVE_FOO=1") will be returned instead. Defines coming from features utilize base strings/names from autoconf for better compatibility.
|
||||
|
||||
* **libs**([< _string_ >lang]) - _array_ - Returns a list of (`'-l'`-prefixed) libraries known to be required for features and functions defined by this build environment instance. `lang` is either `'c'` or `'c++'` If `lang` is not set, defines for both `'c'` and `'c++'` will be returned.
|
||||
|
||||
* **tryCompile**(< _string_ >lang, < _string_ >code[, < _array_ >compilerParams]) - _mixed_ - Attempts to compile `code` where `lang` is either `'c'` or `'c++'`. `compilerParams` is an optional array of compiler/linker flags to include. Returns `true` on successful compilation, or an _Error_ instance with an `output` property containing the compiler error output.
|
||||
250
server/node_modules/buildcheck/deps/Find-VisualStudio.cs
generated
vendored
Normal file
250
server/node_modules/buildcheck/deps/Find-VisualStudio.cs
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
// Copyright 2017 - Refael Ackermann
|
||||
// Distributed under MIT style license
|
||||
// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
|
||||
|
||||
// Usage:
|
||||
// powershell -ExecutionPolicy Unrestricted -Command "Add-Type -Path Find-VisualStudio.cs; [VisualStudioConfiguration.Main]::PrintJson()"
|
||||
// This script needs to be compatible with PowerShell v2 to run on Windows 2008R2 and Windows 7.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VisualStudioConfiguration
|
||||
{
|
||||
[Flags]
|
||||
public enum InstanceState : uint
|
||||
{
|
||||
None = 0,
|
||||
Local = 1,
|
||||
Registered = 2,
|
||||
NoRebootRequired = 4,
|
||||
NoErrors = 8,
|
||||
Complete = 4294967295,
|
||||
}
|
||||
|
||||
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface IEnumSetupInstances
|
||||
{
|
||||
|
||||
void Next([MarshalAs(UnmanagedType.U4), In] int celt,
|
||||
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
|
||||
[MarshalAs(UnmanagedType.U4)] out int pceltFetched);
|
||||
|
||||
void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
|
||||
|
||||
void Reset();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances Clone();
|
||||
}
|
||||
|
||||
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupConfiguration
|
||||
{
|
||||
}
|
||||
|
||||
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupConfiguration2 : ISetupConfiguration
|
||||
{
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances EnumInstances();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForCurrentProcess();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances EnumAllInstances();
|
||||
}
|
||||
|
||||
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupInstance
|
||||
{
|
||||
}
|
||||
|
||||
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupInstance2 : ISetupInstance
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstanceId();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Struct)]
|
||||
System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationName();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationPath();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationVersion();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
InstanceState GetState();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||||
ISetupPackageReference[] GetPackages();
|
||||
|
||||
ISetupPackageReference GetProduct();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetProductPath();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool IsLaunchable();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool IsComplete();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||||
ISetupPropertyStore GetProperties();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetEnginePath();
|
||||
}
|
||||
|
||||
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupPackageReference
|
||||
{
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetId();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetVersion();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetChip();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetLanguage();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetBranch();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetType();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetUniqueId();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool GetIsExtension();
|
||||
}
|
||||
|
||||
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface ISetupPropertyStore
|
||||
{
|
||||
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
|
||||
string[] GetNames();
|
||||
|
||||
object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
|
||||
}
|
||||
|
||||
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||||
[CoClass(typeof(SetupConfigurationClass))]
|
||||
[ComImport]
|
||||
public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
|
||||
{
|
||||
}
|
||||
|
||||
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComImport]
|
||||
public class SetupConfigurationClass
|
||||
{
|
||||
}
|
||||
|
||||
public static class Main
|
||||
{
|
||||
public static void PrintJson()
|
||||
{
|
||||
ISetupConfiguration query = new SetupConfiguration();
|
||||
ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
|
||||
IEnumSetupInstances e = query2.EnumAllInstances();
|
||||
|
||||
int pceltFetched;
|
||||
ISetupInstance2[] rgelt = new ISetupInstance2[1];
|
||||
List<string> instances = new List<string>();
|
||||
while (true)
|
||||
{
|
||||
e.Next(1, rgelt, out pceltFetched);
|
||||
if (pceltFetched <= 0)
|
||||
{
|
||||
Console.WriteLine(String.Format("[{0}]", string.Join(",", instances.ToArray())));
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
instances.Add(InstanceJson(rgelt[0]));
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
// Ignore instances that can't be queried.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string JsonString(string s)
|
||||
{
|
||||
return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
|
||||
}
|
||||
|
||||
private static string InstanceJson(ISetupInstance2 setupInstance2)
|
||||
{
|
||||
// Visual Studio component directory:
|
||||
// https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
|
||||
|
||||
StringBuilder json = new StringBuilder();
|
||||
json.Append("{");
|
||||
|
||||
string path = JsonString(setupInstance2.GetInstallationPath());
|
||||
json.Append(String.Format("\"path\":{0},", path));
|
||||
|
||||
string version = JsonString(setupInstance2.GetInstallationVersion());
|
||||
json.Append(String.Format("\"version\":{0},", version));
|
||||
|
||||
List<string> packages = new List<string>();
|
||||
foreach (ISetupPackageReference package in setupInstance2.GetPackages())
|
||||
{
|
||||
string id = JsonString(package.GetId());
|
||||
packages.Add(id);
|
||||
}
|
||||
json.Append(String.Format("\"packages\":[{0}]", string.Join(",", packages.ToArray())));
|
||||
|
||||
json.Append("}");
|
||||
return json.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
361
server/node_modules/buildcheck/lib/findvs.js
generated
vendored
Normal file
361
server/node_modules/buildcheck/lib/findvs.js
generated
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
'use strict';
|
||||
|
||||
const { execFileSync } = require('child_process');
|
||||
const { readFileSync, statSync } = require('fs');
|
||||
const { win32: path } = require('path');
|
||||
|
||||
const modernMSBuildPath = (() => {
|
||||
let arch;
|
||||
switch (process.arch) {
|
||||
case 'x64':
|
||||
arch = 'amd64';
|
||||
break;
|
||||
case 'arm64':
|
||||
arch = process.arch;
|
||||
break;
|
||||
default:
|
||||
arch = '';
|
||||
}
|
||||
return path.join('MSBuild', 'Current', 'Bin', arch, 'MSBuild.exe');
|
||||
})();
|
||||
const VS_VERSIONS_MODERN = new Map([
|
||||
[15, {
|
||||
year: 2017,
|
||||
msbuild: path.join('MSBuild', '15.0', 'Bin', 'MSBuild.exe'),
|
||||
toolset: 'v141',
|
||||
}],
|
||||
[16, {
|
||||
year: 2019,
|
||||
msbuild: path.join('MSBuild', 'Current', 'Bin', 'MSBuild.exe'),
|
||||
toolset: 'v142',
|
||||
}],
|
||||
[17, {
|
||||
year: 2022,
|
||||
msbuild: modernMSBuildPath,
|
||||
toolset: 'v143',
|
||||
}],
|
||||
[18, {
|
||||
year: 2026,
|
||||
msbuild: modernMSBuildPath,
|
||||
toolset: 'v145',
|
||||
}],
|
||||
]);
|
||||
const PACKAGES = {
|
||||
msbuild: /^Microsoft[.]VisualStudio[.]VC[.]MSBuild[.](?:v\d+[.])?Base$/i,
|
||||
vctools: /^Microsoft[.]VisualStudio[.]Component[.]VC[.]Tools[.](x86[.]x64|ARM64)$/i,
|
||||
express: /^Microsoft[.]VisualStudio[.]WDExpress$/i,
|
||||
winsdk:
|
||||
/^Microsoft[.]VisualStudio[.]Component[.]Windows(81|10|11)SDK(?:[.](\d+)(?:[.]Desktop.*)?)?$/,
|
||||
};
|
||||
const SDK_REG = 'HKLM\\Software\\Microsoft\\Microsoft SDKs\\Windows';
|
||||
const SDK32_REG =
|
||||
'HKLM\\Software\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows';
|
||||
|
||||
function checkRequiredPackages(packages) {
|
||||
if (!Array.isArray(packages))
|
||||
return false;
|
||||
|
||||
let foundMSBuild = false;
|
||||
let foundVCTools = false;
|
||||
let foundExpress = false;
|
||||
for (const pkg of packages) {
|
||||
if (!foundMSBuild && PACKAGES.msbuild.test(pkg))
|
||||
foundMSBuild = true;
|
||||
else if (!foundVCTools && PACKAGES.vctools.test(pkg))
|
||||
foundVCTools = true;
|
||||
else if (!foundExpress && PACKAGES.express.test(pkg))
|
||||
foundExpress = true;
|
||||
|
||||
if (foundMSBuild && (foundVCTools || foundExpress))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorts newest to oldest
|
||||
function versionStringCompare(a, b) {
|
||||
const splitA = a.split('.');
|
||||
const splitB = b.split('.');
|
||||
const len = Math.min(splitA.length, splitB.length);
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const nA = parseInt(splitA[i], 10);
|
||||
const nB = parseInt(splitB[i], 10);
|
||||
if (nA > nB)
|
||||
return -1;
|
||||
if (nA < nB)
|
||||
return 1;
|
||||
}
|
||||
if (splitA.length > splitB.length)
|
||||
return -1;
|
||||
else if (splitA.length < splitB.length)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function sdkVersionCompare(a, b) {
|
||||
return versionStringCompare(a.fullVersion, b.fullVersion);
|
||||
}
|
||||
|
||||
function getSDKPaths(fullVer) {
|
||||
if (typeof fullVer !== 'string' || !fullVer)
|
||||
return;
|
||||
try {
|
||||
const arch = (process.arch === 'ia32' ? 'x86' : process.arch);
|
||||
const shortVer = `v${/^\d+[.]\d+/.exec(fullVer)[0]}`;
|
||||
let verPath = getRegValue(`${SDK_REG}\\${shortVer}`, 'InstallationFolder');
|
||||
if (!verPath)
|
||||
verPath = getRegValue(`${SDK32_REG}\\${shortVer}`, 'InstallationFolder');
|
||||
if (!verPath)
|
||||
return;
|
||||
|
||||
// Includes
|
||||
const includePaths = [];
|
||||
for (const type of ['shared', 'um', 'ucrt']) {
|
||||
const testPath = path.resolve(verPath, 'Include', fullVer, type);
|
||||
statSync(testPath);
|
||||
includePaths.push(testPath);
|
||||
}
|
||||
|
||||
// Libraries
|
||||
const libPaths = [];
|
||||
for (const type of ['um', 'ucrt']) {
|
||||
const testPath = path.resolve(verPath, 'Lib', fullVer, type, arch);
|
||||
statSync(testPath);
|
||||
libPaths.push(testPath);
|
||||
}
|
||||
|
||||
return { includePaths, libPaths };
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const execOpts = {
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
windowsHide: true,
|
||||
};
|
||||
|
||||
function findModernVS() {
|
||||
const versions = [];
|
||||
const ps = path.join(
|
||||
process.env.SystemRoot,
|
||||
'System32',
|
||||
'WindowsPowerShell',
|
||||
'v1.0',
|
||||
'powershell.exe'
|
||||
);
|
||||
const cs = path.resolve(__dirname, '..', 'deps', 'Find-VisualStudio.cs');
|
||||
const args = [
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-NoProfile',
|
||||
'-Command',
|
||||
`&{Add-Type -Path '${cs}';[VisualStudioConfiguration.Main]::PrintJson()}`
|
||||
];
|
||||
try {
|
||||
const out = execFileSync(ps, args, execOpts);
|
||||
const info = JSON.parse(out);
|
||||
if (Array.isArray(info)) {
|
||||
for (const vs of info) {
|
||||
const vsPath = path.resolve(vs.path);
|
||||
let vsVer = /^(?<major>\d+)[.](?<minor>\d+)[.]/.exec(vs.version);
|
||||
if (!vsVer)
|
||||
continue;
|
||||
vsVer = {
|
||||
full: vs.version,
|
||||
major: +vsVer.groups.major,
|
||||
minor: +vsVer.groups.minor,
|
||||
};
|
||||
const verInfo = VS_VERSIONS_MODERN.get(vsVer.major);
|
||||
if (verInfo === undefined)
|
||||
continue;
|
||||
if (!checkRequiredPackages(vs.packages))
|
||||
continue;
|
||||
const vsSDKs = [];
|
||||
for (const pkg of vs.packages) {
|
||||
let fullVersion;
|
||||
let version;
|
||||
const m = PACKAGES.winsdk.exec(pkg);
|
||||
if (!m)
|
||||
continue;
|
||||
const sdk = m[1];
|
||||
switch (sdk) {
|
||||
case '81':
|
||||
fullVersion = version = '8.1';
|
||||
break;
|
||||
case '10':
|
||||
case '11': {
|
||||
if (m[2] === undefined)
|
||||
continue;
|
||||
const sdkVer = parseInt(m[2], 10);
|
||||
if (!isFinite(sdkVer) || sdkVer < 0)
|
||||
continue;
|
||||
fullVersion = `10.0.${sdkVer}.0`;
|
||||
version = '10.0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
const paths = getSDKPaths(fullVersion);
|
||||
if (!paths)
|
||||
continue;
|
||||
vsSDKs.push({
|
||||
version,
|
||||
fullVersion,
|
||||
...paths,
|
||||
});
|
||||
}
|
||||
if (vsSDKs.length === 0)
|
||||
continue;
|
||||
let clPath;
|
||||
const includePaths = [];
|
||||
const libPaths = [];
|
||||
try {
|
||||
let vcVerFile;
|
||||
let clVer;
|
||||
try {
|
||||
vcVerFile = path.join(
|
||||
vsPath,
|
||||
'VC',
|
||||
'Auxiliary',
|
||||
'Build',
|
||||
`Microsoft.VCToolsVersion.${verInfo.toolset}.default.txt`
|
||||
);
|
||||
clVer = readFileSync(vcVerFile, { encoding: 'utf8' }).trim();
|
||||
} catch {}
|
||||
if (!clVer) {
|
||||
vcVerFile = path.join(
|
||||
vsPath,
|
||||
'VC',
|
||||
'Auxiliary',
|
||||
'Build',
|
||||
'Microsoft.VCToolsVersion.default.txt'
|
||||
);
|
||||
clVer = readFileSync(vcVerFile, { encoding: 'utf8' }).trim();
|
||||
}
|
||||
const arch = (process.arch === 'ia32' ? 'x86' : process.arch);
|
||||
let testPath = path.join(
|
||||
vsPath,
|
||||
'VC',
|
||||
'Tools',
|
||||
'MSVC',
|
||||
clVer,
|
||||
'bin',
|
||||
`Host${arch}`,
|
||||
arch,
|
||||
'cl.exe'
|
||||
);
|
||||
statSync(testPath);
|
||||
clPath = testPath;
|
||||
|
||||
testPath = path.join(
|
||||
vsPath,
|
||||
'VC',
|
||||
'Tools',
|
||||
'MSVC',
|
||||
clVer,
|
||||
'include'
|
||||
);
|
||||
statSync(testPath);
|
||||
includePaths.push(testPath);
|
||||
|
||||
testPath = path.join(
|
||||
vsPath,
|
||||
'VC',
|
||||
'Tools',
|
||||
'MSVC',
|
||||
clVer,
|
||||
'lib',
|
||||
arch
|
||||
);
|
||||
statSync(testPath);
|
||||
libPaths.push(testPath);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
vsSDKs.sort(sdkVersionCompare);
|
||||
versions.push({
|
||||
path: vsPath,
|
||||
version: vsVer,
|
||||
sdks: vsSDKs,
|
||||
...verInfo,
|
||||
msbuild: path.join(vsPath, verInfo.msbuild),
|
||||
cl: clPath,
|
||||
includePaths,
|
||||
libPaths,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
return versions;
|
||||
}
|
||||
|
||||
const VS_VERSIONS_OLDER = [
|
||||
{
|
||||
version: { full: '12.0', major: 12, minor: 0 },
|
||||
year: 2013,
|
||||
toolset: 'v120',
|
||||
},
|
||||
{
|
||||
version: { full: '14.0', major: 14, minor: 0 },
|
||||
year: 2015,
|
||||
toolset: 'v140',
|
||||
},
|
||||
];
|
||||
|
||||
const VC_REG = 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7';
|
||||
const VC32_REG =
|
||||
'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7';
|
||||
const MSBUILD_REG = 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions';
|
||||
|
||||
function getRegValue(key, value, use32) {
|
||||
const extraArgs = (use32 ? [ '/reg:32' ] : []);
|
||||
const regexp = new RegExp(`^\\s+${value}\\s+REG_\\w+\\s+(\\S.*)$`, 'im');
|
||||
const reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe');
|
||||
const args = [ 'query', key, '/v', value, ...extraArgs ];
|
||||
|
||||
try {
|
||||
const out = execFileSync(reg, args, execOpts);
|
||||
const m = regexp.exec(out);
|
||||
if (m)
|
||||
return m[1];
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function findOlderVS() {
|
||||
const versions = [];
|
||||
try {
|
||||
for (const vs of VS_VERSIONS_OLDER) {
|
||||
let vsPath = getRegValue(VC_REG, vs.version.full);
|
||||
if (!vsPath)
|
||||
vsPath = getRegValue(VC32_REG, vs.version.full);
|
||||
if (!vsPath)
|
||||
continue;
|
||||
vsPath = path.resolve(vsPath, '..');
|
||||
|
||||
const msbuildPath = getRegValue(
|
||||
`${MSBUILD_REG}\\${vs.version.full}`,
|
||||
'MSBuildToolsPath',
|
||||
(process.arch === 'ia32')
|
||||
);
|
||||
if (!msbuildPath)
|
||||
continue;
|
||||
versions.push({
|
||||
path: vsPath,
|
||||
...vs,
|
||||
msbuild: path.join(msbuildPath, 'MSBuild.exe'),
|
||||
cl: path.join(vsPath, 'VC', 'bin', 'cl.exe'),
|
||||
includePaths: [path.join(vsPath, 'VC', 'include')],
|
||||
libPaths: [path.join(vsPath, 'VC', 'lib')],
|
||||
sdks: [],
|
||||
});
|
||||
}
|
||||
} catch {}
|
||||
return versions;
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
const versions = findModernVS().concat(findOlderVS());
|
||||
// Sorts newest to oldest
|
||||
versions.sort((a, b) => {
|
||||
return versionStringCompare(a.version.full, b.version.full);
|
||||
});
|
||||
return versions;
|
||||
};
|
||||
738
server/node_modules/buildcheck/lib/index.js
generated
vendored
Normal file
738
server/node_modules/buildcheck/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,738 @@
|
||||
'use strict';
|
||||
|
||||
// TODO: take `compilerParams`, headers into account in cache for all cached
|
||||
// results
|
||||
// TODO: debug output
|
||||
|
||||
const { spawnSync } = require('child_process');
|
||||
const { unlinkSync, writeFileSync } = require('fs');
|
||||
const { tmpdir } = require('os');
|
||||
const { win32: path } = require('path');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const isWindows = (process.platform === 'win32');
|
||||
const findVS = require('./findvs.js');
|
||||
|
||||
const RE_HEADER_DECORATED = /^(?:"(.+)")|(?:<(.+)>)$/;
|
||||
|
||||
const genWinTmpFilenames = (() => {
|
||||
let instance = 1;
|
||||
return () => {
|
||||
const base =
|
||||
path.resolve(tmpdir(), `_buildcheck-${process.pid}-${instance++}`);
|
||||
return {
|
||||
input: `${base}.in.tmp`,
|
||||
object: `${base}.out.obj`,
|
||||
output: `${base}.out.tmp`,
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
||||
function getKind(prop) {
|
||||
const spawnOpts = {
|
||||
encoding: 'utf8',
|
||||
stdio: 'pipe',
|
||||
windowsHide: true,
|
||||
};
|
||||
|
||||
const lang = (prop === '_cc' ? 'c' : 'c++');
|
||||
|
||||
if (isWindows) {
|
||||
spawnOpts.stdio = [ 'ignore', 'pipe', 'pipe' ];
|
||||
writeFileSync(this._tmpInFile, [
|
||||
'_MSC_VER',
|
||||
].join(' '));
|
||||
const result = spawnSync(
|
||||
this[prop],
|
||||
[ '-EP', `-T${lang === 'c' ? 'c' : 'p'}`, this._tmpInFile],
|
||||
spawnOpts
|
||||
);
|
||||
unlinkSync(this._tmpInFile);
|
||||
|
||||
if (result.status === 0) {
|
||||
const values = result.stdout.trim().split(' ');
|
||||
if (values.length === 1 && /^\d+$/.test(values[0])) {
|
||||
this[`${prop}Kind`] = 'msvc';
|
||||
this[`${prop}Version`] = values[0];
|
||||
this[`${prop}SpawnOpts`] = spawnOpts;
|
||||
this._debug(
|
||||
`>>> Detected MSVC ${values[0]} for ${lang.toUpperCase()} language`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const result = spawnSync(
|
||||
this[prop],
|
||||
[ '-E', '-P', '-x', lang, '-' ],
|
||||
{
|
||||
...spawnOpts,
|
||||
input: [
|
||||
'__clang__',
|
||||
'__GNUC__',
|
||||
'__GNUC_MINOR__',
|
||||
'__GNUC_PATCHLEVEL__',
|
||||
'__clang_major__',
|
||||
'__clang_minor__',
|
||||
'__clang_patchlevel__',
|
||||
].join(' '),
|
||||
}
|
||||
);
|
||||
|
||||
if (result.status === 0) {
|
||||
const values = result.stdout.trim().split(' ');
|
||||
if (values.length === 7) {
|
||||
let kind;
|
||||
let version;
|
||||
if (values[0] === '1') {
|
||||
kind = 'clang';
|
||||
version = values.slice(4).map((v) => +v);
|
||||
} else {
|
||||
kind = 'gnu';
|
||||
version = values.slice(1, 4).map((v) => +v);
|
||||
}
|
||||
let good = true;
|
||||
for (const part of version) {
|
||||
if (!isFinite(part) || part < 0) {
|
||||
good = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
this[`${prop}Kind`] = kind;
|
||||
this[`${prop}Version`] = version;
|
||||
this[`${prop}SpawnOpts`] = spawnOpts;
|
||||
const verStr = version.join('.');
|
||||
this._debug(
|
||||
`>>> Detected ${kind} ${verStr} for ${lang.toUpperCase()} language`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Unable to detect compiler type');
|
||||
}
|
||||
|
||||
class BuildEnvironment {
|
||||
constructor(cfg) {
|
||||
if (typeof cfg !== 'object' || cfg === null)
|
||||
cfg = {};
|
||||
|
||||
this._debug = (typeof cfg.debug === 'function' ? cfg.debug : () => {});
|
||||
|
||||
let cc;
|
||||
let cxx;
|
||||
if (isWindows) {
|
||||
const versions = findVS();
|
||||
this._debug(
|
||||
`>>> Detected MSVS installations: ${inspect(versions, false, 10)}`
|
||||
);
|
||||
if (versions.length === 0)
|
||||
throw new Error('Unable to detect compiler type');
|
||||
let selected_msvs;
|
||||
if (cfg.msvs_version
|
||||
&& (typeof cfg.msvs_version === 'string'
|
||||
|| typeof cfg.msvs_version === 'number')) {
|
||||
this._debug(`>>> Explicit MSVS requested: ${cfg.msvs_version}`);
|
||||
// Try to select compiler by year
|
||||
const msvs_version = cfg.msvs_version.toString();
|
||||
for (const vs of versions) {
|
||||
if (vs.year.toString() === msvs_version) {
|
||||
selected_msvs = vs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (selected_msvs === undefined)
|
||||
throw new Error(`Unable to find MSVS with year '${msvs_version}'`);
|
||||
} else {
|
||||
selected_msvs = versions[0]; // Use newest
|
||||
}
|
||||
this._debug(`>>> Using MSVS: ${selected_msvs.year}`);
|
||||
cc = selected_msvs.cl;
|
||||
cxx = cc;
|
||||
this._includePaths = selected_msvs.includePaths;
|
||||
this._libPaths = selected_msvs.libPaths;
|
||||
// Add (newest) SDK paths if we have them
|
||||
for (const sdk of selected_msvs.sdks) {
|
||||
this._debug(`>>> Using Windows SDK: ${sdk.fullVersion}`);
|
||||
this._includePaths = this._includePaths.concat(sdk.includePaths);
|
||||
this._libPaths = this._libPaths.concat(sdk.libPaths);
|
||||
break;
|
||||
}
|
||||
|
||||
const { input, object, output } = genWinTmpFilenames();
|
||||
this._tmpInFile = input;
|
||||
this._tmpObjFile = object;
|
||||
this._tmpOutFile = output;
|
||||
} else {
|
||||
cc = ((typeof cfg.compilerC === 'string' && cfg.compilerC)
|
||||
|| process.env.CC
|
||||
|| 'cc');
|
||||
cxx = ((typeof cfg.compilerCXX === 'string' && cfg.compilerCXX)
|
||||
|| process.env.CXX
|
||||
|| 'c++');
|
||||
this._debug(`>>> Using C compiler: ${cc}`);
|
||||
this._debug(`>>> Using C++ compiler: ${cxx}`);
|
||||
}
|
||||
|
||||
this._cc = cc;
|
||||
this._ccKind = undefined;
|
||||
this._ccVersion = undefined;
|
||||
this._ccSpawnOpts = undefined;
|
||||
|
||||
this._cxx = cxx;
|
||||
this._cxxKind = undefined;
|
||||
this._cxxVersion = undefined;
|
||||
this._cxxSpawnOpts = undefined;
|
||||
|
||||
if (cfg.cache !== false) {
|
||||
this._cache = new Map(Object.entries({
|
||||
c: new Map(),
|
||||
cxx: new Map(),
|
||||
}));
|
||||
} else {
|
||||
this._cache = null;
|
||||
}
|
||||
}
|
||||
|
||||
checkDeclared(type, symbolName, opts) {
|
||||
validateType(type);
|
||||
if (typeof symbolName !== 'string' || !symbolName)
|
||||
throw new Error(`Invalid symbol name: ${inspect(symbolName)}`);
|
||||
|
||||
const cached = getCachedValue(type, this._cache, 'declared', symbolName);
|
||||
if (cached !== undefined) {
|
||||
this._debug(
|
||||
`>>> Checking if '${symbolName}' is declared... ${cached} (cached)`
|
||||
);
|
||||
return cached;
|
||||
}
|
||||
|
||||
if (typeof opts !== 'object' || opts === null)
|
||||
opts = {};
|
||||
|
||||
const { headers, searchLibs } = opts;
|
||||
const headersList = renderHeaders(Array.isArray(headers)
|
||||
? headers
|
||||
: getDefaultHeaders(this, type));
|
||||
|
||||
const declName = symbolName.replace(/ *\(.*/, '');
|
||||
const declUse = symbolName.replace(/\(/, '((')
|
||||
.replace(/\)/, ') 0)')
|
||||
.replace(/,/g, ') 0, (');
|
||||
|
||||
const libs = [
|
||||
'',
|
||||
...(Array.isArray(searchLibs) ? searchLibs : [])
|
||||
];
|
||||
|
||||
for (let lib of libs) {
|
||||
if (typeof lib !== 'string')
|
||||
continue;
|
||||
lib = lib.trim();
|
||||
|
||||
const code = `
|
||||
${headersList}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
#ifndef ${declName}
|
||||
#ifdef __cplusplus
|
||||
(void) ${declUse};
|
||||
#else
|
||||
(void) ${declName};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
;
|
||||
return 0;
|
||||
}`;
|
||||
const compilerParams = (lib ? [`-l${lib}`] : []);
|
||||
const result = this.tryCompile(type, code, compilerParams);
|
||||
|
||||
this._debug(
|
||||
`>>> Checking if '${symbolName}' is declared `
|
||||
+ `(using ${lib ? `'${lib}'` : 'no'} library)... ${result === true}`
|
||||
);
|
||||
|
||||
if (result !== true) {
|
||||
this._debug('... check failed with compiler output:');
|
||||
this._debug(result.output);
|
||||
}
|
||||
|
||||
if (result === true) {
|
||||
setCachedValue(
|
||||
type,
|
||||
this._cache,
|
||||
'declared',
|
||||
symbolName,
|
||||
(result === true)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
checkFeature(name) {
|
||||
const cached = getCachedValue('features', this._cache, null, name);
|
||||
if (cached !== undefined) {
|
||||
if (typeof cached === 'object'
|
||||
&& cached !== null
|
||||
&& typeof cached.val !== undefined) {
|
||||
return cached.val;
|
||||
}
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
const feature = features.get(name);
|
||||
if (feature === undefined)
|
||||
throw new Error(`Invalid feature: ${name}`);
|
||||
|
||||
let result = feature(this);
|
||||
if (result === undefined)
|
||||
result = null;
|
||||
|
||||
setCachedValue('features', this._cache, null, name, result);
|
||||
|
||||
if (typeof result === 'object'
|
||||
&& result !== null
|
||||
&& typeof result.val !== undefined) {
|
||||
return result.val;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
checkFunction(type, funcName, opts) {
|
||||
validateType(type);
|
||||
if (typeof funcName !== 'string' || !funcName)
|
||||
throw new Error(`Invalid function name: ${inspect(funcName)}`);
|
||||
|
||||
const cached = getCachedValue(type, this._cache, 'functions', funcName);
|
||||
if (cached !== undefined) {
|
||||
this._debug(
|
||||
`>>> Checking if function '${funcName}' exists... true (cached)`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof opts !== 'object' || opts === null)
|
||||
opts = {};
|
||||
|
||||
const { searchLibs } = opts;
|
||||
const libs = [
|
||||
'',
|
||||
...(Array.isArray(searchLibs) ? searchLibs : [])
|
||||
];
|
||||
|
||||
for (let lib of libs) {
|
||||
if (typeof lib !== 'string')
|
||||
continue;
|
||||
lib = lib.trim();
|
||||
|
||||
const code = `
|
||||
/* Define ${funcName} to an innocuous variant, in case <limits.h> declares
|
||||
${funcName}.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define ${funcName} innocuous_${funcName}
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char ${funcName} (); below. */
|
||||
#include <limits.h>
|
||||
#undef ${funcName}
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char ${funcName} ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_${funcName} || defined __stub___${funcName}
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return ${funcName} ();
|
||||
;
|
||||
return 0;
|
||||
}`;
|
||||
|
||||
const compilerParams = (lib ? [`-l${lib}`] : []);
|
||||
const result = this.tryCompile(type, code, compilerParams);
|
||||
|
||||
this._debug(
|
||||
`>>> Checking if function '${funcName}' exists `
|
||||
+ `(using ${lib ? `'${lib}'` : 'no'} library)... ${result === true}`
|
||||
);
|
||||
if (result !== true) {
|
||||
this._debug('... check failed with compiler output:');
|
||||
this._debug(result.output);
|
||||
}
|
||||
|
||||
if (result === true) {
|
||||
setCachedValue(
|
||||
type,
|
||||
this._cache,
|
||||
'functions',
|
||||
funcName,
|
||||
compilerParams
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
checkHeader(type, header) {
|
||||
validateType(type);
|
||||
const cached = getCachedValue(
|
||||
type,
|
||||
this._cache,
|
||||
'headers',
|
||||
normalizeHeader(header)
|
||||
);
|
||||
if (cached !== undefined) {
|
||||
this._debug(
|
||||
`>>> Checking if header '${header}' exists... ${cached} (cached)`
|
||||
);
|
||||
return cached;
|
||||
}
|
||||
|
||||
const headersList = renderHeaders([header]);
|
||||
|
||||
const code = `
|
||||
${headersList}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}`;
|
||||
|
||||
const result = this.tryCompile(type, code);
|
||||
setCachedValue(
|
||||
type,
|
||||
this._cache,
|
||||
'headers',
|
||||
normalizeHeader(header),
|
||||
(result === true)
|
||||
);
|
||||
this._debug(
|
||||
`>>> Checking if header '${header}' exists... ${result === true}`
|
||||
);
|
||||
if (result !== true) {
|
||||
this._debug('... check failed with compiler output:');
|
||||
this._debug(result.output);
|
||||
}
|
||||
return (result === true);
|
||||
}
|
||||
|
||||
defines(type, rendered) {
|
||||
if (this._cache === null)
|
||||
return [];
|
||||
|
||||
const defines = new Map();
|
||||
|
||||
let types;
|
||||
if (!['c', 'c++'].includes(type))
|
||||
types = ['c', 'c++'];
|
||||
else
|
||||
types = [type];
|
||||
|
||||
for (const t of types) {
|
||||
const typeCache = this._cache.get(t);
|
||||
if (!typeCache)
|
||||
continue;
|
||||
|
||||
for (const [subtype, entries] of typeCache) {
|
||||
for (let name of entries.keys()) {
|
||||
if (subtype === 'headers')
|
||||
name = name.replace(RE_HEADER_DECORATED, '$1$2');
|
||||
defines.set(makeDefine(name, rendered), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const featuresCache = this._cache.get('features');
|
||||
if (featuresCache) {
|
||||
for (const result of featuresCache.values()) {
|
||||
if (typeof result === 'object'
|
||||
&& result !== null
|
||||
&& Array.isArray(result.defines)) {
|
||||
for (const define of result.defines)
|
||||
defines.set(makeDefine(define, rendered), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(defines.keys());
|
||||
}
|
||||
|
||||
libs(type) {
|
||||
if (this._cache === null)
|
||||
return [];
|
||||
|
||||
const libs = new Map();
|
||||
|
||||
let types;
|
||||
if (!['c', 'c++'].includes(type))
|
||||
types = ['c', 'c++'];
|
||||
else
|
||||
types = [type];
|
||||
|
||||
for (const t of types) {
|
||||
const typeCache = this._cache.get(t);
|
||||
if (!typeCache)
|
||||
continue;
|
||||
|
||||
const functionsCache = typeCache.get('functions');
|
||||
if (!functionsCache)
|
||||
continue;
|
||||
|
||||
for (const compilerParams of functionsCache.values()) {
|
||||
for (const param of compilerParams)
|
||||
libs.set(param, 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const featuresCache = this._cache.get('features');
|
||||
if (featuresCache) {
|
||||
for (const result of featuresCache.values()) {
|
||||
if (typeof result === 'object'
|
||||
&& result !== null
|
||||
&& Array.isArray(result.libs)) {
|
||||
for (const lib of result.libs)
|
||||
libs.set(lib, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(libs.keys());
|
||||
}
|
||||
|
||||
tryCompile(type, code, compilerParams) {
|
||||
validateType(type);
|
||||
if (typeof code !== 'string')
|
||||
throw new TypeError('Invalid code argument');
|
||||
|
||||
type = (type === 'c' ? 'c' : 'c++');
|
||||
const prop = (type === 'c' ? '_cc' : '_cxx');
|
||||
|
||||
if (this[`${prop}Kind`] === undefined)
|
||||
getKind.call(this, prop);
|
||||
|
||||
if (!Array.isArray(compilerParams))
|
||||
compilerParams = [];
|
||||
|
||||
let result;
|
||||
if (this[`${prop}Kind`] === 'msvc') {
|
||||
const cmpOpts = [`-Fo${this._tmpObjFile}`];
|
||||
for (const includePath of this._includePaths)
|
||||
cmpOpts.push('-I', includePath);
|
||||
const lnkOpts = [];
|
||||
for (const libPath of this._libPaths)
|
||||
lnkOpts.push(`-LIBPATH:${libPath}`);
|
||||
for (const opt of compilerParams) {
|
||||
let m;
|
||||
if (m = /^[-/]l(.+)$/.exec(opt))
|
||||
lnkOpts.push(m[1]);
|
||||
else
|
||||
cmpOpts.push(opt);
|
||||
}
|
||||
try {
|
||||
writeFileSync(this._tmpInFile, code);
|
||||
const args = [
|
||||
...cmpOpts,
|
||||
`-T${prop === '_cc' ? 'c' : 'p'}`,
|
||||
this._tmpInFile,
|
||||
'-link',
|
||||
`-out:${this._tmpOutFile}`,
|
||||
...lnkOpts,
|
||||
];
|
||||
result = spawnSync(
|
||||
this[prop],
|
||||
args,
|
||||
this[`${prop}SpawnOpts`]
|
||||
);
|
||||
unlinkSync(this._tmpInFile);
|
||||
// Overwrite stderr with stdout because MSVC seems to print
|
||||
// errors to stdout instead for some reason
|
||||
result.stderr = result.stdout;
|
||||
} catch (ex) {
|
||||
// We had trouble writing or deleting a temp file, fake
|
||||
// the result
|
||||
result = { status: Infinity, stderr: ex.stack };
|
||||
}
|
||||
try { unlinkSync(this._tmpObjFile); } catch {}
|
||||
try { unlinkSync(this._tmpOutFile); } catch {}
|
||||
} else {
|
||||
result = spawnSync(
|
||||
this[prop],
|
||||
[
|
||||
'-x', type,
|
||||
'-o', '/dev/null',
|
||||
'-',
|
||||
...compilerParams,
|
||||
],
|
||||
{
|
||||
...this[`${prop}SpawnOpts`],
|
||||
input: code,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (result.status === 0)
|
||||
return true;
|
||||
|
||||
const err = new Error('Compilation failed');
|
||||
err.output = result.stderr;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
function validateType(type) {
|
||||
if (!['c', 'c++'].includes(type))
|
||||
throw new Error('Invalid type argument');
|
||||
}
|
||||
|
||||
function getCachedValue(type, cache, subtype, key) {
|
||||
if (cache === null)
|
||||
return;
|
||||
|
||||
const typeCache = cache.get(type);
|
||||
if (!typeCache)
|
||||
return;
|
||||
|
||||
const subtypeCache = (typeof subtype !== 'string'
|
||||
? typeCache
|
||||
: typeCache.get(subtype));
|
||||
if (!subtypeCache)
|
||||
return;
|
||||
|
||||
return subtypeCache.get(key);
|
||||
}
|
||||
|
||||
function setCachedValue(type, cache, subtype, key, value) {
|
||||
if (cache === null)
|
||||
return;
|
||||
|
||||
let typeCache = cache.get(type);
|
||||
if (!typeCache)
|
||||
cache.set(type, typeCache = new Map());
|
||||
|
||||
let subtypeCache = (typeof subtype !== 'string'
|
||||
? typeCache
|
||||
: typeCache.get(subtype));
|
||||
if (!subtypeCache)
|
||||
typeCache.set(subtype, subtypeCache = new Map());
|
||||
|
||||
subtypeCache.set(key, value);
|
||||
}
|
||||
|
||||
function renderHeaders(headers) {
|
||||
let ret = '';
|
||||
|
||||
if (Array.isArray(headers)) {
|
||||
for (const header of headers) {
|
||||
if (typeof header !== 'string' || !header)
|
||||
throw new Error(`Invalid header: ${inspect(header)}`);
|
||||
ret += `#include ${normalizeHeader(header)}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function normalizeHeader(header) {
|
||||
if (!RE_HEADER_DECORATED.test(header))
|
||||
header = `<${header}>`;
|
||||
return header;
|
||||
}
|
||||
|
||||
const DEFAULT_HEADERS_POSIX = [
|
||||
'stdio.h',
|
||||
'sys/types.h',
|
||||
'sys/stat.h',
|
||||
'stdlib.h',
|
||||
'stddef.h',
|
||||
'memory.h',
|
||||
'string.h',
|
||||
'strings.h',
|
||||
'inttypes.h',
|
||||
'stdint.h',
|
||||
'unistd.h'
|
||||
];
|
||||
const DEFAULT_HEADERS_MSVC = [
|
||||
'windows.h',
|
||||
];
|
||||
function getDefaultHeaders(be, type) {
|
||||
const prop = (type === 'c' ? '_cc' : '_cxx');
|
||||
if (be[`${prop}Kind`] === undefined)
|
||||
getKind.call(be, prop);
|
||||
|
||||
let headers;
|
||||
if (be[`${prop}Kind`] === 'msvc')
|
||||
headers = DEFAULT_HEADERS_MSVC;
|
||||
else
|
||||
headers = DEFAULT_HEADERS_POSIX;
|
||||
|
||||
return headers.filter((hdr) => be.checkHeader(type, hdr));
|
||||
}
|
||||
|
||||
const features = new Map(Object.entries({
|
||||
'strerror_r': (be) => {
|
||||
const defines = [];
|
||||
let returnsCharPtr = false;
|
||||
|
||||
const declared = be.checkDeclared('c', 'strerror_r');
|
||||
if (declared) {
|
||||
const code = `
|
||||
${renderHeaders(getDefaultHeaders(be, 'c'))}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
char buf[100];
|
||||
char x = *strerror_r (0, buf, sizeof buf);
|
||||
char *p = strerror_r (0, buf, sizeof buf);
|
||||
return !p || x;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}`;
|
||||
returnsCharPtr = (be.tryCompile('c', code) === true);
|
||||
if (returnsCharPtr)
|
||||
defines.push('STRERROR_R_CHAR_P');
|
||||
}
|
||||
|
||||
return {
|
||||
defines,
|
||||
val: { declared, returnsCharPtr }
|
||||
};
|
||||
},
|
||||
}));
|
||||
|
||||
function makeDefine(name, rendered) {
|
||||
name = name.replace(/[*]/g, 'P')
|
||||
.replace(/[^_A-Za-z0-9]/g, '_')
|
||||
.toUpperCase();
|
||||
return (rendered ? `HAVE_${name}=1` : name);
|
||||
}
|
||||
|
||||
module.exports = BuildEnvironment;
|
||||
36
server/node_modules/buildcheck/package.json
generated
vendored
Normal file
36
server/node_modules/buildcheck/package.json
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "buildcheck",
|
||||
"version": "0.0.7",
|
||||
"author": "Brian White <mscdex@mscdex.net>",
|
||||
"description": "Build environment checking (a la autoconf) for node.js",
|
||||
"main": "./lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mscdex/eslint-config": "^1.1.0",
|
||||
"eslint": "^7.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/test.js",
|
||||
"lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js lib",
|
||||
"lint:fix": "npm run lint -- --fix"
|
||||
},
|
||||
"keywords": [
|
||||
"build",
|
||||
"autoconf",
|
||||
"addons",
|
||||
"compiler",
|
||||
"environment"
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/mscdex/buildcheck/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/mscdex/buildcheck.git"
|
||||
}
|
||||
}
|
||||
8
server/node_modules/buildcheck/test/test.js
generated
vendored
Normal file
8
server/node_modules/buildcheck/test/test.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const BE = require('..');
|
||||
|
||||
{
|
||||
// Test compiler detection
|
||||
new BE({ debug: console.log });
|
||||
}
|
||||
Reference in New Issue
Block a user