forked from olcxjas-softworks/LarpixClient
update electron to v43
This commit is contained in:
parent
68ac0beedf
commit
fb6c8b6ee9
5385 changed files with 513060 additions and 123058 deletions
52
electron/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md
generated
vendored
52
electron/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md
generated
vendored
|
|
@ -1,52 +0,0 @@
|
|||
<!--
|
||||
Thank you for reporting an issue!
|
||||
|
||||
Remember, this issue tracker is for reporting issues ONLY with node-gyp.
|
||||
|
||||
If you have an issue installing a specific module, please file an issue on
|
||||
that module's issue tracker (`npm issues modulename`). Open issue here only if
|
||||
you are sure this is an issue with node-gyp, not with the module you are
|
||||
trying to build.
|
||||
|
||||
Fill out the form below. We probably won't investigate an issue that does not
|
||||
provide the basic information we require.
|
||||
|
||||
-->
|
||||
|
||||
Please look thru your error log for the string `gyp info using node-gyp@` and if the version number is less than the [current release of node-gyp](https://github.com/nodejs/node-gyp/releases) then __please upgrade__ using the instructions at https://github.com/nodejs/node-gyp/blob/master/docs/Updating-npm-bundled-node-gyp.md and try your command again.
|
||||
|
||||
Requests for help with [`node-sass` are very common](https://github.com/nodejs/node-gyp/issues?q=label%3A%22Node+Sass+--%3E+Dart+Sass%22). Please be aware that this package is deprecated, you should seek alternatives and avoid opening new issues about it here.
|
||||
|
||||
* **Node Version**: <!-- `node -v` and `npm -v` -->
|
||||
* **Platform**: <!-- `uname -a` (UNIX), or `systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"` (Windows) -->
|
||||
* **Compiler**: <!-- `cc -v` (UNIX) or `msbuild /version & cl` (Windows) -->
|
||||
* **Module**: <!-- what you tried to build/install -->
|
||||
|
||||
<details><summary>Verbose output (from npm or node-gyp):</summary>
|
||||
|
||||
```
|
||||
Paste your log here, between the backticks. It can be:
|
||||
- npm --verbose output,
|
||||
- or contents of npm-debug.log,
|
||||
- or output of node-gyp rebuild --verbose.
|
||||
Include the command you were trying to run.
|
||||
|
||||
This should look like this:
|
||||
|
||||
>npm --verbose
|
||||
npm info it worked if it ends with ok
|
||||
npm verb cli [
|
||||
npm verb cli 'C:\\...\\node\\13.9.0\\x64\\node.exe',
|
||||
npm verb cli 'C:\\...\\node\\13.9.0\\x64\\node_modules\\npm\\bin\\npm-cli.js',
|
||||
npm verb cli '--verbose'
|
||||
npm verb cli ]
|
||||
npm info using npm@6.13.7
|
||||
npm info using node@v13.9.0
|
||||
|
||||
Usage: npm <command>
|
||||
(...)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<!-- Any further details -->
|
||||
17
electron/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
17
electron/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
|
|
@ -1,17 +0,0 @@
|
|||
<!--
|
||||
Thank you for your pull request. Please review the below requirements.
|
||||
|
||||
Contributor guide: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
##### Checklist
|
||||
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||
|
||||
- [ ] `npm install && npm test` passes
|
||||
- [ ] tests are included <!-- Bug fixes and new features should include tests -->
|
||||
- [ ] documentation is changed or added
|
||||
- [ ] commit message follows [commit guidelines](https://github.com/googleapis/release-please#how-should-i-write-my-commits)
|
||||
|
||||
##### Description of change
|
||||
<!-- Provide a description of the change -->
|
||||
|
||||
57
electron/node_modules/node-gyp/.github/workflows/release-please-v9.yml
generated
vendored
57
electron/node_modules/node-gyp/.github/workflows/release-please-v9.yml
generated
vendored
|
|
@ -1,57 +0,0 @@
|
|||
name: release-please
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/v9
|
||||
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: google-github-actions/release-please-action@v2
|
||||
id: release
|
||||
with:
|
||||
package-name: node-gyp
|
||||
release-type: node
|
||||
default-branch: release/v9
|
||||
changelog-types: >
|
||||
[{"type":"feat","section":"Features","hidden":false},
|
||||
{"type":"fix","section":"Bug Fixes","hidden":false},
|
||||
{"type":"bin","section":"Core","hidden":false},
|
||||
{"type":"gyp","section":"Core","hidden":false},
|
||||
{"type":"lib","section":"Core","hidden":false},
|
||||
{"type":"src","section":"Core","hidden":false},
|
||||
{"type":"test","section":"Tests","hidden":false},
|
||||
{"type":"build","section":"Core","hidden":false},
|
||||
{"type":"clean","section":"Core","hidden":false},
|
||||
{"type":"configure","section":"Core","hidden":false},
|
||||
{"type":"install","section":"Core","hidden":false},
|
||||
{"type":"list","section":"Core","hidden":false},
|
||||
{"type":"rebuild","section":"Core","hidden":false},
|
||||
{"type":"remove","section":"Core","hidden":false},
|
||||
{"type":"deps","section":"Core","hidden":false},
|
||||
{"type":"python","section":"Core","hidden":false},
|
||||
{"type":"lin","section":"Core","hidden":false},
|
||||
{"type":"linux","section":"Core","hidden":false},
|
||||
{"type":"mac","section":"Core","hidden":false},
|
||||
{"type":"macos","section":"Core","hidden":false},
|
||||
{"type":"win","section":"Core","hidden":false},
|
||||
{"type":"windows","section":"Core","hidden":false},
|
||||
{"type":"zos","section":"Core","hidden":false},
|
||||
{"type":"doc","section":"Doc","hidden":false},
|
||||
{"type":"docs","section":"Doc","hidden":false},
|
||||
{"type":"readme","section":"Doc","hidden":false},
|
||||
{"type":"chore","section":"Miscellaneous","hidden":false},
|
||||
{"type":"refactor","section":"Miscellaneous","hidden":false},
|
||||
{"type":"ci","section":"Miscellaneous","hidden":false},
|
||||
{"type":"meta","section":"Miscellaneous","hidden":false}]
|
||||
|
||||
# Standard Conventional Commits: `feat` and `fix`
|
||||
# node-gyp subdirectories: `bin`, `gyp`, `lib`, `src`, `test`
|
||||
# node-gyp subcommands: `build`, `clean`, `configure`, `install`, `list`, `rebuild`, `remove`
|
||||
# Core abstract category: `deps`
|
||||
# Languages/platforms: `python`, `lin`, `linux`, `mac`, `macos`, `win`, `window`, `zos`
|
||||
# Documentation: `doc`, `docs`, `readme`
|
||||
# Standard Conventional Commits: `chore` (under "Miscellaneous")
|
||||
# Miscellaneous abstract categories: `refactor`, `ci`, `meta`
|
||||
56
electron/node_modules/node-gyp/.github/workflows/release-please.yml
generated
vendored
56
electron/node_modules/node-gyp/.github/workflows/release-please.yml
generated
vendored
|
|
@ -1,56 +0,0 @@
|
|||
name: release-please
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: google-github-actions/release-please-action@v2
|
||||
id: release
|
||||
with:
|
||||
package-name: node-gyp
|
||||
release-type: node
|
||||
changelog-types: >
|
||||
[{"type":"feat","section":"Features","hidden":false},
|
||||
{"type":"fix","section":"Bug Fixes","hidden":false},
|
||||
{"type":"bin","section":"Core","hidden":false},
|
||||
{"type":"gyp","section":"Core","hidden":false},
|
||||
{"type":"lib","section":"Core","hidden":false},
|
||||
{"type":"src","section":"Core","hidden":false},
|
||||
{"type":"test","section":"Tests","hidden":false},
|
||||
{"type":"build","section":"Core","hidden":false},
|
||||
{"type":"clean","section":"Core","hidden":false},
|
||||
{"type":"configure","section":"Core","hidden":false},
|
||||
{"type":"install","section":"Core","hidden":false},
|
||||
{"type":"list","section":"Core","hidden":false},
|
||||
{"type":"rebuild","section":"Core","hidden":false},
|
||||
{"type":"remove","section":"Core","hidden":false},
|
||||
{"type":"deps","section":"Core","hidden":false},
|
||||
{"type":"python","section":"Core","hidden":false},
|
||||
{"type":"lin","section":"Core","hidden":false},
|
||||
{"type":"linux","section":"Core","hidden":false},
|
||||
{"type":"mac","section":"Core","hidden":false},
|
||||
{"type":"macos","section":"Core","hidden":false},
|
||||
{"type":"win","section":"Core","hidden":false},
|
||||
{"type":"windows","section":"Core","hidden":false},
|
||||
{"type":"zos","section":"Core","hidden":false},
|
||||
{"type":"doc","section":"Doc","hidden":false},
|
||||
{"type":"docs","section":"Doc","hidden":false},
|
||||
{"type":"readme","section":"Doc","hidden":false},
|
||||
{"type":"chore","section":"Miscellaneous","hidden":false},
|
||||
{"type":"refactor","section":"Miscellaneous","hidden":false},
|
||||
{"type":"ci","section":"Miscellaneous","hidden":false},
|
||||
{"type":"meta","section":"Miscellaneous","hidden":false}]
|
||||
|
||||
# Standard Conventional Commits: `feat` and `fix`
|
||||
# node-gyp subdirectories: `bin`, `gyp`, `lib`, `src`, `test`
|
||||
# node-gyp subcommands: `build`, `clean`, `configure`, `install`, `list`, `rebuild`, `remove`
|
||||
# Core abstract category: `deps`
|
||||
# Languages/platforms: `python`, `lin`, `linux`, `mac`, `macos`, `win`, `window`, `zos`
|
||||
# Documentation: `doc`, `docs`, `readme`
|
||||
# Standard Conventional Commits: `chore` (under "Miscellaneous")
|
||||
# Miscellaneous abstract categories: `refactor`, `ci`, `meta`
|
||||
59
electron/node_modules/node-gyp/.github/workflows/tests.yml
generated
vendored
59
electron/node_modules/node-gyp/.github/workflows/tests.yml
generated
vendored
|
|
@ -1,59 +0,0 @@
|
|||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||
# TODO: Line 48, enable pytest --doctest-modules
|
||||
|
||||
name: Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release/v*
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- release/v*
|
||||
jobs:
|
||||
Lint_Python:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: pip install --user ruff
|
||||
- run: ruff --output-format=github --select="E,F,PLC,PLE,UP,W,YTT" --ignore="E721,PLC1901,S101,UP031" --target-version=py38 .
|
||||
Tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 15
|
||||
matrix:
|
||||
node: [16.x, 18.x, 20.x]
|
||||
python: ["3.8", "3.11"]
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- name: Use Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
env:
|
||||
PYTHON_VERSION: ${{ matrix.python }} # Why do this?
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
npm install --no-progress
|
||||
pip install pytest
|
||||
- name: Set Windows environment
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
run: |
|
||||
echo 'GYP_MSVS_VERSION=2015' >> $Env:GITHUB_ENV
|
||||
echo 'GYP_MSVS_OVERRIDE_PATH=C:\\Dummy' >> $Env:GITHUB_ENV
|
||||
- name: Run Python tests
|
||||
run: python -m pytest
|
||||
# - name: Run doctests with pytest
|
||||
# run: python -m pytest --doctest-modules
|
||||
- name: Environment Information
|
||||
run: npx envinfo
|
||||
- name: Run Node tests
|
||||
run: npm test
|
||||
37
electron/node_modules/node-gyp/.github/workflows/visual-studio.yml
generated
vendored
37
electron/node_modules/node-gyp/.github/workflows/visual-studio.yml
generated
vendored
|
|
@ -1,37 +0,0 @@
|
|||
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||
|
||||
name: visual-studio
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release/v*
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- release/v*
|
||||
jobs:
|
||||
visual-studio:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 8
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
msvs-version: [2016, 2019, 2022] # https://github.com/actions/virtual-environments/tree/main/images/win
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
npm install --no-progress
|
||||
# npm audit fix --force
|
||||
- name: Set Windows environment
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
run: |
|
||||
echo 'GYP_MSVS_VERSION=${{ matrix.msvs-version }}' >> $Env:GITHUB_ENV
|
||||
echo 'GYP_MSVS_OVERRIDE_PATH=C:\\Dummy' >> $Env:GITHUB_ENV
|
||||
- name: Environment Information
|
||||
run: npx envinfo
|
||||
- name: Run Node tests
|
||||
run: npm test
|
||||
3
electron/node_modules/node-gyp/.release-please-manifest.json
generated
vendored
Normal file
3
electron/node_modules/node-gyp/.release-please-manifest.json
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
".": "12.4.0"
|
||||
}
|
||||
423
electron/node_modules/node-gyp/CHANGELOG.md
generated
vendored
423
electron/node_modules/node-gyp/CHANGELOG.md
generated
vendored
|
|
@ -1,23 +1,417 @@
|
|||
# Changelog
|
||||
|
||||
### [9.4.1](https://www.github.com/nodejs/node-gyp/compare/v9.4.0...v9.4.1) (2023-10-27)
|
||||
## [12.4.0](https://github.com/nodejs/node-gyp/compare/v12.3.0...v12.4.0) (2026-05-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update gyp-next to v0.22.2 ([#3316](https://github.com/nodejs/node-gyp/issues/3316)) ([8ea71e5](https://github.com/nodejs/node-gyp/commit/8ea71e5a0d5577f8f780df7597fa1f94089e1be4))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Revert "update make-fetch-happen to 11.0.3 ([#2796](https://www.github.com/nodejs/node-gyp/issues/2796))" ([82c2d64](https://www.github.com/nodejs/node-gyp/commit/82c2d64ca8288853c79c6c42b9e49a64ebd21d86))
|
||||
|
||||
|
||||
### Tests
|
||||
|
||||
* update expired certs ([#2908](https://www.github.com/nodejs/node-gyp/issues/2908)) ([cd1b637](https://www.github.com/nodejs/node-gyp/commit/cd1b637aa4e5d97302d673a789cfee3c44f74aa3))
|
||||
* retry downloads on retryable errors ([#3308](https://github.com/nodejs/node-gyp/issues/3308)) ([0793489](https://github.com/nodejs/node-gyp/commit/0793489b961c2cbf6c6b2182d968d0c262c3b573))
|
||||
* stop testing end-of-life Node.js v20 ([#3315](https://github.com/nodejs/node-gyp/issues/3315)) ([5c0ec47](https://github.com/nodejs/node-gyp/commit/5c0ec47797a18d3e65f0c4c83e5812289191cfe1))
|
||||
* test on Node.js v26 ([#3314](https://github.com/nodejs/node-gyp/issues/3314)) ([0e65639](https://github.com/nodejs/node-gyp/commit/0e65639baa8b64b5fecec3820a4f07dc7c4a42ad))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* add release branches as ci targets ([b68da05](https://www.github.com/nodejs/node-gyp/commit/b68da055ed48c58c6cd614232f0e5bfa96ef7b7b))
|
||||
* add release-please to v9 branch ([5a65d03](https://www.github.com/nodejs/node-gyp/commit/5a65d03728b4b42b90912169917ba50be179463f))
|
||||
* increase parallel install timeouts ([fd77b34](https://www.github.com/nodejs/node-gyp/commit/fd77b346a9b5cf7a0bddc237ad71b45deb5d31ea))
|
||||
* add workflow_dispatch trigger to tests workflow ([#3299](https://github.com/nodejs/node-gyp/issues/3299)) ([b2fcdcd](https://github.com/nodejs/node-gyp/commit/b2fcdcdd6aebdf0ab6d7d296fcabccf188883e01))
|
||||
|
||||
## [12.3.0](https://github.com/nodejs/node-gyp/compare/v12.2.0...v12.3.0) (2026-04-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* replace make-fetch-happen with built-in fetch ([#3302](https://github.com/nodejs/node-gyp/issues/3302)) ([393ec2b](https://github.com/nodejs/node-gyp/commit/393ec2be480195b585768eb18ac2d92b858b12db))
|
||||
* update gyp-next to v0.22.1 ([#3295](https://github.com/nodejs/node-gyp/issues/3295)) ([f4242fb](https://github.com/nodejs/node-gyp/commit/f4242fb7bf7592d71848bae5c7f8597f2718dc3f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Switch to URL instead of url.resolve ([#3256](https://github.com/nodejs/node-gyp/issues/3256)) ([#3263](https://github.com/nodejs/node-gyp/issues/3263)) ([46d7576](https://github.com/nodejs/node-gyp/commit/46d75768018d10dc4b5693b35cf58f502425cbbe))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* **deps-dev:** bump neostandard from 0.12.2 to 0.13.0 ([#3289](https://github.com/nodejs/node-gyp/issues/3289)) ([19da158](https://github.com/nodejs/node-gyp/commit/19da1583b3876dce8c97263b168d9dfef637b76b))
|
||||
* improve Add-Type with -IgnoreWarnings ([#3280](https://github.com/nodejs/node-gyp/issues/3280)) ([1381458](https://github.com/nodejs/node-gyp/commit/13814583a476c85a84d5ac902c7ffa310120cb88))
|
||||
|
||||
## [12.2.0](https://github.com/nodejs/node-gyp/compare/v12.1.0...v12.2.0) (2026-01-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* include built package version in error logs ([#3254](https://github.com/nodejs/node-gyp/issues/3254)) ([ee9cbdd](https://github.com/nodejs/node-gyp/commit/ee9cbdd6e1d40dc7c1cdc5ed6a75432c716eaf3f))
|
||||
* update gyp-next to v0.21.1 ([#3273](https://github.com/nodejs/node-gyp/issues/3273)) ([888ff2c](https://github.com/nodejs/node-gyp/commit/888ff2c48a4cf5602013b96b52c6670906976f63))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* cpu concurrency detection on some platforms ([#3255](https://github.com/nodejs/node-gyp/issues/3255)) ([f15b79a](https://github.com/nodejs/node-gyp/commit/f15b79a03c54cea0f66d940a0d6d839df867a319)), closes [#3191](https://github.com/nodejs/node-gyp/issues/3191)
|
||||
* python is no longer a valid npm config setting ([#3258](https://github.com/nodejs/node-gyp/issues/3258)) ([c7c678f](https://github.com/nodejs/node-gyp/commit/c7c678f89837d956194f326b01c5a8eb1d745db3))
|
||||
* Switch to URL instead of url.parse ([#3256](https://github.com/nodejs/node-gyp/issues/3256)) ([3f81949](https://github.com/nodejs/node-gyp/commit/3f819499d8ce6d46c646466de7b9492bf7bde663))
|
||||
* Test Windows on Python 3.14, not 3.13 ([#3262](https://github.com/nodejs/node-gyp/issues/3262)) ([7b4f315](https://github.com/nodejs/node-gyp/commit/7b4f315e4dad880c841d21df641d6dd9b68bf36b))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* **deps:** bump actions/checkout from 5 to 6 ([#3248](https://github.com/nodejs/node-gyp/issues/3248)) ([db5385c](https://github.com/nodejs/node-gyp/commit/db5385c5467e5bfb914b9954f0313c46f1f4e10d))
|
||||
|
||||
|
||||
### Doc
|
||||
|
||||
* add a note about changes in gyp folder ([#3259](https://github.com/nodejs/node-gyp/issues/3259)) ([a52bc81](https://github.com/nodejs/node-gyp/commit/a52bc819f44b881854ff798865ad416430e3dce2))
|
||||
* correct typos ([#3269](https://github.com/nodejs/node-gyp/issues/3269)) ([0f2bc7d](https://github.com/nodejs/node-gyp/commit/0f2bc7d2e0665b1c7bb03e1cd8653ea330277a70))
|
||||
* remove obsolete Microsoft Node.js Guidelines link ([#3268](https://github.com/nodejs/node-gyp/issues/3268)) ([30cda26](https://github.com/nodejs/node-gyp/commit/30cda268730798dc0f67182c8c568d8b8069964e))
|
||||
* update Python manual install instructions for Windows ([#3265](https://github.com/nodejs/node-gyp/issues/3265)) ([0407877](https://github.com/nodejs/node-gyp/commit/0407877e3e26d3201f74cf1a9deabbbfc40bdbb7))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* **deps:** upgrade tar to 7.5.4 to address CVE-2026-23950 ([#3271](https://github.com/nodejs/node-gyp/issues/3271)) ([7bf371c](https://github.com/nodejs/node-gyp/commit/7bf371c4dd7c694232ab3169d02fe8197e1ecc6d))
|
||||
|
||||
## [12.1.0](https://github.com/nodejs/node-gyp/compare/v12.0.0...v12.1.0) (2025-11-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for Visual Studio 2026 (18.x) ([69e5fd2](https://github.com/nodejs/node-gyp/commit/69e5fd2c98ac83dad5200a47515b301ccd80d2d3))
|
||||
* Support for Visual Studio 2026 (18.x) ([69e5fd2](https://github.com/nodejs/node-gyp/commit/69e5fd2c98ac83dad5200a47515b301ccd80d2d3))
|
||||
|
||||
## [12.0.0](https://github.com/nodejs/node-gyp/compare/v11.5.0...v12.0.0) (2025-11-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* align to npm 11 node engine range
|
||||
|
||||
### Features
|
||||
|
||||
* align to npm 11 node engine range ([2f85686](https://github.com/nodejs/node-gyp/commit/2f85686bbe745673350a8f9dbb0e86ee0190f213))
|
||||
* update gyp-next to v0.21.0 ([c57cd2e](https://github.com/nodejs/node-gyp/commit/c57cd2e86dc57707475b9f7e676e189f064817de))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* **deps:** bump actions/setup-node from 5 to 6 ([ae90e63](https://github.com/nodejs/node-gyp/commit/ae90e632d9fab85f4cd902dc9205ba9dfafaf3bc))
|
||||
* **deps:** bump env-paths from 2.2.1 to 3.0.0 ([#3235](https://github.com/nodejs/node-gyp/issues/3235)) ([5fffb2f](https://github.com/nodejs/node-gyp/commit/5fffb2ffee304cc898fdea7a0cd9e41d54c53839))
|
||||
* **deps:** bump which from 5.0.0 to 6.0.0 ([#3238](https://github.com/nodejs/node-gyp/issues/3238)) ([eaa8e34](https://github.com/nodejs/node-gyp/commit/eaa8e34cb5a0710bef0602c42e5840b47eb76822))
|
||||
* make-fetch-happen@15.0.0 ([e2b9d21](https://github.com/nodejs/node-gyp/commit/e2b9d21bce27c35d18fcb6f8583e386d15ce395c))
|
||||
* nopt@9.0.0 ([9bdeaf3](https://github.com/nodejs/node-gyp/commit/9bdeaf307cd7a254946859d306465989fa39dfb2))
|
||||
* proc-log@6.0.0 ([dfc68df](https://github.com/nodejs/node-gyp/commit/dfc68dfba3c17deb0bda9a395bb49d8fb9fa5951))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* increase test timeouts ([#3237](https://github.com/nodejs/node-gyp/issues/3237)) ([3b41971](https://github.com/nodejs/node-gyp/commit/3b41971e2f6b90e02b1d7df592d403b8dfc8fa4d))
|
||||
* setup dependabot for npm ([86d65c7](https://github.com/nodejs/node-gyp/commit/86d65c7874eb41eb49c9b8bbf342becac8e57c6f))
|
||||
* update devDependencies ([41b0cea](https://github.com/nodejs/node-gyp/commit/41b0cea2f12342a790580cc8f844f075d49e096c))
|
||||
|
||||
## [11.5.0](https://github.com/nodejs/node-gyp/compare/v11.4.2...v11.5.0) (2025-10-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update gyp-next to v0.20.5 ([#3222](https://github.com/nodejs/node-gyp/issues/3222)) ([848e950](https://github.com/nodejs/node-gyp/commit/848e950833b90f0b25f346710ee42e9be4797604))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Run Visual Studio test on Windows 11 on ARM ([#3217](https://github.com/nodejs/node-gyp/issues/3217)) ([8bd3f63](https://github.com/nodejs/node-gyp/commit/8bd3f6354b8bd43262a4d99d58a568beab0459e8))
|
||||
* **ci:** Test on Python 3.14 release candidate 3 on Linux and macOS ([#3216](https://github.com/nodejs/node-gyp/issues/3216)) ([085b445](https://github.com/nodejs/node-gyp/commit/085b445d1c00f8f1fc6a6ff80d8a93c6643f11ee))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* **deps:** bump actions/github-script from 7 to 8 ([#3213](https://github.com/nodejs/node-gyp/issues/3213)) ([c6b968c](https://github.com/nodejs/node-gyp/commit/c6b968caf7f4e22687fc10716162675b1411f713))
|
||||
* **deps:** bump actions/setup-node from 4 to 5 ([#3211](https://github.com/nodejs/node-gyp/issues/3211)) ([921c04d](https://github.com/nodejs/node-gyp/commit/921c04d142549f172d3aeae4097c9e0af05599dd))
|
||||
* **deps:** bump actions/setup-python from 5 to 6 ([#3210](https://github.com/nodejs/node-gyp/issues/3210)) ([6b70b05](https://github.com/nodejs/node-gyp/commit/6b70b05ed21cb977214348c97c2b97515c0d08f3))
|
||||
|
||||
## [11.4.2](https://github.com/nodejs/node-gyp/compare/v11.4.1...v11.4.2) (2025-08-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add adaptation for OpenHarmony platform ([#3207](https://github.com/nodejs/node-gyp/issues/3207)) ([b406532](https://github.com/nodejs/node-gyp/commit/b406532c77659c441c845708ec3ecdf09f013a3b))
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* update gyp-next to v0.20.4 ([#3208](https://github.com/nodejs/node-gyp/issues/3208)) ([adc61b1](https://github.com/nodejs/node-gyp/commit/adc61b1458315d9648591e74bf16bbe39511401e))
|
||||
* **ci:** Update Node.js version matrix in `tests.yml` ([#3209](https://github.com/nodejs/node-gyp/issues/3209)) ([a4e1da6](https://github.com/nodejs/node-gyp/commit/a4e1da6683a37fde565e1ea50f1fa86fa99a83c7))
|
||||
* ruff format Python code ([#3203](https://github.com/nodejs/node-gyp/issues/3203)) ([cb30a53](https://github.com/nodejs/node-gyp/commit/cb30a538eadf49ca0310980ffb0bfdb8fcebf0a4))
|
||||
|
||||
## [11.4.1](https://github.com/nodejs/node-gyp/compare/v11.4.0...v11.4.1) (2025-08-20)
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* **release:** use npm@11 for OIDC publishing ([#3202](https://github.com/nodejs/node-gyp/issues/3202)) ([6b9638a](https://github.com/nodejs/node-gyp/commit/6b9638a0f80352e5bf7c1702e6ef622a6474d44a)), closes [#3201](https://github.com/nodejs/node-gyp/issues/3201)
|
||||
|
||||
## [11.4.0](https://github.com/nodejs/node-gyp/compare/v11.3.0...v11.4.0) (2025-08-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* read from config case-insensitively ([#3198](https://github.com/nodejs/node-gyp/issues/3198)) ([5538e6c](https://github.com/nodejs/node-gyp/commit/5538e6c5d78dffd41e2a588adfa7ea9022150b9d))
|
||||
* support reading config from package.json ([#3196](https://github.com/nodejs/node-gyp/issues/3196)) ([1822dff](https://github.com/nodejs/node-gyp/commit/1822dff4f616a30ac3ca72e5946d81389cb8557e)), closes [#3156](https://github.com/nodejs/node-gyp/issues/3156)
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* **deps:** bump actions/checkout from 4 to 5 ([#3193](https://github.com/nodejs/node-gyp/issues/3193)) ([27f5505](https://github.com/nodejs/node-gyp/commit/27f5505ec236551081366bf8a9c13ef5d8e468bf))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* use npm oicd connection for publishing ([#3197](https://github.com/nodejs/node-gyp/issues/3197)) ([0773615](https://github.com/nodejs/node-gyp/commit/077361502933fcb994ca365c3c07c03177503df2))
|
||||
|
||||
## [11.3.0](https://github.com/nodejs/node-gyp/compare/v11.2.0...v11.3.0) (2025-07-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update gyp-next to v0.20.2 ([#3169](https://github.com/nodejs/node-gyp/issues/3169)) ([0e65632](https://github.com/nodejs/node-gyp/commit/0e656322c1e94041331ab3b01bf66c2ef9bd6ead))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Correct Visual Studio 2019 test version ([#3153](https://github.com/nodejs/node-gyp/issues/3153)) ([7d883b5](https://github.com/nodejs/node-gyp/commit/7d883b5cf4c26e76065201f85b0be36d5ebdcc0e))
|
||||
* Normalize win32 library names ([#3189](https://github.com/nodejs/node-gyp/issues/3189)) ([b81a665](https://github.com/nodejs/node-gyp/commit/b81a665acfb9d88102e8044a8ec8ca74a3e9eccc))
|
||||
* use temp dir for tar extraction on all platforms ([#3170](https://github.com/nodejs/node-gyp/issues/3170)) ([b41864f](https://github.com/nodejs/node-gyp/commit/b41864f7c1c60e4a160c1b4dd91558dcaa3f74e4)), closes [#3165](https://github.com/nodejs/node-gyp/issues/3165)
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* retry wasi-sdk download in CI ([#3151](https://github.com/nodejs/node-gyp/issues/3151)) ([8f3cd8b](https://github.com/nodejs/node-gyp/commit/8f3cd8b3a157bccd8d7110e7d46a27c2926625cd))
|
||||
* Windows 2019 has been removed from GitHub Actions ([#3190](https://github.com/nodejs/node-gyp/issues/3190)) ([3df8789](https://github.com/nodejs/node-gyp/commit/3df8789a9aa73c60707eec8f02f4e926491d6102))
|
||||
|
||||
## [11.2.0](https://github.com/nodejs/node-gyp/compare/v11.1.0...v11.2.0) (2025-04-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update gyp-next to v0.20.0 ([#3149](https://github.com/nodejs/node-gyp/issues/3149)) ([80e9c79](https://github.com/nodejs/node-gyp/commit/80e9c795a739c490cfbc85633e63022b36a7c70d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* disable msbuild.exe nodeReuse ([#3112](https://github.com/nodejs/node-gyp/issues/3112)) ([0cf16d2](https://github.com/nodejs/node-gyp/commit/0cf16d29fe604266fb47325496287a63075ea532))
|
||||
* use maxRetries on fs.rm calls ([#3113](https://github.com/nodejs/node-gyp/issues/3113)) ([a2772a7](https://github.com/nodejs/node-gyp/commit/a2772a76709f939af1e80dd8fe766ca2143aa5bf))
|
||||
|
||||
|
||||
### Tests
|
||||
|
||||
* fix wasm test on Windows ([#3145](https://github.com/nodejs/node-gyp/issues/3145)) ([ee1d6fd](https://github.com/nodejs/node-gyp/commit/ee1d6fd8d83c9dd3eae7df7ec533bb6b39e1a812))
|
||||
* use maxRetries with tests too ([#3150](https://github.com/nodejs/node-gyp/issues/3150)) ([0ccbe7e](https://github.com/nodejs/node-gyp/commit/0ccbe7e90afb096b46a7818ba127a4871237952e))
|
||||
|
||||
|
||||
### Doc
|
||||
|
||||
* add ffi-napi to docs/README.md ([#3138](https://github.com/nodejs/node-gyp/issues/3138)) ([4885110](https://github.com/nodejs/node-gyp/commit/48851107ad8c5d2cf18a55e8bd2764f5938e7102))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* switch to tinyglobby ([#3133](https://github.com/nodejs/node-gyp/issues/3133)) ([c3b3ab0](https://github.com/nodejs/node-gyp/commit/c3b3ab06ee0f092cd5c0646120d57e56d41b79fc))
|
||||
* update tinyglobby ([#3136](https://github.com/nodejs/node-gyp/issues/3136)) ([b21cf87](https://github.com/nodejs/node-gyp/commit/b21cf874f58883f3fd4dd07bec3b584fb07e831d))
|
||||
|
||||
## [11.1.0](https://github.com/nodejs/node-gyp/compare/v11.0.0...v11.1.0) (2025-02-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update gyp-next to v0.19.1 ([#3122](https://github.com/nodejs/node-gyp/issues/3122)) ([504250e](https://github.com/nodejs/node-gyp/commit/504250e5e3e27c6ef6dcfcaa744b36e1a99c1be8))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Find VC.Tools.ARM64 on arm64 machine ([#3075](https://github.com/nodejs/node-gyp/issues/3075)) ([b899fae](https://github.com/nodejs/node-gyp/commit/b899faed56270d3d8496da7576b5750b264c2c21))
|
||||
* try libnode.dll first in load_exe_hook ([#2834](https://github.com/nodejs/node-gyp/issues/2834)) ([b9d10a5](https://github.com/nodejs/node-gyp/commit/b9d10a5a37081e2a731937e43eca52c83609e7f5))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* add gyp-next updater ([#3105](https://github.com/nodejs/node-gyp/issues/3105)) ([e3f9a77](https://github.com/nodejs/node-gyp/commit/e3f9a7756f65a7f4e50799017b3dc51d5bc195b2))
|
||||
* Test on Ubuntu-24.04-arm and Node.js v23 ([#3121](https://github.com/nodejs/node-gyp/issues/3121)) ([2530f51](https://github.com/nodejs/node-gyp/commit/2530f51cec3ba595184e5bcb7fe1245e240beb59))
|
||||
* Use astral-sh/ruff-action@v3 to run the Python linter ([#3114](https://github.com/nodejs/node-gyp/issues/3114)) ([94448fc](https://github.com/nodejs/node-gyp/commit/94448fcd9f090814bce1c4361471dae199dc2e82))
|
||||
|
||||
## [11.0.0](https://github.com/nodejs/node-gyp/compare/v10.3.1...v11.0.0) (2024-12-03)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* drop node 16 support ([#3102](https://github.com/nodejs/node-gyp/issues/3102))
|
||||
|
||||
### Features
|
||||
|
||||
* drop node 16 support ([#3102](https://github.com/nodejs/node-gyp/issues/3102)) ([0e6b6f8](https://github.com/nodejs/node-gyp/commit/0e6b6f8bea615cf031d76ecff9102a38e5474c72))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* migrate from standard to neostandard ([#3103](https://github.com/nodejs/node-gyp/issues/3103)) ([a130178](https://github.com/nodejs/node-gyp/commit/a13017807d0ae7da8fa076b0bcf23153af7c60a6))
|
||||
|
||||
## [10.3.1](https://github.com/nodejs/node-gyp/compare/v10.3.0...v10.3.1) (2024-12-02)
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* fix npm-publish dependencies and add provenance ([#3099](https://github.com/nodejs/node-gyp/issues/3099)) ([6dded88](https://github.com/nodejs/node-gyp/commit/6dded88065872a32f44114e60731ba4b701ec057))
|
||||
|
||||
## [10.3.0](https://github.com/nodejs/node-gyp/compare/v10.2.0...v10.3.0) (2024-11-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* prohibit compiling with ClangCL on Windows ([#3098](https://github.com/nodejs/node-gyp/issues/3098)) ([88260bf](https://github.com/nodejs/node-gyp/commit/88260bf86aeb4c39959b78104a5edc3dc88d3aef))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** use correct release-please-action domain after organization url was changed ([#3032](https://github.com/nodejs/node-gyp/issues/3032)) ([d1ed3d4](https://github.com/nodejs/node-gyp/commit/d1ed3d4dc3a53b8ccab4093d002e43945bbece0e))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* add links to Code of Conduct from root file ([#2196](https://github.com/nodejs/node-gyp/issues/2196)) ([d22e2eb](https://github.com/nodejs/node-gyp/commit/d22e2eb080807c6290533a67249c343a7605a989))
|
||||
* publish to npm with release-please ([#3051](https://github.com/nodejs/node-gyp/issues/3051)) ([8319847](https://github.com/nodejs/node-gyp/commit/831984736393a3ea8417efec5255f95d53a70785))
|
||||
|
||||
## [10.2.0](https://github.com/nodejs/node-gyp/compare/v10.1.0...v10.2.0) (2024-07-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow VCINSTALLDIR to specify a portable instance ([#3036](https://github.com/nodejs/node-gyp/issues/3036)) ([d38af2e](https://github.com/nodejs/node-gyp/commit/d38af2e0c2a81b12cd221b1f8517fb89e609d62c))
|
||||
* **gyp:** update gyp to v0.18.1 ([#3039](https://github.com/nodejs/node-gyp/issues/3039)) ([ea99fea](https://github.com/nodejs/node-gyp/commit/ea99fea83485dc5be04db01df9b2fdbe05319b8e))
|
||||
* support `rebuild` and `build` for cross-compiling Node-API module to wasm on Windows ([#2974](https://github.com/nodejs/node-gyp/issues/2974)) ([6318d2b](https://github.com/nodejs/node-gyp/commit/6318d2b210224415ff5932c2863e6cc14d4583dc))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* add an arch check to VS 2019 ([#3025](https://github.com/nodejs/node-gyp/issues/3025)) ([323957b](https://github.com/nodejs/node-gyp/commit/323957b74e9586fb3fbfb2acad5040379c778de6))
|
||||
* **deps:** bump seanmiddleditch/gha-setup-ninja from 4 to 5 ([#3041](https://github.com/nodejs/node-gyp/issues/3041)) ([10f6730](https://github.com/nodejs/node-gyp/commit/10f6730be660e7a38be8a12111937e37fcf74834))
|
||||
* proc-log@4.0.0 ([#3022](https://github.com/nodejs/node-gyp/issues/3022)) ([141aa6b](https://github.com/nodejs/node-gyp/commit/141aa6bf029e6f984be8ea98aaf985e5df894082))
|
||||
* tar@6.2.1 ([#3021](https://github.com/nodejs/node-gyp/issues/3021)) ([b22d5ee](https://github.com/nodejs/node-gyp/commit/b22d5eef861892c968052ffc1c71b551f738163b))
|
||||
|
||||
|
||||
### Doc
|
||||
|
||||
* `node-pre-gyp` is no longer maintained ([#3015](https://github.com/nodejs/node-gyp/issues/3015)) ([93186f1](https://github.com/nodejs/node-gyp/commit/93186f10c966b4148fc500e48f8cbffacccdfa3c))
|
||||
* add the way to configuring Python dependency for Windows PowerShell ([#2996](https://github.com/nodejs/node-gyp/issues/2996)) ([9fd7936](https://github.com/nodejs/node-gyp/commit/9fd7936f0d7232a8a79e6a7b6cbfb814d9042b13))
|
||||
* Installation -- Python >= v3.12 requires `node-gyp` >= v10 ([#3010](https://github.com/nodejs/node-gyp/issues/3010)) ([a6b48fc](https://github.com/nodejs/node-gyp/commit/a6b48fca9993e54d757cd110f6b41f8200d99ca4))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* fix ruff command ([#3044](https://github.com/nodejs/node-gyp/issues/3044)) ([b3916d5](https://github.com/nodejs/node-gyp/commit/b3916d5b25704a53e89be16b500036a14bdc5060))
|
||||
|
||||
## [10.1.0](https://github.com/nodejs/node-gyp/compare/v10.0.1...v10.1.0) (2024-03-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve visual studio detection ([#2957](https://github.com/nodejs/node-gyp/issues/2957)) ([109e3d4](https://github.com/nodejs/node-gyp/commit/109e3d4245504a7b75c99f578e1203c0ef4b518e))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* add support for locally installed headers ([#2964](https://github.com/nodejs/node-gyp/issues/2964)) ([3298731](https://github.com/nodejs/node-gyp/commit/329873141f0d3e3787d3c006801431da04e4ed0c))
|
||||
* **deps:** bump actions/setup-python from 4 to 5 ([#2960](https://github.com/nodejs/node-gyp/issues/2960)) ([3f0df7e](https://github.com/nodejs/node-gyp/commit/3f0df7e9334e49e8c7f6fdbbb9e1e6c5a8cca53b))
|
||||
* **deps:** bump google-github-actions/release-please-action ([#2961](https://github.com/nodejs/node-gyp/issues/2961)) ([b1f1808](https://github.com/nodejs/node-gyp/commit/b1f1808bfff0d51e6d3eb696ab6a5b89b7b9630c))
|
||||
* print Python executable path using UTF-8 ([#2995](https://github.com/nodejs/node-gyp/issues/2995)) ([c472912](https://github.com/nodejs/node-gyp/commit/c4729129daa9bb5204246b857826fb391ac961e1))
|
||||
* update supported vs versions ([#2959](https://github.com/nodejs/node-gyp/issues/2959)) ([391cc5b](https://github.com/nodejs/node-gyp/commit/391cc5b9b25cffe0cb2edcba3583414a771b4a15))
|
||||
|
||||
|
||||
### Doc
|
||||
|
||||
* npm is currently v10 ([#2970](https://github.com/nodejs/node-gyp/issues/2970)) ([7705a22](https://github.com/nodejs/node-gyp/commit/7705a22f31a62076e9f8429780a459f4ad71ea4c))
|
||||
* remove outdated Node versions from readme ([#2955](https://github.com/nodejs/node-gyp/issues/2955)) ([ae8478e](https://github.com/nodejs/node-gyp/commit/ae8478ec32d9b2fa71b591ac22cdf867ef2e9a7d))
|
||||
* remove outdated update engines.node reference in 10.0.0 changelog ([b42e796](https://github.com/nodejs/node-gyp/commit/b42e7966177f006f3d1aab1d27885d8372c8ed01))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* only run release please on push ([cff9ac2](https://github.com/nodejs/node-gyp/commit/cff9ac2c3083769a383e00bc60b91562f03116e3))
|
||||
* upgrade release please action from v2 to v4 ([#2982](https://github.com/nodejs/node-gyp/issues/2982)) ([0035d8e](https://github.com/nodejs/node-gyp/commit/0035d8e9dc98b94f0bc8cd9023a6fa635003703e))
|
||||
|
||||
### [10.0.1](https://www.github.com/nodejs/node-gyp/compare/v10.0.0...v10.0.1) (2023-11-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* use local `util` for `findAccessibleSync()` ([b39e681](https://www.github.com/nodejs/node-gyp/commit/b39e6819aa9e2c45107d6e60a4913ca036ebfbfd))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* add parallel test logging ([7de1f5f](https://www.github.com/nodejs/node-gyp/commit/7de1f5f32d550d26d48fe4f76aed5866744edcba))
|
||||
* lint fixes ([4e0ed99](https://www.github.com/nodejs/node-gyp/commit/4e0ed992566f43abc6e988af091ad07fde04acbf))
|
||||
* use platform specific timeouts in tests ([a68586a](https://www.github.com/nodejs/node-gyp/commit/a68586a67d0af238300662cc062422b42820044d))
|
||||
|
||||
## [10.0.0](https://www.github.com/nodejs/node-gyp/compare/v9.4.0...v10.0.0) (2023-10-28)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* use .npmignore file to limit which files are published (#2921)
|
||||
* the `Gyp` class exported is now created using ECMAScript classes and therefore might have small differences to classes that were previously created with `util.inherits`.
|
||||
* All internal functions have been coverted to return promises and no longer accept callbacks. This is not a breaking change for users but may be breaking to consumers of `node-gyp` if you are requiring internal functions directly.
|
||||
* `node-gyp` now supports node `^16.14.0 || >=18.0.0`
|
||||
|
||||
### Features
|
||||
|
||||
* convert all internal functions to async/await ([355622f](https://www.github.com/nodejs/node-gyp/commit/355622f4aac3bd3056b9e03aac5fa2f42a4b3576))
|
||||
* convert internal classes from util.inherits to classes ([d52997e](https://www.github.com/nodejs/node-gyp/commit/d52997e975b9da6e0cea3d9b99873e9ddc768679))
|
||||
* drop node 14 support ([#2929](https://www.github.com/nodejs/node-gyp/issues/2929)) ([1b3bd34](https://www.github.com/nodejs/node-gyp/commit/1b3bd341b40f384988d03207ce8187e93ba609bc))
|
||||
* drop rimraf dependency ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* **gyp:** update gyp to v0.16.1 ([#2923](https://www.github.com/nodejs/node-gyp/issues/2923)) ([707927c](https://www.github.com/nodejs/node-gyp/commit/707927cd579205ef2b4b17e61c1cce24c056b452))
|
||||
* replace npmlog with proc-log ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* update engines.node to ^14.17.0 || ^16.13.0 || >=18.0.0 ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* use .npmignore file to limit which files are published ([#2921](https://www.github.com/nodejs/node-gyp/issues/2921)) ([864a979](https://www.github.com/nodejs/node-gyp/commit/864a979930cf0ef5ad64bc887b901fa8955d058f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* create Python symlink only during builds, and clean it up after ([#2721](https://www.github.com/nodejs/node-gyp/issues/2721)) ([0f1f667](https://www.github.com/nodejs/node-gyp/commit/0f1f667b737d21905e283df100a2cb639993562a))
|
||||
* promisify build command ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* use fs/promises in favor of fs.promises ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
|
||||
|
||||
### Tests
|
||||
|
||||
* increase mocha timeout ([#2887](https://www.github.com/nodejs/node-gyp/issues/2887)) ([445c28f](https://www.github.com/nodejs/node-gyp/commit/445c28fabc5fbdf9c3bb3341fb70660a3530f6ad))
|
||||
* update expired certs ([#2908](https://www.github.com/nodejs/node-gyp/issues/2908)) ([5746691](https://www.github.com/nodejs/node-gyp/commit/5746691a36f7b37019d4b8d4e9616aec43d20410))
|
||||
|
||||
|
||||
### Doc
|
||||
|
||||
* Add note about Python symlinks (PR 2362) to CHANGELOG.md for 9.1.0 ([#2783](https://www.github.com/nodejs/node-gyp/issues/2783)) ([b3d41ae](https://www.github.com/nodejs/node-gyp/commit/b3d41aeb737ddd54cc292f363abc561dcc0a614e))
|
||||
* README.md Do not hardcode the supported versions of Python ([#2880](https://www.github.com/nodejs/node-gyp/issues/2880)) ([bb93b94](https://www.github.com/nodejs/node-gyp/commit/bb93b946a9c74934b59164deb52128cf913c97d5))
|
||||
* update applicable GitHub links from master to main ([#2843](https://www.github.com/nodejs/node-gyp/issues/2843)) ([d644ce4](https://www.github.com/nodejs/node-gyp/commit/d644ce48311edf090d0e920ad449e5766c757933))
|
||||
* Update windows installation instructions in README.md ([#2882](https://www.github.com/nodejs/node-gyp/issues/2882)) ([c9caa2e](https://www.github.com/nodejs/node-gyp/commit/c9caa2ecf3c7deae68444ce8fabb32d2dca651cd))
|
||||
|
||||
|
||||
### Core
|
||||
|
||||
* find python checks order changed on windows ([#2872](https://www.github.com/nodejs/node-gyp/issues/2872)) ([b030555](https://www.github.com/nodejs/node-gyp/commit/b030555cdb754d9c23906e7e707115cd077bbf76))
|
||||
* glob@10.3.10 ([#2926](https://www.github.com/nodejs/node-gyp/issues/2926)) ([4bef1ec](https://www.github.com/nodejs/node-gyp/commit/4bef1ecc7554097d92beb397fbe1a546c5227545))
|
||||
* glob@8.0.3 ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* make-fetch-happen@13.0.0 ([#2927](https://www.github.com/nodejs/node-gyp/issues/2927)) ([059bb6f](https://www.github.com/nodejs/node-gyp/commit/059bb6fd41bb50955a9efbd97887773d60d53221))
|
||||
* nopt@^7.0.0 ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* standard@17.0.0 and fix linting errors ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* which@3.0.0 ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* which@4.0.0 ([#2928](https://www.github.com/nodejs/node-gyp/issues/2928)) ([e388255](https://www.github.com/nodejs/node-gyp/commit/e38825531403aabeae7abe58e76867f31b832f36))
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* add check engines script to CI ([#2922](https://www.github.com/nodejs/node-gyp/issues/2922)) ([21a7249](https://www.github.com/nodejs/node-gyp/commit/21a7249b40d8f95e7721e450fd18764adb1648a7))
|
||||
* empty commit to add changelog entries from [#2770](https://www.github.com/nodejs/node-gyp/issues/2770) ([4a50fe3](https://www.github.com/nodejs/node-gyp/commit/4a50fe31574217c4b2a798fc72b19947a64ceea1))
|
||||
* GitHub Workflows security hardening ([#2740](https://www.github.com/nodejs/node-gyp/issues/2740)) ([26683e9](https://www.github.com/nodejs/node-gyp/commit/26683e993df038fb94d89f2276f3535e4522d79a))
|
||||
* misc testing fixes ([#2930](https://www.github.com/nodejs/node-gyp/issues/2930)) ([4e493d4](https://www.github.com/nodejs/node-gyp/commit/4e493d4fb262d12ac52c84979071ccc79e666a1a))
|
||||
* run tests after release please PR ([3032e10](https://www.github.com/nodejs/node-gyp/commit/3032e1061cc2b7b49f83c397d385bafddc6b0214))
|
||||
|
||||
## [9.4.0](https://www.github.com/nodejs/node-gyp/compare/v9.3.1...v9.4.0) (2023-06-12)
|
||||
|
||||
|
|
@ -117,6 +511,7 @@
|
|||
### Core
|
||||
|
||||
* update due to rename of primary branch ([ca1f068](https://www.github.com/nodejs/node-gyp/commit/ca1f0681a5567ca8cd51acebccd37a633f19bc6a))
|
||||
* Add Python symlink to path (for non-Windows OSes only) ([#2362](https://github.com/nodejs/node-gyp/pull/2362)) ([b9ddcd5](https://github.com/nodejs/node-gyp/commit/b9ddcd5bbd93b05b03674836b6ebdae2c2e74c8c))
|
||||
|
||||
|
||||
### Tests
|
||||
|
|
@ -646,11 +1041,11 @@ Republish of v5.0.6 with unnecessary tarball removed from pack file.
|
|||
* [[`94c39c604e`](https://github.com/nodejs/node-gyp/commit/94c39c604e)] - **gyp**: fix ninja build failure (GYP patch) (Daniel Bevenius) [nodejs/node#12484](https://github.com/nodejs/node/pull/12484)
|
||||
* [[`e8ea74e0fa`](https://github.com/nodejs/node-gyp/commit/e8ea74e0fa)] - **tools**: patch gyp to avoid xcrun errors (Ujjwal Sharma) [nodejs/node#21520](https://github.com/nodejs/node/pull/21520)
|
||||
* [[`ea9aff44f2`](https://github.com/nodejs/node-gyp/commit/ea9aff44f2)] - **tools**: fix "the the" typos in comments (Masashi Hirano) [nodejs/node#20716](https://github.com/nodejs/node/pull/20716)
|
||||
* [[`207e5aa4fd`](https://github.com/nodejs/node-gyp/commit/207e5aa4fd)] - **gyp**: implement LD/LDXX for ninja and FIPS (Sam Roberts)
|
||||
* [[`207e5aa4fd`](https://github.com/nodejs/node-gyp/commit/207e5aa4fd)] - **gyp**: implement LD/LDXX for ninja and FIPS (Sam Roberts)
|
||||
* [[`b416c5f4b7`](https://github.com/nodejs/node-gyp/commit/b416c5f4b7)] - **gyp**: enable cctest to use objects (gyp part) (Daniel Bevenius) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450)
|
||||
* [[`40692d016b`](https://github.com/nodejs/node-gyp/commit/40692d016b)] - **gyp**: add compile\_commands.json gyp generator (Ben Noordhuis) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450)
|
||||
* [[`fc3c4e2b10`](https://github.com/nodejs/node-gyp/commit/fc3c4e2b10)] - **gyp**: float gyp patch for long filenames (Anna Henningsen) [nodejs/node#7963](https://github.com/nodejs/node/pull/7963)
|
||||
* [[`8aedbfdef6`](https://github.com/nodejs/node-gyp/commit/8aedbfdef6)] - **gyp**: backport GYP fix to fix AIX shared suffix (Stewart Addison)
|
||||
* [[`8aedbfdef6`](https://github.com/nodejs/node-gyp/commit/8aedbfdef6)] - **gyp**: backport GYP fix to fix AIX shared suffix (Stewart Addison)
|
||||
* [[`6cd84b84fc`](https://github.com/nodejs/node-gyp/commit/6cd84b84fc)] - **test**: formatting and minor fixes for execFileSync replacement (Rod Vagg) [#1521](https://github.com/nodejs/node-gyp/pull/1521)
|
||||
* [[`60e421363f`](https://github.com/nodejs/node-gyp/commit/60e421363f)] - **test**: added test/processExecSync.js for when execFileSync is not available. (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492)
|
||||
* [[`969447c5bd`](https://github.com/nodejs/node-gyp/commit/969447c5bd)] - **deps**: bump request to 2.8.7, fixes heok/hawk issues (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492)
|
||||
|
|
@ -712,7 +1107,7 @@ Republish of v5.0.6 with unnecessary tarball removed from pack file.
|
|||
|
||||
## v3.5.0 2017-01-10
|
||||
|
||||
* [[`762d19a39e`](https://github.com/nodejs/node-gyp/commit/762d19a39e)] - \[doc\] merge History.md and CHANGELOG.md (Rod Vagg)
|
||||
* [[`762d19a39e`](https://github.com/nodejs/node-gyp/commit/762d19a39e)] - \[doc\] merge History.md and CHANGELOG.md (Rod Vagg)
|
||||
* [[`80fc5c3d31`](https://github.com/nodejs/node-gyp/commit/80fc5c3d31)] - Fix deprecated dependency warning (Simone Primarosa) [#1069](https://github.com/nodejs/node-gyp/pull/1069)
|
||||
* [[`05c44944fd`](https://github.com/nodejs/node-gyp/commit/05c44944fd)] - Open the build file with universal-newlines mode (Guy Margalit) [#1053](https://github.com/nodejs/node-gyp/pull/1053)
|
||||
* [[`37ae7be114`](https://github.com/nodejs/node-gyp/commit/37ae7be114)] - Try python launcher when stock python is python 3. (Ben Noordhuis) [#992](https://github.com/nodejs/node-gyp/pull/992)
|
||||
|
|
@ -769,7 +1164,7 @@ Republish of v5.0.6 with unnecessary tarball removed from pack file.
|
|||
* [[`0e2dfda1f3`](https://github.com/nodejs/node-gyp/commit/0e2dfda1f3)] - Fix test/test-options when run through `npm test`. (Ben Noordhuis) [#755](https://github.com/nodejs/node-gyp/pull/755)
|
||||
* [[`9bfa0876b4`](https://github.com/nodejs/node-gyp/commit/9bfa0876b4)] - Add support for AIX (Michael Dawson) [#753](https://github.com/nodejs/node-gyp/pull/753)
|
||||
* [[`a8d441a0a2`](https://github.com/nodejs/node-gyp/commit/a8d441a0a2)] - Update README for Windows 10 support. (Jason Williams) [#766](https://github.com/nodejs/node-gyp/pull/766)
|
||||
* [[`d1d6015276`](https://github.com/nodejs/node-gyp/commit/d1d6015276)] - Update broken links and switch to HTTPS. (andrew morton)
|
||||
* [[`d1d6015276`](https://github.com/nodejs/node-gyp/commit/d1d6015276)] - Update broken links and switch to HTTPS. (andrew morton)
|
||||
|
||||
## v3.1.0 2015-11-14
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Code of Conduct
|
||||
|
||||
* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md)
|
||||
* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/HEAD/Moderation-Policy.md)
|
||||
* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md)
|
||||
* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/master/Moderation-Policy.md)
|
||||
12
electron/node_modules/node-gyp/CONTRIBUTING.md
generated
vendored
12
electron/node_modules/node-gyp/CONTRIBUTING.md
generated
vendored
|
|
@ -1,9 +1,17 @@
|
|||
# Contributing to node-gyp
|
||||
|
||||
## Making changes to gyp-next
|
||||
|
||||
Changes in the subfolder `gyp/` should be submitted to the
|
||||
[`gyp-next`][] repository first. The `gyp/` folder is regularly
|
||||
synced from [`gyp-next`][] with GitHub Actions workflow
|
||||
[`update-gyp-next.yml`](.github/workflows/update-gyp-next.yml),
|
||||
and any changes in this folder would be overridden by the workflow.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Please read the
|
||||
[Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md)
|
||||
[Code of Conduct](https://github.com/nodejs/admin/blob/main/CODE_OF_CONDUCT.md)
|
||||
which explains the minimum behavior expectations for node-gyp contributors.
|
||||
|
||||
<a id="developers-certificate-of-origin"></a>
|
||||
|
|
@ -32,3 +40,5 @@ By making a contribution to this project, I certify that:
|
|||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
|
||||
[`gyp-next`]: https://github.com/nodejs/gyp-next
|
||||
|
|
|
|||
97
electron/node_modules/node-gyp/README.md
generated
vendored
97
electron/node_modules/node-gyp/README.md
generated
vendored
|
|
@ -1,18 +1,18 @@
|
|||
# `node-gyp` - Node.js native addon build tool
|
||||
|
||||
[](https://github.com/nodejs/node-gyp/actions?query=workflow%3ATests+branch%3Amaster)
|
||||
[](https://github.com/nodejs/node-gyp/actions?query=workflow%3ATests+branch%3Amain)
|
||||

|
||||
|
||||
`node-gyp` is a cross-platform command-line tool written in Node.js for
|
||||
compiling native addon modules for Node.js. It contains a vendored copy of the
|
||||
[gyp-next](https://github.com/nodejs/gyp-next) project that was previously used
|
||||
by the Chromium team, extended to support the development of Node.js native addons.
|
||||
by the Chromium team and extended to support the development of Node.js native
|
||||
addons.
|
||||
|
||||
Note that `node-gyp` is _not_ used to build Node.js itself.
|
||||
|
||||
Multiple target versions of Node.js are supported (i.e. `0.8`, ..., `4`, `5`, `6`,
|
||||
etc.), regardless of what version of Node.js is actually installed on your system
|
||||
(`node-gyp` downloads the necessary development files or headers for the target version).
|
||||
All current and LTS target versions of Node.js are supported. Depending on what version of Node.js is actually installed on your system
|
||||
`node-gyp` downloads the necessary development files or headers for the target version. List of stable Node.js versions can be found on [Node.js website](https://nodejs.org/en/about/previous-releases).
|
||||
|
||||
## Features
|
||||
|
||||
|
|
@ -21,6 +21,9 @@ etc.), regardless of what version of Node.js is actually installed on your syste
|
|||
|
||||
## Installation
|
||||
|
||||
> [!Important]
|
||||
> Python >= v3.12 requires `node-gyp` >= v10
|
||||
|
||||
You can install `node-gyp` using `npm`:
|
||||
|
||||
``` bash
|
||||
|
|
@ -31,40 +34,44 @@ Depending on your operating system, you will need to install:
|
|||
|
||||
### On Unix
|
||||
|
||||
* Python v3.7, v3.8, v3.9, or v3.10
|
||||
* [A supported version of Python](https://devguide.python.org/versions/)
|
||||
* `make`
|
||||
* A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org)
|
||||
|
||||
### On macOS
|
||||
|
||||
**ATTENTION**: If your Mac has been _upgraded_ to macOS Catalina (10.15) or higher, please read [macOS_Catalina.md](macOS_Catalina.md).
|
||||
|
||||
* Python v3.7, v3.8, v3.9, or v3.10
|
||||
* `XCode Command Line Tools` which will install `clang`, `clang++`, and `make`.
|
||||
* Install the `XCode Command Line Tools` standalone by running `xcode-select --install`. -- OR --
|
||||
* [A supported version of Python](https://devguide.python.org/versions/)
|
||||
* `Xcode Command Line Tools` which will install `clang`, `clang++`, and `make`.
|
||||
* Install the `Xcode Command Line Tools` standalone by running `xcode-select --install`. -- OR --
|
||||
* Alternatively, if you already have the [full Xcode installed](https://developer.apple.com/xcode/download/), you can install the Command Line Tools under the menu `Xcode -> Open Developer Tool -> More Developer Tools...`.
|
||||
|
||||
|
||||
### On Windows
|
||||
|
||||
Install the current version of Python from the [Microsoft Store package](https://www.microsoft.com/en-us/p/python-310/9pjpw5ldxlz5).
|
||||
Install tools with [Chocolatey](https://chocolatey.org):
|
||||
``` bash
|
||||
choco install python visualstudio2022-workload-vctools -y
|
||||
```
|
||||
|
||||
Install tools and configuration manually:
|
||||
* Install Visual C++ Build Environment: [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools)
|
||||
(using "Visual C++ build tools" workload) or [Visual Studio Community](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
|
||||
(using the "Desktop development with C++" workload)
|
||||
Or install and configure Python and Visual Studio tools manually:
|
||||
|
||||
If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips.
|
||||
* Follow the instructions in [Using Python on Windows](https://docs.python.org/3/using/windows.html) to install
|
||||
the current [version of Python](https://www.python.org/downloads/).
|
||||
|
||||
* Install Visual C++ Build Environment: For Visual Studio 2019 or later, use the `Desktop development with C++` workload from [Visual Studio Community](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community). For a version older than Visual Studio 2019, install [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) with the `Visual C++ build tools` option.
|
||||
|
||||
To target native ARM64 Node.js on Windows on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64".
|
||||
|
||||
To use the native ARM64 C++ compiler on Windows on ARM, ensure that you have Visual Studio 2022 [17.4 or later](https://devblogs.microsoft.com/visualstudio/arm64-visual-studio-is-officially-here/) installed.
|
||||
|
||||
It's advised to install the following PowerShell module: [VSSetup](https://github.com/microsoft/vssetup.powershell) using `Install-Module VSSetup -Scope CurrentUser`.
|
||||
This will make Visual Studio detection logic use a more flexible and accessible method, avoiding PowerShell's `ConstrainedLanguage` mode.
|
||||
|
||||
### Configuring Python Dependency
|
||||
|
||||
`node-gyp` requires that you have installed a compatible version of Python, one of: v3.7, v3.8,
|
||||
v3.9, or v3.10. If you have multiple Python versions installed, you can identify which Python
|
||||
version `node-gyp` should use in one of the following ways:
|
||||
`node-gyp` requires that you have installed a [supported version of Python](https://devguide.python.org/versions/).
|
||||
If you have multiple versions of Python installed, you can identify which version
|
||||
`node-gyp` should use in one of the following ways:
|
||||
|
||||
1. by setting the `--python` command-line option, e.g.:
|
||||
|
||||
|
|
@ -73,24 +80,29 @@ node-gyp <command> --python /path/to/executable/python
|
|||
```
|
||||
|
||||
2. If `node-gyp` is called by way of `npm`, *and* you have multiple versions of
|
||||
Python installed, then you can set `npm`'s 'python' config key to the appropriate
|
||||
value:
|
||||
|
||||
Python installed, then you can set the `npm_config_python` environment variable
|
||||
to the appropriate path:
|
||||
``` bash
|
||||
npm config set python /path/to/executable/python
|
||||
export npm_config_python=/path/to/executable/python
|
||||
```
|
||||
Or on Windows:
|
||||
```console
|
||||
py --list-paths # To see the installed Python versions
|
||||
set npm_config_python=C:\path\to\python.exe # CMD
|
||||
$Env:npm_config_python="C:\path\to\python.exe" # PowerShell
|
||||
```
|
||||
|
||||
3. If the `PYTHON` environment variable is set to the path of a Python executable,
|
||||
then that version will be used, if it is a compatible version.
|
||||
then that version will be used if it is a supported version.
|
||||
|
||||
4. If the `NODE_GYP_FORCE_PYTHON` environment variable is set to the path of a
|
||||
Python executable, it will be used instead of any of the other configured or
|
||||
builtin Python search paths. If it's not a compatible version, no further
|
||||
built-in Python search paths. If it's not a compatible version, no further
|
||||
searching will be done.
|
||||
|
||||
### Build for Third Party Node.js Runtimes
|
||||
|
||||
When building modules for third party Node.js runtimes like Electron, which have
|
||||
When building modules for third-party Node.js runtimes like Electron, which have
|
||||
different build configurations from the official Node.js distribution, you
|
||||
should use `--dist-url` or `--nodedir` flags to specify the headers of the
|
||||
runtime to build for.
|
||||
|
|
@ -106,7 +118,7 @@ to work around configuration errors.
|
|||
|
||||
## How to Use
|
||||
|
||||
To compile your native addon, first go to its root directory:
|
||||
To compile your native addon first go to its root directory:
|
||||
|
||||
``` bash
|
||||
cd my_node_addon
|
||||
|
|
@ -168,7 +180,7 @@ The **[docs](./docs/)** directory contains additional documentation on specific
|
|||
Some additional resources for Node.js native addons and writing `gyp` configuration files:
|
||||
|
||||
* ["Going Native" a nodeschool.io tutorial](http://nodeschool.io/#goingnative)
|
||||
* ["Hello World" node addon example](https://github.com/nodejs/node/tree/master/test/addons/hello-world)
|
||||
* ["Hello World" node addon example](https://github.com/nodejs/node/tree/main/test/addons/hello-world)
|
||||
* [gyp user documentation](https://gyp.gsrc.io/docs/UserDocumentation.md)
|
||||
* [gyp input format reference](https://gyp.gsrc.io/docs/InputFormatReference.md)
|
||||
* [*"binding.gyp" files out in the wild* wiki page](./docs/binding.gyp-files-in-the-wild.md)
|
||||
|
|
@ -221,9 +233,24 @@ Some additional resources for Node.js native addons and writing `gyp` configurat
|
|||
|
||||
## Configuration
|
||||
|
||||
### package.json
|
||||
|
||||
Use the `config` object in your package.json with each key in the form `node_gyp_OPTION_NAME`. Any of the command
|
||||
options listed above can be set (dashes in option names should be replaced by underscores).
|
||||
|
||||
For example, to set `devdir` equal to `/tmp/.gyp`, your package.json would contain this:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"node_gyp_devdir": "/tmp/.gyp"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Environment variables
|
||||
|
||||
Use the form `npm_config_OPTION_NAME` for any of the command options listed
|
||||
Use the form `npm_package_config_node_gyp_OPTION_NAME` for any of the command options listed
|
||||
above (dashes in option names should be replaced by underscores).
|
||||
|
||||
For example, to set `devdir` equal to `/tmp/.gyp`, you would:
|
||||
|
|
@ -231,16 +258,20 @@ For example, to set `devdir` equal to `/tmp/.gyp`, you would:
|
|||
Run this on Unix:
|
||||
|
||||
```bash
|
||||
export npm_config_devdir=/tmp/.gyp
|
||||
export npm_package_config_node_gyp_devdir=/tmp/.gyp
|
||||
```
|
||||
|
||||
Or this on Windows:
|
||||
|
||||
```console
|
||||
set npm_config_devdir=c:\temp\.gyp
|
||||
set npm_package_config_node_gyp_devdir=c:\temp\.gyp
|
||||
```
|
||||
|
||||
### `npm` configuration
|
||||
Note that in versions of npm before v11 it was possible to use the prefix `npm_config_` for
|
||||
environment variables. This was deprecated in npm@11 and will be removed in npm@12 so it
|
||||
is recommended to convert your environment variables to the above format.
|
||||
|
||||
### `npm` configuration for npm versions before v9
|
||||
|
||||
Use the form `OPTION_NAME` for any of the command options listed above.
|
||||
|
||||
|
|
|
|||
4
electron/node_modules/node-gyp/addon.gypi
generated
vendored
4
electron/node_modules/node-gyp/addon.gypi
generated
vendored
|
|
@ -179,7 +179,7 @@
|
|||
'-loleaut32.lib',
|
||||
'-luuid.lib',
|
||||
'-lodbc32.lib',
|
||||
'-lDelayImp.lib',
|
||||
'-ldelayimp.lib',
|
||||
'-l"<(node_lib_file)"'
|
||||
],
|
||||
'msvs_disabled_warnings': [
|
||||
|
|
@ -195,7 +195,7 @@
|
|||
'_FILE_OFFSET_BITS=64'
|
||||
],
|
||||
}],
|
||||
[ 'OS in "freebsd openbsd netbsd solaris android" or \
|
||||
[ 'OS in "freebsd openbsd netbsd solaris android openharmony" or \
|
||||
(OS=="linux" and target_arch!="ia32")', {
|
||||
'cflags': [ '-fPIC' ],
|
||||
}],
|
||||
|
|
|
|||
63
electron/node_modules/node-gyp/bin/node-gyp.js
generated
vendored
63
electron/node_modules/node-gyp/bin/node-gyp.js
generated
vendored
|
|
@ -6,7 +6,7 @@ process.title = 'node-gyp'
|
|||
|
||||
const envPaths = require('env-paths')
|
||||
const gyp = require('../')
|
||||
const log = require('npmlog')
|
||||
const log = require('../lib/log')
|
||||
const os = require('os')
|
||||
|
||||
/**
|
||||
|
|
@ -14,11 +14,11 @@ const os = require('os')
|
|||
*/
|
||||
|
||||
const prog = gyp()
|
||||
var completed = false
|
||||
let completed = false
|
||||
prog.parseArgv(process.argv)
|
||||
prog.devDir = prog.opts.devdir
|
||||
|
||||
var homeDir = os.homedir()
|
||||
const homeDir = os.homedir()
|
||||
if (prog.devDir) {
|
||||
prog.devDir = prog.devDir.replace(/^~/, homeDir)
|
||||
} else if (homeDir) {
|
||||
|
|
@ -32,9 +32,9 @@ if (prog.devDir) {
|
|||
|
||||
if (prog.todo.length === 0) {
|
||||
if (~process.argv.indexOf('-v') || ~process.argv.indexOf('--version')) {
|
||||
console.log('v%s', prog.version)
|
||||
log.stdout('v%s', prog.version)
|
||||
} else {
|
||||
console.log('%s', prog.usage())
|
||||
log.stdout('%s', prog.usage())
|
||||
}
|
||||
process.exit(0)
|
||||
}
|
||||
|
|
@ -48,11 +48,11 @@ log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform,
|
|||
* Change dir if -C/--directory was passed.
|
||||
*/
|
||||
|
||||
var dir = prog.opts.directory
|
||||
const dir = prog.opts.directory
|
||||
if (dir) {
|
||||
var fs = require('fs')
|
||||
const fs = require('fs')
|
||||
try {
|
||||
var stat = fs.statSync(dir)
|
||||
const stat = fs.statSync(dir)
|
||||
if (stat.isDirectory()) {
|
||||
log.info('chdir', dir)
|
||||
process.chdir(dir)
|
||||
|
|
@ -68,8 +68,8 @@ if (dir) {
|
|||
}
|
||||
}
|
||||
|
||||
function run () {
|
||||
var command = prog.todo.shift()
|
||||
async function run () {
|
||||
const command = prog.todo.shift()
|
||||
if (!command) {
|
||||
// done!
|
||||
completed = true
|
||||
|
|
@ -77,30 +77,28 @@ function run () {
|
|||
return
|
||||
}
|
||||
|
||||
prog.commands[command.name](command.args, function (err) {
|
||||
if (err) {
|
||||
log.error(command.name + ' error')
|
||||
log.error('stack', err.stack)
|
||||
errorMessage()
|
||||
log.error('not ok')
|
||||
return process.exit(1)
|
||||
}
|
||||
try {
|
||||
const args = await prog.commands[command.name](command.args) ?? []
|
||||
|
||||
if (command.name === 'list') {
|
||||
var versions = arguments[1]
|
||||
if (versions.length > 0) {
|
||||
versions.forEach(function (version) {
|
||||
console.log(version)
|
||||
})
|
||||
if (args.length) {
|
||||
args.forEach((version) => log.stdout(version))
|
||||
} else {
|
||||
console.log('No node development files installed. Use `node-gyp install` to install a version.')
|
||||
log.stdout('No node development files installed. Use `node-gyp install` to install a version.')
|
||||
}
|
||||
} else if (arguments.length >= 2) {
|
||||
console.log.apply(console, [].slice.call(arguments, 1))
|
||||
} else if (args.length >= 1) {
|
||||
log.stdout(...args.slice(1))
|
||||
}
|
||||
|
||||
// now run the next command in the queue
|
||||
process.nextTick(run)
|
||||
})
|
||||
return run()
|
||||
} catch (err) {
|
||||
log.error(command.name + ' error')
|
||||
log.error('stack', err.stack)
|
||||
errorMessage()
|
||||
log.error('not ok')
|
||||
return process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
process.on('exit', function (code) {
|
||||
|
|
@ -120,13 +118,20 @@ process.on('uncaughtException', function (err) {
|
|||
|
||||
function errorMessage () {
|
||||
// copied from npm's lib/utils/error-handler.js
|
||||
var os = require('os')
|
||||
const os = require('os')
|
||||
log.error('System', os.type() + ' ' + os.release())
|
||||
log.error('command', process.argv
|
||||
.map(JSON.stringify).join(' '))
|
||||
log.error('cwd', process.cwd())
|
||||
log.error('node -v', process.version)
|
||||
log.error('node-gyp -v', 'v' + prog.package.version)
|
||||
// print the npm package version
|
||||
for (const env of ['npm_package_name', 'npm_package_version']) {
|
||||
const value = process.env[env]
|
||||
if (value != null) {
|
||||
log.error(`$${env}`, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function issueMessage () {
|
||||
|
|
|
|||
94
electron/node_modules/node-gyp/docs/Error-pre-versions-of-node-cannot-be-installed.md
generated
vendored
94
electron/node_modules/node-gyp/docs/Error-pre-versions-of-node-cannot-be-installed.md
generated
vendored
|
|
@ -1,94 +0,0 @@
|
|||
When using `node-gyp` you might see an error like this when attempting to compile/install a node.js native addon:
|
||||
|
||||
```
|
||||
$ npm install bcrypt
|
||||
npm http GET https://registry.npmjs.org/bcrypt/0.7.5
|
||||
npm http 304 https://registry.npmjs.org/bcrypt/0.7.5
|
||||
npm http GET https://registry.npmjs.org/bindings/1.0.0
|
||||
npm http 304 https://registry.npmjs.org/bindings/1.0.0
|
||||
|
||||
> bcrypt@0.7.5 install /home/ubuntu/public/song-swap/node_modules/bcrypt
|
||||
> node-gyp rebuild
|
||||
|
||||
gyp ERR! configure error
|
||||
gyp ERR! stack Error: "pre" versions of node cannot be installed, use the --nodedir flag instead
|
||||
gyp ERR! stack at install (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/install.js:69:16)
|
||||
gyp ERR! stack at Object.self.commands.(anonymous function) [as install] (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/node-gyp.js:56:37)
|
||||
gyp ERR! stack at getNodeDir (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:219:20)
|
||||
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:105:9
|
||||
gyp ERR! stack at ChildProcess.exithandler (child_process.js:630:7)
|
||||
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:99:17)
|
||||
gyp ERR! stack at maybeClose (child_process.js:730:16)
|
||||
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:797:5)
|
||||
gyp ERR! System Linux 3.5.0-21-generic
|
||||
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
|
||||
gyp ERR! cwd /home/ubuntu/public/song-swap/node_modules/bcrypt
|
||||
gyp ERR! node -v v0.11.2-pre
|
||||
gyp ERR! node-gyp -v v0.9.5
|
||||
gyp ERR! not ok
|
||||
npm ERR! bcrypt@0.7.5 install: `node-gyp rebuild`
|
||||
npm ERR! `sh "-c" "node-gyp rebuild"` failed with 1
|
||||
npm ERR!
|
||||
npm ERR! Failed at the bcrypt@0.7.5 install script.
|
||||
npm ERR! This is most likely a problem with the bcrypt package,
|
||||
npm ERR! not with npm itself.
|
||||
npm ERR! Tell the author that this fails on your system:
|
||||
npm ERR! node-gyp rebuild
|
||||
npm ERR! You can get their info via:
|
||||
npm ERR! npm owner ls bcrypt
|
||||
npm ERR! There is likely additional logging output above.
|
||||
|
||||
npm ERR! System Linux 3.5.0-21-generic
|
||||
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "bcrypt"
|
||||
npm ERR! cwd /home/ubuntu/public/song-swap
|
||||
npm ERR! node -v v0.11.2-pre
|
||||
npm ERR! npm -v 1.2.18
|
||||
npm ERR! code ELIFECYCLE
|
||||
npm ERR!
|
||||
npm ERR! Additional logging details can be found in:
|
||||
npm ERR! /home/ubuntu/public/song-swap/npm-debug.log
|
||||
npm ERR! not ok code 0
|
||||
```
|
||||
|
||||
The main error here is:
|
||||
|
||||
```
|
||||
Error: "pre" versions of node cannot be installed, use the --nodedir flag instead
|
||||
```
|
||||
|
||||
This error is caused when you attempt to compile a native addon using a version of node.js with `-pre` at the end of the version number:
|
||||
|
||||
``` bash
|
||||
$ node -v
|
||||
v0.10.4-pre
|
||||
```
|
||||
|
||||
## How to avoid (the short answer)
|
||||
|
||||
To avoid this error completely just use a stable release of node.js. i.e. `v0.10.4`, and __not__ `v0.10.4-pre`.
|
||||
|
||||
## How to fix (the long answer)
|
||||
|
||||
This error happens because `node-gyp` does not know what header files were used to compile your "pre" version of node, and therefore it needs you to specify the node source code directory path using the `--nodedir` flag.
|
||||
|
||||
For example, if I compiled my development ("pre") version of node.js using the source code in `/Users/nrajlich/node`, then I could invoke `node-gyp` like:
|
||||
|
||||
``` bash
|
||||
$ node-gyp rebuild --nodedir=/Users/nrajlich/node
|
||||
```
|
||||
|
||||
Or install an native addon through `npm` like:
|
||||
|
||||
``` bash
|
||||
$ npm install bcrypt --nodedir=/Users/nrajlich/node
|
||||
```
|
||||
|
||||
### Always use `--nodedir`
|
||||
|
||||
__Note:__ This is for advanced users who use `-pre` versions of node more often than tagged releases.
|
||||
|
||||
If you're invoking `node-gyp` through `npm`, then you can leverage `npm`'s configuration system and not have to specify the `--nodedir` flag all the time:
|
||||
|
||||
``` bash
|
||||
$ npm config set nodedir /Users/nrajlich/node
|
||||
```
|
||||
47
electron/node_modules/node-gyp/docs/Force-npm-to-use-global-node-gyp.md
generated
vendored
47
electron/node_modules/node-gyp/docs/Force-npm-to-use-global-node-gyp.md
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
# Force npm to use global installed node-gyp
|
||||
|
||||
**Note: These instructions only work with npm 6 or older. For a solution that works with npm 8 (or older), see [Updating-npm-bundled-node-gyp.md](Updating-npm-bundled-node-gyp.md).**
|
||||
|
||||
[Many issues](https://github.com/nodejs/node-gyp/labels/ERR%21%20node-gyp%20-v%20%3C%3D%20v5.1.0) are opened by users who are
|
||||
not running a [current version of node-gyp](https://github.com/nodejs/node-gyp/releases).
|
||||
|
||||
npm bundles its own, internal, copy of node-gyp located at `npm/node_modules`, within npm's private dependencies which are separate from *globally* accessible packages. Therefore this internal copy of node-gyp is independent from any globally installed copy of node-gyp that
|
||||
may have been installed via `npm install -g node-gyp`.
|
||||
|
||||
So npm's internal copy of node-gyp **isn't** stored inside *global* `node_modules` and thus isn't available for use as a standalone package. npm uses it's *internal* copy of `node-gyp` to automatically build native addons.
|
||||
|
||||
When you install a _new_ version of node-gyp outside of npm, it'll go into your *global* `node_modules`, but not under the `npm/node_modules` (where internal copy of node-gyp is stored). So it will get into your `$PATH` and you will be able to use this globally installed version (**but not internal node-gyp of npm**) as any other globally installed package.
|
||||
|
||||
The catch is that npm **won't** use global version unless you tell it to, it'll keep on using the **internal one**. You need to instruct it to by setting the `node_gyp` config variable (which goes into your `~/.npmrc`). You do this by running the `npm config set` command as below. Then npm will use the command in the path you supply whenever it needs to build a native addon.
|
||||
|
||||
**Important**: You also need to remember to unset this when you upgrade npm with a newer version of node-gyp, or you have to manually keep your globally installed node-gyp to date. See "Undo" below.
|
||||
|
||||
## Linux and macOS
|
||||
```
|
||||
npm install --global node-gyp@latest
|
||||
npm config set node_gyp $(npm prefix -g)/lib/node_modules/node-gyp/bin/node-gyp.js
|
||||
```
|
||||
|
||||
`sudo` may be required for the first command if you get a permission error.
|
||||
|
||||
## Windows
|
||||
|
||||
### Windows Command Prompt
|
||||
```
|
||||
npm install --global node-gyp@latest
|
||||
for /f "delims=" %P in ('npm prefix -g') do npm config set node_gyp "%P\node_modules\node-gyp\bin\node-gyp.js"
|
||||
```
|
||||
|
||||
### Powershell
|
||||
```
|
||||
npm install --global node-gyp@latest
|
||||
npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js"}
|
||||
```
|
||||
|
||||
## Undo
|
||||
**Beware** if you don't unset the `node_gyp` config option, npm will continue to use the globally installed version of node-gyp rather than the one it ships with, which may end up being newer.
|
||||
|
||||
```
|
||||
npm config delete node_gyp
|
||||
npm uninstall --global node-gyp
|
||||
```
|
||||
7
electron/node_modules/node-gyp/docs/Home.md
generated
vendored
7
electron/node_modules/node-gyp/docs/Home.md
generated
vendored
|
|
@ -1,7 +0,0 @@
|
|||
Welcome to the node-gyp wiki!
|
||||
|
||||
* [["binding.gyp" files out in the wild]]
|
||||
* [[Linking to OpenSSL]]
|
||||
* [[Common Issues]]
|
||||
* [[Updating npm's bundled node-gyp]]
|
||||
* [[Error: "pre" versions of node cannot be installed]]
|
||||
86
electron/node_modules/node-gyp/docs/Linking-to-OpenSSL.md
generated
vendored
86
electron/node_modules/node-gyp/docs/Linking-to-OpenSSL.md
generated
vendored
|
|
@ -1,86 +0,0 @@
|
|||
A handful of native addons require linking to OpenSSL in one way or another. This introduces a small challenge since node will sometimes bundle OpenSSL statically (the default for node >= v0.8.x), or sometimes dynamically link to the system OpenSSL (default for node <= v0.6.x).
|
||||
|
||||
Good native addons should account for both scenarios. It's recommended that you use the `binding.gyp` file provided below as a starting-point for any addon that needs to use OpenSSL:
|
||||
|
||||
``` python
|
||||
{
|
||||
'variables': {
|
||||
# node v0.6.x doesn't give us its build variables,
|
||||
# but on Unix it was only possible to use the system OpenSSL library,
|
||||
# so default the variable to "true", v0.8.x node and up will overwrite it.
|
||||
'node_shared_openssl%': 'true'
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'binding',
|
||||
'sources': [
|
||||
'src/binding.cc'
|
||||
],
|
||||
'conditions': [
|
||||
['node_shared_openssl=="false"', {
|
||||
# so when "node_shared_openssl" is "false", then OpenSSL has been
|
||||
# bundled into the node executable. So we need to include the same
|
||||
# header files that were used when building node.
|
||||
'include_dirs': [
|
||||
'<(node_root_dir)/deps/openssl/openssl/include'
|
||||
],
|
||||
"conditions" : [
|
||||
["target_arch=='ia32'", {
|
||||
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
|
||||
}],
|
||||
["target_arch=='x64'", {
|
||||
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
|
||||
}],
|
||||
["target_arch=='arm'", {
|
||||
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
|
||||
}]
|
||||
]
|
||||
}]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This ensures that when OpenSSL is statically linked into `node` then, the bundled OpenSSL headers are included, but when the system OpenSSL is in use, then only those headers will be used.
|
||||
|
||||
## Windows?
|
||||
|
||||
As you can see this baseline `binding.gyp` file only accounts for the Unix scenario. Currently on Windows the situation is a little less ideal. On Windows, OpenSSL is _always_ statically compiled into the `node` executable, so ideally it would be possible to use that copy of OpenSSL when building native addons.
|
||||
|
||||
Unfortunately it doesn't seem like that is possible at the moment, as there would need to be tweaks made to the generated `node.lib` file to include the openssl glue functions, or a new `openssl.lib` file would need to be created during the node build. I'm not sure which is the easiest/most feasible.
|
||||
|
||||
In the meantime, one possible solution is using another copy of OpenSSL, which is what [`node-bcrypt`](https://github.com/ncb000gt/node.bcrypt.js) currently does. Adding something like this to your `binding.gyp` file's `"conditions"` block would enable this:
|
||||
|
||||
``` python
|
||||
[ 'OS=="win"', {
|
||||
'conditions': [
|
||||
# "openssl_root" is the directory on Windows of the OpenSSL files.
|
||||
# Check the "target_arch" variable to set good default values for
|
||||
# both 64-bit and 32-bit builds of the module.
|
||||
['target_arch=="x64"', {
|
||||
'variables': {
|
||||
'openssl_root%': 'C:/OpenSSL-Win64'
|
||||
},
|
||||
}, {
|
||||
'variables': {
|
||||
'openssl_root%': 'C:/OpenSSL-Win32'
|
||||
},
|
||||
}],
|
||||
],
|
||||
'libraries': [
|
||||
'-l<(openssl_root)/lib/libeay32.lib',
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(openssl_root)/include',
|
||||
],
|
||||
}]
|
||||
```
|
||||
|
||||
Now you can direct your users to install OpenSSL on Windows from here (be sure to tell them to install the 64-bit version if they're compiling against a 64-bit version of node): http://slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
Also note that both `node-gyp` and `npm` allow you to overwrite that default `openssl_root` variable on the command line:
|
||||
|
||||
``` bash
|
||||
$ node-gyp rebuild --openssl-root="C:\Users\Nathan\Desktop\openssl"
|
||||
```
|
||||
19
electron/node_modules/node-gyp/docs/README.md
generated
vendored
19
electron/node_modules/node-gyp/docs/README.md
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
## Versions of `node-gyp` that are earlier than v9.x.x
|
||||
|
||||
Please look thru your error log for the string `gyp info using node-gyp@` and if that version number is less than the [current release of node-gyp](https://github.com/nodejs/node-gyp/releases) then __please upgrade__ using [these instructions](https://github.com/nodejs/node-gyp/blob/master/docs/Updating-npm-bundled-node-gyp.md) and then try your command again.
|
||||
|
||||
## `node-sass` is deprecated
|
||||
|
||||
Please be aware that the package [`node-sass` is deprecated](https://github.com/sass/node-sass#node-sass) so you should actively seek alternatives. You can try:
|
||||
```
|
||||
npm uninstall node-sass
|
||||
npm install sass --save
|
||||
# or ...
|
||||
npm install --global node-sass@latest
|
||||
```
|
||||
`node-sass` projects _may_ work by downgrading to Node.js v14 but [that release is end-of-life](https://github.com/nodejs/release#release-schedule).
|
||||
But in any case, please avoid opening new `node-sass` issues on this repo because we [cannot help much](https://github.com/nodejs/node-gyp/issues?q=is%3Aissue+label%3A%22Node+Sass+--%3E+Dart+Sass%22+).
|
||||
|
||||
## Issues finding the installed Visual Studio
|
||||
|
||||
In cmd, [`npm config set msvs_version 20xx`](https://github.com/nodejs/node-gyp#on-windows) with ___xx___ matching your locally installed version of Visual Studio.
|
||||
72
electron/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md
generated
vendored
72
electron/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md
generated
vendored
|
|
@ -1,72 +0,0 @@
|
|||
# Updating the npm-bundled version of node-gyp
|
||||
|
||||
**Note: These instructions are (only) tested and known to work with npm 8 and older.**
|
||||
|
||||
**Note: These instructions will be undone if you reinstall or upgrade npm or node! For a more permanent (and simpler) solution, see [Force-npm-to-use-global-node-gyp.md](Force-npm-to-use-global-node-gyp.md). (npm 6 or older only!)**
|
||||
|
||||
[Many issues](https://github.com/nodejs/node-gyp/issues?q=label%3A"ERR!+node-gyp+-v+<%3D+v9.x.x") are opened by users who are
|
||||
not running a [current version of node-gyp](https://github.com/nodejs/node-gyp/releases).
|
||||
|
||||
`npm` bundles its own, internal, copy of `node-gyp`. This internal copy is independent of any globally installed copy of node-gyp that
|
||||
may have been installed via `npm install -g node-gyp`.
|
||||
|
||||
This means that while `node-gyp` doesn't get installed into your `$PATH` by default, npm still keeps its own copy to invoke when you
|
||||
attempt to `npm install` a native add-on.
|
||||
|
||||
Sometimes, you may need to update npm's internal node-gyp to a newer version than what is installed. A simple `npm install -g node-gyp`
|
||||
_won't_ do the trick since npm will still continue to use its internal copy over the global one.
|
||||
|
||||
So instead:
|
||||
|
||||
## Version of npm
|
||||
|
||||
We need to start by knowing your version of `npm`:
|
||||
```bash
|
||||
npm --version
|
||||
```
|
||||
|
||||
## Linux, macOS, Solaris, etc.
|
||||
|
||||
Unix is easy. Just run the following command.
|
||||
|
||||
If your npm is version ___7 or 8___, do:
|
||||
```bash
|
||||
$ npm explore npm/node_modules/@npmcli/run-script -g -- npm_config_global=false npm install node-gyp@latest
|
||||
```
|
||||
|
||||
Else if your npm is version ___less than 7___, do:
|
||||
```bash
|
||||
$ npm explore npm/node_modules/npm-lifecycle -g -- npm install node-gyp@latest
|
||||
```
|
||||
|
||||
If the command fails with a permissions error, please try `sudo` and then the command.
|
||||
|
||||
## Windows
|
||||
|
||||
Windows is a bit trickier, since `npm` might be installed to the "Program Files" directory, which needs admin privileges in order to
|
||||
modify on current Windows. Therefore, run the following commands __inside a `cmd.exe` started with "Run as Administrator"__:
|
||||
|
||||
First we need to find the location of `node`. If you don't already know the location that `node.exe` got installed to, then run:
|
||||
```bash
|
||||
$ where node
|
||||
```
|
||||
|
||||
Now `cd` to the directory that `node.exe` is contained in e.g.:
|
||||
```bash
|
||||
$ cd "C:\Program Files\nodejs"
|
||||
```
|
||||
|
||||
If your npm version is ___7 or 8___, do:
|
||||
```bash
|
||||
cd node_modules\npm\node_modules\@npmcli\run-script
|
||||
```
|
||||
|
||||
Else if your npm version is ___less than 7___, do:
|
||||
```bash
|
||||
cd node_modules\npm\node_modules\npm-lifecycle
|
||||
```
|
||||
|
||||
Finish by running:
|
||||
```bash
|
||||
$ npm install node-gyp@latest
|
||||
```
|
||||
49
electron/node_modules/node-gyp/docs/binding.gyp-files-in-the-wild.md
generated
vendored
49
electron/node_modules/node-gyp/docs/binding.gyp-files-in-the-wild.md
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
This page contains links to some examples of existing `binding.gyp` files that other node modules are using. Take a look at them for inspiration.
|
||||
|
||||
To add to this page, just add the link to the project's `binding.gyp` file below:
|
||||
|
||||
* [ons](https://github.com/XadillaX/aliyun-ons/blob/master/binding.gyp)
|
||||
* [thmclrx](https://github.com/XadillaX/thmclrx/blob/master/binding.gyp)
|
||||
* [libxmljs](https://github.com/polotek/libxmljs/blob/master/binding.gyp)
|
||||
* [node-buffertools](https://github.com/bnoordhuis/node-buffertools/blob/master/binding.gyp)
|
||||
* [node-canvas](https://github.com/LearnBoost/node-canvas/blob/master/binding.gyp)
|
||||
* [node-ffi](https://github.com/rbranson/node-ffi/blob/master/binding.gyp) + [libffi](https://github.com/rbranson/node-ffi/blob/master/deps/libffi/libffi.gyp)
|
||||
* [node-time](https://github.com/TooTallNate/node-time/blob/master/binding.gyp)
|
||||
* [node-sass](https://github.com/sass/node-sass/blob/master/binding.gyp) + [libsass](https://github.com/sass/node-sass/blob/master/src/libsass.gyp)
|
||||
* [node-serialport](https://github.com/voodootikigod/node-serialport/blob/master/binding.gyp)
|
||||
* [node-weak](https://github.com/TooTallNate/node-weak/blob/master/binding.gyp)
|
||||
* [pty.js](https://github.com/chjj/pty.js/blob/master/binding.gyp)
|
||||
* [ref](https://github.com/TooTallNate/ref/blob/master/binding.gyp)
|
||||
* [appjs](https://github.com/milani/appjs/blob/master/binding.gyp)
|
||||
* [nwm](https://github.com/mixu/nwm/blob/master/binding.gyp)
|
||||
* [bcrypt](https://github.com/ncb000gt/node.bcrypt.js/blob/master/binding.gyp)
|
||||
* [nk-mysql](https://github.com/mmod/nodamysql/blob/master/binding.gyp)
|
||||
* [nk-xrm-installer](https://github.com/mmod/nk-xrm-installer/blob/master/binding.gyp) + [includable.gypi](https://github.com/mmod/nk-xrm-installer/blob/master/includable.gypi) + [unpack.py](https://github.com/mmod/nk-xrm-installer/blob/master/unpack.py) + [disburse.py](https://github.com/mmod/nk-xrm-installer/blob/master/disburse.py)
|
||||
<sub>.py files above provide complete reference for examples of fetching source via http, extracting, and moving files.</sub>
|
||||
* [node-memwatch](https://github.com/lloyd/node-memwatch/blob/master/binding.gyp)
|
||||
* [node-ip2location](https://github.com/bolgovr/node-ip2location/blob/master/binding.gyp)
|
||||
* [node-midi](https://github.com/justinlatimer/node-midi/blob/master/binding.gyp)
|
||||
* [node-sqlite3](https://github.com/developmentseed/node-sqlite3/blob/master/binding.gyp) + [libsqlite3](https://github.com/developmentseed/node-sqlite3/blob/master/deps/sqlite3.gyp)
|
||||
* [node-zipfile](https://github.com/mapbox/node-zipfile/blob/master/binding.gyp)
|
||||
* [node-mapnik](https://github.com/mapnik/node-mapnik/blob/master/binding.gyp)
|
||||
* [node-inotify](https://github.com/c4milo/node-inotify/blob/master/binding.gyp)
|
||||
* [v8-profiler](https://github.com/c4milo/v8-profiler/blob/master/binding.gyp)
|
||||
* [airtunes](https://github.com/radioline/node_airtunes/blob/master/binding.gyp)
|
||||
* [node-fann](https://github.com/c4milo/node-fann/blob/master/binding.gyp)
|
||||
* [node-talib](https://github.com/oransel/node-talib/blob/master/binding.gyp)
|
||||
* [node-leveldown](https://github.com/rvagg/node-leveldown/blob/master/binding.gyp) + [leveldb.gyp](https://github.com/rvagg/node-leveldown/blob/master/deps/leveldb/leveldb.gyp) + [snappy.gyp](https://github.com/rvagg/node-leveldown/blob/master/deps/snappy/snappy.gyp)
|
||||
* [node-expat](https://github.com/astro/node-expat/blob/master/binding.gyp) + [libexpat](https://github.com/astro/node-expat/blob/master/deps/libexpat/libexpat.gyp)
|
||||
* [node-openvg-canvas](https://github.com/luismreis/node-openvg-canvas/blob/master/binding.gyp) + [node-openvg](https://github.com/luismreis/node-openvg/blob/master/binding.gyp)
|
||||
* [node-cryptopp](https://github.com/BatikhSouri/node-cryptopp/blob/master/binding.gyp)
|
||||
* [topcube](https://github.com/creationix/topcube/blob/master/binding.gyp)
|
||||
* [node-osmium](https://github.com/osmcode/node-osmium/blob/master/binding.gyp)
|
||||
* [node-osrm](https://github.com/DennisOSRM/node-osrm)
|
||||
* [node-oracle](https://github.com/joeferner/node-oracle/blob/master/binding.gyp)
|
||||
* [node-process-list](https://github.com/ReklatsMasters/node-process-list/blob/master/binding.gyp)
|
||||
* [node-nanomsg](https://github.com/nickdesaulniers/node-nanomsg/blob/master/binding.gyp)
|
||||
* [Ghostscript4JS](https://github.com/NickNaso/ghostscript4js/blob/master/binding.gyp)
|
||||
* [nodecv](https://github.com/xudafeng/nodecv/blob/master/binding.gyp)
|
||||
* [magick-cli](https://github.com/NickNaso/magick-cli/blob/master/binding.gyp)
|
||||
* [sharp](https://github.com/lovell/sharp/blob/master/binding.gyp)
|
||||
* [krb5](https://github.com/adaltas/node-krb5/blob/master/binding.gyp)
|
||||
* [node-heapdump](https://github.com/bnoordhuis/node-heapdump/blob/master/binding.gyp)
|
||||
3
electron/node_modules/node-gyp/eslint.config.js
generated
vendored
Normal file
3
electron/node_modules/node-gyp/eslint.config.js
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = require('neostandard')({})
|
||||
4
electron/node_modules/node-gyp/gyp/.flake8
generated
vendored
4
electron/node_modules/node-gyp/gyp/.flake8
generated
vendored
|
|
@ -1,4 +0,0 @@
|
|||
[flake8]
|
||||
max-complexity = 101
|
||||
max-line-length = 88
|
||||
extend-ignore = E203 # whitespace before ':' to agree with psf/black
|
||||
36
electron/node_modules/node-gyp/gyp/.github/workflows/Python_tests.yml
generated
vendored
36
electron/node_modules/node-gyp/gyp/.github/workflows/Python_tests.yml
generated
vendored
|
|
@ -1,36 +0,0 @@
|
|||
# TODO: Enable os: windows-latest
|
||||
# TODO: Enable pytest --doctest-modules
|
||||
|
||||
name: Python_tests
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
Python_tests:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 8
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest] # , windows-latest]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11-dev"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools
|
||||
pip install --editable ".[dev]"
|
||||
- run: ./gyp -V && ./gyp --version && gyp -V && gyp --version
|
||||
- name: Lint with flake8
|
||||
run: flake8 . --ignore=E203,W503 --max-complexity=101 --max-line-length=88 --show-source --statistics
|
||||
- name: Test with pytest
|
||||
run: pytest
|
||||
# - name: Run doctests with pytest
|
||||
# run: pytest --doctest-modules
|
||||
45
electron/node_modules/node-gyp/gyp/.github/workflows/node-gyp.yml
generated
vendored
45
electron/node_modules/node-gyp/gyp/.github/workflows/node-gyp.yml
generated
vendored
|
|
@ -1,45 +0,0 @@
|
|||
name: node-gyp integration
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
integration:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
python: ["3.7", "3.10"]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Clone gyp-next
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: gyp-next
|
||||
- name: Clone nodejs/node-gyp
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nodejs/node-gyp
|
||||
path: node-gyp
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14.x
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd node-gyp
|
||||
npm install --no-progress
|
||||
- name: Replace gyp in node-gyp
|
||||
shell: bash
|
||||
run: |
|
||||
rm -rf node-gyp/gyp
|
||||
cp -r gyp-next node-gyp/gyp
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd node-gyp
|
||||
npm test
|
||||
32
electron/node_modules/node-gyp/gyp/.github/workflows/nodejs-windows.yml
generated
vendored
32
electron/node_modules/node-gyp/gyp/.github/workflows/nodejs-windows.yml
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
name: Node.js Windows integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Clone gyp-next
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: gyp-next
|
||||
- name: Clone nodejs/node
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nodejs/node
|
||||
path: node
|
||||
- name: Install deps
|
||||
run: choco install nasm
|
||||
- name: Replace gyp in Node.js
|
||||
run: |
|
||||
rm -Recurse node/tools/gyp
|
||||
cp -Recurse gyp-next node/tools/gyp
|
||||
- name: Build Node.js
|
||||
run: |
|
||||
cd node
|
||||
./vcbuild.bat
|
||||
16
electron/node_modules/node-gyp/gyp/.github/workflows/release-please.yml
generated
vendored
16
electron/node_modules/node-gyp/gyp/.github/workflows/release-please.yml
generated
vendored
|
|
@ -1,16 +0,0 @@
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
name: release-please
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: google-github-actions/release-please-action@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
release-type: python
|
||||
package-name: gyp-next
|
||||
bump-minor-pre-major: true
|
||||
3
electron/node_modules/node-gyp/gyp/.release-please-manifest.json
generated
vendored
Normal file
3
electron/node_modules/node-gyp/gyp/.release-please-manifest.json
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
".": "0.22.2"
|
||||
}
|
||||
16
electron/node_modules/node-gyp/gyp/AUTHORS
generated
vendored
16
electron/node_modules/node-gyp/gyp/AUTHORS
generated
vendored
|
|
@ -1,16 +0,0 @@
|
|||
# Names should be added to this file like so:
|
||||
# Name or Organization <email address>
|
||||
|
||||
Google Inc. <*@google.com>
|
||||
Bloomberg Finance L.P. <*@bloomberg.net>
|
||||
IBM Inc. <*@*.ibm.com>
|
||||
Yandex LLC <*@yandex-team.ru>
|
||||
|
||||
Steven Knight <knight@baldmt.com>
|
||||
Ryan Norton <rnorton10@gmail.com>
|
||||
David J. Sankel <david@sankelsoftware.com>
|
||||
Eric N. Vander Weele <ericvw@gmail.com>
|
||||
Tom Freudenberg <th.freudenberg@gmail.com>
|
||||
Julien Brianceau <jbriance@cisco.com>
|
||||
Refael Ackermann <refack@gmail.com>
|
||||
Ujjwal Sharma <ryzokuken@disroot.org>
|
||||
233
electron/node_modules/node-gyp/gyp/CHANGELOG.md
generated
vendored
233
electron/node_modules/node-gyp/gyp/CHANGELOG.md
generated
vendored
|
|
@ -1,233 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
## [0.14.0](https://github.com/nodejs/gyp-next/compare/v0.13.0...v0.14.0) (2022-10-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add command line argument for `gyp --version` ([#164](https://github.com/nodejs/gyp-next/issues/164)) ([5c9f4d0](https://github.com/nodejs/gyp-next/commit/5c9f4d05678dd855e18ed2327219e5d18e5374db))
|
||||
* ninja build for iOS ([#174](https://github.com/nodejs/gyp-next/issues/174)) ([b6f2714](https://github.com/nodejs/gyp-next/commit/b6f271424e0033d7ed54d437706695af2ba7a1bf))
|
||||
* **zos:** support IBM Open XL C/C++ & PL/I compilers on z/OS ([#178](https://github.com/nodejs/gyp-next/issues/178)) ([43a7211](https://github.com/nodejs/gyp-next/commit/43a72110ae3fafb13c9625cc7a969624b27cda47))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* lock windows env ([#163](https://github.com/nodejs/gyp-next/issues/163)) ([44bd0dd](https://github.com/nodejs/gyp-next/commit/44bd0ddc93ea0b5770a44dd326a2e4ae62c21442))
|
||||
* move configuration information into pyproject.toml ([#176](https://github.com/nodejs/gyp-next/issues/176)) ([d69d8ec](https://github.com/nodejs/gyp-next/commit/d69d8ece6dbff7af4f2ea073c9fd170baf8cb7f7))
|
||||
* node.js debugger adds stderr (but exit code is 0) -> shouldn't throw ([#179](https://github.com/nodejs/gyp-next/issues/179)) ([1a457d9](https://github.com/nodejs/gyp-next/commit/1a457d9ed08cfd30c9fa551bc5cf0d90fb583787))
|
||||
|
||||
## [0.13.0](https://www.github.com/nodejs/gyp-next/compare/v0.12.1...v0.13.0) (2022-05-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add PRODUCT_DIR_ABS variable ([#151](https://www.github.com/nodejs/gyp-next/issues/151)) ([80d2626](https://www.github.com/nodejs/gyp-next/commit/80d26263581db829b61b312a7bdb5cc791df7824))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* execvp: printf: Argument list too long ([#147](https://www.github.com/nodejs/gyp-next/issues/147)) ([c4e14f3](https://www.github.com/nodejs/gyp-next/commit/c4e14f301673fadbac3ab7882d0b5f4d02530cb9))
|
||||
|
||||
### [0.12.1](https://www.github.com/nodejs/gyp-next/compare/v0.12.0...v0.12.1) (2022-04-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **msvs:** avoid fixing path for arguments with "=" ([#143](https://www.github.com/nodejs/gyp-next/issues/143)) ([7e8f16e](https://www.github.com/nodejs/gyp-next/commit/7e8f16eb165e042e64bec98fa6c2a0232a42c26b))
|
||||
|
||||
## [0.12.0](https://www.github.com/nodejs/gyp-next/compare/v0.11.0...v0.12.0) (2022-04-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support building shared libraries on z/OS ([#137](https://www.github.com/nodejs/gyp-next/issues/137)) ([293bcfa](https://www.github.com/nodejs/gyp-next/commit/293bcfa4c25c6adb743377adafc45a80fee492c6))
|
||||
|
||||
## [0.11.0](https://www.github.com/nodejs/gyp-next/compare/v0.10.1...v0.11.0) (2022-03-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add proper support for IBM i ([#140](https://www.github.com/nodejs/gyp-next/issues/140)) ([fdda4a3](https://www.github.com/nodejs/gyp-next/commit/fdda4a3038b8a7042ad960ce7a223687c24a21b1))
|
||||
|
||||
### [0.10.1](https://www.github.com/nodejs/gyp-next/compare/v0.10.0...v0.10.1) (2021-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **make:** only generate makefile for multiple toolsets if requested ([#133](https://www.github.com/nodejs/gyp-next/issues/133)) ([f463a77](https://www.github.com/nodejs/gyp-next/commit/f463a77705973289ea38fec1b244c922ac438e26))
|
||||
|
||||
## [0.10.0](https://www.github.com/nodejs/gyp-next/compare/v0.9.6...v0.10.0) (2021-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **msvs:** add support for Visual Studio 2022 ([#124](https://www.github.com/nodejs/gyp-next/issues/124)) ([4bd9215](https://www.github.com/nodejs/gyp-next/commit/4bd9215c44d300f06e916aec1d6327c22b78272d))
|
||||
|
||||
### [0.9.6](https://www.github.com/nodejs/gyp-next/compare/v0.9.5...v0.9.6) (2021-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* align flake8 test ([#122](https://www.github.com/nodejs/gyp-next/issues/122)) ([f1faa8d](https://www.github.com/nodejs/gyp-next/commit/f1faa8d3081e1a47e917ff910892f00dff16cf8a))
|
||||
* **msvs:** fix paths again in action command arguments ([#121](https://www.github.com/nodejs/gyp-next/issues/121)) ([7159dfb](https://www.github.com/nodejs/gyp-next/commit/7159dfbc5758c9ec717e215f2c36daf482c846a1))
|
||||
|
||||
### [0.9.5](https://www.github.com/nodejs/gyp-next/compare/v0.9.4...v0.9.5) (2021-08-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add python 3.6 to node-gyp integration test ([3462d4c](https://www.github.com/nodejs/gyp-next/commit/3462d4ce3c31cce747513dc7ca9760c81d57c60e))
|
||||
* revert for windows compatibility ([d078e7d](https://www.github.com/nodejs/gyp-next/commit/d078e7d7ae080ddae243188f6415f940376a7368))
|
||||
* support msvs_quote_cmd in ninja generator ([#117](https://www.github.com/nodejs/gyp-next/issues/117)) ([46486ac](https://www.github.com/nodejs/gyp-next/commit/46486ac6e9329529d51061e006a5b39631e46729))
|
||||
|
||||
### [0.9.4](https://www.github.com/nodejs/gyp-next/compare/v0.9.3...v0.9.4) (2021-08-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* .S is an extension for asm file on Windows ([#115](https://www.github.com/nodejs/gyp-next/issues/115)) ([d2fad44](https://www.github.com/nodejs/gyp-next/commit/d2fad44ef3a79ca8900f1307060153ded57053fc))
|
||||
|
||||
### [0.9.3](https://www.github.com/nodejs/gyp-next/compare/v0.9.2...v0.9.3) (2021-07-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* build failure with ninja and Python 3 on Windows ([#113](https://www.github.com/nodejs/gyp-next/issues/113)) ([c172d10](https://www.github.com/nodejs/gyp-next/commit/c172d105deff5db4244e583942215918fa80dd3c))
|
||||
|
||||
### [0.9.2](https://www.github.com/nodejs/gyp-next/compare/v0.9.1...v0.9.2) (2021-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add support of utf8 encoding ([#105](https://www.github.com/nodejs/gyp-next/issues/105)) ([4d0f93c](https://www.github.com/nodejs/gyp-next/commit/4d0f93c249286d1f0c0f665f5fe7346119f98cf1))
|
||||
|
||||
### [0.9.1](https://www.github.com/nodejs/gyp-next/compare/v0.9.0...v0.9.1) (2021-05-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* py lint ([3b6a8ee](https://www.github.com/nodejs/gyp-next/commit/3b6a8ee7a66193a8a6867eba9e1d2b70bdf04402))
|
||||
|
||||
## [0.9.0](https://www.github.com/nodejs/gyp-next/compare/v0.8.1...v0.9.0) (2021-05-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* use LDFLAGS_host for host toolset ([#98](https://www.github.com/nodejs/gyp-next/issues/98)) ([bea5c7b](https://www.github.com/nodejs/gyp-next/commit/bea5c7bd67d6ad32acbdce79767a5481c70675a2))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* msvs.py: remove overindentation ([#102](https://www.github.com/nodejs/gyp-next/issues/102)) ([3f83e99](https://www.github.com/nodejs/gyp-next/commit/3f83e99056d004d9579ceb786e06b624ddc36529))
|
||||
* update gyp.el to change case to cl-case ([#93](https://www.github.com/nodejs/gyp-next/issues/93)) ([13d5b66](https://www.github.com/nodejs/gyp-next/commit/13d5b66aab35985af9c2fb1174fdc6e1c1407ecc))
|
||||
|
||||
### [0.8.1](https://www.github.com/nodejs/gyp-next/compare/v0.8.0...v0.8.1) (2021-02-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update shebang lines from python to python3 ([#94](https://www.github.com/nodejs/gyp-next/issues/94)) ([a1b0d41](https://www.github.com/nodejs/gyp-next/commit/a1b0d4171a8049a4ab7a614202063dec332f2df4))
|
||||
|
||||
## [0.8.0](https://www.github.com/nodejs/gyp-next/compare/v0.7.0...v0.8.0) (2021-01-15)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* remove support for Python 2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revert posix build job ([#86](https://www.github.com/nodejs/gyp-next/issues/86)) ([39dc34f](https://www.github.com/nodejs/gyp-next/commit/39dc34f0799c074624005fb9bbccf6e028607f9d))
|
||||
|
||||
|
||||
### gyp
|
||||
|
||||
* Remove support for Python 2 ([#88](https://www.github.com/nodejs/gyp-next/issues/88)) ([22e4654](https://www.github.com/nodejs/gyp-next/commit/22e465426fd892403c95534229af819a99c3f8dc))
|
||||
|
||||
## [0.7.0](https://www.github.com/nodejs/gyp-next/compare/v0.6.2...v0.7.0) (2020-12-17)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **msvs:** On Windows, arguments passed to the "action" commands are no longer transformed to replace slashes with backslashes.
|
||||
|
||||
### Features
|
||||
|
||||
* **xcode:** --cross-compiling overrides arch-specific settings ([973bae0](https://www.github.com/nodejs/gyp-next/commit/973bae0b7b08be7b680ecae9565fbd04b3e0787d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **msvs:** do not fix paths in action command arguments ([fc22f83](https://www.github.com/nodejs/gyp-next/commit/fc22f8335e2016da4aae4f4233074bd651d2faea))
|
||||
* cmake on python 3 ([fd61f5f](https://www.github.com/nodejs/gyp-next/commit/fd61f5faa5275ec8fc98e3c7868c0dd46f109540))
|
||||
* ValueError: invalid mode: 'rU' while trying to load binding.gyp ([d0504e6](https://www.github.com/nodejs/gyp-next/commit/d0504e6700ce48f44957a4d5891b142a60be946f))
|
||||
* xcode cmake parsing ([eefe8d1](https://www.github.com/nodejs/gyp-next/commit/eefe8d10e99863bc4ac7e2ed32facd608d400d4b))
|
||||
|
||||
### [0.6.2](https://www.github.com/nodejs/gyp-next/compare/v0.6.1...v0.6.2) (2020-10-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* do not rewrite absolute paths to avoid long paths ([#74](https://www.github.com/nodejs/gyp-next/issues/74)) ([c2ccc1a](https://www.github.com/nodejs/gyp-next/commit/c2ccc1a81f7f94433a94f4d01a2e820db4c4331a))
|
||||
* only include MARMASM when toolset is target ([5a2794a](https://www.github.com/nodejs/gyp-next/commit/5a2794aefb58f0c00404ff042b61740bc8b8d5cd))
|
||||
|
||||
### [0.6.1](https://github.com/nodejs/gyp-next/compare/v0.6.0...v0.6.1) (2020-10-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Correctly rename object files for absolute paths in MSVS generator.
|
||||
|
||||
## [0.6.0](https://github.com/nodejs/gyp-next/compare/v0.5.0...v0.6.0) (2020-10-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* The Makefile generator will now output shared libraries directly to the product directory on all platforms (previously only macOS).
|
||||
|
||||
## [0.5.0](https://github.com/nodejs/gyp-next/compare/v0.4.0...v0.5.0) (2020-09-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Extended compile_commands_json generator to consider more file extensions than just `c` and `cc`. `cpp` and `cxx` are now supported.
|
||||
* Source files with duplicate basenames are now supported.
|
||||
|
||||
### Removed
|
||||
|
||||
* The `--no-duplicate-basename-check` option was removed.
|
||||
* The `msvs_enable_marmasm` configuration option was removed in favor of auto-inclusion of the "marmasm" sections for Windows on ARM.
|
||||
|
||||
## [0.4.0](https://github.com/nodejs/gyp-next/compare/v0.3.0...v0.4.0) (2020-07-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Added support for passing arbitrary architectures to Xcode builds, enables `arm64` builds.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug on Solaris where copying archives failed.
|
||||
|
||||
## [0.3.0](https://github.com/nodejs/gyp-next/compare/v0.2.1...v0.3.0) (2020-06-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Added support for MSVC cross-compilation. This allows compilation on x64 for a Windows ARM target.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed XCode CLT version detection on macOS Catalina.
|
||||
|
||||
### [0.2.1](https://github.com/nodejs/gyp-next/compare/v0.2.0...v0.2.1) (2020-05-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Relicensed to Node.js contributors.
|
||||
* Fixed Windows bug introduced in v0.2.0.
|
||||
|
||||
## [0.2.0](https://github.com/nodejs/gyp-next/releases/tag/v0.2.0) (2020-04-06)
|
||||
|
||||
This is the first release of this project, based on https://chromium.googlesource.com/external/gyp with changes made over the years in Node.js and node-gyp.
|
||||
32
electron/node_modules/node-gyp/gyp/CONTRIBUTING.md
generated
vendored
32
electron/node_modules/node-gyp/gyp/CONTRIBUTING.md
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
# Contributing to gyp-next
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project is bound to the [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md).
|
||||
|
||||
<a id="developers-certificate-of-origin"></a>
|
||||
## Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
* (a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
* (b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
* (c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
* (d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
7
electron/node_modules/node-gyp/gyp/README.md
generated
vendored
7
electron/node_modules/node-gyp/gyp/README.md
generated
vendored
|
|
@ -1,7 +0,0 @@
|
|||
GYP can Generate Your Projects.
|
||||
===================================
|
||||
|
||||
Documents are available at [gyp.gsrc.io](https://gyp.gsrc.io), or you can check out ```md-pages``` branch to read those documents offline.
|
||||
|
||||
__gyp-next__ is [released](https://github.com/nodejs/gyp-next/releases) to the [__Python Packaging Index__](https://pypi.org/project/gyp-next) (PyPI) and can be installed with the command:
|
||||
* `python3 -m pip install gyp-next`
|
||||
4
electron/node_modules/node-gyp/gyp/data/ninja/build.ninja
generated
vendored
Normal file
4
electron/node_modules/node-gyp/gyp/data/ninja/build.ninja
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
rule cc
|
||||
command = cc $in $out
|
||||
|
||||
build my.out: cc my.in
|
||||
116
electron/node_modules/node-gyp/gyp/docs/GypVsCMake.md
generated
vendored
Normal file
116
electron/node_modules/node-gyp/gyp/docs/GypVsCMake.md
generated
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# vs. CMake
|
||||
|
||||
GYP was originally created to generate native IDE project files (Visual Studio, Xcode) for building [Chromium](http://www.chromim.org).
|
||||
|
||||
The functionality of GYP is very similar to the [CMake](http://www.cmake.org)
|
||||
build tool. Bradley Nelson wrote up the following description of why the team
|
||||
created GYP instead of using CMake. The text below is copied from
|
||||
http://www.mail-archive.com/webkit-dev@lists.webkit.org/msg11029.html
|
||||
|
||||
```
|
||||
|
||||
Re: [webkit-dev] CMake as a build system?
|
||||
Bradley Nelson
|
||||
Mon, 19 Apr 2010 22:38:30 -0700
|
||||
|
||||
Here's the innards of an email with a laundry list of stuff I came up with a
|
||||
while back on the gyp-developers list in response to Mike Craddick regarding
|
||||
what motivated gyp's development, since we were aware of cmake at the time
|
||||
(we'd even started a speculative port):
|
||||
|
||||
|
||||
I did an exploratory port of portions of Chromium to cmake (I think I got as
|
||||
far as net, base, sandbox, and part of webkit).
|
||||
There were a number of motivations, not all of which would apply to other
|
||||
projects. Also, some of the design of gyp was informed by experience at
|
||||
Google with large projects built wholly from source, leading to features
|
||||
absent from cmake, but not strictly required for Chromium.
|
||||
|
||||
1. Ability to incrementally transition on Windows. It took us about 6 months
|
||||
to switch fully to gyp. Previous attempts to move to scons had taken a long
|
||||
time and failed, due to the requirement to transition while in flight. For a
|
||||
substantial period of time, we had a hybrid of checked in vcproj and gyp generated
|
||||
vcproj. To this day we still have a good number of GUIDs pinned in the gyp files,
|
||||
because different parts of our release pipeline have leftover assumptions
|
||||
regarding manipulating the raw sln/vcprojs. This transition occurred from
|
||||
the bottom up, largely because modules like base were easier to convert, and
|
||||
had a lower churn rate. During early stages of the transition, the majority
|
||||
of the team wasn't even aware they were using gyp, as it integrated into
|
||||
their existing workflow, and only affected modules that had been converted.
|
||||
|
||||
2. Generation of a more 'normal' vcproj file. Gyp attempts, particularly on
|
||||
Windows, to generate vcprojs which resemble hand generated projects. It
|
||||
doesn't generate any Makefile type projects, but instead produces msvs
|
||||
Custom Build Steps and Custom Build Rules. This makes the resulting projects
|
||||
easier to understand from the IDE and avoids parts of the IDE that simply
|
||||
don't function correctly if you use Makefile projects. Our early hope with
|
||||
gyp was to support the least common denominator of features present in each
|
||||
of the platform specific project file formats, rather than falling back on
|
||||
generated Makefiles/shell scripts to emulate some common abstraction. CMake by
|
||||
comparison makes a good faith attempt to use native project features, but
|
||||
falls back on generated scripts in order to preserve the same semantics on
|
||||
each platforms.
|
||||
|
||||
3. Abstraction on the level of project settings, rather than command line
|
||||
flags. In gyp's syntax you can add nearly any option present in a hand
|
||||
generated xcode/vcproj file. This allows you to use abstractions built into
|
||||
the IDEs rather than reverse engineering them possibly incorrectly for
|
||||
things like: manifest generation, precompiled headers, bundle generation.
|
||||
When somebody wants to use a particular menu option from msvs, I'm able to
|
||||
do a web search on the name of the setting from the IDE and provide them
|
||||
with a gyp stanza that does the equivalent. In many cases, not all project
|
||||
file constructs correspond to command line flags.
|
||||
|
||||
4. Strong notion of module public/private interface. Gyp allows targets to
|
||||
publish a set of direct_dependent_settings, specifying things like
|
||||
include_dirs, defines, platforms specific settings, etc. This means that
|
||||
when module A depends on module B, it automatically acquires the right build
|
||||
settings without module A being filled with assumptions/knowledge of exactly
|
||||
how module B is built. Additionally, all of the transitive dependencies of
|
||||
module B are pulled in. This avoids their being a single top level view of
|
||||
the project, rather each gyp file expresses knowledge about its immediate
|
||||
neighbors. This keep local knowledge local. CMake effectively has a large
|
||||
shared global namespace.
|
||||
|
||||
5. Cross platform generation. CMake is not able to generate all project
|
||||
files on all platforms. For example xcode projects cannot be generated from
|
||||
windows (cmake uses mac specific libraries to do project generation). This
|
||||
means that for instance generating a tarball containing pregenerated
|
||||
projects for all platforms is hard with Cmake (requires distribution to
|
||||
several machine types).
|
||||
|
||||
6. Gyp has rudimentary cross compile support. Currently we've added enough
|
||||
functionality to gyp to support x86 -> arm cross compiles. Last I checked
|
||||
this functionality wasn't present in cmake. (This occurred later).
|
||||
|
||||
|
||||
That being said there are a number of drawbacks currently to gyp:
|
||||
|
||||
1. Because platform specific settings are expressed at the project file
|
||||
level (rather than the command line level). Settings which might otherwise
|
||||
be shared in common between platforms (flags to gcc on mac/linux), end up
|
||||
being repeated twice. Though in fairness there is actually less sharing here
|
||||
than you'd think. include_dirs and defines actually represent 90% of what
|
||||
can be typically shared.
|
||||
|
||||
2. CMake may be more mature, having been applied to a broader range of
|
||||
projects. There a number of 'tool modules' for cmake, which are shared in a
|
||||
common community.
|
||||
|
||||
3. gyp currently makes some nasty assumptions about the availability of
|
||||
chromium's hermetic copy of cygwin on windows. This causes you to either
|
||||
have to special case a number of rules, or swallow this copy of cygwin as a
|
||||
build time dependency.
|
||||
|
||||
4. CMake includes a fairly readable imperative language. Currently Gyp has a
|
||||
somewhat poorly specified declarative language (variable expansion happens
|
||||
in sometimes weird and counter-intuitive ways). In fairness though, gyp assumes
|
||||
that external python scripts can be used as an escape hatch. Also gyp avoids
|
||||
a lot of the things you'd need imperative code for, by having a nice target
|
||||
settings publication mechanism.
|
||||
|
||||
5. (Feature/drawback depending on personal preference). Gyp's syntax is
|
||||
DEEPLY nested. It suffers from all of Lisp's advantages and drawbacks.
|
||||
|
||||
-BradN
|
||||
```
|
||||
46
electron/node_modules/node-gyp/gyp/docs/Hacking.md
generated
vendored
Normal file
46
electron/node_modules/node-gyp/gyp/docs/Hacking.md
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Hacking
|
||||
|
||||
## Getting the sources
|
||||
|
||||
Git is required to hack on anything, you can set up a git clone of GYP
|
||||
as follows:
|
||||
|
||||
```
|
||||
mkdir foo
|
||||
cd foo
|
||||
git clone git@github.com:nodejs/gyp-next.git
|
||||
cd gyp
|
||||
```
|
||||
|
||||
(this will clone gyp underneath it into `foo/gyp`.
|
||||
`foo` can be any directory name you want. Once you've done that,
|
||||
you can use the repo like anything other Git repo.
|
||||
|
||||
## Testing your change
|
||||
|
||||
GYP has a suite of tests which you can run with the provided test driver
|
||||
to make sure your changes aren't breaking anything important.
|
||||
|
||||
You run the test driver with e.g.
|
||||
|
||||
``` sh
|
||||
$ python -m pip install --upgrade pip
|
||||
$ pip install --editable ".[dev]"
|
||||
$ python -m pytest
|
||||
```
|
||||
|
||||
See [Testing](Testing.md) for more details on the test framework.
|
||||
|
||||
Note that it can be handy to look at the project files output by the tests
|
||||
to diagnose problems. The easiest way to do that is by kindly asking the
|
||||
test driver to leave the temporary directories it creates in-place.
|
||||
This is done by setting the environment variable "PRESERVE", e.g.
|
||||
|
||||
```
|
||||
set PRESERVE=all # On Windows
|
||||
export PRESERVE=all # On saner platforms.
|
||||
```
|
||||
|
||||
## Reviewing your change
|
||||
|
||||
All changes to GYP must be code reviewed before submission.
|
||||
1083
electron/node_modules/node-gyp/gyp/docs/InputFormatReference.md
generated
vendored
Normal file
1083
electron/node_modules/node-gyp/gyp/docs/InputFormatReference.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
430
electron/node_modules/node-gyp/gyp/docs/LanguageSpecification.md
generated
vendored
Normal file
430
electron/node_modules/node-gyp/gyp/docs/LanguageSpecification.md
generated
vendored
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
# Language Specification
|
||||
|
||||
## Objective
|
||||
|
||||
Create a tool for the Chromium project that generates native Visual Studio,
|
||||
Xcode and SCons and/or make build files from a platform-independent input
|
||||
format. Make the input format as reasonably general as possible without
|
||||
spending extra time trying to "get everything right," except where not doing so
|
||||
would likely lead Chromium to an eventual dead end. When in doubt, do what
|
||||
Chromium needs and don't worry about generalizing the solution.
|
||||
|
||||
## Background
|
||||
|
||||
Numerous other projects, both inside and outside Google, have tried to
|
||||
create a simple, universal cross-platform build representation that
|
||||
still allows sufficient per-platform flexibility to accommodate
|
||||
irreconcilable differences. The fact that no obvious working candidate
|
||||
exists that meets Chromium's requirements indicates this is probably a
|
||||
tougher problem than it appears at first glance. We aim to succeed by
|
||||
creating a tool that is highly specific to Chromium's specific use case,
|
||||
not to the general case of design a completely platform-independent tool
|
||||
for expressing any possible build.
|
||||
|
||||
The Mac has the most sophisticated model for application development
|
||||
through an IDE. Consequently, we will use the Xcode model as the
|
||||
starting point (the input file format must handle Chromium's use of
|
||||
Xcode seamlessly) and adapt the design as necessary for the other
|
||||
platforms.
|
||||
|
||||
## Overview
|
||||
|
||||
The overall design has the following characteristics:
|
||||
|
||||
* Input configurations are specified in files with the suffix `.gyp`.
|
||||
* Each `.gyp` file specifies how to build the targets for the
|
||||
"component" defined by that file.
|
||||
* Each `.gyp` file generates one or more output files appropriate to
|
||||
the platform:
|
||||
* On Mac, a `.gyp` file generates one Xcode .xcodeproj bundle with
|
||||
information about how its targets are built.
|
||||
* On Windows, a `.gyp` file generates one Visual Studio .sln file,
|
||||
and one Visual Studio .vcproj file per target.
|
||||
* On Linux, a `.gyp` file generates one SCons file and/or one
|
||||
Makefile per target
|
||||
* The `.gyp` file syntax is a Python data structure.
|
||||
* Use of arbitrary Python in `.gyp` files is forbidden.
|
||||
* Use of eval() with restricted globals and locals on `.gyp` file
|
||||
contents restricts the input to an evaluated expression, not
|
||||
arbitrary Python statements.
|
||||
* All input is expected to comply with JSON, with two exceptions:
|
||||
the # character (not inside strings) begins a comment that lasts
|
||||
until the end of the line, and trailing commas are permitted at
|
||||
the end of list and dict contents.
|
||||
* Input data is a dictionary of keywords and values.
|
||||
* "Invalid" keywords on any given data structure are not illegal,
|
||||
they're just ignored.
|
||||
* TODO: providing warnings on use of illegal keywords would help
|
||||
users catch typos. Figure out something nice to do with this.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
Some up-front design principles/thoughts/TODOs:
|
||||
|
||||
* Re-use keywords consistently.
|
||||
* Keywords that allow configuration of a platform-specific concept get
|
||||
prefixed appropriately:
|
||||
* Examples: `msvs_disabled_warnings`, `xcode_framework_dirs`
|
||||
* The input syntax is declarative and data-driven.
|
||||
* This gets enforced by using Python `eval()` (which only evaluates
|
||||
an expression) instead of `exec` (which executes arbitrary python)
|
||||
* Semantic meanings of specific keyword values get deferred until all
|
||||
are read and the configuration is being evaluated to spit out the
|
||||
appropriate file(s)
|
||||
* Source file lists:
|
||||
* Are flat lists. Any imposed ordering within the `.gyp` file (e.g.
|
||||
alphabetically) is purely by convention and for developer
|
||||
convenience. When source files are linked or archived together,
|
||||
it is expected that this will occur in the order that files are
|
||||
listed in the `.gyp` file.
|
||||
* Source file lists contain no mechanism for by-hand folder
|
||||
configuration (`Filter` tags in Visual Studio, `Groups` in Xcode)
|
||||
* A folder hierarchy is created automatically that mirrors the file
|
||||
system
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
{
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'U_STATIC_IMPLEMENTATION',
|
||||
['LOGFILE', 'foo.log',],
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'foo/src/foo.cc',
|
||||
'foo/src/foo_main.cc',
|
||||
],
|
||||
'include_dirs': [
|
||||
'foo',
|
||||
'foo/include',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS==mac', { 'sources': [ 'platform_test_mac.mm' ] } ]
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'UNIT_TEST',
|
||||
],
|
||||
'include_dirs': [
|
||||
'foo',
|
||||
'foo/include',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Structural Elements
|
||||
|
||||
### Top-level Dictionary
|
||||
|
||||
This is the single dictionary in the `.gyp` file that defines the
|
||||
targets and how they're to be built.
|
||||
|
||||
The following keywords are meaningful within the top-level dictionary
|
||||
definition:
|
||||
|
||||
| *Keyword* | *Description* |
|
||||
|:------------------|:------------------|
|
||||
| `conditions` | A conditional section that may contain other items that can be present in a top-level dictionary, on a conditional basis. See the "Conditionals" section below. |
|
||||
| `includes` | A list of `.gypi` files to be included in the top-level dictionary. |
|
||||
| `target_defaults` | A dictionary of default settings to be inherited by all targets in the top-level dictionary. See the "Settings keywords" section below. |
|
||||
| `targets` | A list of target specifications. See the "targets" below. |
|
||||
| `variables` | A dictionary containing variable definitions. Each key in this dictionary is the name of a variable, and each value must be a string value that the variable is to be set to. |
|
||||
|
||||
### targets
|
||||
|
||||
A list of dictionaries defining targets to be built by the files
|
||||
generated from this `.gyp` file.
|
||||
|
||||
Targets may contain `includes`, `conditions`, and `variables` sections
|
||||
as permitted in the root dictionary. The following additional keywords
|
||||
have structural meaning for target definitions:
|
||||
|
||||
| *Keyword* | *Description* |
|
||||
|:---------------------------- |:------------------------------------------|
|
||||
| `actions` | A list of special custom actions to perform on a specific input file, or files, to produce output files. See the "Actions" section below. |
|
||||
| `all_dependent_settings` | A dictionary of settings to be applied to all dependents of the target, transitively. This includes direct dependents and the entire set of their dependents, and so on. This section may contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare `direct_dependent_settings` and `link_settings`. |
|
||||
| `configurations` | A list of dictionaries defining build configurations for the target. See the "Configurations" section below. |
|
||||
| `copies` | A list of copy actions to perform. See the "Copies" section below. |
|
||||
| `defines` | A list of preprocessor definitions to be passed on the command line to the C/C++ compiler (via `-D` or `/D` options). |
|
||||
| `dependencies` | A list of targets on which this target depends. Targets in other `.gyp` files are specified as `../path/to/other.gyp:target_we_want`. |
|
||||
| `direct_dependent_settings` | A dictionary of settings to be applied to other targets that depend on this target. These settings will only be applied to direct dependents. This section may contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare with `all_dependent_settings` and `link_settings`. |
|
||||
| `include_dirs` | A list of include directories to be passed on the command line to the C/C++ compiler (via `-I` or `/I` options). |
|
||||
| `libraries` | A list of list of libraries (and/or frameworks) on which this target depends. |
|
||||
| `link_settings` | A dictionary of settings to be applied to targets in which this target's contents are linked. `executable` and `shared_library` targets are linkable, so if they depend on a non-linkable target such as a `static_library`, they will adopt its `link_settings`. This section can contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare `all_dependent_settings` and `direct_dependent_settings`. |
|
||||
| `rules` | A special custom action to perform on a list of input files, to produce output files. See the "Rules" section below. |
|
||||
| `sources` | A list of source files that are used to build this target or which should otherwise show up in the IDE for this target. In practice, we expect this list to be a union of all files necessary to build the target on all platforms, as well as other related files that aren't actually used for building, like README files. |
|
||||
| `target_conditions` | Like `conditions`, but evaluation is delayed until the settings have been merged into an actual target. `target_conditions` may be used to place conditionals into a `target_defaults` section but have them still depend on specific target settings. |
|
||||
| `target_name` | The name of a target being defined. |
|
||||
| `type` | The type of target being defined. This field currently supports `executable`, `static_library`, `shared_library`, and `none`. The `none` target type is useful when producing output which is not linked. For example, converting raw translation files into resources or documentation into platform specific help files. |
|
||||
| `msvs_props` | A list of Visual Studio property sheets (`.vsprops` files) to be used to build the target. |
|
||||
| `xcode_config_file` | An Xcode configuration (`.xcconfig` file) to be used to build the target. |
|
||||
| `xcode_framework_dirs` | A list of framework directories be used to build the target. |
|
||||
|
||||
You can affect the way that lists/dictionaries are merged together (for
|
||||
example the way a list in target\_defaults interacts with the same named
|
||||
list in the target itself) with a couple of special characters, which
|
||||
are covered in [Merge
|
||||
Basics](InputFormatReference#Merge_Basics_(=,_?,_+).md) and [List
|
||||
Filters](InputFormatReference#List_Filters.md) on the
|
||||
InputFormatReference page.
|
||||
|
||||
### configurations
|
||||
|
||||
`configurations` sections may be found within `targets` or
|
||||
`target_defaults` sections. The `configurations` section is a list of
|
||||
dictionaries specifying different build configurations. Because
|
||||
configurations are implemented as lists, it is not currently possible to
|
||||
override aspects of configurations that are imported into a target from
|
||||
a `target_defaults` section.
|
||||
|
||||
NOTE: It is extremely important that each target within a project define
|
||||
the same set of configurations. This continues to apply even when a
|
||||
project spans across multiple `.gyp` files.
|
||||
|
||||
A configuration dictionary may contain anything that can be found within
|
||||
a target dictionary, except for `actions`, `all_dependent_settings`,
|
||||
`configurations`, `dependencies`, `direct_dependent_settings`,
|
||||
`libraries`, `link_settings`, `sources`, `target_name`, and `type`.
|
||||
|
||||
Configuration dictionaries may also contain these elements:
|
||||
|
||||
| *Keyword* | *Description* |
|
||||
|:---------------------|:----------------------------------------------------|
|
||||
| `configuration_name` | Required attribute. The name of the configuration. |
|
||||
|
||||
### Conditionals
|
||||
|
||||
Conditionals may appear within any dictionary in a `.gyp` file. There
|
||||
are two tpes of conditionals, which differ only in the timing of their
|
||||
processing. `conditions` sections are processed shortly after loading
|
||||
`.gyp` files, and `target_conditions` sections are processed after all
|
||||
dependencies have been computed.
|
||||
|
||||
A conditional section is introduced with a `conditions` or
|
||||
`target_conditions` dictionary keyword, and is composed of a list. Each
|
||||
list contains two or three elements. The first two elements, which are
|
||||
always required, are the conditional expression to evaluate and a
|
||||
dictionary containing settings to merge into the dictionary containing
|
||||
the `conditions` or `target_conditions` section if the expression
|
||||
evaluates to true. The third, optional, list element is a dictionary to
|
||||
merge if the expression evaluates to false.
|
||||
|
||||
The `eval()` of the expression string takes place in the context of
|
||||
global and/or local dictionaries that constructed from the `.gyp` input
|
||||
data, and overrides the `__builtin__` dictionary, to prevent the
|
||||
execution of arbitrary Python code.
|
||||
|
||||
### Actions
|
||||
|
||||
An `actions` section provides a list of custom build actions to perform
|
||||
on inputs, producing outputs. The `actions` section is organized as a
|
||||
list. Each item in the list is a dictionary having the following form:
|
||||
|
||||
| *Keyword* | *Type* | *Description* |
|
||||
|:--------------|:-------|:-----------------------------|
|
||||
| `action_name` | string | The name of the action. Depending on how actions are implemented in the various generators, some may desire or require this property to be set to a unique name; others may ignore this property entirely. |
|
||||
| `inputs` | list | A list of pathnames treated as inputs to the custom action. |
|
||||
| `outputs` | list | A list of pathnames that the custom action produces. |
|
||||
| `action` | list | A command line invocation used to produce `outputs` from `inputs`. For maximum cross-platform compatibility, invocations that require a Python interpreter should be specified with a first element `"python"`. This will enable generators for environments with specialized Python installations to be able to perform the action in an appropriate Python environment. |
|
||||
| `message` | string | A message to be displayed to the user by the build system when the action is run. |
|
||||
|
||||
Build environments will compare `inputs` and `outputs`. If any `output`
|
||||
is missing or is outdated relative to any `input`, the custom action
|
||||
will be invoked. If all `outputs` are present and newer than all
|
||||
`inputs`, the `outputs` are considered up-to-date and the action need
|
||||
not be invoked.
|
||||
|
||||
Actions are implemented in Xcode as shell script build phases performed
|
||||
prior to the compilation phase. In the Visual Studio generator, actions
|
||||
appear files with a `FileConfiguration` containing a custom
|
||||
`VCCustomBuildTool` specifying the remainder of the inputs, the outputs,
|
||||
and the action.
|
||||
|
||||
Combined with variable expansions, actions can be quite powerful. Here
|
||||
is an example action that leverages variable expansions to minimize
|
||||
duplication of pathnames:
|
||||
|
||||
```
|
||||
'sources': [
|
||||
# libraries.cc is generated by the js2c action below.
|
||||
'<(INTERMEDIATE_DIR)/libraries.cc',
|
||||
],
|
||||
'actions': [
|
||||
{
|
||||
'variables': {
|
||||
'core_library_files': [
|
||||
'src/runtime.js',
|
||||
'src/v8natives.js',
|
||||
'src/macros.py',
|
||||
],
|
||||
},
|
||||
'action_name': 'js2c',
|
||||
'inputs': [
|
||||
'tools/js2c.py',
|
||||
'<@(core_library_files)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(INTERMEDIATE_DIR)/libraries.cc',
|
||||
'<(INTERMEDIATE_DIR)/libraries-empty.cc',
|
||||
],
|
||||
'action': ['python', 'tools/js2c.py', '<@(_outputs)', 'CORE', '<@(core_library_files)'],
|
||||
},
|
||||
],
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
A `rules` section provides custom build action to perform on inputs, producing
|
||||
outputs. The `rules` section is organized as a list. Each item in the list is
|
||||
a dictionary having the following form:
|
||||
|
||||
| *Keyword* | *Type* | *Description* |
|
||||
|:------------|:-------|:-----------------------------------------|
|
||||
| `rule_name` | string | The name of the rule. Depending on how Rules are implemented in the various generators, some may desire or require this property to be set to a unique name; others may ignore this property entirely. |
|
||||
| `extension` | string | All source files of the current target with the given extension will be treated successively as inputs to the rule. |
|
||||
| `inputs` | list | Additional dependencies of the rule. |
|
||||
| `outputs` | list | A list of pathnames that the rule produces. Has access to `RULE_INPUT_` variables (see below). |
|
||||
| `action` | list | A command line invocation used to produce `outputs` from `inputs`. For maximum cross-platform compatibility, invocations that require a Python interpreter should be specified with a first element `"python"`. This will enable generators for environments with specialized Python installations to be able to perform the action in an appropriate Python environment. Has access to `RULE_INPUT_` variables (see below). |
|
||||
| `message` | string | A message to be displayed to the user by the build system when the action is run. Has access to `RULE_INPUT_` variables (see below). |
|
||||
|
||||
There are several variables available to `outputs`, `action`, and `message`.
|
||||
|
||||
| *Variable* | *Description* |
|
||||
|:---------------------|:------------------------------------|
|
||||
| `RULE_INPUT_PATH` | The full path to the current input. |
|
||||
| `RULE_INPUT_DIRNAME` | The directory of the current input. |
|
||||
| `RULE_INPUT_NAME` | The file name of the current input. |
|
||||
| `RULE_INPUT_ROOT` | The file name of the current input without extension. |
|
||||
| `RULE_INPUT_EXT` | The file name extension of the current input. |
|
||||
|
||||
Rules can be thought of as Action generators. For each source selected
|
||||
by `extension` an special action is created. This action starts out with
|
||||
the same `inputs`, `outputs`, `action`, and `message` as the rule. The
|
||||
source is added to the action's `inputs`. The `outputs`, `action`, and
|
||||
`message` are then handled the same but with the additional variables.
|
||||
If the `_output` variable is used in the `action` or `message` the
|
||||
`RULE_INPUT_` variables in `output` will be expanded for the current
|
||||
source.
|
||||
|
||||
### Copies
|
||||
|
||||
A `copies` section provides a simple means of copying files. The
|
||||
`copies` section is organized as a list. Each item in the list is a
|
||||
dictionary having the following form:
|
||||
|
||||
| *Keyword* | *Type* | *Description* |
|
||||
|:--------------|:-------|:------------------------------|
|
||||
| `destination` | string | The directory into which the `files` will be copied. |
|
||||
| `files` | list | A list of files to be copied. |
|
||||
|
||||
The copies will be created in `destination` and have the same file name
|
||||
as the file they are copied from. Even if the `files` are from multiple
|
||||
directories they will all be copied into the `destination` directory.
|
||||
Each `destination` file has an implicit build dependency on the file it
|
||||
is copied from.
|
||||
|
||||
### Generated Xcode .pbxproj Files
|
||||
|
||||
We derive the following things in a `project.pbxproj` plist file within
|
||||
an `.xcodeproj` bundle from the above input file formats as follows:
|
||||
|
||||
* `Group hierarchy`: This is generated in a fixed format with contents
|
||||
derived from the input files. There is no provision for the user to
|
||||
specify additional groups or create a custom hierarchy.
|
||||
* `Configuration group`: This will be used with the
|
||||
`xcode_config_file` property above, if needed.
|
||||
* `Source group`: The union of the `sources` lists of all `targets`
|
||||
after applying appropriate `conditions`. The resulting list is
|
||||
sorted and put into a group hierarchy that matches the layout of
|
||||
the directory tree on disk, with a root of // (the top of the
|
||||
hierarchy).
|
||||
* `Frameworks group`: Taken directly from `libraries` value for the
|
||||
target, after applying appropriate conditions.
|
||||
* `Projects group`: References to other `.xcodeproj` bundles that
|
||||
are needed by the `.xcodeproj` in which the group is contained.
|
||||
* `Products group`: Output from the various targets.
|
||||
* `Project References`:
|
||||
* `Project Configurations`:
|
||||
* Per-`.xcodeproj` file settings are not supported, all settings are
|
||||
applied at the target level.
|
||||
* `Targets`:
|
||||
* `Phases`: Copy sources, link with libraries/frameworks, ...
|
||||
* `Target Configurations`: Specified by input.
|
||||
* `Dependencies`: (local and remote)
|
||||
|
||||
### Generated Visual Studio .vcproj Files
|
||||
|
||||
We derive the following sections in a `.vcproj` file from the above
|
||||
input file formats as follows:
|
||||
|
||||
* `VisualStudioProject`:
|
||||
* `Platforms`:
|
||||
* `ToolFiles`:
|
||||
* `Configurations`:
|
||||
* `Configuration`:
|
||||
* `References`:
|
||||
* `Files`:
|
||||
* `Filter`:
|
||||
* `File`:
|
||||
* `FileConfiguration`:
|
||||
* `Tool`:
|
||||
* `Globals`:
|
||||
|
||||
### Generated Visual Studio .sln Files
|
||||
|
||||
We derive the following sections in a `.sln` file from the above input
|
||||
file formats as follows:
|
||||
|
||||
* `Projects`:
|
||||
* `WebsiteProperties`:
|
||||
* `ProjectDependencies`:
|
||||
* `Global`:
|
||||
* `SolutionConfigurationPlatforms`:
|
||||
* `ProjectConfigurationPlatforms`:
|
||||
* `SolutionProperties`:
|
||||
* `NestedProjects`:
|
||||
|
||||
## Caveats
|
||||
|
||||
Notes/Question from very first prototype draft of the language.
|
||||
Make sure these issues are addressed somewhere before deleting.
|
||||
|
||||
* Libraries are easy, application abstraction is harder
|
||||
* Applications involves resource compilation
|
||||
* Applications involve many inputs
|
||||
* Applications include transitive closure of dependencies
|
||||
* Specific use cases like cc\_library
|
||||
* Mac compiles more than just .c/.cpp files (specifically, .m and .mm
|
||||
files)
|
||||
* Compiler options vary by:
|
||||
* File type
|
||||
* Target type
|
||||
* Individual file
|
||||
* Files may have custom settings per file per platform, but we probably
|
||||
don't care or need to support this in gyp.
|
||||
* Will all linked non-Chromium projects always use the same versions of every
|
||||
subsystem?
|
||||
* Variants are difficult. We've identified the following variants (some
|
||||
specific to Chromium, some typical of other projects in the same ballpark):
|
||||
* Target platform
|
||||
* V8 vs. JSC
|
||||
* Debug vs. Release
|
||||
* Toolchain (VS version, gcc, version)
|
||||
* Host platform
|
||||
* L10N
|
||||
* Vendor
|
||||
* Purify / Valgrind
|
||||
* Will everyone upgrade VS at once?
|
||||
* What does a dylib dependency mean?
|
||||
27
electron/node_modules/node-gyp/gyp/docs/README.md
generated
vendored
Normal file
27
electron/node_modules/node-gyp/gyp/docs/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Generate Your Projects (gyp-next)
|
||||
|
||||
GYP is a Meta-Build system: a build system that generates other build systems.
|
||||
|
||||
* [User documentation](./UserDocumentation.md)
|
||||
* [Input Format Reference](./InputFormatReference.md)
|
||||
* [Language specification](./LanguageSpecification.md)
|
||||
* [Hacking](./Hacking.md)
|
||||
* [Testing](./Testing.md)
|
||||
* [GYP vs. CMake](./GypVsCMake.md)
|
||||
|
||||
GYP is intended to support large projects that need to be built on multiple
|
||||
platforms (e.g., Mac, Windows, Linux), and where it is important that
|
||||
the project can be built using the IDEs that are popular on each platform
|
||||
as if the project is a "native" one.
|
||||
|
||||
It can be used to generate XCode projects, Visual Studio projects, Ninja
|
||||
build files, and Makefiles. In each case GYP's goal is to replicate as
|
||||
closely as possible the way one would set up a native build of the project
|
||||
using the IDE.
|
||||
|
||||
GYP can also be used to generate "hybrid" projects that provide the IDE
|
||||
scaffolding for a nice user experience but call out to Ninja to do the actual
|
||||
building (which is usually much faster than the native build systems of the
|
||||
IDEs).
|
||||
|
||||
For more information on GYP, click on the links above.
|
||||
450
electron/node_modules/node-gyp/gyp/docs/Testing.md
generated
vendored
Normal file
450
electron/node_modules/node-gyp/gyp/docs/Testing.md
generated
vendored
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
# Testing
|
||||
|
||||
NOTE: this document is outdated and needs to be updated. Read with your own discretion.
|
||||
|
||||
## Introduction
|
||||
|
||||
This document describes the GYP testing infrastructure,
|
||||
as provided by the `TestGyp.py` module.
|
||||
|
||||
These tests emphasize testing the _behavior_ of the
|
||||
various GYP-generated build configurations:
|
||||
Visual Studio, Xcode, SCons, Make, etc.
|
||||
The goal is _not_ to test the output of the GYP generators by,
|
||||
for example, comparing a GYP-generated Makefile
|
||||
against a set of known "golden" Makefiles
|
||||
(although the testing infrastructure could
|
||||
be used to write those kinds of tests).
|
||||
The idea is that the generated build configuration files
|
||||
could be completely written to add a feature or fix a bug
|
||||
so long as they continue to support the functional behaviors
|
||||
defined by the tests: building programs, shared libraries, etc.
|
||||
|
||||
## "Hello, world!" GYP test configuration
|
||||
|
||||
Here is an actual test configuration,
|
||||
a simple build of a C program to print `"Hello, world!"`.
|
||||
|
||||
```
|
||||
$ ls -l test/hello
|
||||
total 20
|
||||
-rw-r--r-- 1 knight knight 312 Jul 30 20:22 gyptest-all.py
|
||||
-rw-r--r-- 1 knight knight 307 Jul 30 20:22 gyptest-default.py
|
||||
-rwxr-xr-x 1 knight knight 326 Jul 30 20:22 gyptest-target.py
|
||||
-rw-r--r-- 1 knight knight 98 Jul 30 20:22 hello.c
|
||||
-rw-r--r-- 1 knight knight 142 Jul 30 20:22 hello.gyp
|
||||
$
|
||||
```
|
||||
|
||||
The `gyptest-*.py` files are three separate tests (test scripts)
|
||||
that use this configuration. The first one, `gyptest-all.py`,
|
||||
looks like this:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Verifies simplest-possible build of a "Hello, world!" program
|
||||
using an explicit build target of 'all'.
|
||||
"""
|
||||
|
||||
import TestGyp
|
||||
|
||||
test = TestGyp.TestGyp()
|
||||
|
||||
test.run_gyp('hello.gyp')
|
||||
|
||||
test.build_all('hello.gyp')
|
||||
|
||||
test.run_built_executable('hello', stdout="Hello, world!\n")
|
||||
|
||||
test.pass_test()
|
||||
```
|
||||
|
||||
The test script above runs GYP against the specified input file
|
||||
(`hello.gyp`) to generate a build configuration.
|
||||
It then tries to build the `'all'` target
|
||||
(or its equivalent) using the generated build configuration.
|
||||
Last, it verifies that the build worked as expected
|
||||
by running the executable program (`hello`)
|
||||
that was just presumably built by the generated configuration,
|
||||
and verifies that the output from the program
|
||||
matches the expected `stdout` string (`"Hello, world!\n"`).
|
||||
|
||||
Which configuration is generated
|
||||
(i.e., which build tool to test)
|
||||
is specified when the test is run;
|
||||
see the next section.
|
||||
|
||||
Surrounding the functional parts of the test
|
||||
described above are the header,
|
||||
which should be basically the same for each test
|
||||
(modulo a different description in the docstring):
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Verifies simplest-possible build of a "Hello, world!" program
|
||||
using an explicit build target of 'all'.
|
||||
"""
|
||||
|
||||
import TestGyp
|
||||
|
||||
test = TestGyp.TestGyp()
|
||||
```
|
||||
|
||||
Similarly, the footer should be the same in every test:
|
||||
|
||||
```
|
||||
test.pass_test()
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
Test scripts are run by the `gyptest.py` script.
|
||||
You can specify (an) explicit test script(s) to run:
|
||||
|
||||
```
|
||||
$ python gyptest.py test/hello/gyptest-all.py
|
||||
PYTHONPATH=/home/knight/src/gyp/trunk/test/lib
|
||||
TESTGYP_FORMAT=scons
|
||||
/usr/bin/python test/hello/gyptest-all.py
|
||||
PASSED
|
||||
$
|
||||
```
|
||||
|
||||
If you specify a directory, all test scripts
|
||||
(scripts prefixed with `gyptest-`) underneath
|
||||
the directory will be run:
|
||||
|
||||
```
|
||||
$ python gyptest.py test/hello
|
||||
PYTHONPATH=/home/knight/src/gyp/trunk/test/lib
|
||||
TESTGYP_FORMAT=scons
|
||||
/usr/bin/python test/hello/gyptest-all.py
|
||||
PASSED
|
||||
/usr/bin/python test/hello/gyptest-default.py
|
||||
PASSED
|
||||
/usr/bin/python test/hello/gyptest-target.py
|
||||
PASSED
|
||||
$
|
||||
```
|
||||
|
||||
Or you can specify the `-a` option to run all scripts
|
||||
in the tree:
|
||||
|
||||
```
|
||||
$ python gyptest.py -a
|
||||
PYTHONPATH=/home/knight/src/gyp/trunk/test/lib
|
||||
TESTGYP_FORMAT=scons
|
||||
/usr/bin/python test/configurations/gyptest-configurations.py
|
||||
PASSED
|
||||
/usr/bin/python test/defines/gyptest-defines.py
|
||||
PASSED
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
/usr/bin/python test/variables/gyptest-commands.py
|
||||
PASSED
|
||||
$
|
||||
```
|
||||
|
||||
If any tests fail during the run,
|
||||
the `gyptest.py` script will report them in a
|
||||
summary at the end.
|
||||
|
||||
## Debugging tests
|
||||
|
||||
Tests that create intermediate output do so under the gyp/out/testworkarea
|
||||
directory. On test completion, intermediate output is cleaned up. To preserve
|
||||
this output, set the environment variable PRESERVE=1. This can be handy to
|
||||
inspect intermediate data when debugging a test.
|
||||
|
||||
You can also set PRESERVE\_PASS=1, PRESERVE\_FAIL=1 or PRESERVE\_NO\_RESULT=1
|
||||
to preserve output for tests that fall into one of those categories.
|
||||
|
||||
# Specifying the format (build tool) to use
|
||||
|
||||
By default, the `gyptest.py` script will generate configurations for
|
||||
the "primary" supported build tool for the platform you're on:
|
||||
Visual Studio on Windows,
|
||||
Xcode on Mac,
|
||||
and (currently) SCons on Linux.
|
||||
An alternate format (build tool) may be specified
|
||||
using the `-f` option:
|
||||
|
||||
```
|
||||
$ python gyptest.py -f make test/hello/gyptest-all.py
|
||||
PYTHONPATH=/home/knight/src/gyp/trunk/test/lib
|
||||
TESTGYP_FORMAT=make
|
||||
/usr/bin/python test/hello/gyptest-all.py
|
||||
PASSED
|
||||
$
|
||||
```
|
||||
|
||||
Multiple tools may be specified in a single pass as
|
||||
a comma-separated list:
|
||||
|
||||
```
|
||||
$ python gyptest.py -f make,scons test/hello/gyptest-all.py
|
||||
PYTHONPATH=/home/knight/src/gyp/trunk/test/lib
|
||||
TESTGYP_FORMAT=make
|
||||
/usr/bin/python test/hello/gyptest-all.py
|
||||
PASSED
|
||||
TESTGYP_FORMAT=scons
|
||||
/usr/bin/python test/hello/gyptest-all.py
|
||||
PASSED
|
||||
$
|
||||
```
|
||||
|
||||
## Test script functions and methods
|
||||
|
||||
The `TestGyp` class contains a lot of functionality
|
||||
intended to make it easy to write tests.
|
||||
This section describes the most useful pieces for GYP testing.
|
||||
|
||||
(The `TestGyp` class is actually a subclass of more generic
|
||||
`TestCommon` and `TestCmd` base classes
|
||||
that contain even more functionality than is
|
||||
described here.)
|
||||
|
||||
### Initialization
|
||||
|
||||
The standard initialization formula is:
|
||||
|
||||
```
|
||||
import TestGyp
|
||||
test = TestGyp.TestGyp()
|
||||
```
|
||||
|
||||
This copies the contents of the directory tree in which
|
||||
the test script lives to a temporary directory for execution,
|
||||
and arranges for the temporary directory's removal on exit.
|
||||
|
||||
By default, any comparisons of output or file contents
|
||||
must be exact matches for the test to pass.
|
||||
If you need to use regular expressions for matches,
|
||||
a useful alternative initialization is:
|
||||
|
||||
```
|
||||
import TestGyp
|
||||
test = TestGyp.TestGyp(match = TestGyp.match_re,
|
||||
diff = TestGyp.diff_re)`
|
||||
```
|
||||
|
||||
### Running GYP
|
||||
|
||||
The canonical invocation is to simply specify the `.gyp` file to be executed:
|
||||
|
||||
```
|
||||
test.run_gyp('file.gyp')
|
||||
```
|
||||
|
||||
Additional GYP arguments may be specified:
|
||||
|
||||
```
|
||||
test.run_gyp('file.gyp', arguments=['arg1', 'arg2', ...])
|
||||
```
|
||||
|
||||
To execute GYP from a subdirectory (where, presumably, the specified file
|
||||
lives):
|
||||
|
||||
```
|
||||
test.run_gyp('file.gyp', chdir='subdir')
|
||||
```
|
||||
|
||||
### Running the build tool
|
||||
|
||||
Running the build tool requires passing in a `.gyp` file, which may be used to
|
||||
calculate the name of a specific build configuration file (such as a MSVS
|
||||
solution file corresponding to the `.gyp` file).
|
||||
|
||||
There are several different `.build_*()` methods for invoking different types
|
||||
of builds.
|
||||
|
||||
To invoke a build tool with an explicit `all` target (or equivalent):
|
||||
|
||||
```
|
||||
test.build_all('file.gyp')
|
||||
```
|
||||
|
||||
To invoke a build tool with its default behavior (for example, executing `make`
|
||||
with no targets specified):
|
||||
|
||||
```
|
||||
test.build_default('file.gyp')
|
||||
```
|
||||
|
||||
To invoke a build tool with an explicit specified target:
|
||||
|
||||
```
|
||||
test.build_target('file.gyp', 'target')
|
||||
```
|
||||
|
||||
### Running executables
|
||||
|
||||
The most useful method executes a program built by the GYP-generated
|
||||
configuration:
|
||||
|
||||
```
|
||||
test.run_built_executable('program')
|
||||
```
|
||||
|
||||
The `.run_built_executable()` method will account for the actual built target
|
||||
output location for the build tool being tested, as well as tack on any
|
||||
necessary executable file suffix for the platform (for example `.exe` on
|
||||
Windows).
|
||||
|
||||
`stdout=` and `stderr=` keyword arguments specify expected standard output and
|
||||
error output, respectively. Failure to match these (if specified) will cause
|
||||
the test to fail. An explicit `None` value will suppress that verification:
|
||||
|
||||
```
|
||||
test.run_built_executable('program',
|
||||
stdout="expect this output\n",
|
||||
stderr=None)
|
||||
```
|
||||
|
||||
Note that the default values are `stdout=None` and `stderr=''` (that is, no
|
||||
check for standard output, and error output must be empty).
|
||||
|
||||
Arbitrary executables (not necessarily those built by GYP) can be executed with
|
||||
the lower-level `.run()` method:
|
||||
|
||||
```
|
||||
test.run('program')
|
||||
```
|
||||
|
||||
The program must be in the local directory (that is, the temporary directory
|
||||
for test execution) or be an absolute path name.
|
||||
|
||||
### Fetching command output
|
||||
|
||||
```
|
||||
test.stdout()
|
||||
```
|
||||
|
||||
Returns the standard output from the most recent executed command (including
|
||||
`.run_gyp()`, `.build_*()`, or `.run*()` methods).
|
||||
|
||||
```
|
||||
test.stderr()
|
||||
```
|
||||
|
||||
Returns the error output from the most recent executed command (including
|
||||
`.run_gyp()`, `.build_*()`, or `.run*()` methods).
|
||||
|
||||
### Verifying existence or non-existence of files or directories
|
||||
|
||||
```
|
||||
test.must_exist('file_or_dir')
|
||||
```
|
||||
|
||||
Verifies that the specified file or directory exists, and fails the test if it
|
||||
doesn't.
|
||||
|
||||
```
|
||||
test.must_not_exist('file_or_dir')
|
||||
```
|
||||
|
||||
Verifies that the specified file or directory does not exist, and fails the
|
||||
test if it does.
|
||||
|
||||
### Verifying file contents
|
||||
|
||||
```
|
||||
test.must_match('file', 'expected content\n')
|
||||
```
|
||||
|
||||
Verifies that the content of the specified file match the expected string, and
|
||||
fails the test if it does not. By default, the match must be exact, but
|
||||
line-by-line regular expressions may be used if the `TestGyp` object was
|
||||
initialized with `TestGyp.match_re`.
|
||||
|
||||
```
|
||||
test.must_not_match('file', 'expected content\n')
|
||||
```
|
||||
|
||||
Verifies that the content of the specified file does _not_ match the expected
|
||||
string, and fails the test if it does. By default, the match must be exact,
|
||||
but line-by-line regular expressions may be used if the `TestGyp` object was
|
||||
initialized with `TestGyp.match_re`.
|
||||
|
||||
```
|
||||
test.must_contain('file', 'substring')
|
||||
```
|
||||
|
||||
Verifies that the specified file contains the specified substring, and fails
|
||||
the test if it does not.
|
||||
|
||||
```
|
||||
test.must_not_contain('file', 'substring')
|
||||
```
|
||||
|
||||
Verifies that the specified file does not contain the specified substring, and
|
||||
fails the test if it does.
|
||||
|
||||
```
|
||||
test.must_contain_all_lines(output, lines)
|
||||
```
|
||||
|
||||
Verifies that the output string contains all of the "lines" in the specified
|
||||
list of lines. In practice, the lines can be any substring and need not be
|
||||
`\n`-terminated lines per se. If any line is missing, the test fails.
|
||||
|
||||
```
|
||||
test.must_not_contain_any_lines(output, lines)
|
||||
```
|
||||
|
||||
Verifies that the output string does _not_ contain any of the "lines" in the
|
||||
specified list of lines. In practice, the lines can be any substring and need
|
||||
not be `\n`-terminated lines per se. If any line exists in the output string,
|
||||
the test fails.
|
||||
|
||||
```
|
||||
test.must_contain_any_line(output, lines)
|
||||
```
|
||||
|
||||
Verifies that the output string contains at least one of the "lines" in the
|
||||
specified list of lines. In practice, the lines can be any substring and need
|
||||
not be `\n`-terminated lines per se. If none of the specified lines is present,
|
||||
the test fails.
|
||||
|
||||
### Reading file contents
|
||||
|
||||
```
|
||||
test.read('file')
|
||||
```
|
||||
|
||||
Returns the contents of the specified file. Directory elements contained in a
|
||||
list will be joined:
|
||||
|
||||
```
|
||||
test.read(['subdir', 'file'])
|
||||
```
|
||||
|
||||
### Test success or failure
|
||||
|
||||
```
|
||||
test.fail_test()
|
||||
```
|
||||
|
||||
Fails the test, reporting `FAILED` on standard output and exiting with an exit
|
||||
status of `1`.
|
||||
|
||||
```
|
||||
test.pass_test()
|
||||
```
|
||||
|
||||
Passes the test, reporting `PASSED` on standard output and exiting with an exit
|
||||
status of `0`.
|
||||
|
||||
```
|
||||
test.no_result()
|
||||
```
|
||||
|
||||
Indicates the test had no valid result (i.e., the conditions could not be
|
||||
tested because of an external factor like a full file system). Reports `NO
|
||||
RESULT` on standard output and exits with a status of `2`.
|
||||
965
electron/node_modules/node-gyp/gyp/docs/UserDocumentation.md
generated
vendored
Normal file
965
electron/node_modules/node-gyp/gyp/docs/UserDocumentation.md
generated
vendored
Normal file
|
|
@ -0,0 +1,965 @@
|
|||
# User Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
This document is intended to provide a user-level guide to GYP. The
|
||||
emphasis here is on how to use GYP to accomplish specific tasks, not on
|
||||
the complete technical language specification. (For that, see the
|
||||
[LanguageSpecification](LanguageSpecification.md).)
|
||||
|
||||
The document below starts with some overviews to provide context: an
|
||||
overview of the structure of a `.gyp` file itself, an overview of a
|
||||
typical executable-program target in a `.gyp` file, an an overview of a
|
||||
typical library target in a `.gyp` file.
|
||||
|
||||
After the overviews, there are examples of `gyp` patterns for different
|
||||
common use cases.
|
||||
|
||||
## Skeleton of a typical Chromium .gyp file
|
||||
|
||||
Here is the skeleton of a typical `.gyp` file in the Chromium tree:
|
||||
|
||||
```
|
||||
{
|
||||
'variables': {
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
'includes': [
|
||||
'../build/common.gypi',
|
||||
],
|
||||
'target_defaults': {
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'target_1',
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
{
|
||||
'target_name': 'target_2',
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'linux_target_3',
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
],
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'windows_target_4',
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
],
|
||||
}, { # OS != "win"
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'non_windows_target_5',
|
||||
.
|
||||
.
|
||||
.
|
||||
},
|
||||
}],
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The entire file just contains a Python dictionary. (It's actually JSON,
|
||||
with two small Pythonic deviations: comments are introduced with `#`,
|
||||
and a `,` (comma)) is legal after the last element in a list or
|
||||
dictionary.)
|
||||
|
||||
The top-level pieces in the `.gyp` file are as follows:
|
||||
|
||||
`'variables'`: Definitions of variables that can be interpolated and
|
||||
used in various other parts of the file.
|
||||
|
||||
`'includes'`: A list of of other files that will be included in this
|
||||
file. By convention, included files have the suffix `.gypi` (gyp
|
||||
include).
|
||||
|
||||
`'target_defaults'`: Settings that will apply to _all_ of the targets
|
||||
defined in this `.gyp` file.
|
||||
|
||||
`'targets'`: The list of targets for which this `.gyp` file can
|
||||
generate builds. Each target is a dictionary that contains settings
|
||||
describing all the information necessary to build the target.
|
||||
|
||||
`'conditions'`: A list of condition specifications that can modify the
|
||||
contents of the items in the global dictionary defined by this `.gyp`
|
||||
file based on the values of different variables. As implied by the
|
||||
above example, the most common use of a `conditions` section in the
|
||||
top-level dictionary is to add platform-specific targets to the
|
||||
`targets` list.
|
||||
|
||||
## Skeleton of a typical executable target in a .gyp file
|
||||
|
||||
The most straightforward target is probably a simple executable program.
|
||||
Here is an example `executable` target that demonstrates the features
|
||||
that should cover most simple uses of gyp:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',
|
||||
'dependencies': [
|
||||
'xyzzy',
|
||||
'../bar/bar.gyp:bar',
|
||||
],
|
||||
'defines': [
|
||||
'DEFINE_FOO',
|
||||
'DEFINE_A_VALUE=value',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'file1.cc',
|
||||
'file2.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'defines': [
|
||||
'LINUX_DEFINE',
|
||||
],
|
||||
'include_dirs': [
|
||||
'include/linux',
|
||||
],
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'defines': [
|
||||
'WINDOWS_SPECIFIC_DEFINE',
|
||||
],
|
||||
}, { # OS != "win",
|
||||
'defines': [
|
||||
'NON_WINDOWS_DEFINE',
|
||||
],
|
||||
}]
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The top-level settings in the target include:
|
||||
|
||||
`'target_name'`: The name by which the target should be known, which
|
||||
should be unique across all `.gyp` files. This name will be used as the
|
||||
project name in the generated Visual Studio solution, as the target name
|
||||
in the generated XCode configuration, and as the alias for building this
|
||||
target from the command line of the generated SCons configuration.
|
||||
|
||||
`'type'`: Set to `executable`, logically enough.
|
||||
|
||||
`'msvs_guid'`: THIS IS ONLY TRANSITIONAL. This is a hard-coded GUID
|
||||
values that will be used in the generated Visual Studio solution
|
||||
file(s). This allows us to check in a `chrome.sln` file that
|
||||
interoperates with gyp-generated project files. Once everything in
|
||||
Chromium is being generated by gyp, it will no longer be important that
|
||||
the GUIDs stay constant across invocations, and we'll likely get rid of
|
||||
these settings,
|
||||
|
||||
`'dependencies'`: This lists other targets that this target depends on.
|
||||
The gyp-generated files will guarantee that the other targets are built
|
||||
before this target. Any library targets in the `dependencies` list will
|
||||
be linked with this target. The various settings (`defines`,
|
||||
`include_dirs`, etc.) listed in the `direct_dependent_settings` sections
|
||||
of the targets in this list will be applied to how _this_ target is
|
||||
built and linked. See the more complete discussion of
|
||||
`direct_dependent_settings`, below.
|
||||
|
||||
`'defines'`: The C preprocessor definitions that will be passed in on
|
||||
compilation command lines (using `-D` or `/D` options).
|
||||
|
||||
`'include_dirs'`: The directories in which included header files live.
|
||||
These will be passed in on compilation command lines (using `-I` or `/I`
|
||||
options).
|
||||
|
||||
`'sources'`: The source files for this target.
|
||||
|
||||
`'conditions'`: A block of conditions that will be evaluated to update
|
||||
the different settings in the target dictionary.
|
||||
|
||||
## Skeleton of a typical library target in a .gyp file
|
||||
|
||||
The vast majority of targets are libraries. Here is an example of a
|
||||
library target including the additional features that should cover most
|
||||
needs of libraries:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': '<(library)'
|
||||
'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',
|
||||
'dependencies': [
|
||||
'xyzzy',
|
||||
'../bar/bar.gyp:bar',
|
||||
],
|
||||
'defines': [
|
||||
'DEFINE_FOO',
|
||||
'DEFINE_A_VALUE=value',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'DEFINE_FOO',
|
||||
'DEFINE_ADDITIONAL',
|
||||
],
|
||||
'linkflags': [
|
||||
],
|
||||
},
|
||||
'export_dependent_settings': [
|
||||
'../bar/bar.gyp:bar',
|
||||
],
|
||||
'sources': [
|
||||
'file1.cc',
|
||||
'file2.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'defines': [
|
||||
'LINUX_DEFINE',
|
||||
],
|
||||
'include_dirs': [
|
||||
'include/linux',
|
||||
],
|
||||
],
|
||||
['OS=="win"', {
|
||||
'defines': [
|
||||
'WINDOWS_SPECIFIC_DEFINE',
|
||||
],
|
||||
}, { # OS != "win",
|
||||
'defines': [
|
||||
'NON_WINDOWS_DEFINE',
|
||||
],
|
||||
}]
|
||||
],
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The possible entries in a library target are largely the same as those
|
||||
that can be specified for an executable target (`defines`,
|
||||
`include_dirs`, etc.). The differences include:
|
||||
|
||||
`'type'`: This should almost always be set to '<(library)', which allows
|
||||
the user to define at gyp time whether libraries are to be built static
|
||||
or shared. (On Linux, at least, linking with shared libraries saves
|
||||
significant link time.) If it's necessary to pin down the type of
|
||||
library to be built, the `type` can be set explicitly to
|
||||
`static_library` or `shared_library`.
|
||||
|
||||
`'direct_dependent_settings'`: This defines the settings that will be
|
||||
applied to other targets that _directly depend_ on this target--that is,
|
||||
that list _this_ target in their `'dependencies'` setting. This is
|
||||
where you list the `defines`, `include_dirs`, `cflags` and `linkflags`
|
||||
that other targets that compile or link against this target need to
|
||||
build consistently.
|
||||
|
||||
`'export_dependent_settings'`: This lists the targets whose
|
||||
`direct_dependent_settings` should be "passed on" to other targets that
|
||||
use (depend on) this target. `TODO: expand on this description.`
|
||||
|
||||
## Use Cases
|
||||
|
||||
These use cases are intended to cover the most common actions performed
|
||||
by developers using GYP.
|
||||
|
||||
Note that these examples are _not_ fully-functioning, self-contained
|
||||
examples (or else they'd be way too long). Each example mostly contains
|
||||
just the keywords and settings relevant to the example, with perhaps a
|
||||
few extra keywords for context. The intent is to try to show the
|
||||
specific pieces you need to pay attention to when doing something.
|
||||
[NOTE: if practical use shows that these examples are confusing without
|
||||
additional context, please add what's necessary to clarify things.]
|
||||
|
||||
### Add new source files
|
||||
|
||||
There are similar but slightly different patterns for adding a
|
||||
platform-independent source file vs. adding a source file that only
|
||||
builds on some of the supported platforms.
|
||||
|
||||
#### Add a source file that builds on all platforms
|
||||
|
||||
**Simplest possible case**: You are adding a file(s) that builds on all
|
||||
platforms.
|
||||
|
||||
Just add the file(s) to the `sources` list of the appropriate dictionary
|
||||
in the `targets` list:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'my_target',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'../other/file_1.cc',
|
||||
'new_file.cc',
|
||||
'subdir/file3.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
File path names are relative to the directory in which the `.gyp` file lives.
|
||||
|
||||
Keep the list sorted alphabetically (unless there's a really, really,
|
||||
_really_ good reason not to).
|
||||
|
||||
#### Add a platform-specific source file
|
||||
|
||||
##### Your platform-specific file is named `*_linux.{ext}`, `*_mac.{ext}`, `*_posix.{ext}` or `*_win.{ext}`
|
||||
|
||||
The simplest way to add a platform-specific source file, assuming you're
|
||||
adding a completely new file and get to name it, is to use one of the
|
||||
following standard suffixes:
|
||||
|
||||
* `_linux` (e.g. `foo_linux.cc`)
|
||||
* `_mac` (e.g. `foo_mac.cc`)
|
||||
* `_posix` (e.g. `foo_posix.cc`)
|
||||
* `_win` (e.g. `foo_win.cc`)
|
||||
|
||||
Simply add the file to the `sources` list of the appropriate dict within
|
||||
the `targets` list, like you would any other source file.
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'independent.cc',
|
||||
'specific_win.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
The Chromium `.gyp` files all have appropriate `conditions` entries to
|
||||
filter out the files that aren't appropriate for the current platform.
|
||||
In the above example, the `specific_win.cc` file will be removed
|
||||
automatically from the source-list on non-Windows builds.
|
||||
|
||||
##### Your platform-specific file does not use an already-defined pattern
|
||||
|
||||
If your platform-specific file does not contain a
|
||||
`*_{linux,mac,posix,win}` substring (or some other pattern that's
|
||||
already in the `conditions` for the target), and you can't change the
|
||||
file name, there are two patterns that can be used.
|
||||
|
||||
**Preferred**: Add the file to the `sources` list of the appropriate
|
||||
dictionary within the `targets` list. Add an appropriate `conditions`
|
||||
section to exclude the specific files name:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'linux_specific.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS != "linux"', {
|
||||
'sources!': [
|
||||
# Linux-only; exclude on other platforms.
|
||||
'linux_specific.cc',
|
||||
]
|
||||
}[,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
Despite the duplicate listing, the above is generally preferred because
|
||||
the `sources` list contains a useful global list of all sources on all
|
||||
platforms with consistent sorting on all platforms.
|
||||
|
||||
**Non-preferred**: In some situations, however, it might make sense to
|
||||
list a platform-specific file only in a `conditions` section that
|
||||
specifically _includes_ it in the `sources` list:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'sources': [],
|
||||
['OS == "linux"', {
|
||||
'sources': [
|
||||
# Only add to sources list on Linux.
|
||||
'linux_specific.cc',
|
||||
]
|
||||
}],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
The above two examples end up generating equivalent builds, with the
|
||||
small exception that the `sources` lists will list the files in
|
||||
different orders. (The first example defines explicitly where
|
||||
`linux_specific.cc` appears in the list--perhaps in in the
|
||||
middle--whereas the second example will always tack it on to the end of
|
||||
the list.)
|
||||
|
||||
**Including or excluding files using patterns**: There are more
|
||||
complicated ways to construct a `sources` list based on patterns. See
|
||||
`TODO` below.
|
||||
|
||||
### Add a new executable
|
||||
|
||||
An executable program is probably the most straightforward type of
|
||||
target, since all it typically needs is a list of source files, some
|
||||
compiler/linker settings (probably varied by platform), and some library
|
||||
targets on which it depends and which must be used in the final link.
|
||||
|
||||
#### Add an executable that builds on all platforms
|
||||
|
||||
Add a dictionary defining the new executable target to the `targets`
|
||||
list in the appropriate `.gyp` file. Example:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'new_unit_tests',
|
||||
'type': 'executable',
|
||||
'defines': [
|
||||
'FOO',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'dependencies': [
|
||||
'other_target_in_this_file',
|
||||
'other_gyp2:target_in_other_gyp2',
|
||||
],
|
||||
'sources': [
|
||||
'new_additional_source.cc',
|
||||
'new_unit_tests.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
#### Add a platform-specific executable
|
||||
|
||||
Add a dictionary defining the new executable target to the `targets`
|
||||
list within an appropriate `conditions` block for the platform. The
|
||||
`conditions` block should be a sibling to the top-level `targets` list:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'new_unit_tests',
|
||||
'type': 'executable',
|
||||
'defines': [
|
||||
'FOO',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'dependencies': [
|
||||
'other_target_in_this_file',
|
||||
'other_gyp2:target_in_other_gyp2',
|
||||
],
|
||||
'sources': [
|
||||
'new_additional_source.cc',
|
||||
'new_unit_tests.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Add settings to a target
|
||||
|
||||
There are several different types of settings that can be defined for
|
||||
any given target.
|
||||
|
||||
#### Add new preprocessor definitions (`-D` or `/D` flags)
|
||||
|
||||
New preprocessor definitions are added by the `defines` setting:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'existing_target',
|
||||
'defines': [
|
||||
'FOO',
|
||||
'BAR=some_value',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
These may be specified directly in a target's settings, as in the above
|
||||
example, or in a `conditions` section.
|
||||
|
||||
#### Add a new include directory (`-I` or `/I` flags)
|
||||
|
||||
New include directories are added by the `include_dirs` setting:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'existing_target',
|
||||
'include_dirs': [
|
||||
'..',
|
||||
'include',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
These may be specified directly in a target's settings, as in the above
|
||||
example, or in a `conditions` section.
|
||||
|
||||
#### Add new compiler flags
|
||||
|
||||
Specific compiler flags can be added with the `cflags` setting:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'existing_target',
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'cflags': [
|
||||
'/WX',
|
||||
],
|
||||
}, { # OS != "win"
|
||||
'cflags': [
|
||||
'-Werror',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
Because these flags will be specific to the actual compiler involved,
|
||||
they will almost always be only set within a `conditions` section.
|
||||
|
||||
#### Add new linker flags
|
||||
|
||||
Setting linker flags is OS-specific. On linux and most non-mac posix
|
||||
systems, they can be added with the `ldflags` setting:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'existing_target',
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'ldflags': [
|
||||
'-pthread',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
Because these flags will be specific to the actual linker involved,
|
||||
they will almost always be only set within a `conditions` section.
|
||||
|
||||
On OS X, linker settings are set via `xcode_settings`, on Windows via
|
||||
`msvs_settings`.
|
||||
|
||||
#### Exclude settings on a platform
|
||||
|
||||
Any given settings keyword (`defines`, `include_dirs`, etc.) has a
|
||||
corresponding form with a trailing `!` (exclamation point) to remove
|
||||
values from a setting. One useful example of this is to remove the
|
||||
Linux `-Werror` flag from the global settings defined in
|
||||
`build/common.gypi`:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'third_party_target',
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'cflags!': [
|
||||
'-Werror',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
### Cross-compiling
|
||||
|
||||
GYP has some (relatively limited) support for cross-compiling.
|
||||
|
||||
If the variable `GYP_CROSSCOMPILE` or one of the toolchain-related
|
||||
variables (like `CC_host` or `CC_target`) is set, GYP will think that
|
||||
you wish to do a cross-compile.
|
||||
|
||||
When cross-compiling, each target can be part of a "host" build, a
|
||||
"target" build, or both. By default, the target is assumed to be (only)
|
||||
part of the "target" build. The 'toolsets' property can be set on a
|
||||
target to change the default.
|
||||
|
||||
A target's dependencies are assumed to match the build type (so, if A
|
||||
depends on B, by default that means that a target build of A depends on
|
||||
a target build of B). You can explicitly depend on targets across
|
||||
toolchains by specifying "#host" or "#target" in the dependencies list.
|
||||
If GYP is not doing a cross-compile, the "#host" and "#target" will be
|
||||
stripped as needed, so nothing breaks.
|
||||
|
||||
### Add a new library
|
||||
|
||||
TODO: write intro
|
||||
|
||||
#### Add a library that builds on all platforms
|
||||
|
||||
Add the a dictionary defining the new library target to the `targets`
|
||||
list in the appropriate `.gyp` file. Example:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'new_library',
|
||||
'type': '<(library)',
|
||||
'defines': [
|
||||
'FOO',
|
||||
'BAR=some_value',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'dependencies': [
|
||||
'other_target_in_this_file',
|
||||
'other_gyp2:target_in_other_gyp2',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': '.',
|
||||
},
|
||||
'export_dependent_settings': [
|
||||
'other_target_in_this_file',
|
||||
],
|
||||
'sources': [
|
||||
'new_additional_source.cc',
|
||||
'new_library.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The use of the `<(library)` variable above should be the default `type`
|
||||
setting for most library targets, as it allows the developer to choose,
|
||||
at `gyp` time, whether to build with static or shared libraries.
|
||||
(Building with shared libraries saves a _lot_ of link time on Linux.)
|
||||
|
||||
It may be necessary to build a specific library as a fixed type. Is so,
|
||||
the `type` field can be hard-wired appropriately. For a static library:
|
||||
|
||||
```
|
||||
'type': 'static_library',
|
||||
```
|
||||
|
||||
For a shared library:
|
||||
|
||||
```
|
||||
'type': 'shared_library',
|
||||
```
|
||||
|
||||
#### Add a platform-specific library
|
||||
|
||||
Add a dictionary defining the new library target to the `targets` list
|
||||
within a `conditions` block that's a sibling to the top-level `targets`
|
||||
list:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'new_library',
|
||||
'type': '<(library)',
|
||||
'defines': [
|
||||
'FOO',
|
||||
'BAR=some_value',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'dependencies': [
|
||||
'other_target_in_this_file',
|
||||
'other_gyp2:target_in_other_gyp2',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': '.',
|
||||
},
|
||||
'export_dependent_settings': [
|
||||
'other_target_in_this_file',
|
||||
],
|
||||
'sources': [
|
||||
'new_additional_source.cc',
|
||||
'new_library.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Dependencies between targets
|
||||
|
||||
GYP provides useful primitives for establishing dependencies between
|
||||
targets, which need to be configured in the following situations.
|
||||
|
||||
#### Linking with another library target
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'dependencies': [
|
||||
'libbar',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'libbar',
|
||||
'type': '<(library)',
|
||||
'sources': [
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Note that if the library target is in a different `.gyp` file, you have
|
||||
to specify the path to other `.gyp` file, relative to this `.gyp` file's
|
||||
directory:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'dependencies': [
|
||||
'../bar/bar.gyp:libbar',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Adding a library often involves updating multiple `.gyp` files, adding
|
||||
the target to the appropriate `.gyp` file (possibly a newly-added `.gyp`
|
||||
file), and updating targets in the other `.gyp` files that depend on
|
||||
(link with) the new library.
|
||||
|
||||
#### Compiling with necessary flags for a library target dependency
|
||||
|
||||
We need to build a library (often a third-party library) with specific
|
||||
preprocessor definitions or command-line flags, and need to ensure that
|
||||
targets that depend on the library build with the same settings. This
|
||||
situation is handled by a `direct_dependent_settings` block:
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'libbar',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'libbar',
|
||||
'type': '<(library)',
|
||||
'defines': [
|
||||
'LOCAL_DEFINE_FOR_LIBBAR',
|
||||
'DEFINE_TO_USE_LIBBAR',
|
||||
],
|
||||
'include_dirs': [
|
||||
'..',
|
||||
'include/libbar',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'DEFINE_TO_USE_LIBBAR',
|
||||
],
|
||||
'include_dirs': [
|
||||
'include/libbar',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, the sources of the `foo` executable will be
|
||||
compiled with the options `-DDEFINE_TO_USE_LIBBAR -Iinclude/libbar`,
|
||||
because of those settings' being listed in the
|
||||
`direct_dependent_settings` block.
|
||||
|
||||
Note that these settings will likely need to be replicated in the
|
||||
settings for the library target itself, so that the library will build
|
||||
with the same options. This does not prevent the target from defining
|
||||
additional options for its "internal" use when compiling its own source
|
||||
files. (In the above example, these are the `LOCAL_DEFINE_FOR_LIBBAR`
|
||||
define, and the `..` entry in the `include_dirs` list.)
|
||||
|
||||
#### When a library depends on an additional library at final link time
|
||||
|
||||
```
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'foo',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'libbar',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'libbar',
|
||||
'type': '<(library)',
|
||||
'dependencies': [
|
||||
'libother'
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'libother'
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'libother',
|
||||
'type': '<(library)',
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'DEFINE_FOR_LIBOTHER',
|
||||
],
|
||||
'include_dirs': [
|
||||
'include/libother',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Support for Mac OS X bundles
|
||||
|
||||
gyp supports building bundles on OS X (.app, .framework, .bundle, etc).
|
||||
Here is an example of this:
|
||||
|
||||
```
|
||||
{
|
||||
'target_name': 'test_app',
|
||||
'product_name': 'Test App Gyp',
|
||||
'type': 'executable',
|
||||
'mac_bundle': 1,
|
||||
'sources': [
|
||||
'main.m',
|
||||
'TestAppAppDelegate.h',
|
||||
'TestAppAppDelegate.m',
|
||||
],
|
||||
'mac_bundle_resources': [
|
||||
'TestApp/English.lproj/InfoPlist.strings',
|
||||
'TestApp/English.lproj/MainMenu.xib',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
|
||||
],
|
||||
},
|
||||
'xcode_settings': {
|
||||
'INFOPLIST_FILE': 'TestApp/TestApp-Info.plist',
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
The `mac_bundle` key tells gyp that this target should be a bundle.
|
||||
`executable` targets get extension `.app` by default, `shared_library`
|
||||
targets get `.framework` – but you can change the bundle extensions by
|
||||
setting `product_extension` if you want. Files listed in
|
||||
`mac_bundle_resources` will be copied to the bundle's `Resource` folder
|
||||
of the bundle. You can also set
|
||||
`process_outputs_as_mac_bundle_resources` to 1 in actions and rules to
|
||||
let the output of actions and rules be added to that folder (similar to
|
||||
`process_outputs_as_sources`). If `product_name` is not set, the bundle
|
||||
will be named after `target_name`as usual.
|
||||
|
||||
### Move files (refactoring)
|
||||
|
||||
TODO
|
||||
|
||||
### Custom build steps
|
||||
|
||||
TODO
|
||||
|
||||
#### Adding an explicit build step to generate specific files
|
||||
|
||||
TODO
|
||||
|
||||
#### Adding a rule to handle files with a new suffix
|
||||
|
||||
TODO
|
||||
|
||||
### Build flavors
|
||||
|
||||
TODO
|
||||
2
electron/node_modules/node-gyp/gyp/gyp_main.py
generated
vendored
2
electron/node_modules/node-gyp/gyp/gyp_main.py
generated
vendored
|
|
@ -5,8 +5,8 @@
|
|||
# found in the LICENSE file.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def IsCygwin():
|
||||
|
|
|
|||
120
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py
generated
vendored
120
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py
generated
vendored
|
|
@ -32,20 +32,20 @@ ENTRY_TYPE_GUIDS = {
|
|||
def MakeGuid(name, seed="msvs_new"):
|
||||
"""Returns a GUID for the specified target name.
|
||||
|
||||
Args:
|
||||
name: Target name.
|
||||
seed: Seed for MD5 hash.
|
||||
Returns:
|
||||
A GUID-line string calculated from the name and seed.
|
||||
Args:
|
||||
name: Target name.
|
||||
seed: Seed for SHA-256 hash.
|
||||
Returns:
|
||||
A GUID-line string calculated from the name and seed.
|
||||
|
||||
This generates something which looks like a GUID, but depends only on the
|
||||
name and seed. This means the same name/seed will always generate the same
|
||||
GUID, so that projects and solutions which refer to each other can explicitly
|
||||
determine the GUID to refer to explicitly. It also means that the GUID will
|
||||
not change when the project for a target is rebuilt.
|
||||
"""
|
||||
# Calculate a MD5 signature for the seed and name.
|
||||
d = hashlib.md5((str(seed) + str(name)).encode("utf-8")).hexdigest().upper()
|
||||
This generates something which looks like a GUID, but depends only on the
|
||||
name and seed. This means the same name/seed will always generate the same
|
||||
GUID, so that projects and solutions which refer to each other can explicitly
|
||||
determine the GUID to refer to explicitly. It also means that the GUID will
|
||||
not change when the project for a target is rebuilt.
|
||||
"""
|
||||
# Calculate a SHA-256 signature for the seed and name.
|
||||
d = hashlib.sha256((str(seed) + str(name)).encode("utf-8")).hexdigest().upper()
|
||||
# Convert most of the signature to GUID form (discard the rest)
|
||||
guid = (
|
||||
"{"
|
||||
|
|
@ -78,15 +78,15 @@ class MSVSFolder(MSVSSolutionEntry):
|
|||
def __init__(self, path, name=None, entries=None, guid=None, items=None):
|
||||
"""Initializes the folder.
|
||||
|
||||
Args:
|
||||
path: Full path to the folder.
|
||||
name: Name of the folder.
|
||||
entries: List of folder entries to nest inside this folder. May contain
|
||||
Folder or Project objects. May be None, if the folder is empty.
|
||||
guid: GUID to use for folder, if not None.
|
||||
items: List of solution items to include in the folder project. May be
|
||||
None, if the folder does not directly contain items.
|
||||
"""
|
||||
Args:
|
||||
path: Full path to the folder.
|
||||
name: Name of the folder.
|
||||
entries: List of folder entries to nest inside this folder. May contain
|
||||
Folder or Project objects. May be None, if the folder is empty.
|
||||
guid: GUID to use for folder, if not None.
|
||||
items: List of solution items to include in the folder project. May be
|
||||
None, if the folder does not directly contain items.
|
||||
"""
|
||||
if name:
|
||||
self.name = name
|
||||
else:
|
||||
|
|
@ -128,19 +128,19 @@ class MSVSProject(MSVSSolutionEntry):
|
|||
):
|
||||
"""Initializes the project.
|
||||
|
||||
Args:
|
||||
path: Absolute path to the project file.
|
||||
name: Name of project. If None, the name will be the same as the base
|
||||
name of the project file.
|
||||
dependencies: List of other Project objects this project is dependent
|
||||
upon, if not None.
|
||||
guid: GUID to use for project, if not None.
|
||||
spec: Dictionary specifying how to build this project.
|
||||
build_file: Filename of the .gyp file that the vcproj file comes from.
|
||||
config_platform_overrides: optional dict of configuration platforms to
|
||||
used in place of the default for this target.
|
||||
fixpath_prefix: the path used to adjust the behavior of _fixpath
|
||||
"""
|
||||
Args:
|
||||
path: Absolute path to the project file.
|
||||
name: Name of project. If None, the name will be the same as the base
|
||||
name of the project file.
|
||||
dependencies: List of other Project objects this project is dependent
|
||||
upon, if not None.
|
||||
guid: GUID to use for project, if not None.
|
||||
spec: Dictionary specifying how to build this project.
|
||||
build_file: Filename of the .gyp file that the vcproj file comes from.
|
||||
config_platform_overrides: optional dict of configuration platforms to
|
||||
used in place of the default for this target.
|
||||
fixpath_prefix: the path used to adjust the behavior of _fixpath
|
||||
"""
|
||||
self.path = path
|
||||
self.guid = guid
|
||||
self.spec = spec
|
||||
|
|
@ -195,16 +195,16 @@ class MSVSSolution:
|
|||
):
|
||||
"""Initializes the solution.
|
||||
|
||||
Args:
|
||||
path: Path to solution file.
|
||||
version: Format version to emit.
|
||||
entries: List of entries in solution. May contain Folder or Project
|
||||
objects. May be None, if the folder is empty.
|
||||
variants: List of build variant strings. If none, a default list will
|
||||
be used.
|
||||
websiteProperties: Flag to decide if the website properties section
|
||||
is generated.
|
||||
"""
|
||||
Args:
|
||||
path: Path to solution file.
|
||||
version: Format version to emit.
|
||||
entries: List of entries in solution. May contain Folder or Project
|
||||
objects. May be None, if the folder is empty.
|
||||
variants: List of build variant strings. If none, a default list will
|
||||
be used.
|
||||
websiteProperties: Flag to decide if the website properties section
|
||||
is generated.
|
||||
"""
|
||||
self.path = path
|
||||
self.websiteProperties = websiteProperties
|
||||
self.version = version
|
||||
|
|
@ -230,9 +230,9 @@ class MSVSSolution:
|
|||
def Write(self, writer=gyp.common.WriteOnDiff):
|
||||
"""Writes the solution file to disk.
|
||||
|
||||
Raises:
|
||||
IndexError: An entry appears multiple times.
|
||||
"""
|
||||
Raises:
|
||||
IndexError: An entry appears multiple times.
|
||||
"""
|
||||
# Walk the entry tree and collect all the folders and projects.
|
||||
all_entries = set()
|
||||
entries_to_check = self.entries[:]
|
||||
|
|
@ -285,19 +285,17 @@ class MSVSSolution:
|
|||
"\tEndProjectSection\r\n"
|
||||
)
|
||||
|
||||
if isinstance(e, MSVSFolder):
|
||||
if e.items:
|
||||
f.write("\tProjectSection(SolutionItems) = preProject\r\n")
|
||||
for i in e.items:
|
||||
f.write(f"\t\t{i} = {i}\r\n")
|
||||
f.write("\tEndProjectSection\r\n")
|
||||
if isinstance(e, MSVSFolder) and e.items:
|
||||
f.write("\tProjectSection(SolutionItems) = preProject\r\n")
|
||||
for i in e.items:
|
||||
f.write(f"\t\t{i} = {i}\r\n")
|
||||
f.write("\tEndProjectSection\r\n")
|
||||
|
||||
if isinstance(e, MSVSProject):
|
||||
if e.dependencies:
|
||||
f.write("\tProjectSection(ProjectDependencies) = postProject\r\n")
|
||||
for d in e.dependencies:
|
||||
f.write(f"\t\t{d.get_guid()} = {d.get_guid()}\r\n")
|
||||
f.write("\tEndProjectSection\r\n")
|
||||
if isinstance(e, MSVSProject) and e.dependencies:
|
||||
f.write("\tProjectSection(ProjectDependencies) = postProject\r\n")
|
||||
for d in e.dependencies:
|
||||
f.write(f"\t\t{d.get_guid()} = {d.get_guid()}\r\n")
|
||||
f.write("\tEndProjectSection\r\n")
|
||||
|
||||
f.write("EndProject\r\n")
|
||||
|
||||
|
|
@ -353,7 +351,7 @@ class MSVSSolution:
|
|||
|
||||
# Folder mappings
|
||||
# Omit this section if there are no folders
|
||||
if any([e.entries for e in all_entries if isinstance(e, MSVSFolder)]):
|
||||
if any(e.entries for e in all_entries if isinstance(e, MSVSFolder)):
|
||||
f.write("\tGlobalSection(NestedProjects) = preSolution\r\n")
|
||||
for e in all_entries:
|
||||
if not isinstance(e, MSVSFolder):
|
||||
|
|
|
|||
108
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py
generated
vendored
108
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"""Visual Studio project reader/writer."""
|
||||
|
||||
import gyp.easy_xml as easy_xml
|
||||
from gyp import easy_xml
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -15,19 +15,19 @@ class Tool:
|
|||
def __init__(self, name, attrs=None):
|
||||
"""Initializes the tool.
|
||||
|
||||
Args:
|
||||
name: Tool name.
|
||||
attrs: Dict of tool attributes; may be None.
|
||||
"""
|
||||
Args:
|
||||
name: Tool name.
|
||||
attrs: Dict of tool attributes; may be None.
|
||||
"""
|
||||
self._attrs = attrs or {}
|
||||
self._attrs["Name"] = name
|
||||
|
||||
def _GetSpecification(self):
|
||||
"""Creates an element for the tool.
|
||||
|
||||
Returns:
|
||||
A new xml.dom.Element for the tool.
|
||||
"""
|
||||
Returns:
|
||||
A new xml.dom.Element for the tool.
|
||||
"""
|
||||
return ["Tool", self._attrs]
|
||||
|
||||
|
||||
|
|
@ -37,10 +37,10 @@ class Filter:
|
|||
def __init__(self, name, contents=None):
|
||||
"""Initializes the folder.
|
||||
|
||||
Args:
|
||||
name: Filter (folder) name.
|
||||
contents: List of filenames and/or Filter objects contained.
|
||||
"""
|
||||
Args:
|
||||
name: Filter (folder) name.
|
||||
contents: List of filenames and/or Filter objects contained.
|
||||
"""
|
||||
self.name = name
|
||||
self.contents = list(contents or [])
|
||||
|
||||
|
|
@ -54,13 +54,13 @@ class Writer:
|
|||
def __init__(self, project_path, version, name, guid=None, platforms=None):
|
||||
"""Initializes the project.
|
||||
|
||||
Args:
|
||||
project_path: Path to the project file.
|
||||
version: Format version to emit.
|
||||
name: Name of the project.
|
||||
guid: GUID to use for project, if not None.
|
||||
platforms: Array of string, the supported platforms. If null, ['Win32']
|
||||
"""
|
||||
Args:
|
||||
project_path: Path to the project file.
|
||||
version: Format version to emit.
|
||||
name: Name of the project.
|
||||
guid: GUID to use for project, if not None.
|
||||
platforms: Array of string, the supported platforms. If null, ['Win32']
|
||||
"""
|
||||
self.project_path = project_path
|
||||
self.version = version
|
||||
self.name = name
|
||||
|
|
@ -79,26 +79,26 @@ class Writer:
|
|||
self.files_section = ["Files"]
|
||||
|
||||
# Keep a dict keyed on filename to speed up access.
|
||||
self.files_dict = dict()
|
||||
self.files_dict = {}
|
||||
|
||||
def AddToolFile(self, path):
|
||||
"""Adds a tool file to the project.
|
||||
|
||||
Args:
|
||||
path: Relative path from project to tool file.
|
||||
"""
|
||||
Args:
|
||||
path: Relative path from project to tool file.
|
||||
"""
|
||||
self.tool_files_section.append(["ToolFile", {"RelativePath": path}])
|
||||
|
||||
def _GetSpecForConfiguration(self, config_type, config_name, attrs, tools):
|
||||
"""Returns the specification for a configuration.
|
||||
|
||||
Args:
|
||||
config_type: Type of configuration node.
|
||||
config_name: Configuration name.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
Returns:
|
||||
"""
|
||||
Args:
|
||||
config_type: Type of configuration node.
|
||||
config_name: Configuration name.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
Returns:
|
||||
"""
|
||||
# Handle defaults
|
||||
if not attrs:
|
||||
attrs = {}
|
||||
|
|
@ -122,23 +122,23 @@ class Writer:
|
|||
def AddConfig(self, name, attrs=None, tools=None):
|
||||
"""Adds a configuration to the project.
|
||||
|
||||
Args:
|
||||
name: Configuration name.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
"""
|
||||
Args:
|
||||
name: Configuration name.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
"""
|
||||
spec = self._GetSpecForConfiguration("Configuration", name, attrs, tools)
|
||||
self.configurations_section.append(spec)
|
||||
|
||||
def _AddFilesToNode(self, parent, files):
|
||||
"""Adds files and/or filters to the parent node.
|
||||
|
||||
Args:
|
||||
parent: Destination node
|
||||
files: A list of Filter objects and/or relative paths to files.
|
||||
Args:
|
||||
parent: Destination node
|
||||
files: A list of Filter objects and/or relative paths to files.
|
||||
|
||||
Will call itself recursively, if the files list contains Filter objects.
|
||||
"""
|
||||
Will call itself recursively, if the files list contains Filter objects.
|
||||
"""
|
||||
for f in files:
|
||||
if isinstance(f, Filter):
|
||||
node = ["Filter", {"Name": f.name}]
|
||||
|
|
@ -151,13 +151,13 @@ class Writer:
|
|||
def AddFiles(self, files):
|
||||
"""Adds files to the project.
|
||||
|
||||
Args:
|
||||
files: A list of Filter objects and/or relative paths to files.
|
||||
Args:
|
||||
files: A list of Filter objects and/or relative paths to files.
|
||||
|
||||
This makes a copy of the file/filter tree at the time of this call. If you
|
||||
later add files to a Filter object which was passed into a previous call
|
||||
to AddFiles(), it will not be reflected in this project.
|
||||
"""
|
||||
This makes a copy of the file/filter tree at the time of this call. If you
|
||||
later add files to a Filter object which was passed into a previous call
|
||||
to AddFiles(), it will not be reflected in this project.
|
||||
"""
|
||||
self._AddFilesToNode(self.files_section, files)
|
||||
# TODO(rspangler) This also doesn't handle adding files to an existing
|
||||
# filter. That is, it doesn't merge the trees.
|
||||
|
|
@ -165,15 +165,15 @@ class Writer:
|
|||
def AddFileConfig(self, path, config, attrs=None, tools=None):
|
||||
"""Adds a configuration to a file.
|
||||
|
||||
Args:
|
||||
path: Relative path to the file.
|
||||
config: Name of configuration to add.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
Args:
|
||||
path: Relative path to the file.
|
||||
config: Name of configuration to add.
|
||||
attrs: Dict of configuration attributes; may be None.
|
||||
tools: List of tools (strings or Tool objects); may be None.
|
||||
|
||||
Raises:
|
||||
ValueError: Relative path does not match any file added via AddFiles().
|
||||
"""
|
||||
Raises:
|
||||
ValueError: Relative path does not match any file added via AddFiles().
|
||||
"""
|
||||
# Find the file node with the right relative path
|
||||
parent = self.files_dict.get(path)
|
||||
if not parent:
|
||||
|
|
|
|||
245
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py
generated
vendored
245
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py
generated
vendored
|
|
@ -35,10 +35,10 @@ _msbuild_name_of_tool = {}
|
|||
class _Tool:
|
||||
"""Represents a tool used by MSVS or MSBuild.
|
||||
|
||||
Attributes:
|
||||
msvs_name: The name of the tool in MSVS.
|
||||
msbuild_name: The name of the tool in MSBuild.
|
||||
"""
|
||||
Attributes:
|
||||
msvs_name: The name of the tool in MSVS.
|
||||
msbuild_name: The name of the tool in MSBuild.
|
||||
"""
|
||||
|
||||
def __init__(self, msvs_name, msbuild_name):
|
||||
self.msvs_name = msvs_name
|
||||
|
|
@ -48,11 +48,11 @@ class _Tool:
|
|||
def _AddTool(tool):
|
||||
"""Adds a tool to the four dictionaries used to process settings.
|
||||
|
||||
This only defines the tool. Each setting also needs to be added.
|
||||
This only defines the tool. Each setting also needs to be added.
|
||||
|
||||
Args:
|
||||
tool: The _Tool object to be added.
|
||||
"""
|
||||
Args:
|
||||
tool: The _Tool object to be added.
|
||||
"""
|
||||
_msvs_validators[tool.msvs_name] = {}
|
||||
_msbuild_validators[tool.msbuild_name] = {}
|
||||
_msvs_to_msbuild_converters[tool.msvs_name] = {}
|
||||
|
|
@ -70,35 +70,35 @@ class _Type:
|
|||
def ValidateMSVS(self, value):
|
||||
"""Verifies that the value is legal for MSVS.
|
||||
|
||||
Args:
|
||||
value: the value to check for this type.
|
||||
Args:
|
||||
value: the value to check for this type.
|
||||
|
||||
Raises:
|
||||
ValueError if value is not valid for MSVS.
|
||||
"""
|
||||
Raises:
|
||||
ValueError if value is not valid for MSVS.
|
||||
"""
|
||||
|
||||
def ValidateMSBuild(self, value):
|
||||
"""Verifies that the value is legal for MSBuild.
|
||||
|
||||
Args:
|
||||
value: the value to check for this type.
|
||||
Args:
|
||||
value: the value to check for this type.
|
||||
|
||||
Raises:
|
||||
ValueError if value is not valid for MSBuild.
|
||||
"""
|
||||
Raises:
|
||||
ValueError if value is not valid for MSBuild.
|
||||
"""
|
||||
|
||||
def ConvertToMSBuild(self, value):
|
||||
"""Returns the MSBuild equivalent of the MSVS value given.
|
||||
|
||||
Args:
|
||||
value: the MSVS value to convert.
|
||||
Args:
|
||||
value: the MSVS value to convert.
|
||||
|
||||
Returns:
|
||||
the MSBuild equivalent.
|
||||
Returns:
|
||||
the MSBuild equivalent.
|
||||
|
||||
Raises:
|
||||
ValueError if value is not valid.
|
||||
"""
|
||||
Raises:
|
||||
ValueError if value is not valid.
|
||||
"""
|
||||
return value
|
||||
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ class _Boolean(_Type):
|
|||
"""Boolean settings, can have the values 'false' or 'true'."""
|
||||
|
||||
def _Validate(self, value):
|
||||
if value != "true" and value != "false":
|
||||
if value not in {"true", "false"}:
|
||||
raise ValueError("expected bool; got %r" % value)
|
||||
|
||||
def ValidateMSVS(self, value):
|
||||
|
|
@ -171,22 +171,22 @@ class _Integer(_Type):
|
|||
int(value, self._msbuild_base)
|
||||
|
||||
def ConvertToMSBuild(self, value):
|
||||
msbuild_format = (self._msbuild_base == 10) and "%d" or "0x%04x"
|
||||
msbuild_format = ((self._msbuild_base == 10) and "%d") or "0x%04x"
|
||||
return msbuild_format % int(value)
|
||||
|
||||
|
||||
class _Enumeration(_Type):
|
||||
"""Type of settings that is an enumeration.
|
||||
|
||||
In MSVS, the values are indexes like '0', '1', and '2'.
|
||||
MSBuild uses text labels that are more representative, like 'Win32'.
|
||||
In MSVS, the values are indexes like '0', '1', and '2'.
|
||||
MSBuild uses text labels that are more representative, like 'Win32'.
|
||||
|
||||
Constructor args:
|
||||
label_list: an array of MSBuild labels that correspond to the MSVS index.
|
||||
In the rare cases where MSVS has skipped an index value, None is
|
||||
used in the array to indicate the unused spot.
|
||||
new: an array of labels that are new to MSBuild.
|
||||
"""
|
||||
Constructor args:
|
||||
label_list: an array of MSBuild labels that correspond to the MSVS index.
|
||||
In the rare cases where MSVS has skipped an index value, None is
|
||||
used in the array to indicate the unused spot.
|
||||
new: an array of labels that are new to MSBuild.
|
||||
"""
|
||||
|
||||
def __init__(self, label_list, new=None):
|
||||
_Type.__init__(self)
|
||||
|
|
@ -234,23 +234,23 @@ _newly_boolean = _Enumeration(["", "false", "true"])
|
|||
def _Same(tool, name, setting_type):
|
||||
"""Defines a setting that has the same name in MSVS and MSBuild.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
_Renamed(tool, name, name, setting_type)
|
||||
|
||||
|
||||
def _Renamed(tool, msvs_name, msbuild_name, setting_type):
|
||||
"""Defines a setting for which the name has changed.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_name: the name of the MSVS setting.
|
||||
msbuild_name: the name of the MSBuild setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_name: the name of the MSVS setting.
|
||||
msbuild_name: the name of the MSBuild setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
|
||||
def _Translate(value, msbuild_settings):
|
||||
msbuild_tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool)
|
||||
|
|
@ -272,13 +272,13 @@ def _MovedAndRenamed(
|
|||
):
|
||||
"""Defines a setting that may have moved to a new section.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_settings_name: the MSVS name of the setting.
|
||||
msbuild_tool_name: the name of the MSBuild tool to place the setting under.
|
||||
msbuild_settings_name: the MSBuild name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_settings_name: the MSVS name of the setting.
|
||||
msbuild_tool_name: the name of the MSBuild tool to place the setting under.
|
||||
msbuild_settings_name: the MSBuild name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
|
||||
def _Translate(value, msbuild_settings):
|
||||
tool_settings = msbuild_settings.setdefault(msbuild_tool_name, {})
|
||||
|
|
@ -293,11 +293,11 @@ def _MovedAndRenamed(
|
|||
def _MSVSOnly(tool, name, setting_type):
|
||||
"""Defines a setting that is only found in MSVS.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
|
||||
def _Translate(unused_value, unused_msbuild_settings):
|
||||
# Since this is for MSVS only settings, no translation will happen.
|
||||
|
|
@ -310,11 +310,11 @@ def _MSVSOnly(tool, name, setting_type):
|
|||
def _MSBuildOnly(tool, name, setting_type):
|
||||
"""Defines a setting that is only found in MSBuild.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
name: the name of the setting.
|
||||
setting_type: the type of this setting.
|
||||
"""
|
||||
|
||||
def _Translate(value, msbuild_settings):
|
||||
# Let msbuild-only properties get translated as-is from msvs_settings.
|
||||
|
|
@ -328,11 +328,11 @@ def _MSBuildOnly(tool, name, setting_type):
|
|||
def _ConvertedToAdditionalOption(tool, msvs_name, flag):
|
||||
"""Defines a setting that's handled via a command line option in MSBuild.
|
||||
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_name: the name of the MSVS setting that if 'true' becomes a flag
|
||||
flag: the flag to insert at the end of the AdditionalOptions
|
||||
"""
|
||||
Args:
|
||||
tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
|
||||
msvs_name: the name of the MSVS setting that if 'true' becomes a flag
|
||||
flag: the flag to insert at the end of the AdditionalOptions
|
||||
"""
|
||||
|
||||
def _Translate(value, msbuild_settings):
|
||||
if value == "true":
|
||||
|
|
@ -384,20 +384,19 @@ _EXCLUDED_SUFFIX_RE = re.compile("^(.*)_excluded$")
|
|||
def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr):
|
||||
"""Verify that 'setting' is valid if it is generated from an exclusion list.
|
||||
|
||||
If the setting appears to be generated from an exclusion list, the root name
|
||||
is checked.
|
||||
If the setting appears to be generated from an exclusion list, the root name
|
||||
is checked.
|
||||
|
||||
Args:
|
||||
setting: A string that is the setting name to validate
|
||||
settings: A dictionary where the keys are valid settings
|
||||
error_msg: The message to emit in the event of error
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
Args:
|
||||
setting: A string that is the setting name to validate
|
||||
settings: A dictionary where the keys are valid settings
|
||||
error_msg: The message to emit in the event of error
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
# This may be unrecognized because it's an exclusion list. If the
|
||||
# setting name has the _excluded suffix, then check the root name.
|
||||
unrecognized = True
|
||||
m = re.match(_EXCLUDED_SUFFIX_RE, setting)
|
||||
if m:
|
||||
if m := re.match(_EXCLUDED_SUFFIX_RE, setting):
|
||||
root_setting = m.group(1)
|
||||
unrecognized = root_setting not in settings
|
||||
|
||||
|
|
@ -409,11 +408,11 @@ def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr):
|
|||
def FixVCMacroSlashes(s):
|
||||
"""Replace macros which have excessive following slashes.
|
||||
|
||||
These macros are known to have a built-in trailing slash. Furthermore, many
|
||||
scripts hiccup on processing paths with extra slashes in the middle.
|
||||
These macros are known to have a built-in trailing slash. Furthermore, many
|
||||
scripts hiccup on processing paths with extra slashes in the middle.
|
||||
|
||||
This list is probably not exhaustive. Add as needed.
|
||||
"""
|
||||
This list is probably not exhaustive. Add as needed.
|
||||
"""
|
||||
if "$" in s:
|
||||
s = fix_vc_macro_slashes_regex.sub(r"\1", s)
|
||||
return s
|
||||
|
|
@ -422,8 +421,8 @@ def FixVCMacroSlashes(s):
|
|||
def ConvertVCMacrosToMSBuild(s):
|
||||
"""Convert the MSVS macros found in the string to the MSBuild equivalent.
|
||||
|
||||
This list is probably not exhaustive. Add as needed.
|
||||
"""
|
||||
This list is probably not exhaustive. Add as needed.
|
||||
"""
|
||||
if "$" in s:
|
||||
replace_map = {
|
||||
"$(ConfigurationName)": "$(Configuration)",
|
||||
|
|
@ -445,16 +444,16 @@ def ConvertVCMacrosToMSBuild(s):
|
|||
def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr):
|
||||
"""Converts MSVS settings (VS2008 and earlier) to MSBuild settings (VS2010+).
|
||||
|
||||
Args:
|
||||
msvs_settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
Args:
|
||||
msvs_settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
|
||||
Returns:
|
||||
A dictionary of MSBuild settings. The key is either the MSBuild tool name
|
||||
or the empty string (for the global settings). The values are themselves
|
||||
dictionaries of settings and their values.
|
||||
"""
|
||||
Returns:
|
||||
A dictionary of MSBuild settings. The key is either the MSBuild tool name
|
||||
or the empty string (for the global settings). The values are themselves
|
||||
dictionaries of settings and their values.
|
||||
"""
|
||||
msbuild_settings = {}
|
||||
for msvs_tool_name, msvs_tool_settings in msvs_settings.items():
|
||||
if msvs_tool_name in _msvs_to_msbuild_converters:
|
||||
|
|
@ -493,36 +492,36 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr):
|
|||
def ValidateMSVSSettings(settings, stderr=sys.stderr):
|
||||
"""Validates that the names of the settings are valid for MSVS.
|
||||
|
||||
Args:
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
Args:
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
_ValidateSettings(_msvs_validators, settings, stderr)
|
||||
|
||||
|
||||
def ValidateMSBuildSettings(settings, stderr=sys.stderr):
|
||||
"""Validates that the names of the settings are valid for MSBuild.
|
||||
|
||||
Args:
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
Args:
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
_ValidateSettings(_msbuild_validators, settings, stderr)
|
||||
|
||||
|
||||
def _ValidateSettings(validators, settings, stderr):
|
||||
"""Validates that the settings are valid for MSBuild or MSVS.
|
||||
|
||||
We currently only validate the names of the settings, not their values.
|
||||
We currently only validate the names of the settings, not their values.
|
||||
|
||||
Args:
|
||||
validators: A dictionary of tools and their validators.
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
Args:
|
||||
validators: A dictionary of tools and their validators.
|
||||
settings: A dictionary. The key is the tool name. The values are
|
||||
themselves dictionaries of settings and their values.
|
||||
stderr: The stream receiving the error messages.
|
||||
"""
|
||||
for tool_name in settings:
|
||||
if tool_name in validators:
|
||||
tool_validators = validators[tool_name]
|
||||
|
|
@ -638,7 +637,9 @@ _Same(
|
|||
),
|
||||
) # /RTC1
|
||||
_Same(
|
||||
_compile, "BrowseInformation", _Enumeration(["false", "true", "true"]) # /FR
|
||||
_compile,
|
||||
"BrowseInformation",
|
||||
_Enumeration(["false", "true", "true"]), # /FR
|
||||
) # /Fr
|
||||
_Same(
|
||||
_compile,
|
||||
|
|
@ -696,7 +697,9 @@ _Same(
|
|||
_Enumeration(["false", "Sync", "Async"], new=["SyncCThrow"]), # /EHsc # /EHa
|
||||
) # /EHs
|
||||
_Same(
|
||||
_compile, "FavorSizeOrSpeed", _Enumeration(["Neither", "Speed", "Size"]) # /Ot
|
||||
_compile,
|
||||
"FavorSizeOrSpeed",
|
||||
_Enumeration(["Neither", "Speed", "Size"]), # /Ot
|
||||
) # /Os
|
||||
_Same(
|
||||
_compile,
|
||||
|
|
@ -793,6 +796,8 @@ _MSBuildOnly(
|
|||
_compile, "CompileAsManaged", _Enumeration([], new=["false", "true"])
|
||||
) # /clr
|
||||
_MSBuildOnly(_compile, "CreateHotpatchableImage", _boolean) # /hotpatch
|
||||
_MSBuildOnly(_compile, "LanguageStandard", _string)
|
||||
_MSBuildOnly(_compile, "LanguageStandard_C", _string)
|
||||
_MSBuildOnly(_compile, "MultiProcessorCompilation", _boolean) # /MP
|
||||
_MSBuildOnly(_compile, "PreprocessOutputPath", _string) # /Fi
|
||||
_MSBuildOnly(_compile, "ProcessorNumber", _integer) # the number of processors
|
||||
|
|
@ -907,7 +912,9 @@ _target_machine_enumeration = _Enumeration(
|
|||
) # /MACHINE:X64
|
||||
|
||||
_Same(
|
||||
_link, "AssemblyDebug", _Enumeration(["", "true", "false"]) # /ASSEMBLYDEBUG
|
||||
_link,
|
||||
"AssemblyDebug",
|
||||
_Enumeration(["", "true", "false"]), # /ASSEMBLYDEBUG
|
||||
) # /ASSEMBLYDEBUG:DISABLE
|
||||
_Same(
|
||||
_link,
|
||||
|
|
@ -1157,17 +1164,23 @@ _Renamed(_midl, "ValidateParameters", "ValidateAllParameters", _boolean) # /rob
|
|||
_MSBuildOnly(_midl, "ApplicationConfigurationMode", _boolean) # /app_config
|
||||
_MSBuildOnly(_midl, "ClientStubFile", _file_name) # /cstub
|
||||
_MSBuildOnly(
|
||||
_midl, "GenerateClientFiles", _Enumeration([], new=["Stub", "None"]) # /client stub
|
||||
_midl,
|
||||
"GenerateClientFiles",
|
||||
_Enumeration([], new=["Stub", "None"]), # /client stub
|
||||
) # /client none
|
||||
_MSBuildOnly(
|
||||
_midl, "GenerateServerFiles", _Enumeration([], new=["Stub", "None"]) # /client stub
|
||||
_midl,
|
||||
"GenerateServerFiles",
|
||||
_Enumeration([], new=["Stub", "None"]), # /client stub
|
||||
) # /client none
|
||||
_MSBuildOnly(_midl, "LocaleID", _integer) # /lcid DECIMAL
|
||||
_MSBuildOnly(_midl, "ServerStubFile", _file_name) # /sstub
|
||||
_MSBuildOnly(_midl, "SuppressCompilerWarnings", _boolean) # /no_warn
|
||||
_MSBuildOnly(_midl, "TrackerLogDirectory", _folder_name)
|
||||
_MSBuildOnly(
|
||||
_midl, "TypeLibFormat", _Enumeration([], new=["NewFormat", "OldFormat"]) # /newtlb
|
||||
_midl,
|
||||
"TypeLibFormat",
|
||||
_Enumeration([], new=["NewFormat", "OldFormat"]), # /newtlb
|
||||
) # /oldtlb
|
||||
|
||||
|
||||
|
|
|
|||
90
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py
generated
vendored
90
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py
generated
vendored
|
|
@ -7,10 +7,10 @@
|
|||
"""Unit tests for the MSVSSettings.py file."""
|
||||
|
||||
import unittest
|
||||
import gyp.MSVSSettings as MSVSSettings
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from gyp import MSVSSettings
|
||||
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
|
@ -1143,47 +1143,47 @@ class TestSequenceFunctions(unittest.TestCase):
|
|||
def testConvertToMSBuildSettings_actual(self):
|
||||
"""Tests the conversion of an actual project.
|
||||
|
||||
A VS2008 project with most of the options defined was created through the
|
||||
VS2008 IDE. It was then converted to VS2010. The tool settings found in
|
||||
the .vcproj and .vcxproj files were converted to the two dictionaries
|
||||
msvs_settings and expected_msbuild_settings.
|
||||
A VS2008 project with most of the options defined was created through the
|
||||
VS2008 IDE. It was then converted to VS2010. The tool settings found in
|
||||
the .vcproj and .vcxproj files were converted to the two dictionaries
|
||||
msvs_settings and expected_msbuild_settings.
|
||||
|
||||
Note that for many settings, the VS2010 converter adds macros like
|
||||
%(AdditionalIncludeDirectories) to make sure than inherited values are
|
||||
included. Since the Gyp projects we generate do not use inheritance,
|
||||
we removed these macros. They were:
|
||||
ClCompile:
|
||||
AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)'
|
||||
AdditionalOptions: ' %(AdditionalOptions)'
|
||||
AdditionalUsingDirectories: ';%(AdditionalUsingDirectories)'
|
||||
DisableSpecificWarnings: ';%(DisableSpecificWarnings)',
|
||||
ForcedIncludeFiles: ';%(ForcedIncludeFiles)',
|
||||
ForcedUsingFiles: ';%(ForcedUsingFiles)',
|
||||
PreprocessorDefinitions: ';%(PreprocessorDefinitions)',
|
||||
UndefinePreprocessorDefinitions:
|
||||
';%(UndefinePreprocessorDefinitions)',
|
||||
Link:
|
||||
AdditionalDependencies: ';%(AdditionalDependencies)',
|
||||
AdditionalLibraryDirectories: ';%(AdditionalLibraryDirectories)',
|
||||
AdditionalManifestDependencies:
|
||||
';%(AdditionalManifestDependencies)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
AddModuleNamesToAssembly: ';%(AddModuleNamesToAssembly)',
|
||||
AssemblyLinkResource: ';%(AssemblyLinkResource)',
|
||||
DelayLoadDLLs: ';%(DelayLoadDLLs)',
|
||||
EmbedManagedResourceFile: ';%(EmbedManagedResourceFile)',
|
||||
ForceSymbolReferences: ';%(ForceSymbolReferences)',
|
||||
IgnoreSpecificDefaultLibraries:
|
||||
';%(IgnoreSpecificDefaultLibraries)',
|
||||
ResourceCompile:
|
||||
AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
PreprocessorDefinitions: ';%(PreprocessorDefinitions)',
|
||||
Manifest:
|
||||
AdditionalManifestFiles: ';%(AdditionalManifestFiles)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
InputResourceManifests: ';%(InputResourceManifests)',
|
||||
"""
|
||||
Note that for many settings, the VS2010 converter adds macros like
|
||||
%(AdditionalIncludeDirectories) to make sure than inherited values are
|
||||
included. Since the Gyp projects we generate do not use inheritance,
|
||||
we removed these macros. They were:
|
||||
ClCompile:
|
||||
AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)'
|
||||
AdditionalOptions: ' %(AdditionalOptions)'
|
||||
AdditionalUsingDirectories: ';%(AdditionalUsingDirectories)'
|
||||
DisableSpecificWarnings: ';%(DisableSpecificWarnings)',
|
||||
ForcedIncludeFiles: ';%(ForcedIncludeFiles)',
|
||||
ForcedUsingFiles: ';%(ForcedUsingFiles)',
|
||||
PreprocessorDefinitions: ';%(PreprocessorDefinitions)',
|
||||
UndefinePreprocessorDefinitions:
|
||||
';%(UndefinePreprocessorDefinitions)',
|
||||
Link:
|
||||
AdditionalDependencies: ';%(AdditionalDependencies)',
|
||||
AdditionalLibraryDirectories: ';%(AdditionalLibraryDirectories)',
|
||||
AdditionalManifestDependencies:
|
||||
';%(AdditionalManifestDependencies)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
AddModuleNamesToAssembly: ';%(AddModuleNamesToAssembly)',
|
||||
AssemblyLinkResource: ';%(AssemblyLinkResource)',
|
||||
DelayLoadDLLs: ';%(DelayLoadDLLs)',
|
||||
EmbedManagedResourceFile: ';%(EmbedManagedResourceFile)',
|
||||
ForceSymbolReferences: ';%(ForceSymbolReferences)',
|
||||
IgnoreSpecificDefaultLibraries:
|
||||
';%(IgnoreSpecificDefaultLibraries)',
|
||||
ResourceCompile:
|
||||
AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
PreprocessorDefinitions: ';%(PreprocessorDefinitions)',
|
||||
Manifest:
|
||||
AdditionalManifestFiles: ';%(AdditionalManifestFiles)',
|
||||
AdditionalOptions: ' %(AdditionalOptions)',
|
||||
InputResourceManifests: ';%(InputResourceManifests)',
|
||||
"""
|
||||
msvs_settings = {
|
||||
"VCCLCompilerTool": {
|
||||
"AdditionalIncludeDirectories": "dir1",
|
||||
|
|
@ -1346,8 +1346,7 @@ class TestSequenceFunctions(unittest.TestCase):
|
|||
"EmbedManifest": "false",
|
||||
"GenerateCatalogFiles": "true",
|
||||
"InputResourceManifests": "asfsfdafs",
|
||||
"ManifestResourceFile":
|
||||
"$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf",
|
||||
"ManifestResourceFile": "$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf", # noqa: E501
|
||||
"OutputManifestFile": "$(TargetPath).manifestdfs",
|
||||
"RegistrarScriptFile": "sdfsfd",
|
||||
"ReplacementsFile": "sdffsd",
|
||||
|
|
@ -1531,8 +1530,7 @@ class TestSequenceFunctions(unittest.TestCase):
|
|||
"LinkIncremental": "",
|
||||
},
|
||||
"ManifestResourceCompile": {
|
||||
"ResourceOutputFileName":
|
||||
"$(IntDir)$(TargetFileName).embed.manifest.resfdsf"
|
||||
"ResourceOutputFileName": "$(IntDir)$(TargetFileName).embed.manifest.resfdsf" # noqa: E501
|
||||
},
|
||||
}
|
||||
self.maxDiff = 9999 # on failure display a long diff
|
||||
|
|
|
|||
26
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py
generated
vendored
26
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"""Visual Studio project reader/writer."""
|
||||
|
||||
import gyp.easy_xml as easy_xml
|
||||
from gyp import easy_xml
|
||||
|
||||
|
||||
class Writer:
|
||||
|
|
@ -13,10 +13,10 @@ class Writer:
|
|||
def __init__(self, tool_file_path, name):
|
||||
"""Initializes the tool file.
|
||||
|
||||
Args:
|
||||
tool_file_path: Path to the tool file.
|
||||
name: Name of the tool file.
|
||||
"""
|
||||
Args:
|
||||
tool_file_path: Path to the tool file.
|
||||
name: Name of the tool file.
|
||||
"""
|
||||
self.tool_file_path = tool_file_path
|
||||
self.name = name
|
||||
self.rules_section = ["Rules"]
|
||||
|
|
@ -26,14 +26,14 @@ class Writer:
|
|||
):
|
||||
"""Adds a rule to the tool file.
|
||||
|
||||
Args:
|
||||
name: Name of the rule.
|
||||
description: Description of the rule.
|
||||
cmd: Command line of the rule.
|
||||
additional_dependencies: other files which may trigger the rule.
|
||||
outputs: outputs of the rule.
|
||||
extensions: extensions handled by the rule.
|
||||
"""
|
||||
Args:
|
||||
name: Name of the rule.
|
||||
description: Description of the rule.
|
||||
cmd: Command line of the rule.
|
||||
additional_dependencies: other files which may trigger the rule.
|
||||
outputs: outputs of the rule.
|
||||
extensions: extensions handled by the rule.
|
||||
"""
|
||||
rule = [
|
||||
"CustomBuildRule",
|
||||
{
|
||||
|
|
|
|||
41
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py
generated
vendored
41
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py
generated
vendored
|
|
@ -8,19 +8,18 @@ import os
|
|||
import re
|
||||
import socket # for gethostname
|
||||
|
||||
import gyp.easy_xml as easy_xml
|
||||
|
||||
from gyp import easy_xml
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _FindCommandInPath(command):
|
||||
"""If there are no slashes in the command given, this function
|
||||
searches the PATH env to find the given command, and converts it
|
||||
to an absolute path. We have to do this because MSVS is looking
|
||||
for an actual file to launch a debugger on, not just a command
|
||||
line. Note that this happens at GYP time, so anything needing to
|
||||
be built needs to have a full path."""
|
||||
searches the PATH env to find the given command, and converts it
|
||||
to an absolute path. We have to do this because MSVS is looking
|
||||
for an actual file to launch a debugger on, not just a command
|
||||
line. Note that this happens at GYP time, so anything needing to
|
||||
be built needs to have a full path."""
|
||||
if "/" in command or "\\" in command:
|
||||
# If the command already has path elements (either relative or
|
||||
# absolute), then assume it is constructed properly.
|
||||
|
|
@ -59,11 +58,11 @@ class Writer:
|
|||
def __init__(self, user_file_path, version, name):
|
||||
"""Initializes the user file.
|
||||
|
||||
Args:
|
||||
user_file_path: Path to the user file.
|
||||
version: Version info.
|
||||
name: Name of the user file.
|
||||
"""
|
||||
Args:
|
||||
user_file_path: Path to the user file.
|
||||
version: Version info.
|
||||
name: Name of the user file.
|
||||
"""
|
||||
self.user_file_path = user_file_path
|
||||
self.version = version
|
||||
self.name = name
|
||||
|
|
@ -72,9 +71,9 @@ class Writer:
|
|||
def AddConfig(self, name):
|
||||
"""Adds a configuration to the project.
|
||||
|
||||
Args:
|
||||
name: Configuration name.
|
||||
"""
|
||||
Args:
|
||||
name: Configuration name.
|
||||
"""
|
||||
self.configurations[name] = ["Configuration", {"Name": name}]
|
||||
|
||||
def AddDebugSettings(
|
||||
|
|
@ -82,12 +81,12 @@ class Writer:
|
|||
):
|
||||
"""Adds a DebugSettings node to the user file for a particular config.
|
||||
|
||||
Args:
|
||||
command: command line to run. First element in the list is the
|
||||
executable. All elements of the command will be quoted if
|
||||
necessary.
|
||||
working_directory: other files which may trigger the rule. (optional)
|
||||
"""
|
||||
Args:
|
||||
command: command line to run. First element in the list is the
|
||||
executable. All elements of the command will be quoted if
|
||||
necessary.
|
||||
working_directory: other files which may trigger the rule. (optional)
|
||||
"""
|
||||
command = _QuoteWin32CommandLineArgs(command)
|
||||
|
||||
abs_command = _FindCommandInPath(command[0])
|
||||
|
|
|
|||
97
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py
generated
vendored
97
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py
generated
vendored
|
|
@ -7,7 +7,6 @@
|
|||
import copy
|
||||
import os
|
||||
|
||||
|
||||
# A dictionary mapping supported target types to extensions.
|
||||
TARGET_TYPE_EXT = {
|
||||
"executable": "exe",
|
||||
|
|
@ -30,13 +29,13 @@ def _GetLargePdbShimCcPath():
|
|||
def _DeepCopySomeKeys(in_dict, keys):
|
||||
"""Performs a partial deep-copy on |in_dict|, only copying the keys in |keys|.
|
||||
|
||||
Arguments:
|
||||
in_dict: The dictionary to copy.
|
||||
keys: The keys to be copied. If a key is in this list and doesn't exist in
|
||||
|in_dict| this is not an error.
|
||||
Returns:
|
||||
The partially deep-copied dictionary.
|
||||
"""
|
||||
Arguments:
|
||||
in_dict: The dictionary to copy.
|
||||
keys: The keys to be copied. If a key is in this list and doesn't exist in
|
||||
|in_dict| this is not an error.
|
||||
Returns:
|
||||
The partially deep-copied dictionary.
|
||||
"""
|
||||
d = {}
|
||||
for key in keys:
|
||||
if key not in in_dict:
|
||||
|
|
@ -48,12 +47,12 @@ def _DeepCopySomeKeys(in_dict, keys):
|
|||
def _SuffixName(name, suffix):
|
||||
"""Add a suffix to the end of a target.
|
||||
|
||||
Arguments:
|
||||
name: name of the target (foo#target)
|
||||
suffix: the suffix to be added
|
||||
Returns:
|
||||
Target name with suffix added (foo_suffix#target)
|
||||
"""
|
||||
Arguments:
|
||||
name: name of the target (foo#target)
|
||||
suffix: the suffix to be added
|
||||
Returns:
|
||||
Target name with suffix added (foo_suffix#target)
|
||||
"""
|
||||
parts = name.rsplit("#", 1)
|
||||
parts[0] = f"{parts[0]}_{suffix}"
|
||||
return "#".join(parts)
|
||||
|
|
@ -62,24 +61,24 @@ def _SuffixName(name, suffix):
|
|||
def _ShardName(name, number):
|
||||
"""Add a shard number to the end of a target.
|
||||
|
||||
Arguments:
|
||||
name: name of the target (foo#target)
|
||||
number: shard number
|
||||
Returns:
|
||||
Target name with shard added (foo_1#target)
|
||||
"""
|
||||
Arguments:
|
||||
name: name of the target (foo#target)
|
||||
number: shard number
|
||||
Returns:
|
||||
Target name with shard added (foo_1#target)
|
||||
"""
|
||||
return _SuffixName(name, str(number))
|
||||
|
||||
|
||||
def ShardTargets(target_list, target_dicts):
|
||||
"""Shard some targets apart to work around the linkers limits.
|
||||
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
Returns:
|
||||
Tuple of the new sharded versions of the inputs.
|
||||
"""
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
Returns:
|
||||
Tuple of the new sharded versions of the inputs.
|
||||
"""
|
||||
# Gather the targets to shard, and how many pieces.
|
||||
targets_to_shard = {}
|
||||
for t in target_dicts:
|
||||
|
|
@ -129,22 +128,22 @@ def ShardTargets(target_list, target_dicts):
|
|||
|
||||
def _GetPdbPath(target_dict, config_name, vars):
|
||||
"""Returns the path to the PDB file that will be generated by a given
|
||||
configuration.
|
||||
configuration.
|
||||
|
||||
The lookup proceeds as follows:
|
||||
- Look for an explicit path in the VCLinkerTool configuration block.
|
||||
- Look for an 'msvs_large_pdb_path' variable.
|
||||
- Use '<(PRODUCT_DIR)/<(product_name).(exe|dll).pdb' if 'product_name' is
|
||||
specified.
|
||||
- Use '<(PRODUCT_DIR)/<(target_name).(exe|dll).pdb'.
|
||||
The lookup proceeds as follows:
|
||||
- Look for an explicit path in the VCLinkerTool configuration block.
|
||||
- Look for an 'msvs_large_pdb_path' variable.
|
||||
- Use '<(PRODUCT_DIR)/<(product_name).(exe|dll).pdb' if 'product_name' is
|
||||
specified.
|
||||
- Use '<(PRODUCT_DIR)/<(target_name).(exe|dll).pdb'.
|
||||
|
||||
Arguments:
|
||||
target_dict: The target dictionary to be searched.
|
||||
config_name: The name of the configuration of interest.
|
||||
vars: A dictionary of common GYP variables with generator-specific values.
|
||||
Returns:
|
||||
The path of the corresponding PDB file.
|
||||
"""
|
||||
Arguments:
|
||||
target_dict: The target dictionary to be searched.
|
||||
config_name: The name of the configuration of interest.
|
||||
vars: A dictionary of common GYP variables with generator-specific values.
|
||||
Returns:
|
||||
The path of the corresponding PDB file.
|
||||
"""
|
||||
config = target_dict["configurations"][config_name]
|
||||
msvs = config.setdefault("msvs_settings", {})
|
||||
|
||||
|
|
@ -169,16 +168,16 @@ def _GetPdbPath(target_dict, config_name, vars):
|
|||
def InsertLargePdbShims(target_list, target_dicts, vars):
|
||||
"""Insert a shim target that forces the linker to use 4KB pagesize PDBs.
|
||||
|
||||
This is a workaround for targets with PDBs greater than 1GB in size, the
|
||||
limit for the 1KB pagesize PDBs created by the linker by default.
|
||||
This is a workaround for targets with PDBs greater than 1GB in size, the
|
||||
limit for the 1KB pagesize PDBs created by the linker by default.
|
||||
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
vars: A dictionary of common GYP variables with generator-specific values.
|
||||
Returns:
|
||||
Tuple of the shimmed version of the inputs.
|
||||
"""
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
vars: A dictionary of common GYP variables with generator-specific values.
|
||||
Returns:
|
||||
Tuple of the shimmed version of the inputs.
|
||||
"""
|
||||
# Determine which targets need shimming.
|
||||
targets_to_shim = []
|
||||
for t in target_dicts:
|
||||
|
|
|
|||
183
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py
generated
vendored
183
electron/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py
generated
vendored
|
|
@ -5,11 +5,11 @@
|
|||
"""Handle version information related to Visual Stuio."""
|
||||
|
||||
import errno
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import glob
|
||||
|
||||
|
||||
def JoinPath(*args):
|
||||
|
|
@ -69,25 +69,25 @@ class VisualStudioVersion:
|
|||
|
||||
def ProjectExtension(self):
|
||||
"""Returns the file extension for the project."""
|
||||
return self.uses_vcxproj and ".vcxproj" or ".vcproj"
|
||||
return (self.uses_vcxproj and ".vcxproj") or ".vcproj"
|
||||
|
||||
def Path(self):
|
||||
"""Returns the path to Visual Studio installation."""
|
||||
return self.path
|
||||
|
||||
def ToolPath(self, tool):
|
||||
"""Returns the path to a given compiler tool. """
|
||||
"""Returns the path to a given compiler tool."""
|
||||
return os.path.normpath(os.path.join(self.path, "VC/bin", tool))
|
||||
|
||||
def DefaultToolset(self):
|
||||
"""Returns the msbuild toolset version that will be used in the absence
|
||||
of a user override."""
|
||||
of a user override."""
|
||||
return self.default_toolset
|
||||
|
||||
def _SetupScriptInternal(self, target_arch):
|
||||
"""Returns a command (with arguments) to be used to set up the
|
||||
environment."""
|
||||
assert target_arch in ("x86", "x64"), "target_arch not supported"
|
||||
environment."""
|
||||
assert target_arch in ("x86", "x64", "arm64"), "target_arch not supported"
|
||||
# If WindowsSDKDir is set and SetEnv.Cmd exists then we are using the
|
||||
# depot_tools build tools and should run SetEnv.Cmd to set up the
|
||||
# environment. The check for WindowsSDKDir alone is not sufficient because
|
||||
|
|
@ -109,8 +109,16 @@ class VisualStudioVersion:
|
|||
)
|
||||
|
||||
# Always use a native executable, cross-compiling if necessary.
|
||||
host_arch = "amd64" if is_host_arch_x64 else "x86"
|
||||
msvc_target_arch = "amd64" if target_arch == "x64" else "x86"
|
||||
host_arch = (
|
||||
"amd64"
|
||||
if is_host_arch_x64
|
||||
else (
|
||||
"arm64"
|
||||
if os.environ.get("PROCESSOR_ARCHITECTURE") == "ARM64"
|
||||
else "x86"
|
||||
)
|
||||
)
|
||||
msvc_target_arch = {"x64": "amd64"}.get(target_arch, target_arch)
|
||||
arg = host_arch
|
||||
if host_arch != msvc_target_arch:
|
||||
arg += "_" + msvc_target_arch
|
||||
|
|
@ -154,16 +162,16 @@ class VisualStudioVersion:
|
|||
def _RegistryQueryBase(sysdir, key, value):
|
||||
"""Use reg.exe to read a particular key.
|
||||
|
||||
While ideally we might use the win32 module, we would like gyp to be
|
||||
python neutral, so for instance cygwin python lacks this module.
|
||||
While ideally we might use the win32 module, we would like gyp to be
|
||||
python neutral, so for instance cygwin python lacks this module.
|
||||
|
||||
Arguments:
|
||||
sysdir: The system subdirectory to attempt to launch reg.exe from.
|
||||
key: The registry key to read from.
|
||||
value: The particular value to read.
|
||||
Return:
|
||||
stdout from reg.exe, or None for failure.
|
||||
"""
|
||||
Arguments:
|
||||
sysdir: The system subdirectory to attempt to launch reg.exe from.
|
||||
key: The registry key to read from.
|
||||
value: The particular value to read.
|
||||
Return:
|
||||
stdout from reg.exe, or None for failure.
|
||||
"""
|
||||
# Skip if not on Windows or Python Win32 setup issue
|
||||
if sys.platform not in ("win32", "cygwin"):
|
||||
return None
|
||||
|
|
@ -184,20 +192,20 @@ def _RegistryQueryBase(sysdir, key, value):
|
|||
def _RegistryQuery(key, value=None):
|
||||
r"""Use reg.exe to read a particular key through _RegistryQueryBase.
|
||||
|
||||
First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If
|
||||
that fails, it falls back to System32. Sysnative is available on Vista and
|
||||
up and available on Windows Server 2003 and XP through KB patch 942589. Note
|
||||
that Sysnative will always fail if using 64-bit python due to it being a
|
||||
virtual directory and System32 will work correctly in the first place.
|
||||
First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If
|
||||
that fails, it falls back to System32. Sysnative is available on Vista and
|
||||
up and available on Windows Server 2003 and XP through KB patch 942589. Note
|
||||
that Sysnative will always fail if using 64-bit python due to it being a
|
||||
virtual directory and System32 will work correctly in the first place.
|
||||
|
||||
KB 942589 - http://support.microsoft.com/kb/942589/en-us.
|
||||
KB 942589 - http://support.microsoft.com/kb/942589/en-us.
|
||||
|
||||
Arguments:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read (optional).
|
||||
Return:
|
||||
stdout from reg.exe, or None for failure.
|
||||
"""
|
||||
Arguments:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read (optional).
|
||||
Return:
|
||||
stdout from reg.exe, or None for failure.
|
||||
"""
|
||||
text = None
|
||||
try:
|
||||
text = _RegistryQueryBase("Sysnative", key, value)
|
||||
|
|
@ -212,14 +220,15 @@ def _RegistryQuery(key, value=None):
|
|||
def _RegistryGetValueUsingWinReg(key, value):
|
||||
"""Use the _winreg module to obtain the value of a registry key.
|
||||
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure. Throws
|
||||
ImportError if winreg is unavailable.
|
||||
"""
|
||||
from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure. Throws
|
||||
ImportError if winreg is unavailable.
|
||||
"""
|
||||
from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx # noqa: PLC0415
|
||||
|
||||
try:
|
||||
root, subkey = key.split("\\", 1)
|
||||
assert root == "HKLM" # Only need HKLM for now.
|
||||
|
|
@ -232,17 +241,17 @@ def _RegistryGetValueUsingWinReg(key, value):
|
|||
def _RegistryGetValue(key, value):
|
||||
"""Use _winreg or reg.exe to obtain the value of a registry key.
|
||||
|
||||
Using _winreg is preferable because it solves an issue on some corporate
|
||||
environments where access to reg.exe is locked down. However, we still need
|
||||
to fallback to reg.exe for the case where the _winreg module is not available
|
||||
(for example in cygwin python).
|
||||
Using _winreg is preferable because it solves an issue on some corporate
|
||||
environments where access to reg.exe is locked down. However, we still need
|
||||
to fallback to reg.exe for the case where the _winreg module is not available
|
||||
(for example in cygwin python).
|
||||
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure.
|
||||
"""
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure.
|
||||
"""
|
||||
try:
|
||||
return _RegistryGetValueUsingWinReg(key, value)
|
||||
except ImportError:
|
||||
|
|
@ -262,13 +271,25 @@ def _RegistryGetValue(key, value):
|
|||
def _CreateVersion(name, path, sdk_based=False):
|
||||
"""Sets up MSVS project generation.
|
||||
|
||||
Setup is based off the GYP_MSVS_VERSION environment variable or whatever is
|
||||
autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
|
||||
passed in that doesn't match a value in versions python will throw a error.
|
||||
"""
|
||||
Setup is based off the GYP_MSVS_VERSION environment variable or whatever is
|
||||
autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
|
||||
passed in that doesn't match a value in versions python will throw a error.
|
||||
"""
|
||||
if path:
|
||||
path = os.path.normpath(path)
|
||||
versions = {
|
||||
"2026": VisualStudioVersion(
|
||||
"2026",
|
||||
"Visual Studio 2026",
|
||||
solution_version="12.00",
|
||||
project_version="18.0",
|
||||
flat_sln=False,
|
||||
uses_vcxproj=True,
|
||||
path=path,
|
||||
sdk_based=sdk_based,
|
||||
default_toolset="v145",
|
||||
compatible_sdks=["v8.1", "v10.0"],
|
||||
),
|
||||
"2022": VisualStudioVersion(
|
||||
"2022",
|
||||
"Visual Studio 2022",
|
||||
|
|
@ -435,22 +456,22 @@ def _ConvertToCygpath(path):
|
|||
def _DetectVisualStudioVersions(versions_to_check, force_express):
|
||||
"""Collect the list of installed visual studio versions.
|
||||
|
||||
Returns:
|
||||
A list of visual studio versions installed in descending order of
|
||||
usage preference.
|
||||
Base this on the registry and a quick check if devenv.exe exists.
|
||||
Possibilities are:
|
||||
2005(e) - Visual Studio 2005 (8)
|
||||
2008(e) - Visual Studio 2008 (9)
|
||||
2010(e) - Visual Studio 2010 (10)
|
||||
2012(e) - Visual Studio 2012 (11)
|
||||
2013(e) - Visual Studio 2013 (12)
|
||||
2015 - Visual Studio 2015 (14)
|
||||
2017 - Visual Studio 2017 (15)
|
||||
2019 - Visual Studio 2019 (16)
|
||||
2022 - Visual Studio 2022 (17)
|
||||
Where (e) is e for express editions of MSVS and blank otherwise.
|
||||
"""
|
||||
Returns:
|
||||
A list of visual studio versions installed in descending order of
|
||||
usage preference.
|
||||
Base this on the registry and a quick check if devenv.exe exists.
|
||||
Possibilities are:
|
||||
2005(e) - Visual Studio 2005 (8)
|
||||
2008(e) - Visual Studio 2008 (9)
|
||||
2010(e) - Visual Studio 2010 (10)
|
||||
2012(e) - Visual Studio 2012 (11)
|
||||
2013(e) - Visual Studio 2013 (12)
|
||||
2015 - Visual Studio 2015 (14)
|
||||
2017 - Visual Studio 2017 (15)
|
||||
2019 - Visual Studio 2019 (16)
|
||||
2022 - Visual Studio 2022 (17)
|
||||
Where (e) is e for express editions of MSVS and blank otherwise.
|
||||
"""
|
||||
version_to_year = {
|
||||
"8.0": "2005",
|
||||
"9.0": "2008",
|
||||
|
|
@ -461,6 +482,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
|
|||
"15.0": "2017",
|
||||
"16.0": "2019",
|
||||
"17.0": "2022",
|
||||
"18.0": "2026",
|
||||
}
|
||||
versions = []
|
||||
for version in versions_to_check:
|
||||
|
|
@ -527,16 +549,27 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
|
|||
def SelectVisualStudioVersion(version="auto", allow_fallback=True):
|
||||
"""Select which version of Visual Studio projects to generate.
|
||||
|
||||
Arguments:
|
||||
version: Hook to allow caller to force a particular version (vs auto).
|
||||
Returns:
|
||||
An object representing a visual studio project format version.
|
||||
"""
|
||||
Arguments:
|
||||
version: Hook to allow caller to force a particular version (vs auto).
|
||||
Returns:
|
||||
An object representing a visual studio project format version.
|
||||
"""
|
||||
# In auto mode, check environment variable for override.
|
||||
if version == "auto":
|
||||
version = os.environ.get("GYP_MSVS_VERSION", "auto")
|
||||
version_map = {
|
||||
"auto": ("17.0", "16.0", "15.0", "14.0", "12.0", "10.0", "9.0", "8.0", "11.0"),
|
||||
"auto": (
|
||||
"18.0",
|
||||
"17.0",
|
||||
"16.0",
|
||||
"15.0",
|
||||
"14.0",
|
||||
"12.0",
|
||||
"10.0",
|
||||
"9.0",
|
||||
"8.0",
|
||||
"11.0",
|
||||
),
|
||||
"2005": ("8.0",),
|
||||
"2005e": ("8.0",),
|
||||
"2008": ("9.0",),
|
||||
|
|
@ -551,9 +584,9 @@ def SelectVisualStudioVersion(version="auto", allow_fallback=True):
|
|||
"2017": ("15.0",),
|
||||
"2019": ("16.0",),
|
||||
"2022": ("17.0",),
|
||||
"2026": ("18.0",),
|
||||
}
|
||||
override_path = os.environ.get("GYP_MSVS_OVERRIDE_PATH")
|
||||
if override_path:
|
||||
if override_path := os.environ.get("GYP_MSVS_OVERRIDE_PATH"):
|
||||
msvs_version = os.environ.get("GYP_MSVS_VERSION")
|
||||
if not msvs_version:
|
||||
raise ValueError(
|
||||
|
|
|
|||
132
electron/node_modules/node-gyp/gyp/pylib/gyp/__init__.py
generated
vendored
132
electron/node_modules/node-gyp/gyp/pylib/gyp/__init__.py
generated
vendored
|
|
@ -4,17 +4,19 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import gyp.input
|
||||
import argparse
|
||||
import copy
|
||||
import os.path
|
||||
import re
|
||||
import shlex
|
||||
import sys
|
||||
import traceback
|
||||
from gyp.common import GypError
|
||||
from importlib.metadata import version
|
||||
|
||||
import gyp.input
|
||||
from gyp.common import GypError
|
||||
|
||||
# Default debug modes for GYP
|
||||
debug = {}
|
||||
|
|
@ -25,6 +27,20 @@ DEBUG_VARIABLES = "variables"
|
|||
DEBUG_INCLUDES = "includes"
|
||||
|
||||
|
||||
def EscapeForCString(string: bytes | str) -> str:
|
||||
if isinstance(string, str):
|
||||
string = string.encode(encoding="utf8")
|
||||
|
||||
backslash_or_double_quote = {ord("\\"), ord('"')}
|
||||
result = ""
|
||||
for char in string:
|
||||
if char in backslash_or_double_quote or not 32 <= char < 127:
|
||||
result += "\\%03o" % char
|
||||
else:
|
||||
result += chr(char)
|
||||
return result
|
||||
|
||||
|
||||
def DebugOutput(mode, message, *args):
|
||||
if "all" in gyp.debug or mode in gyp.debug:
|
||||
ctx = ("unknown", 0, "unknown")
|
||||
|
|
@ -63,11 +79,11 @@ def Load(
|
|||
circular_check=True,
|
||||
):
|
||||
"""
|
||||
Loads one or more specified build files.
|
||||
default_variables and includes will be copied before use.
|
||||
Returns the generator for the specified format and the
|
||||
data returned by loading the specified build files.
|
||||
"""
|
||||
Loads one or more specified build files.
|
||||
default_variables and includes will be copied before use.
|
||||
Returns the generator for the specified format and the
|
||||
data returned by loading the specified build files.
|
||||
"""
|
||||
if params is None:
|
||||
params = {}
|
||||
|
||||
|
|
@ -101,21 +117,24 @@ def Load(
|
|||
# These parameters are passed in order (as opposed to by key)
|
||||
# because ActivePython cannot handle key parameters to __import__.
|
||||
generator = __import__(generator_name, globals(), locals(), generator_name)
|
||||
for (key, val) in generator.generator_default_variables.items():
|
||||
for key, val in generator.generator_default_variables.items():
|
||||
default_variables.setdefault(key, val)
|
||||
|
||||
output_dir = params["options"].generator_output or params["options"].toplevel_dir
|
||||
if default_variables["GENERATOR"] == "ninja":
|
||||
default_variables.setdefault(
|
||||
"PRODUCT_DIR_ABS",
|
||||
os.path.join(output_dir, "out", default_variables["build_type"]),
|
||||
product_dir_abs = os.path.join(
|
||||
output_dir, "out", default_variables.get("build_type", "default")
|
||||
)
|
||||
else:
|
||||
default_variables.setdefault(
|
||||
"PRODUCT_DIR_ABS",
|
||||
os.path.join(output_dir, default_variables["CONFIGURATION_NAME"]),
|
||||
product_dir_abs = os.path.join(
|
||||
output_dir, default_variables["CONFIGURATION_NAME"]
|
||||
)
|
||||
|
||||
default_variables.setdefault("PRODUCT_DIR_ABS", product_dir_abs)
|
||||
default_variables.setdefault(
|
||||
"PRODUCT_DIR_ABS_CSTR", EscapeForCString(product_dir_abs)
|
||||
)
|
||||
|
||||
# Give the generator the opportunity to set additional variables based on
|
||||
# the params it will receive in the output phase.
|
||||
if getattr(generator, "CalculateVariables", None):
|
||||
|
|
@ -168,10 +187,10 @@ def Load(
|
|||
|
||||
def NameValueListToDict(name_value_list):
|
||||
"""
|
||||
Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary
|
||||
of the pairs. If a string is simply NAME, then the value in the dictionary
|
||||
is set to True. If VALUE can be converted to an integer, it is.
|
||||
"""
|
||||
Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary
|
||||
of the pairs. If a string is simply NAME, then the value in the dictionary
|
||||
is set to True. If VALUE can be converted to an integer, it is.
|
||||
"""
|
||||
result = {}
|
||||
for item in name_value_list:
|
||||
tokens = item.split("=", 1)
|
||||
|
|
@ -190,8 +209,7 @@ def NameValueListToDict(name_value_list):
|
|||
|
||||
|
||||
def ShlexEnv(env_name):
|
||||
flags = os.environ.get(env_name, [])
|
||||
if flags:
|
||||
if flags := os.environ.get(env_name) or []:
|
||||
flags = shlex.split(flags)
|
||||
return flags
|
||||
|
||||
|
|
@ -205,13 +223,13 @@ def FormatOpt(opt, value):
|
|||
def RegenerateAppendFlag(flag, values, predicate, env_name, options):
|
||||
"""Regenerate a list of command line flags, for an option of action='append'.
|
||||
|
||||
The |env_name|, if given, is checked in the environment and used to generate
|
||||
an initial list of options, then the options that were specified on the
|
||||
command line (given in |values|) are appended. This matches the handling of
|
||||
environment variables and command line flags where command line flags override
|
||||
the environment, while not requiring the environment to be set when the flags
|
||||
are used again.
|
||||
"""
|
||||
The |env_name|, if given, is checked in the environment and used to generate
|
||||
an initial list of options, then the options that were specified on the
|
||||
command line (given in |values|) are appended. This matches the handling of
|
||||
environment variables and command line flags where command line flags override
|
||||
the environment, while not requiring the environment to be set when the flags
|
||||
are used again.
|
||||
"""
|
||||
flags = []
|
||||
if options.use_environment and env_name:
|
||||
for flag_value in ShlexEnv(env_name):
|
||||
|
|
@ -227,14 +245,14 @@ def RegenerateAppendFlag(flag, values, predicate, env_name, options):
|
|||
|
||||
def RegenerateFlags(options):
|
||||
"""Given a parsed options object, and taking the environment variables into
|
||||
account, returns a list of flags that should regenerate an equivalent options
|
||||
object (even in the absence of the environment variables.)
|
||||
account, returns a list of flags that should regenerate an equivalent options
|
||||
object (even in the absence of the environment variables.)
|
||||
|
||||
Any path options will be normalized relative to depth.
|
||||
Any path options will be normalized relative to depth.
|
||||
|
||||
The format flag is not included, as it is assumed the calling generator will
|
||||
set that as appropriate.
|
||||
"""
|
||||
The format flag is not included, as it is assumed the calling generator will
|
||||
set that as appropriate.
|
||||
"""
|
||||
|
||||
def FixPath(path):
|
||||
path = gyp.common.FixIfRelativePath(path, options.depth)
|
||||
|
|
@ -251,7 +269,7 @@ def RegenerateFlags(options):
|
|||
for name, metadata in options._regeneration_metadata.items():
|
||||
opt = metadata["opt"]
|
||||
value = getattr(options, name)
|
||||
value_predicate = metadata["type"] == "path" and FixPath or Noop
|
||||
value_predicate = (metadata["type"] == "path" and FixPath) or Noop
|
||||
action = metadata["action"]
|
||||
env_name = metadata["env_name"]
|
||||
if action == "append":
|
||||
|
|
@ -292,15 +310,15 @@ class RegeneratableOptionParser(argparse.ArgumentParser):
|
|||
def add_argument(self, *args, **kw):
|
||||
"""Add an option to the parser.
|
||||
|
||||
This accepts the same arguments as ArgumentParser.add_argument, plus the
|
||||
following:
|
||||
regenerate: can be set to False to prevent this option from being included
|
||||
in regeneration.
|
||||
env_name: name of environment variable that additional values for this
|
||||
option come from.
|
||||
type: adds type='path', to tell the regenerator that the values of
|
||||
this option need to be made relative to options.depth
|
||||
"""
|
||||
This accepts the same arguments as ArgumentParser.add_argument, plus the
|
||||
following:
|
||||
regenerate: can be set to False to prevent this option from being included
|
||||
in regeneration.
|
||||
env_name: name of environment variable that additional values for this
|
||||
option come from.
|
||||
type: adds type='path', to tell the regenerator that the values of
|
||||
this option need to be made relative to options.depth
|
||||
"""
|
||||
env_name = kw.pop("env_name", None)
|
||||
if "dest" in kw and kw.pop("regenerate", True):
|
||||
dest = kw["dest"]
|
||||
|
|
@ -328,7 +346,7 @@ class RegeneratableOptionParser(argparse.ArgumentParser):
|
|||
|
||||
def gyp_main(args):
|
||||
my_name = os.path.basename(sys.argv[0])
|
||||
usage = "usage: %(prog)s [options ...] [build_file ...]"
|
||||
usage = "%(prog)s [options ...] [build_file ...]"
|
||||
|
||||
parser = RegeneratableOptionParser(usage=usage.replace("%s", "%(prog)s"))
|
||||
parser.add_argument(
|
||||
|
|
@ -346,7 +364,7 @@ def gyp_main(args):
|
|||
action="store",
|
||||
env_name="GYP_CONFIG_DIR",
|
||||
default=None,
|
||||
help="The location for configuration files like " "include.gypi.",
|
||||
help="The location for configuration files like include.gypi.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
|
|
@ -474,8 +492,7 @@ def gyp_main(args):
|
|||
|
||||
options, build_files_arg = parser.parse_args(args)
|
||||
if options.version:
|
||||
import pkg_resources
|
||||
print(f"v{pkg_resources.get_distribution('gyp-next').version}")
|
||||
print(f"v{version('gyp-next')}")
|
||||
return 0
|
||||
build_files = build_files_arg
|
||||
|
||||
|
|
@ -510,19 +527,18 @@ def gyp_main(args):
|
|||
# If no format was given on the command line, then check the env variable.
|
||||
generate_formats = []
|
||||
if options.use_environment:
|
||||
generate_formats = os.environ.get("GYP_GENERATORS", [])
|
||||
generate_formats = os.environ.get("GYP_GENERATORS") or []
|
||||
if generate_formats:
|
||||
generate_formats = re.split(r"[\s,]", generate_formats)
|
||||
if generate_formats:
|
||||
options.formats = generate_formats
|
||||
# Nothing in the variable, default based on platform.
|
||||
elif sys.platform == "darwin":
|
||||
options.formats = ["xcode"]
|
||||
elif sys.platform in ("win32", "cygwin"):
|
||||
options.formats = ["msvs"]
|
||||
else:
|
||||
# Nothing in the variable, default based on platform.
|
||||
if sys.platform == "darwin":
|
||||
options.formats = ["xcode"]
|
||||
elif sys.platform in ("win32", "cygwin"):
|
||||
options.formats = ["msvs"]
|
||||
else:
|
||||
options.formats = ["make"]
|
||||
options.formats = ["make"]
|
||||
|
||||
if not options.generator_output and options.use_environment:
|
||||
g_o = os.environ.get("GYP_GENERATOR_OUTPUT")
|
||||
|
|
@ -622,7 +638,7 @@ def gyp_main(args):
|
|||
if options.generator_flags:
|
||||
gen_flags += options.generator_flags
|
||||
generator_flags = NameValueListToDict(gen_flags)
|
||||
if DEBUG_GENERAL in gyp.debug.keys():
|
||||
if DEBUG_GENERAL in gyp.debug:
|
||||
DebugOutput(DEBUG_GENERAL, "generator_flags: %s", generator_flags)
|
||||
|
||||
# Generate all requested formats (use a set in case we got one format request
|
||||
|
|
@ -681,7 +697,7 @@ def main(args):
|
|||
return 1
|
||||
|
||||
|
||||
# NOTE: setuptools generated console_scripts calls function with no arguments
|
||||
# NOTE: console_scripts calls this function with no arguments
|
||||
def script_main():
|
||||
return main(sys.argv[1:])
|
||||
|
||||
|
|
|
|||
206
electron/node_modules/node-gyp/gyp/pylib/gyp/common.py
generated
vendored
206
electron/node_modules/node-gyp/gyp/pylib/gyp/common.py
generated
vendored
|
|
@ -6,10 +6,10 @@ import errno
|
|||
import filecmp
|
||||
import os.path
|
||||
import re
|
||||
import tempfile
|
||||
import sys
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
from collections.abc import MutableSet
|
||||
|
||||
|
||||
|
|
@ -31,10 +31,8 @@ class memoize:
|
|||
|
||||
class GypError(Exception):
|
||||
"""Error class representing an error, which is to be presented
|
||||
to the user. The main entry point will catch and display this.
|
||||
"""
|
||||
|
||||
pass
|
||||
to the user. The main entry point will catch and display this.
|
||||
"""
|
||||
|
||||
|
||||
def ExceptionAppend(e, msg):
|
||||
|
|
@ -49,9 +47,9 @@ def ExceptionAppend(e, msg):
|
|||
|
||||
def FindQualifiedTargets(target, qualified_list):
|
||||
"""
|
||||
Given a list of qualified targets, return the qualified targets for the
|
||||
specified |target|.
|
||||
"""
|
||||
Given a list of qualified targets, return the qualified targets for the
|
||||
specified |target|.
|
||||
"""
|
||||
return [t for t in qualified_list if ParseQualifiedTarget(t)[1] == target]
|
||||
|
||||
|
||||
|
|
@ -116,7 +114,7 @@ def BuildFile(fully_qualified_target):
|
|||
|
||||
def GetEnvironFallback(var_list, default):
|
||||
"""Look up a key in the environment, with fallback to secondary keys
|
||||
and finally falling back to a default value."""
|
||||
and finally falling back to a default value."""
|
||||
for var in var_list:
|
||||
if var in os.environ:
|
||||
return os.environ[var]
|
||||
|
|
@ -144,20 +142,16 @@ def RelativePath(path, relative_to, follow_path_symlink=True):
|
|||
# symlink, this option has no effect.
|
||||
|
||||
# Convert to normalized (and therefore absolute paths).
|
||||
if follow_path_symlink:
|
||||
path = os.path.realpath(path)
|
||||
else:
|
||||
path = os.path.abspath(path)
|
||||
path = os.path.realpath(path) if follow_path_symlink else os.path.abspath(path)
|
||||
relative_to = os.path.realpath(relative_to)
|
||||
|
||||
# On Windows, we can't create a relative path to a different drive, so just
|
||||
# use the absolute path.
|
||||
if sys.platform == "win32":
|
||||
if (
|
||||
os.path.splitdrive(path)[0].lower()
|
||||
!= os.path.splitdrive(relative_to)[0].lower()
|
||||
):
|
||||
return path
|
||||
if sys.platform == "win32" and (
|
||||
os.path.splitdrive(path)[0].lower()
|
||||
!= os.path.splitdrive(relative_to)[0].lower()
|
||||
):
|
||||
return path
|
||||
|
||||
# Split the paths into components.
|
||||
path_split = path.split(os.path.sep)
|
||||
|
|
@ -183,11 +177,11 @@ def RelativePath(path, relative_to, follow_path_symlink=True):
|
|||
@memoize
|
||||
def InvertRelativePath(path, toplevel_dir=None):
|
||||
"""Given a path like foo/bar that is relative to toplevel_dir, return
|
||||
the inverse relative path back to the toplevel_dir.
|
||||
the inverse relative path back to the toplevel_dir.
|
||||
|
||||
E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path)))
|
||||
should always produce the empty string, unless the path contains symlinks.
|
||||
"""
|
||||
E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path)))
|
||||
should always produce the empty string, unless the path contains symlinks.
|
||||
"""
|
||||
if not path:
|
||||
return path
|
||||
toplevel_dir = "." if toplevel_dir is None else toplevel_dir
|
||||
|
|
@ -267,20 +261,17 @@ _escape = re.compile(r'(["\\`])')
|
|||
def EncodePOSIXShellArgument(argument):
|
||||
"""Encodes |argument| suitably for consumption by POSIX shells.
|
||||
|
||||
argument may be quoted and escaped as necessary to ensure that POSIX shells
|
||||
treat the returned value as a literal representing the argument passed to
|
||||
this function. Parameter (variable) expansions beginning with $ are allowed
|
||||
to remain intact without escaping the $, to allow the argument to contain
|
||||
references to variables to be expanded by the shell.
|
||||
"""
|
||||
argument may be quoted and escaped as necessary to ensure that POSIX shells
|
||||
treat the returned value as a literal representing the argument passed to
|
||||
this function. Parameter (variable) expansions beginning with $ are allowed
|
||||
to remain intact without escaping the $, to allow the argument to contain
|
||||
references to variables to be expanded by the shell.
|
||||
"""
|
||||
|
||||
if not isinstance(argument, str):
|
||||
argument = str(argument)
|
||||
|
||||
if _quote.search(argument):
|
||||
quote = '"'
|
||||
else:
|
||||
quote = ""
|
||||
quote = '"' if _quote.search(argument) else ""
|
||||
|
||||
encoded = quote + re.sub(_escape, r"\\\1", argument) + quote
|
||||
|
||||
|
|
@ -290,9 +281,9 @@ def EncodePOSIXShellArgument(argument):
|
|||
def EncodePOSIXShellList(list):
|
||||
"""Encodes |list| suitably for consumption by POSIX shells.
|
||||
|
||||
Returns EncodePOSIXShellArgument for each item in list, and joins them
|
||||
together using the space character as an argument separator.
|
||||
"""
|
||||
Returns EncodePOSIXShellArgument for each item in list, and joins them
|
||||
together using the space character as an argument separator.
|
||||
"""
|
||||
|
||||
encoded_arguments = []
|
||||
for argument in list:
|
||||
|
|
@ -320,14 +311,12 @@ def DeepDependencyTargets(target_dicts, roots):
|
|||
|
||||
|
||||
def BuildFileTargets(target_list, build_file):
|
||||
"""From a target_list, returns the subset from the specified build_file.
|
||||
"""
|
||||
"""From a target_list, returns the subset from the specified build_file."""
|
||||
return [p for p in target_list if BuildFile(p) == build_file]
|
||||
|
||||
|
||||
def AllTargets(target_list, target_dicts, build_file):
|
||||
"""Returns all targets (direct and dependencies) for the specified build_file.
|
||||
"""
|
||||
"""Returns all targets (direct and dependencies) for the specified build_file."""
|
||||
bftargets = BuildFileTargets(target_list, build_file)
|
||||
deptargets = DeepDependencyTargets(target_dicts, bftargets)
|
||||
return bftargets + deptargets
|
||||
|
|
@ -336,12 +325,12 @@ def AllTargets(target_list, target_dicts, build_file):
|
|||
def WriteOnDiff(filename):
|
||||
"""Write to a file only if the new contents differ.
|
||||
|
||||
Arguments:
|
||||
filename: name of the file to potentially write to.
|
||||
Returns:
|
||||
A file like object which will write to temporary file and only overwrite
|
||||
the target if it differs (on close).
|
||||
"""
|
||||
Arguments:
|
||||
filename: name of the file to potentially write to.
|
||||
Returns:
|
||||
A file like object which will write to temporary file and only overwrite
|
||||
the target if it differs (on close).
|
||||
"""
|
||||
|
||||
class Writer:
|
||||
"""Wrapper around file which only covers the target if it differs."""
|
||||
|
|
@ -430,7 +419,70 @@ def EnsureDirExists(path):
|
|||
pass
|
||||
|
||||
|
||||
def GetFlavor(params):
|
||||
def GetCompilerPredefines(): # -> dict
|
||||
cmd = []
|
||||
defines = {}
|
||||
|
||||
# shlex.split() will eat '\' in posix mode, but
|
||||
# setting posix=False will preserve extra '"' cause CreateProcess fail on Windows
|
||||
# this makes '\' in %CC_target% and %CFLAGS% work
|
||||
def replace_sep(s):
|
||||
return s.replace(os.sep, "/") if os.sep != "/" else s
|
||||
|
||||
if CC := os.environ.get("CC_target") or os.environ.get("CC"):
|
||||
cmd += shlex.split(replace_sep(CC))
|
||||
if CFLAGS := os.environ.get("CFLAGS"):
|
||||
cmd += shlex.split(replace_sep(CFLAGS))
|
||||
elif CXX := os.environ.get("CXX_target") or os.environ.get("CXX"):
|
||||
cmd += shlex.split(replace_sep(CXX))
|
||||
if CXXFLAGS := os.environ.get("CXXFLAGS"):
|
||||
cmd += shlex.split(replace_sep(CXXFLAGS))
|
||||
else:
|
||||
return defines
|
||||
|
||||
if sys.platform == "win32":
|
||||
fd, input = tempfile.mkstemp(suffix=".c")
|
||||
real_cmd = [*cmd, "-dM", "-E", "-x", "c", input]
|
||||
try:
|
||||
os.close(fd)
|
||||
stdout = subprocess.run(
|
||||
real_cmd, shell=True, capture_output=True, check=True
|
||||
).stdout
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
"Warning: failed to get compiler predefines\n"
|
||||
"cmd: %s\n"
|
||||
"status: %d" % (e.cmd, e.returncode),
|
||||
file=sys.stderr,
|
||||
)
|
||||
return defines
|
||||
finally:
|
||||
os.unlink(input)
|
||||
else:
|
||||
input = "/dev/null"
|
||||
real_cmd = [*cmd, "-dM", "-E", "-x", "c", input]
|
||||
try:
|
||||
stdout = subprocess.run(
|
||||
real_cmd, shell=False, capture_output=True, check=True
|
||||
).stdout
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
"Warning: failed to get compiler predefines\n"
|
||||
"cmd: %s\n"
|
||||
"status: %d" % (e.cmd, e.returncode),
|
||||
file=sys.stderr,
|
||||
)
|
||||
return defines
|
||||
|
||||
lines = stdout.decode("utf-8").replace("\r\n", "\n").split("\n")
|
||||
for line in lines:
|
||||
if (line or "").startswith("#define "):
|
||||
_, key, *value = line.split(" ")
|
||||
defines[key] = " ".join(value)
|
||||
return defines
|
||||
|
||||
|
||||
def GetFlavorByPlatform():
|
||||
"""Returns |params.flavor| if it's set, the system's default flavor else."""
|
||||
flavors = {
|
||||
"cygwin": "win",
|
||||
|
|
@ -438,8 +490,6 @@ def GetFlavor(params):
|
|||
"darwin": "mac",
|
||||
}
|
||||
|
||||
if "flavor" in params:
|
||||
return params["flavor"]
|
||||
if sys.platform in flavors:
|
||||
return flavors[sys.platform]
|
||||
if sys.platform.startswith("sunos"):
|
||||
|
|
@ -460,9 +510,22 @@ def GetFlavor(params):
|
|||
return "linux"
|
||||
|
||||
|
||||
def GetFlavor(params):
|
||||
if "flavor" in params:
|
||||
return params["flavor"]
|
||||
|
||||
defines = GetCompilerPredefines()
|
||||
if "__EMSCRIPTEN__" in defines:
|
||||
return "emscripten"
|
||||
if "__wasm__" in defines:
|
||||
return "wasi" if "__wasi__" in defines else "wasm"
|
||||
|
||||
return GetFlavorByPlatform()
|
||||
|
||||
|
||||
def CopyTool(flavor, out_path, generator_flags={}):
|
||||
"""Finds (flock|mac|win)_tool.gyp in the gyp directory and copies it
|
||||
to |out_path|."""
|
||||
to |out_path|."""
|
||||
# aix and solaris just need flock emulation. mac and win use more complicated
|
||||
# support scripts.
|
||||
prefix = {
|
||||
|
|
@ -518,7 +581,8 @@ def uniquer(seq, idfun=lambda x: x):
|
|||
|
||||
|
||||
# Based on http://code.activestate.com/recipes/576694/.
|
||||
class OrderedSet(MutableSet):
|
||||
class OrderedSet(MutableSet): # noqa: PLW1641
|
||||
# TODO (cclauss): Fix eq-without-hash ruff rule PLW1641
|
||||
def __init__(self, iterable=None):
|
||||
self.end = end = []
|
||||
end += [None, end, end] # sentinel node for doubly linked list
|
||||
|
|
@ -596,24 +660,24 @@ class CycleError(Exception):
|
|||
def TopologicallySorted(graph, get_edges):
|
||||
r"""Topologically sort based on a user provided edge definition.
|
||||
|
||||
Args:
|
||||
graph: A list of node names.
|
||||
get_edges: A function mapping from node name to a hashable collection
|
||||
of node names which this node has outgoing edges to.
|
||||
Returns:
|
||||
A list containing all of the node in graph in topological order.
|
||||
It is assumed that calling get_edges once for each node and caching is
|
||||
cheaper than repeatedly calling get_edges.
|
||||
Raises:
|
||||
CycleError in the event of a cycle.
|
||||
Example:
|
||||
graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'}
|
||||
def GetEdges(node):
|
||||
return re.findall(r'\$\(([^))]\)', graph[node])
|
||||
print TopologicallySorted(graph.keys(), GetEdges)
|
||||
==>
|
||||
['a', 'c', b']
|
||||
"""
|
||||
Args:
|
||||
graph: A list of node names.
|
||||
get_edges: A function mapping from node name to a hashable collection
|
||||
of node names which this node has outgoing edges to.
|
||||
Returns:
|
||||
A list containing all of the node in graph in topological order.
|
||||
It is assumed that calling get_edges once for each node and caching is
|
||||
cheaper than repeatedly calling get_edges.
|
||||
Raises:
|
||||
CycleError in the event of a cycle.
|
||||
Example:
|
||||
graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'}
|
||||
def GetEdges(node):
|
||||
return re.findall(r'\$\(([^))]\)', graph[node])
|
||||
print TopologicallySorted(graph.keys(), GetEdges)
|
||||
==>
|
||||
['a', 'c', b']
|
||||
"""
|
||||
get_edges = memoize(get_edges)
|
||||
visited = set()
|
||||
visiting = set()
|
||||
|
|
|
|||
120
electron/node_modules/node-gyp/gyp/pylib/gyp/common_test.py
generated
vendored
120
electron/node_modules/node-gyp/gyp/pylib/gyp/common_test.py
generated
vendored
|
|
@ -6,9 +6,13 @@
|
|||
|
||||
"""Unit tests for the common.py file."""
|
||||
|
||||
import gyp.common
|
||||
import unittest
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import gyp.common
|
||||
|
||||
|
||||
class TestTopologicallySorted(unittest.TestCase):
|
||||
|
|
@ -24,9 +28,12 @@ class TestTopologicallySorted(unittest.TestCase):
|
|||
def GetEdge(node):
|
||||
return tuple(graph[node])
|
||||
|
||||
self.assertEqual(
|
||||
gyp.common.TopologicallySorted(graph.keys(), GetEdge), ["a", "c", "d", "b"]
|
||||
)
|
||||
assert gyp.common.TopologicallySorted(graph.keys(), GetEdge) == [
|
||||
"a",
|
||||
"c",
|
||||
"d",
|
||||
"b",
|
||||
]
|
||||
|
||||
def test_Cycle(self):
|
||||
"""Test that an exception is thrown on a cyclic graph."""
|
||||
|
|
@ -58,7 +65,7 @@ class TestGetFlavor(unittest.TestCase):
|
|||
|
||||
def assertFlavor(self, expected, argument, param):
|
||||
sys.platform = argument
|
||||
self.assertEqual(expected, gyp.common.GetFlavor(param))
|
||||
assert expected == gyp.common.GetFlavor(param)
|
||||
|
||||
def test_platform_default(self):
|
||||
self.assertFlavor("freebsd", "freebsd9", {})
|
||||
|
|
@ -73,6 +80,107 @@ class TestGetFlavor(unittest.TestCase):
|
|||
def test_param(self):
|
||||
self.assertFlavor("foobar", "linux2", {"flavor": "foobar"})
|
||||
|
||||
class MockCommunicate:
|
||||
def __init__(self, stdout):
|
||||
self.stdout = stdout
|
||||
|
||||
def decode(self, encoding):
|
||||
return self.stdout
|
||||
|
||||
@patch("os.close")
|
||||
@patch("os.unlink")
|
||||
@patch("tempfile.mkstemp")
|
||||
def test_GetCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close):
|
||||
mock_close.return_value = None
|
||||
mock_unlink.return_value = None
|
||||
mock_mkstemp.return_value = (0, "temp.c")
|
||||
|
||||
def mock_run(env, defines_stdout, expected_cmd, throws=False):
|
||||
with patch("subprocess.run") as mock_run:
|
||||
expected_input = "temp.c" if sys.platform == "win32" else "/dev/null"
|
||||
if throws:
|
||||
mock_run.side_effect = subprocess.CalledProcessError(
|
||||
returncode=1,
|
||||
cmd=[*expected_cmd, "-dM", "-E", "-x", "c", expected_input],
|
||||
)
|
||||
else:
|
||||
mock_process = MagicMock()
|
||||
mock_process.returncode = 0
|
||||
mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout)
|
||||
mock_run.return_value = mock_process
|
||||
with patch.dict(os.environ, env):
|
||||
try:
|
||||
defines = gyp.common.GetCompilerPredefines()
|
||||
except Exception as e:
|
||||
self.fail(f"GetCompilerPredefines raised an exception: {e}")
|
||||
flavor = gyp.common.GetFlavor({})
|
||||
if env.get("CC_target") or env.get("CC"):
|
||||
mock_run.assert_called_with(
|
||||
[*expected_cmd, "-dM", "-E", "-x", "c", expected_input],
|
||||
shell=sys.platform == "win32",
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
return [defines, flavor]
|
||||
|
||||
[defines0, _] = mock_run({"CC": "cl.exe"}, "", ["cl.exe"], True)
|
||||
assert defines0 == {}
|
||||
|
||||
[defines1, _] = mock_run({}, "", [])
|
||||
assert defines1 == {}
|
||||
|
||||
[defines2, flavor2] = mock_run(
|
||||
{"CC_target": "/opt/wasi-sdk/bin/clang"},
|
||||
"#define __wasm__ 1\n#define __wasi__ 1\n",
|
||||
["/opt/wasi-sdk/bin/clang"],
|
||||
)
|
||||
assert defines2 == {"__wasm__": "1", "__wasi__": "1"}
|
||||
assert flavor2 == "wasi"
|
||||
|
||||
[defines3, flavor3] = mock_run(
|
||||
{"CC_target": "/opt/wasi-sdk/bin/clang --target=wasm32"},
|
||||
"#define __wasm__ 1\n",
|
||||
["/opt/wasi-sdk/bin/clang", "--target=wasm32"],
|
||||
)
|
||||
assert defines3 == {"__wasm__": "1"}
|
||||
assert flavor3 == "wasm"
|
||||
|
||||
[defines4, flavor4] = mock_run(
|
||||
{"CC_target": "/emsdk/upstream/emscripten/emcc"},
|
||||
"#define __EMSCRIPTEN__ 1\n",
|
||||
["/emsdk/upstream/emscripten/emcc"],
|
||||
)
|
||||
assert defines4 == {"__EMSCRIPTEN__": "1"}
|
||||
assert flavor4 == "emscripten"
|
||||
|
||||
# Test path which include white space
|
||||
[defines5, flavor5] = mock_run(
|
||||
{
|
||||
"CC_target": '"/Users/Toyo Li/wasi-sdk/bin/clang" -O3',
|
||||
"CFLAGS": "--target=wasm32-wasi-threads -pthread",
|
||||
},
|
||||
"#define __wasm__ 1\n#define __wasi__ 1\n#define _REENTRANT 1\n",
|
||||
[
|
||||
"/Users/Toyo Li/wasi-sdk/bin/clang",
|
||||
"-O3",
|
||||
"--target=wasm32-wasi-threads",
|
||||
"-pthread",
|
||||
],
|
||||
)
|
||||
assert defines5 == {"__wasm__": "1", "__wasi__": "1", "_REENTRANT": "1"}
|
||||
assert flavor5 == "wasi"
|
||||
|
||||
original_sep = os.sep
|
||||
os.sep = "\\"
|
||||
[defines6, flavor6] = mock_run(
|
||||
{"CC_target": '"C:\\Program Files\\wasi-sdk\\clang.exe"'},
|
||||
"#define __wasm__ 1\n#define __wasi__ 1\n",
|
||||
["C:/Program Files/wasi-sdk/clang.exe"],
|
||||
)
|
||||
os.sep = original_sep
|
||||
assert defines6 == {"__wasm__": "1", "__wasi__": "1"}
|
||||
assert flavor6 == "wasi"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
107
electron/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py
generated
vendored
107
electron/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py
generated
vendored
|
|
@ -2,51 +2,51 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import locale
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def XmlToString(content, encoding="utf-8", pretty=False):
|
||||
""" Writes the XML content to disk, touching the file only if it has changed.
|
||||
"""Writes the XML content to disk, touching the file only if it has changed.
|
||||
|
||||
Visual Studio files have a lot of pre-defined structures. This function makes
|
||||
it easy to represent these structures as Python data structures, instead of
|
||||
having to create a lot of function calls.
|
||||
Visual Studio files have a lot of pre-defined structures. This function makes
|
||||
it easy to represent these structures as Python data structures, instead of
|
||||
having to create a lot of function calls.
|
||||
|
||||
Each XML element of the content is represented as a list composed of:
|
||||
1. The name of the element, a string,
|
||||
2. The attributes of the element, a dictionary (optional), and
|
||||
3+. The content of the element, if any. Strings are simple text nodes and
|
||||
lists are child elements.
|
||||
Each XML element of the content is represented as a list composed of:
|
||||
1. The name of the element, a string,
|
||||
2. The attributes of the element, a dictionary (optional), and
|
||||
3+. The content of the element, if any. Strings are simple text nodes and
|
||||
lists are child elements.
|
||||
|
||||
Example 1:
|
||||
<test/>
|
||||
becomes
|
||||
['test']
|
||||
Example 1:
|
||||
<test/>
|
||||
becomes
|
||||
['test']
|
||||
|
||||
Example 2:
|
||||
<myelement a='value1' b='value2'>
|
||||
<childtype>This is</childtype>
|
||||
<childtype>it!</childtype>
|
||||
</myelement>
|
||||
Example 2:
|
||||
<myelement a='value1' b='value2'>
|
||||
<childtype>This is</childtype>
|
||||
<childtype>it!</childtype>
|
||||
</myelement>
|
||||
|
||||
becomes
|
||||
['myelement', {'a':'value1', 'b':'value2'},
|
||||
['childtype', 'This is'],
|
||||
['childtype', 'it!'],
|
||||
]
|
||||
becomes
|
||||
['myelement', {'a':'value1', 'b':'value2'},
|
||||
['childtype', 'This is'],
|
||||
['childtype', 'it!'],
|
||||
]
|
||||
|
||||
Args:
|
||||
content: The structured content to be converted.
|
||||
encoding: The encoding to report on the first XML line.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
Args:
|
||||
content: The structured content to be converted.
|
||||
encoding: The encoding to report on the first XML line.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
|
||||
Returns:
|
||||
The XML content as a string.
|
||||
"""
|
||||
Returns:
|
||||
The XML content as a string.
|
||||
"""
|
||||
# We create a huge list of all the elements of the file.
|
||||
xml_parts = ['<?xml version="1.0" encoding="%s"?>' % encoding]
|
||||
if pretty:
|
||||
|
|
@ -58,14 +58,14 @@ def XmlToString(content, encoding="utf-8", pretty=False):
|
|||
|
||||
|
||||
def _ConstructContentList(xml_parts, specification, pretty, level=0):
|
||||
""" Appends the XML parts corresponding to the specification.
|
||||
"""Appends the XML parts corresponding to the specification.
|
||||
|
||||
Args:
|
||||
xml_parts: A list of XML parts to be appended to.
|
||||
specification: The specification of the element. See EasyXml docs.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
level: Indentation level.
|
||||
"""
|
||||
Args:
|
||||
xml_parts: A list of XML parts to be appended to.
|
||||
specification: The specification of the element. See EasyXml docs.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
level: Indentation level.
|
||||
"""
|
||||
# The first item in a specification is the name of the element.
|
||||
if pretty:
|
||||
indentation = " " * level
|
||||
|
|
@ -107,21 +107,26 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0):
|
|||
xml_parts.append("/>%s" % new_line)
|
||||
|
||||
|
||||
def WriteXmlIfChanged(content, path, encoding="utf-8", pretty=False,
|
||||
win32=(sys.platform == "win32")):
|
||||
""" Writes the XML content to disk, touching the file only if it has changed.
|
||||
def WriteXmlIfChanged(
|
||||
content, path, encoding="utf-8", pretty=False, win32=(sys.platform == "win32")
|
||||
):
|
||||
"""Writes the XML content to disk, touching the file only if it has changed.
|
||||
|
||||
Args:
|
||||
content: The structured content to be written.
|
||||
path: Location of the file.
|
||||
encoding: The encoding to report on the first line of the XML file.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
"""
|
||||
Args:
|
||||
content: The structured content to be written.
|
||||
path: Location of the file.
|
||||
encoding: The encoding to report on the first line of the XML file.
|
||||
pretty: True if we want pretty printing with indents and new lines.
|
||||
"""
|
||||
xml_string = XmlToString(content, encoding, pretty)
|
||||
if win32 and os.linesep != "\r\n":
|
||||
xml_string = xml_string.replace("\n", "\r\n")
|
||||
|
||||
default_encoding = locale.getdefaultlocale()[1]
|
||||
try: # getdefaultlocale() was removed in Python 3.11
|
||||
default_encoding = locale.getdefaultlocale()[1]
|
||||
except AttributeError:
|
||||
default_encoding = locale.getencoding()
|
||||
|
||||
if default_encoding and default_encoding.upper() != encoding.upper():
|
||||
xml_string = xml_string.encode(encoding)
|
||||
|
||||
|
|
@ -153,7 +158,7 @@ _xml_escape_re = re.compile("(%s)" % "|".join(map(re.escape, _xml_escape_map.key
|
|||
|
||||
|
||||
def _XmlEscape(value, attr=False):
|
||||
""" Escape a string for inclusion in XML."""
|
||||
"""Escape a string for inclusion in XML."""
|
||||
|
||||
def replace(match):
|
||||
m = match.string[match.start() : match.end()]
|
||||
|
|
|
|||
10
electron/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py
generated
vendored
10
electron/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py
generated
vendored
|
|
@ -4,13 +4,13 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
""" Unit tests for the easy_xml.py file. """
|
||||
"""Unit tests for the easy_xml.py file."""
|
||||
|
||||
import gyp.easy_xml as easy_xml
|
||||
import unittest
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from gyp import easy_xml
|
||||
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
|
@ -76,6 +76,8 @@ class TestSequenceFunctions(unittest.TestCase):
|
|||
'\'Debug|Win32\'" Label="Configuration">'
|
||||
"<ConfigurationType>Application</ConfigurationType>"
|
||||
"<CharacterSet>Unicode</CharacterSet>"
|
||||
"<SpectreMitigation>SpectreLoadCF</SpectreMitigation>"
|
||||
"<VCToolsVersion>14.36.32532</VCToolsVersion>"
|
||||
"</PropertyGroup>"
|
||||
"</Project>"
|
||||
)
|
||||
|
|
@ -99,6 +101,8 @@ class TestSequenceFunctions(unittest.TestCase):
|
|||
},
|
||||
["ConfigurationType", "Application"],
|
||||
["CharacterSet", "Unicode"],
|
||||
["SpectreMitigation", "SpectreLoadCF"],
|
||||
["VCToolsVersion", "14.36.32532"],
|
||||
],
|
||||
]
|
||||
)
|
||||
|
|
|
|||
157
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py
generated
vendored
157
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py
generated
vendored
|
|
@ -62,12 +62,12 @@ directly supplied to gyp. OTOH if both "a.gyp" and "b.gyp" are supplied to gyp
|
|||
then the "all" target includes "b1" and "b2".
|
||||
"""
|
||||
|
||||
|
||||
import gyp.common
|
||||
import json
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
import gyp.common
|
||||
|
||||
debug = False
|
||||
|
||||
found_dependency_string = "Found dependency"
|
||||
|
|
@ -129,8 +129,8 @@ def _ToGypPath(path):
|
|||
|
||||
def _ResolveParent(path, base_path_components):
|
||||
"""Resolves |path|, which starts with at least one '../'. Returns an empty
|
||||
string if the path shouldn't be considered. See _AddSources() for a
|
||||
description of |base_path_components|."""
|
||||
string if the path shouldn't be considered. See _AddSources() for a
|
||||
description of |base_path_components|."""
|
||||
depth = 0
|
||||
while path.startswith("../"):
|
||||
depth += 1
|
||||
|
|
@ -150,14 +150,14 @@ def _ResolveParent(path, base_path_components):
|
|||
|
||||
def _AddSources(sources, base_path, base_path_components, result):
|
||||
"""Extracts valid sources from |sources| and adds them to |result|. Each
|
||||
source file is relative to |base_path|, but may contain '..'. To make
|
||||
resolving '..' easier |base_path_components| contains each of the
|
||||
directories in |base_path|. Additionally each source may contain variables.
|
||||
Such sources are ignored as it is assumed dependencies on them are expressed
|
||||
and tracked in some other means."""
|
||||
source file is relative to |base_path|, but may contain '..'. To make
|
||||
resolving '..' easier |base_path_components| contains each of the
|
||||
directories in |base_path|. Additionally each source may contain variables.
|
||||
Such sources are ignored as it is assumed dependencies on them are expressed
|
||||
and tracked in some other means."""
|
||||
# NOTE: gyp paths are always posix style.
|
||||
for source in sources:
|
||||
if not len(source) or source.startswith("!!!") or source.startswith("$"):
|
||||
if not len(source) or source.startswith(("!!!", "$")):
|
||||
continue
|
||||
# variable expansion may lead to //.
|
||||
org_source = source
|
||||
|
|
@ -217,23 +217,23 @@ def _ExtractSources(target, target_dict, toplevel_dir):
|
|||
|
||||
class Target:
|
||||
"""Holds information about a particular target:
|
||||
deps: set of Targets this Target depends upon. This is not recursive, only the
|
||||
direct dependent Targets.
|
||||
match_status: one of the MatchStatus values.
|
||||
back_deps: set of Targets that have a dependency on this Target.
|
||||
visited: used during iteration to indicate whether we've visited this target.
|
||||
This is used for two iterations, once in building the set of Targets and
|
||||
again in _GetBuildTargets().
|
||||
name: fully qualified name of the target.
|
||||
requires_build: True if the target type is such that it needs to be built.
|
||||
See _DoesTargetTypeRequireBuild for details.
|
||||
added_to_compile_targets: used when determining if the target was added to the
|
||||
set of targets that needs to be built.
|
||||
in_roots: true if this target is a descendant of one of the root nodes.
|
||||
is_executable: true if the type of target is executable.
|
||||
is_static_library: true if the type of target is static_library.
|
||||
is_or_has_linked_ancestor: true if the target does a link (eg executable), or
|
||||
if there is a target in back_deps that does a link."""
|
||||
deps: set of Targets this Target depends upon. This is not recursive, only the
|
||||
direct dependent Targets.
|
||||
match_status: one of the MatchStatus values.
|
||||
back_deps: set of Targets that have a dependency on this Target.
|
||||
visited: used during iteration to indicate whether we've visited this target.
|
||||
This is used for two iterations, once in building the set of Targets and
|
||||
again in _GetBuildTargets().
|
||||
name: fully qualified name of the target.
|
||||
requires_build: True if the target type is such that it needs to be built.
|
||||
See _DoesTargetTypeRequireBuild for details.
|
||||
added_to_compile_targets: used when determining if the target was added to the
|
||||
set of targets that needs to be built.
|
||||
in_roots: true if this target is a descendant of one of the root nodes.
|
||||
is_executable: true if the type of target is executable.
|
||||
is_static_library: true if the type of target is static_library.
|
||||
is_or_has_linked_ancestor: true if the target does a link (eg executable), or
|
||||
if there is a target in back_deps that does a link."""
|
||||
|
||||
def __init__(self, name):
|
||||
self.deps = set()
|
||||
|
|
@ -253,8 +253,8 @@ class Target:
|
|||
|
||||
class Config:
|
||||
"""Details what we're looking for
|
||||
files: set of files to search for
|
||||
targets: see file description for details."""
|
||||
files: set of files to search for
|
||||
targets: see file description for details."""
|
||||
|
||||
def __init__(self):
|
||||
self.files = []
|
||||
|
|
@ -264,7 +264,7 @@ class Config:
|
|||
|
||||
def Init(self, params):
|
||||
"""Initializes Config. This is a separate method as it raises an exception
|
||||
if there is a parse error."""
|
||||
if there is a parse error."""
|
||||
generator_flags = params.get("generator_flags", {})
|
||||
config_path = generator_flags.get("config_path", None)
|
||||
if not config_path:
|
||||
|
|
@ -288,8 +288,8 @@ class Config:
|
|||
|
||||
def _WasBuildFileModified(build_file, data, files, toplevel_dir):
|
||||
"""Returns true if the build file |build_file| is either in |files| or
|
||||
one of the files included by |build_file| is in |files|. |toplevel_dir| is
|
||||
the root of the source tree."""
|
||||
one of the files included by |build_file| is in |files|. |toplevel_dir| is
|
||||
the root of the source tree."""
|
||||
if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files:
|
||||
if debug:
|
||||
print("gyp file modified", build_file)
|
||||
|
|
@ -318,8 +318,8 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir):
|
|||
|
||||
def _GetOrCreateTargetByName(targets, target_name):
|
||||
"""Creates or returns the Target at targets[target_name]. If there is no
|
||||
Target for |target_name| one is created. Returns a tuple of whether a new
|
||||
Target was created and the Target."""
|
||||
Target for |target_name| one is created. Returns a tuple of whether a new
|
||||
Target was created and the Target."""
|
||||
if target_name in targets:
|
||||
return False, targets[target_name]
|
||||
target = Target(target_name)
|
||||
|
|
@ -339,13 +339,13 @@ def _DoesTargetTypeRequireBuild(target_dict):
|
|||
|
||||
def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build_files):
|
||||
"""Returns a tuple of the following:
|
||||
. A dictionary mapping from fully qualified name to Target.
|
||||
. A list of the targets that have a source file in |files|.
|
||||
. Targets that constitute the 'all' target. See description at top of file
|
||||
for details on the 'all' target.
|
||||
This sets the |match_status| of the targets that contain any of the source
|
||||
files in |files| to MATCH_STATUS_MATCHES.
|
||||
|toplevel_dir| is the root of the source tree."""
|
||||
. A dictionary mapping from fully qualified name to Target.
|
||||
. A list of the targets that have a source file in |files|.
|
||||
. Targets that constitute the 'all' target. See description at top of file
|
||||
for details on the 'all' target.
|
||||
This sets the |match_status| of the targets that contain any of the source
|
||||
files in |files| to MATCH_STATUS_MATCHES.
|
||||
|toplevel_dir| is the root of the source tree."""
|
||||
# Maps from target name to Target.
|
||||
name_to_target = {}
|
||||
|
||||
|
|
@ -378,9 +378,10 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build
|
|||
target_type = target_dicts[target_name]["type"]
|
||||
target.is_executable = target_type == "executable"
|
||||
target.is_static_library = target_type == "static_library"
|
||||
target.is_or_has_linked_ancestor = (
|
||||
target_type == "executable" or target_type == "shared_library"
|
||||
)
|
||||
target.is_or_has_linked_ancestor = target_type in {
|
||||
"executable",
|
||||
"shared_library",
|
||||
}
|
||||
|
||||
build_file = gyp.common.ParseQualifiedTarget(target_name)[0]
|
||||
if build_file not in build_file_in_files:
|
||||
|
|
@ -426,34 +427,34 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build
|
|||
|
||||
def _GetUnqualifiedToTargetMapping(all_targets, to_find):
|
||||
"""Returns a tuple of the following:
|
||||
. mapping (dictionary) from unqualified name to Target for all the
|
||||
Targets in |to_find|.
|
||||
. any target names not found. If this is empty all targets were found."""
|
||||
. mapping (dictionary) from unqualified name to Target for all the
|
||||
Targets in |to_find|.
|
||||
. any target names not found. If this is empty all targets were found."""
|
||||
result = {}
|
||||
if not to_find:
|
||||
return {}, []
|
||||
to_find = set(to_find)
|
||||
for target_name in all_targets.keys():
|
||||
for target_name in all_targets:
|
||||
extracted = gyp.common.ParseQualifiedTarget(target_name)
|
||||
if len(extracted) > 1 and extracted[1] in to_find:
|
||||
to_find.remove(extracted[1])
|
||||
result[extracted[1]] = all_targets[target_name]
|
||||
if not to_find:
|
||||
return result, []
|
||||
return result, [x for x in to_find]
|
||||
return result, list(to_find)
|
||||
|
||||
|
||||
def _DoesTargetDependOnMatchingTargets(target):
|
||||
"""Returns true if |target| or any of its dependencies is one of the
|
||||
targets containing the files supplied as input to analyzer. This updates
|
||||
|matches| of the Targets as it recurses.
|
||||
target: the Target to look for."""
|
||||
targets containing the files supplied as input to analyzer. This updates
|
||||
|matches| of the Targets as it recurses.
|
||||
target: the Target to look for."""
|
||||
if target.match_status == MATCH_STATUS_DOESNT_MATCH:
|
||||
return False
|
||||
if (
|
||||
target.match_status == MATCH_STATUS_MATCHES
|
||||
or target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY
|
||||
):
|
||||
if target.match_status in {
|
||||
MATCH_STATUS_MATCHES,
|
||||
MATCH_STATUS_MATCHES_BY_DEPENDENCY,
|
||||
}:
|
||||
return True
|
||||
for dep in target.deps:
|
||||
if _DoesTargetDependOnMatchingTargets(dep):
|
||||
|
|
@ -466,9 +467,9 @@ def _DoesTargetDependOnMatchingTargets(target):
|
|||
|
||||
def _GetTargetsDependingOnMatchingTargets(possible_targets):
|
||||
"""Returns the list of Targets in |possible_targets| that depend (either
|
||||
directly on indirectly) on at least one of the targets containing the files
|
||||
supplied as input to analyzer.
|
||||
possible_targets: targets to search from."""
|
||||
directly on indirectly) on at least one of the targets containing the files
|
||||
supplied as input to analyzer.
|
||||
possible_targets: targets to search from."""
|
||||
found = []
|
||||
print("Targets that matched by dependency:")
|
||||
for target in possible_targets:
|
||||
|
|
@ -479,11 +480,11 @@ def _GetTargetsDependingOnMatchingTargets(possible_targets):
|
|||
|
||||
def _AddCompileTargets(target, roots, add_if_no_ancestor, result):
|
||||
"""Recurses through all targets that depend on |target|, adding all targets
|
||||
that need to be built (and are in |roots|) to |result|.
|
||||
roots: set of root targets.
|
||||
add_if_no_ancestor: If true and there are no ancestors of |target| then add
|
||||
|target| to |result|. |target| must still be in |roots|.
|
||||
result: targets that need to be built are added here."""
|
||||
that need to be built (and are in |roots|) to |result|.
|
||||
roots: set of root targets.
|
||||
add_if_no_ancestor: If true and there are no ancestors of |target| then add
|
||||
|target| to |result|. |target| must still be in |roots|.
|
||||
result: targets that need to be built are added here."""
|
||||
if target.visited:
|
||||
return
|
||||
|
||||
|
|
@ -536,8 +537,8 @@ def _AddCompileTargets(target, roots, add_if_no_ancestor, result):
|
|||
|
||||
def _GetCompileTargets(matching_targets, supplied_targets):
|
||||
"""Returns the set of Targets that require a build.
|
||||
matching_targets: targets that changed and need to be built.
|
||||
supplied_targets: set of targets supplied to analyzer to search from."""
|
||||
matching_targets: targets that changed and need to be built.
|
||||
supplied_targets: set of targets supplied to analyzer to search from."""
|
||||
result = set()
|
||||
for target in matching_targets:
|
||||
print("finding compile targets for match", target.name)
|
||||
|
|
@ -591,7 +592,7 @@ def _WriteOutput(params, **values):
|
|||
|
||||
def _WasGypIncludeFileModified(params, files):
|
||||
"""Returns true if one of the files in |files| is in the set of included
|
||||
files."""
|
||||
files."""
|
||||
if params["options"].includes:
|
||||
for include in params["options"].includes:
|
||||
if _ToGypPath(os.path.normpath(include)) in files:
|
||||
|
|
@ -607,7 +608,7 @@ def _NamesNotIn(names, mapping):
|
|||
|
||||
def _LookupTargets(names, mapping):
|
||||
"""Returns a list of the mapping[name] for each value in |names| that is in
|
||||
|mapping|."""
|
||||
|mapping|."""
|
||||
return [mapping[name] for name in names if name in mapping]
|
||||
|
||||
|
||||
|
|
@ -683,11 +684,9 @@ class TargetCalculator:
|
|||
)
|
||||
test_target_names_contains_all = "all" in self._test_target_names
|
||||
if test_target_names_contains_all:
|
||||
test_targets = [
|
||||
x for x in (set(test_targets_no_all) | set(self._root_targets))
|
||||
]
|
||||
test_targets = list(set(test_targets_no_all) | set(self._root_targets))
|
||||
else:
|
||||
test_targets = [x for x in test_targets_no_all]
|
||||
test_targets = list(test_targets_no_all)
|
||||
print("supplied test_targets")
|
||||
for target_name in self._test_target_names:
|
||||
print("\t", target_name)
|
||||
|
|
@ -701,10 +700,10 @@ class TargetCalculator:
|
|||
) & set(self._root_targets)
|
||||
if matching_test_targets_contains_all:
|
||||
# Remove any of the targets for all that were not explicitly supplied,
|
||||
# 'all' is subsequentely added to the matching names below.
|
||||
matching_test_targets = [
|
||||
x for x in (set(matching_test_targets) & set(test_targets_no_all))
|
||||
]
|
||||
# 'all' is subsequently added to the matching names below.
|
||||
matching_test_targets = list(
|
||||
set(matching_test_targets) & set(test_targets_no_all)
|
||||
)
|
||||
print("matched test_targets")
|
||||
for target in matching_test_targets:
|
||||
print("\t", target.name)
|
||||
|
|
@ -729,9 +728,7 @@ class TargetCalculator:
|
|||
self._supplied_target_names_no_all(), self._unqualified_mapping
|
||||
)
|
||||
if "all" in self._supplied_target_names():
|
||||
supplied_targets = [
|
||||
x for x in (set(supplied_targets) | set(self._root_targets))
|
||||
]
|
||||
supplied_targets = list(set(supplied_targets) | set(self._root_targets))
|
||||
print("Supplied test_targets & compile_targets")
|
||||
for target in supplied_targets:
|
||||
print("\t", target.name)
|
||||
|
|
@ -751,7 +748,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
|
||||
if not config.files:
|
||||
raise Exception(
|
||||
"Must specify files to analyze via config_path generator " "flag"
|
||||
"Must specify files to analyze via config_path generator flag"
|
||||
)
|
||||
|
||||
toplevel_dir = _ToGypPath(os.path.abspath(params["options"].toplevel_dir))
|
||||
|
|
|
|||
70
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
generated
vendored
70
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
generated
vendored
|
|
@ -15,13 +15,14 @@
|
|||
# Try to avoid setting global variables where possible.
|
||||
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.generator.make as make # Reuse global functions from make backend.
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
from gyp.generator import make # Reuse global functions from make backend.
|
||||
|
||||
generator_default_variables = {
|
||||
"OS": "android",
|
||||
"EXECUTABLE_PREFIX": "",
|
||||
|
|
@ -176,9 +177,7 @@ class AndroidMkWriter:
|
|||
self.WriteLn("LOCAL_IS_HOST_MODULE := true")
|
||||
self.WriteLn("LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)")
|
||||
elif sdk_version > 0:
|
||||
self.WriteLn(
|
||||
"LOCAL_MODULE_TARGET_ARCH := " "$(TARGET_$(GYP_VAR_PREFIX)ARCH)"
|
||||
)
|
||||
self.WriteLn("LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)")
|
||||
self.WriteLn("LOCAL_SDK_VERSION := %s" % sdk_version)
|
||||
|
||||
# Grab output directories; needed for Actions and Rules.
|
||||
|
|
@ -379,7 +378,7 @@ class AndroidMkWriter:
|
|||
inputs = rule.get("inputs")
|
||||
for rule_source in rule.get("rule_sources", []):
|
||||
(rule_source_dirname, rule_source_basename) = os.path.split(rule_source)
|
||||
(rule_source_root, rule_source_ext) = os.path.splitext(
|
||||
(rule_source_root, _rule_source_ext) = os.path.splitext(
|
||||
rule_source_basename
|
||||
)
|
||||
|
||||
|
|
@ -587,11 +586,11 @@ class AndroidMkWriter:
|
|||
local_files = []
|
||||
for source in sources:
|
||||
(root, ext) = os.path.splitext(source)
|
||||
if "$(gyp_shared_intermediate_dir)" in source:
|
||||
extra_sources.append(source)
|
||||
elif "$(gyp_intermediate_dir)" in source:
|
||||
extra_sources.append(source)
|
||||
elif IsCPPExtension(ext) and ext != local_cpp_extension:
|
||||
if (
|
||||
"$(gyp_shared_intermediate_dir)" in source
|
||||
or "$(gyp_intermediate_dir)" in source
|
||||
or (IsCPPExtension(ext) and ext != local_cpp_extension)
|
||||
):
|
||||
extra_sources.append(source)
|
||||
else:
|
||||
local_files.append(os.path.normpath(os.path.join(self.path, source)))
|
||||
|
|
@ -697,7 +696,7 @@ class AndroidMkWriter:
|
|||
target,
|
||||
)
|
||||
|
||||
if self.type != "static_library" and self.type != "shared_library":
|
||||
if self.type not in {"static_library", "shared_library"}:
|
||||
target_prefix = spec.get("product_prefix", target_prefix)
|
||||
target = spec.get("product_name", target)
|
||||
product_ext = spec.get("product_extension")
|
||||
|
|
@ -730,19 +729,17 @@ class AndroidMkWriter:
|
|||
path = "$($(GYP_HOST_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)"
|
||||
else:
|
||||
path = "$($(GYP_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)"
|
||||
# Other targets just get built into their intermediate dir.
|
||||
elif self.toolset == "host":
|
||||
path = (
|
||||
"$(call intermediates-dir-for,%s,%s,true,,"
|
||||
"$(GYP_HOST_VAR_PREFIX))" % (self.android_class, self.android_module)
|
||||
)
|
||||
else:
|
||||
# Other targets just get built into their intermediate dir.
|
||||
if self.toolset == "host":
|
||||
path = (
|
||||
"$(call intermediates-dir-for,%s,%s,true,,"
|
||||
"$(GYP_HOST_VAR_PREFIX))"
|
||||
% (self.android_class, self.android_module)
|
||||
)
|
||||
else:
|
||||
path = "$(call intermediates-dir-for,{},{},,,$(GYP_VAR_PREFIX))".format(
|
||||
self.android_class,
|
||||
self.android_module,
|
||||
)
|
||||
path = (
|
||||
f"$(call intermediates-dir-for,{self.android_class},"
|
||||
f"{self.android_module},,,$(GYP_VAR_PREFIX))"
|
||||
)
|
||||
|
||||
assert spec.get("product_dir") is None # TODO: not supported?
|
||||
return os.path.join(path, self.ComputeOutputBasename(spec))
|
||||
|
|
@ -769,7 +766,7 @@ class AndroidMkWriter:
|
|||
Args:
|
||||
cflags: A list of compiler flags, which may be mixed with "-I.."
|
||||
Returns:
|
||||
A tuple of lists: (clean_clfags, include_paths). "-I.." is trimmed.
|
||||
A tuple of lists: (clean_cflags, include_paths). "-I.." is trimmed.
|
||||
"""
|
||||
clean_cflags = []
|
||||
include_paths = []
|
||||
|
|
@ -901,8 +898,7 @@ class AndroidMkWriter:
|
|||
if self.type != "none":
|
||||
self.WriteTargetFlags(spec, configs, link_deps)
|
||||
|
||||
settings = spec.get("aosp_build_settings", {})
|
||||
if settings:
|
||||
if settings := spec.get("aosp_build_settings", {}):
|
||||
self.WriteLn("### Set directly by aosp_build_settings.")
|
||||
for k, v in settings.items():
|
||||
if isinstance(v, list):
|
||||
|
|
@ -1003,9 +999,9 @@ class AndroidMkWriter:
|
|||
# - i.e. that the resulting path is still inside the project tree. The
|
||||
# path may legitimately have ended up containing just $(LOCAL_PATH), though,
|
||||
# so we don't look for a slash.
|
||||
assert local_path.startswith(
|
||||
"$(LOCAL_PATH)"
|
||||
), f"Path {path} attempts to escape from gyp path {self.path} !)"
|
||||
assert local_path.startswith("$(LOCAL_PATH)"), (
|
||||
f"Path {path} attempts to escape from gyp path {self.path} !)"
|
||||
)
|
||||
return local_path
|
||||
|
||||
def ExpandInputRoot(self, template, expansion, dirname):
|
||||
|
|
@ -1047,9 +1043,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
base_path = gyp.common.RelativePath(os.path.dirname(build_file), options.depth)
|
||||
# We write the file in the base_path directory.
|
||||
output_file = os.path.join(options.depth, base_path, base_name)
|
||||
assert (
|
||||
not options.generator_output
|
||||
), "The Android backend does not support options.generator_output."
|
||||
assert not options.generator_output, (
|
||||
"The Android backend does not support options.generator_output."
|
||||
)
|
||||
base_path = gyp.common.RelativePath(
|
||||
os.path.dirname(build_file), options.toplevel_dir
|
||||
)
|
||||
|
|
@ -1069,9 +1065,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
|
||||
makefile_name = "GypAndroid" + options.suffix + ".mk"
|
||||
makefile_path = os.path.join(options.toplevel_dir, makefile_name)
|
||||
assert (
|
||||
not options.generator_output
|
||||
), "The Android backend does not support options.generator_output."
|
||||
assert not options.generator_output, (
|
||||
"The Android backend does not support options.generator_output."
|
||||
)
|
||||
gyp.common.EnsureDirExists(makefile_path)
|
||||
root_makefile = open(makefile_path, "w")
|
||||
|
||||
|
|
|
|||
149
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py
generated
vendored
149
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py
generated
vendored
|
|
@ -28,11 +28,11 @@ not be able to find the header file directories described in the generated
|
|||
CMakeLists.txt file.
|
||||
"""
|
||||
|
||||
|
||||
import multiprocessing
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
import gyp.common
|
||||
import gyp.xcode_emulation
|
||||
|
||||
|
|
@ -96,14 +96,14 @@ def Linkable(filename):
|
|||
def NormjoinPathForceCMakeSource(base_path, rel_path):
|
||||
"""Resolves rel_path against base_path and returns the result.
|
||||
|
||||
If rel_path is an absolute path it is returned unchanged.
|
||||
Otherwise it is resolved against base_path and normalized.
|
||||
If the result is a relative path, it is forced to be relative to the
|
||||
CMakeLists.txt.
|
||||
"""
|
||||
If rel_path is an absolute path it is returned unchanged.
|
||||
Otherwise it is resolved against base_path and normalized.
|
||||
If the result is a relative path, it is forced to be relative to the
|
||||
CMakeLists.txt.
|
||||
"""
|
||||
if os.path.isabs(rel_path):
|
||||
return rel_path
|
||||
if any([rel_path.startswith(var) for var in FULL_PATH_VARS]):
|
||||
if any(rel_path.startswith(var) for var in FULL_PATH_VARS):
|
||||
return rel_path
|
||||
# TODO: do we need to check base_path for absolute variables as well?
|
||||
return os.path.join(
|
||||
|
|
@ -113,10 +113,10 @@ def NormjoinPathForceCMakeSource(base_path, rel_path):
|
|||
|
||||
def NormjoinPath(base_path, rel_path):
|
||||
"""Resolves rel_path against base_path and returns the result.
|
||||
TODO: what is this really used for?
|
||||
If rel_path begins with '$' it is returned unchanged.
|
||||
Otherwise it is resolved against base_path if relative, then normalized.
|
||||
"""
|
||||
TODO: what is this really used for?
|
||||
If rel_path begins with '$' it is returned unchanged.
|
||||
Otherwise it is resolved against base_path if relative, then normalized.
|
||||
"""
|
||||
if rel_path.startswith("$") and not rel_path.startswith("${configuration}"):
|
||||
return rel_path
|
||||
return os.path.normpath(os.path.join(base_path, rel_path))
|
||||
|
|
@ -125,19 +125,19 @@ def NormjoinPath(base_path, rel_path):
|
|||
def CMakeStringEscape(a):
|
||||
"""Escapes the string 'a' for use inside a CMake string.
|
||||
|
||||
This means escaping
|
||||
'\' otherwise it may be seen as modifying the next character
|
||||
'"' otherwise it will end the string
|
||||
';' otherwise the string becomes a list
|
||||
This means escaping
|
||||
'\' otherwise it may be seen as modifying the next character
|
||||
'"' otherwise it will end the string
|
||||
';' otherwise the string becomes a list
|
||||
|
||||
The following do not need to be escaped
|
||||
'#' when the lexer is in string state, this does not start a comment
|
||||
The following do not need to be escaped
|
||||
'#' when the lexer is in string state, this does not start a comment
|
||||
|
||||
The following are yet unknown
|
||||
'$' generator variables (like ${obj}) must not be escaped,
|
||||
but text $ should be escaped
|
||||
what is wanted is to know which $ come from generator variables
|
||||
"""
|
||||
The following are yet unknown
|
||||
'$' generator variables (like ${obj}) must not be escaped,
|
||||
but text $ should be escaped
|
||||
what is wanted is to know which $ come from generator variables
|
||||
"""
|
||||
return a.replace("\\", "\\\\").replace(";", "\\;").replace('"', '\\"')
|
||||
|
||||
|
||||
|
|
@ -236,25 +236,25 @@ cmake_target_type_from_gyp_target_type = {
|
|||
def StringToCMakeTargetName(a):
|
||||
"""Converts the given string 'a' to a valid CMake target name.
|
||||
|
||||
All invalid characters are replaced by '_'.
|
||||
Invalid for cmake: ' ', '/', '(', ')', '"'
|
||||
Invalid for make: ':'
|
||||
Invalid for unknown reasons but cause failures: '.'
|
||||
"""
|
||||
All invalid characters are replaced by '_'.
|
||||
Invalid for cmake: ' ', '/', '(', ')', '"'
|
||||
Invalid for make: ':'
|
||||
Invalid for unknown reasons but cause failures: '.'
|
||||
"""
|
||||
return a.translate(_maketrans(' /():."', "_______"))
|
||||
|
||||
|
||||
def WriteActions(target_name, actions, extra_sources, extra_deps, path_to_gyp, output):
|
||||
"""Write CMake for the 'actions' in the target.
|
||||
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
|
||||
extra_deps: [<cmake_taget>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
|
||||
extra_deps: [<cmake_target>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
for action in actions:
|
||||
action_name = StringToCMakeTargetName(action["action_name"])
|
||||
action_target_name = f"{target_name}__{action_name}"
|
||||
|
|
@ -328,7 +328,7 @@ def WriteActions(target_name, actions, extra_sources, extra_deps, path_to_gyp, o
|
|||
|
||||
def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source):
|
||||
if rel_path.startswith(("${RULE_INPUT_PATH}", "${RULE_INPUT_DIRNAME}")):
|
||||
if any([rule_source.startswith(var) for var in FULL_PATH_VARS]):
|
||||
if any(rule_source.startswith(var) for var in FULL_PATH_VARS):
|
||||
return rel_path
|
||||
return NormjoinPathForceCMakeSource(base_path, rel_path)
|
||||
|
||||
|
|
@ -336,14 +336,14 @@ def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source):
|
|||
def WriteRules(target_name, rules, extra_sources, extra_deps, path_to_gyp, output):
|
||||
"""Write CMake for the 'rules' in the target.
|
||||
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
|
||||
extra_deps: [<cmake_taget>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
|
||||
extra_deps: [<cmake_target>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
for rule in rules:
|
||||
rule_name = StringToCMakeTargetName(target_name + "__" + rule["rule_name"])
|
||||
|
||||
|
|
@ -454,13 +454,13 @@ def WriteRules(target_name, rules, extra_sources, extra_deps, path_to_gyp, outpu
|
|||
def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output):
|
||||
"""Write CMake for the 'copies' in the target.
|
||||
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_deps: [<cmake_taget>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
Args:
|
||||
target_name: the name of the CMake target being generated.
|
||||
actions: the Gyp 'actions' dict for this target.
|
||||
extra_deps: [<cmake_target>] to append with generated targets.
|
||||
path_to_gyp: relative path from CMakeLists.txt being generated to
|
||||
the Gyp file in which the target being generated is defined.
|
||||
"""
|
||||
copy_name = target_name + "__copies"
|
||||
|
||||
# CMake gets upset with custom targets with OUTPUT which specify no output.
|
||||
|
|
@ -584,26 +584,26 @@ def CreateCMakeTargetFullName(qualified_target):
|
|||
class CMakeNamer:
|
||||
"""Converts Gyp target names into CMake target names.
|
||||
|
||||
CMake requires that target names be globally unique. One way to ensure
|
||||
this is to fully qualify the names of the targets. Unfortunately, this
|
||||
ends up with all targets looking like "chrome_chrome_gyp_chrome" instead
|
||||
of just "chrome". If this generator were only interested in building, it
|
||||
would be possible to fully qualify all target names, then create
|
||||
unqualified target names which depend on all qualified targets which
|
||||
should have had that name. This is more or less what the 'make' generator
|
||||
does with aliases. However, one goal of this generator is to create CMake
|
||||
files for use with IDEs, and fully qualified names are not as user
|
||||
friendly.
|
||||
CMake requires that target names be globally unique. One way to ensure
|
||||
this is to fully qualify the names of the targets. Unfortunately, this
|
||||
ends up with all targets looking like "chrome_chrome_gyp_chrome" instead
|
||||
of just "chrome". If this generator were only interested in building, it
|
||||
would be possible to fully qualify all target names, then create
|
||||
unqualified target names which depend on all qualified targets which
|
||||
should have had that name. This is more or less what the 'make' generator
|
||||
does with aliases. However, one goal of this generator is to create CMake
|
||||
files for use with IDEs, and fully qualified names are not as user
|
||||
friendly.
|
||||
|
||||
Since target name collision is rare, we do the above only when required.
|
||||
Since target name collision is rare, we do the above only when required.
|
||||
|
||||
Toolset variants are always qualified from the base, as this is required for
|
||||
building. However, it also makes sense for an IDE, as it is possible for
|
||||
defines to be different.
|
||||
"""
|
||||
Toolset variants are always qualified from the base, as this is required for
|
||||
building. However, it also makes sense for an IDE, as it is possible for
|
||||
defines to be different.
|
||||
"""
|
||||
|
||||
def __init__(self, target_list):
|
||||
self.cmake_target_base_names_conficting = set()
|
||||
self.cmake_target_base_names_conflicting = set()
|
||||
|
||||
cmake_target_base_names_seen = set()
|
||||
for qualified_target in target_list:
|
||||
|
|
@ -612,11 +612,11 @@ class CMakeNamer:
|
|||
if cmake_target_base_name not in cmake_target_base_names_seen:
|
||||
cmake_target_base_names_seen.add(cmake_target_base_name)
|
||||
else:
|
||||
self.cmake_target_base_names_conficting.add(cmake_target_base_name)
|
||||
self.cmake_target_base_names_conflicting.add(cmake_target_base_name)
|
||||
|
||||
def CreateCMakeTargetName(self, qualified_target):
|
||||
base_name = CreateCMakeTargetBaseName(qualified_target)
|
||||
if base_name in self.cmake_target_base_names_conficting:
|
||||
if base_name in self.cmake_target_base_names_conflicting:
|
||||
return CreateCMakeTargetFullName(qualified_target)
|
||||
return base_name
|
||||
|
||||
|
|
@ -809,8 +809,7 @@ def WriteTarget(
|
|||
# link directories to targets defined after it is called.
|
||||
# As a result, link_directories must come before the target definition.
|
||||
# CMake unfortunately has no means of removing entries from LINK_DIRECTORIES.
|
||||
library_dirs = config.get("library_dirs")
|
||||
if library_dirs is not None:
|
||||
if (library_dirs := config.get("library_dirs")) is not None:
|
||||
output.write("link_directories(")
|
||||
for library_dir in library_dirs:
|
||||
output.write(" ")
|
||||
|
|
@ -929,10 +928,7 @@ def WriteTarget(
|
|||
product_prefix = spec.get("product_prefix", default_product_prefix)
|
||||
product_name = spec.get("product_name", default_product_name)
|
||||
product_ext = spec.get("product_extension")
|
||||
if product_ext:
|
||||
product_ext = "." + product_ext
|
||||
else:
|
||||
product_ext = default_product_ext
|
||||
product_ext = "." + product_ext if product_ext else default_product_ext
|
||||
|
||||
SetTargetProperty(output, cmake_target_name, "PREFIX", product_prefix)
|
||||
SetTargetProperty(
|
||||
|
|
@ -1297,8 +1293,7 @@ def CallGenerateOutputForConfig(arglist):
|
|||
|
||||
|
||||
def GenerateOutput(target_list, target_dicts, data, params):
|
||||
user_config = params.get("generator_flags", {}).get("config", None)
|
||||
if user_config:
|
||||
if user_config := params.get("generator_flags", {}).get("config", None):
|
||||
GenerateOutputForConfig(target_list, target_dicts, data, params, user_config)
|
||||
else:
|
||||
config_names = target_dicts[target_list[0]]["configurations"]
|
||||
|
|
|
|||
20
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py
generated
vendored
20
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py
generated
vendored
|
|
@ -2,11 +2,12 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import gyp.common
|
||||
import gyp.xcode_emulation
|
||||
import json
|
||||
import os
|
||||
|
||||
import gyp.common
|
||||
import gyp.xcode_emulation
|
||||
|
||||
generator_additional_non_configuration_keys = []
|
||||
generator_additional_path_sections = []
|
||||
generator_extra_sources_for_rules = []
|
||||
|
|
@ -34,7 +35,7 @@ generator_default_variables = {
|
|||
|
||||
|
||||
def IsMac(params):
|
||||
return "mac" == gyp.common.GetFlavor(params)
|
||||
return gyp.common.GetFlavor(params) == "mac"
|
||||
|
||||
|
||||
def CalculateVariables(default_variables, params):
|
||||
|
|
@ -93,13 +94,13 @@ def AddCommandsForTarget(cwd, target, params, per_config_commands):
|
|||
gyp.common.EncodePOSIXShellArgument(file),
|
||||
)
|
||||
)
|
||||
commands.append(dict(command=command, directory=output_dir, file=file))
|
||||
commands.append({"command": command, "directory": output_dir, "file": file})
|
||||
|
||||
|
||||
def GenerateOutput(target_list, target_dicts, data, params):
|
||||
per_config_commands = {}
|
||||
for qualified_target, target in target_dicts.items():
|
||||
build_file, target_name, toolset = gyp.common.ParseQualifiedTarget(
|
||||
build_file, _target_name, _toolset = gyp.common.ParseQualifiedTarget(
|
||||
qualified_target
|
||||
)
|
||||
if IsMac(params):
|
||||
|
|
@ -108,7 +109,14 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
cwd = os.path.dirname(build_file)
|
||||
AddCommandsForTarget(cwd, target, params, per_config_commands)
|
||||
|
||||
output_dir = params["generator_flags"].get("output_dir", "out")
|
||||
output_dir = None
|
||||
try:
|
||||
# generator_output can be `None` on Windows machines, or even not
|
||||
# defined in other cases
|
||||
output_dir = params.get("options").generator_output
|
||||
except AttributeError:
|
||||
pass
|
||||
output_dir = output_dir or params["generator_flags"].get("output_dir", "out")
|
||||
for configuration_name, commands in per_config_commands.items():
|
||||
filename = os.path.join(output_dir, configuration_name, "compile_commands.json")
|
||||
gyp.common.EnsureDirExists(filename)
|
||||
|
|
|
|||
5
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py
generated
vendored
5
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py
generated
vendored
|
|
@ -3,11 +3,12 @@
|
|||
# found in the LICENSE file.
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.msvs_emulation
|
||||
import json
|
||||
|
||||
generator_supports_multiple_toolsets = True
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ def CalculateVariables(default_variables, params):
|
|||
|
||||
def CalculateGeneratorInputInfo(params):
|
||||
"""Calculate the generator specific info that gets fed to input (called by
|
||||
gyp)."""
|
||||
gyp)."""
|
||||
generator_flags = params.get("generator_flags", {})
|
||||
if generator_flags.get("adjust_static_libraries", False):
|
||||
global generator_wants_static_library_dependencies_adjusted
|
||||
|
|
|
|||
47
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
generated
vendored
47
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
generated
vendored
|
|
@ -17,14 +17,15 @@ still result in a few indexer issues here and there.
|
|||
This generator has no automated tests, so expect it to be broken.
|
||||
"""
|
||||
|
||||
from xml.sax.saxutils import escape
|
||||
import os.path
|
||||
import shlex
|
||||
import subprocess
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.msvs_emulation
|
||||
import shlex
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
generator_wants_static_library_dependencies_adjusted = False
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ def CalculateVariables(default_variables, params):
|
|||
|
||||
def CalculateGeneratorInputInfo(params):
|
||||
"""Calculate the generator specific info that gets fed to input (called by
|
||||
gyp)."""
|
||||
gyp)."""
|
||||
generator_flags = params.get("generator_flags", {})
|
||||
if generator_flags.get("adjust_static_libraries", False):
|
||||
global generator_wants_static_library_dependencies_adjusted
|
||||
|
|
@ -85,10 +86,10 @@ def GetAllIncludeDirectories(
|
|||
):
|
||||
"""Calculate the set of include directories to be used.
|
||||
|
||||
Returns:
|
||||
A list including all the include_dir's specified for every target followed
|
||||
by any include directories that were added as cflag compiler options.
|
||||
"""
|
||||
Returns:
|
||||
A list including all the include_dir's specified for every target followed
|
||||
by any include directories that were added as cflag compiler options.
|
||||
"""
|
||||
|
||||
gyp_includes_set = set()
|
||||
compiler_includes_list = []
|
||||
|
|
@ -177,11 +178,11 @@ def GetAllIncludeDirectories(
|
|||
def GetCompilerPath(target_list, data, options):
|
||||
"""Determine a command that can be used to invoke the compiler.
|
||||
|
||||
Returns:
|
||||
If this is a gyp project that has explicit make settings, try to determine
|
||||
the compiler from that. Otherwise, see if a compiler was specified via the
|
||||
CC_target environment variable.
|
||||
"""
|
||||
Returns:
|
||||
If this is a gyp project that has explicit make settings, try to determine
|
||||
the compiler from that. Otherwise, see if a compiler was specified via the
|
||||
CC_target environment variable.
|
||||
"""
|
||||
# First, see if the compiler is configured in make's settings.
|
||||
build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
|
||||
make_global_settings_dict = data[build_file].get("make_global_settings", {})
|
||||
|
|
@ -201,10 +202,10 @@ def GetCompilerPath(target_list, data, options):
|
|||
def GetAllDefines(target_list, target_dicts, data, config_name, params, compiler_path):
|
||||
"""Calculate the defines for a project.
|
||||
|
||||
Returns:
|
||||
A dict that includes explicit defines declared in gyp files along with all
|
||||
of the default defines that the compiler uses.
|
||||
"""
|
||||
Returns:
|
||||
A dict that includes explicit defines declared in gyp files along with all
|
||||
of the default defines that the compiler uses.
|
||||
"""
|
||||
|
||||
# Get defines declared in the gyp files.
|
||||
all_defines = {}
|
||||
|
|
@ -248,10 +249,7 @@ def GetAllDefines(target_list, target_dicts, data, config_name, params, compiler
|
|||
continue
|
||||
cpp_line_parts = cpp_line.split(" ", 2)
|
||||
key = cpp_line_parts[1]
|
||||
if len(cpp_line_parts) >= 3:
|
||||
val = cpp_line_parts[2]
|
||||
else:
|
||||
val = "1"
|
||||
val = cpp_line_parts[2] if len(cpp_line_parts) >= 3 else "1"
|
||||
all_defines[key] = val
|
||||
|
||||
return all_defines
|
||||
|
|
@ -375,8 +373,8 @@ def GenerateClasspathFile(
|
|||
target_list, target_dicts, toplevel_dir, toplevel_build, out_name
|
||||
):
|
||||
"""Generates a classpath file suitable for symbol navigation and code
|
||||
completion of Java code (such as in Android projects) by finding all
|
||||
.java and .jar files used as action inputs."""
|
||||
completion of Java code (such as in Android projects) by finding all
|
||||
.java and .jar files used as action inputs."""
|
||||
gyp.common.EnsureDirExists(out_name)
|
||||
result = ET.Element("classpath")
|
||||
|
||||
|
|
@ -453,8 +451,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
if params["options"].generator_output:
|
||||
raise NotImplementedError("--generator_output not implemented for eclipse")
|
||||
|
||||
user_config = params.get("generator_flags", {}).get("config", None)
|
||||
if user_config:
|
||||
if user_config := params.get("generator_flags", {}).get("config", None):
|
||||
GenerateOutputForConfig(target_list, target_dicts, data, params, user_config)
|
||||
else:
|
||||
config_names = target_dicts[target_list[0]]["configurations"]
|
||||
|
|
|
|||
5
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py
generated
vendored
5
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py
generated
vendored
|
|
@ -30,10 +30,9 @@ The specific formatting of the output generated by this module is subject
|
|||
to change.
|
||||
"""
|
||||
|
||||
|
||||
import gyp.common
|
||||
import pprint
|
||||
|
||||
import gyp.common
|
||||
|
||||
# These variables should just be spit back out as variable references.
|
||||
_generator_identity_variables = [
|
||||
|
|
@ -74,7 +73,7 @@ for v in _generator_identity_variables:
|
|||
def GenerateOutput(target_list, target_dicts, data, params):
|
||||
output_files = {}
|
||||
for qualified_target in target_list:
|
||||
[input_file, target] = gyp.common.ParseQualifiedTarget(qualified_target)[0:2]
|
||||
[input_file, _target] = gyp.common.ParseQualifiedTarget(qualified_target)[0:2]
|
||||
|
||||
if input_file[-4:] != ".gyp":
|
||||
continue
|
||||
|
|
|
|||
9
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py
generated
vendored
9
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py
generated
vendored
|
|
@ -13,11 +13,9 @@ by the input module.
|
|||
The expected usage is "gyp -f gypsh -D OS=desired_os".
|
||||
"""
|
||||
|
||||
|
||||
import code
|
||||
import sys
|
||||
|
||||
|
||||
# All of this stuff about generator variables was lovingly ripped from gypd.py.
|
||||
# That module has a much better description of what's going on and why.
|
||||
_generator_identity_variables = [
|
||||
|
|
@ -49,10 +47,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
# Use a banner that looks like the stock Python one and like what
|
||||
# code.interact uses by default, but tack on something to indicate what
|
||||
# locals are available, and identify gypsh.
|
||||
banner = "Python {} on {}\nlocals.keys() = {}\ngypsh".format(
|
||||
sys.version,
|
||||
sys.platform,
|
||||
repr(sorted(locals.keys())),
|
||||
banner = (
|
||||
f"Python {sys.version} on {sys.platform}\nlocals.keys() = "
|
||||
f"{sorted(locals.keys())!r}\ngypsh"
|
||||
)
|
||||
|
||||
code.interact(banner, local=locals)
|
||||
|
|
|
|||
201
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py
generated
vendored
201
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py
generated
vendored
|
|
@ -22,16 +22,17 @@
|
|||
# the side to keep the files readable.
|
||||
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.xcode_emulation
|
||||
from gyp.common import GetEnvironFallback
|
||||
|
||||
import hashlib
|
||||
|
||||
generator_default_variables = {
|
||||
"EXECUTABLE_PREFIX": "",
|
||||
"EXECUTABLE_SUFFIX": "",
|
||||
|
|
@ -77,7 +78,7 @@ def CalculateVariables(default_variables, params):
|
|||
|
||||
# Copy additional generator configuration data from Xcode, which is shared
|
||||
# by the Mac Make generator.
|
||||
import gyp.generator.xcode as xcode_generator
|
||||
import gyp.generator.xcode as xcode_generator # noqa: PLC0415
|
||||
|
||||
global generator_additional_non_configuration_keys
|
||||
generator_additional_non_configuration_keys = getattr(
|
||||
|
|
@ -207,7 +208,7 @@ cmd_solink_module = $(LINK.$(TOOLSET)) -o $@ -shared $(GYP_LDFLAGS) $(LDFLAGS.$(
|
|||
|
||||
LINK_COMMANDS_MAC = """\
|
||||
quiet_cmd_alink = LIBTOOL-STATIC $@
|
||||
cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^)
|
||||
cmd_alink = rm -f $@ && %(python)s gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %%.o,$^)
|
||||
|
||||
quiet_cmd_link = LINK($(TOOLSET)) $@
|
||||
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
|
||||
|
|
@ -217,7 +218,7 @@ cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o
|
|||
|
||||
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
|
||||
cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
|
||||
""" # noqa: E501
|
||||
""" % {"python": sys.executable} # noqa: E501
|
||||
|
||||
LINK_COMMANDS_ANDROID = """\
|
||||
quiet_cmd_alink = AR($(TOOLSET)) $@
|
||||
|
|
@ -378,7 +379,7 @@ CXX.target ?= %(CXX.target)s
|
|||
CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS)
|
||||
LINK.target ?= %(LINK.target)s
|
||||
LDFLAGS.target ?= $(LDFLAGS)
|
||||
AR.target ?= $(AR)
|
||||
AR.target ?= %(AR.target)s
|
||||
PLI.target ?= %(PLI.target)s
|
||||
|
||||
# C++ apps need to be linked with g++.
|
||||
|
|
@ -442,13 +443,27 @@ DEPFLAGS = %(makedep_args)s -MF $(depfile).raw
|
|||
define fixup_dep
|
||||
# The depfile may not exist if the input file didn't have any #includes.
|
||||
touch $(depfile).raw
|
||||
# Fixup path as in (1).
|
||||
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
|
||||
# Fixup path as in (1)."""
|
||||
+ (
|
||||
r"""
|
||||
sed -e "s|^$(notdir $@)|$@|" -re 's/\\\\([^$$])/\/\1/g' $(depfile).raw >> $(depfile)"""
|
||||
if sys.platform == "win32"
|
||||
else r"""
|
||||
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)"""
|
||||
)
|
||||
+ r"""
|
||||
# Add extra rules as in (2).
|
||||
# We remove slashes and replace spaces with new lines;
|
||||
# remove blank lines;
|
||||
# delete the first line and append a colon to the remaining lines.
|
||||
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
|
||||
# delete the first line and append a colon to the remaining lines."""
|
||||
+ (
|
||||
"""
|
||||
sed -e 's/\\\\\\\\$$//' -e 's/\\\\\\\\/\\//g' -e 'y| |\\n|' $(depfile).raw |\\"""
|
||||
if sys.platform == "win32"
|
||||
else """
|
||||
sed -e 's|\\\\||' -e 'y| |\\n|' $(depfile).raw |\\"""
|
||||
)
|
||||
+ r"""
|
||||
grep -v '^$$' |\
|
||||
sed -e 1d -e 's|$$|:|' \
|
||||
>> $(depfile)
|
||||
|
|
@ -600,14 +615,14 @@ cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
|
|||
# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd
|
||||
# already.
|
||||
quiet_cmd_mac_tool = MACTOOL $(4) $<
|
||||
cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@"
|
||||
cmd_mac_tool = %(python)s gyp-mac-tool $(4) $< "$@"
|
||||
|
||||
quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@
|
||||
cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4)
|
||||
cmd_mac_package_framework = %(python)s gyp-mac-tool package-framework "$@" $(4)
|
||||
|
||||
quiet_cmd_infoplist = INFOPLIST $@
|
||||
cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@"
|
||||
""" # noqa: E501
|
||||
""" % {"python": sys.executable} # noqa: E501
|
||||
|
||||
|
||||
def WriteRootHeaderSuffixRules(writer):
|
||||
|
|
@ -681,10 +696,7 @@ COMPILABLE_EXTENSIONS = {
|
|||
|
||||
def Compilable(filename):
|
||||
"""Return true if the file is compilable (should be in OBJS)."""
|
||||
for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS):
|
||||
if res:
|
||||
return True
|
||||
return False
|
||||
return any(res for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS))
|
||||
|
||||
|
||||
def Linkable(filename):
|
||||
|
|
@ -728,6 +740,12 @@ def QuoteIfNecessary(string):
|
|||
return string
|
||||
|
||||
|
||||
def replace_sep(string):
|
||||
if sys.platform == "win32":
|
||||
string = string.replace("\\\\", "/").replace("\\", "/")
|
||||
return string
|
||||
|
||||
|
||||
def StringToMakefileVariable(string):
|
||||
"""Convert a string to a value that is acceptable as a make variable name."""
|
||||
return re.sub("[^a-zA-Z0-9_]", "_", string)
|
||||
|
|
@ -778,7 +796,7 @@ class MakefileWriter:
|
|||
self.suffix_rules_objdir2 = {}
|
||||
|
||||
# Generate suffix rules for all compilable extensions.
|
||||
for ext in COMPILABLE_EXTENSIONS.keys():
|
||||
for ext, value in COMPILABLE_EXTENSIONS.items():
|
||||
# Suffix rules for source folder.
|
||||
self.suffix_rules_srcdir.update(
|
||||
{
|
||||
|
|
@ -787,7 +805,7 @@ class MakefileWriter:
|
|||
$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD
|
||||
\t@$(call do_cmd,%s,1)
|
||||
"""
|
||||
% (ext, COMPILABLE_EXTENSIONS[ext])
|
||||
% (ext, value)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -800,7 +818,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD
|
|||
$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD
|
||||
\t@$(call do_cmd,%s,1)
|
||||
"""
|
||||
% (ext, COMPILABLE_EXTENSIONS[ext])
|
||||
% (ext, value)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -811,7 +829,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD
|
|||
$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
||||
\t@$(call do_cmd,%s,1)
|
||||
"""
|
||||
% (ext, COMPILABLE_EXTENSIONS[ext])
|
||||
% (ext, value)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -862,7 +880,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
self.output = self.ComputeMacBundleOutput(spec)
|
||||
self.output_binary = self.ComputeMacBundleBinaryOutput(spec)
|
||||
else:
|
||||
self.output = self.output_binary = self.ComputeOutput(spec)
|
||||
self.output = self.output_binary = replace_sep(self.ComputeOutput(spec))
|
||||
|
||||
self.is_standalone_static_library = bool(
|
||||
spec.get("standalone_static_library", 0)
|
||||
|
|
@ -988,7 +1006,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# sub-project dir (see test/subdirectory/gyptest-subdir-all.py).
|
||||
self.WriteLn(
|
||||
"export builddir_name ?= %s"
|
||||
% os.path.join(os.path.dirname(output_filename), build_dir)
|
||||
% replace_sep(os.path.join(os.path.dirname(output_filename), build_dir))
|
||||
)
|
||||
self.WriteLn(".PHONY: all")
|
||||
self.WriteLn("all:")
|
||||
|
|
@ -1066,7 +1084,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# libraries, but until everything is made cross-compile safe, also use
|
||||
# target libraries.
|
||||
# TODO(piman): when everything is cross-compile safe, remove lib.target
|
||||
if self.flavor == "zos" or self.flavor == "aix":
|
||||
if self.flavor in {"zos", "aix"}:
|
||||
self.WriteLn(
|
||||
"cmd_%s = LIBPATH=$(builddir)/lib.host:"
|
||||
"$(builddir)/lib.target:$$LIBPATH; "
|
||||
|
|
@ -1151,7 +1169,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
for rule_source in rule.get("rule_sources", []):
|
||||
dirs = set()
|
||||
(rule_source_dirname, rule_source_basename) = os.path.split(rule_source)
|
||||
(rule_source_root, rule_source_ext) = os.path.splitext(
|
||||
(rule_source_root, _rule_source_ext) = os.path.splitext(
|
||||
rule_source_basename
|
||||
)
|
||||
|
||||
|
|
@ -1429,9 +1447,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
|
||||
for obj in objs:
|
||||
assert " " not in obj, "Spaces in object filenames not supported (%s)" % obj
|
||||
self.WriteLn(
|
||||
"# Add to the list of files we specially track " "dependencies for."
|
||||
)
|
||||
self.WriteLn("# Add to the list of files we specially track dependencies for.")
|
||||
self.WriteLn("all_deps += $(OBJS)")
|
||||
self.WriteLn()
|
||||
|
||||
|
|
@ -1440,7 +1456,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
self.WriteMakeRule(
|
||||
["$(OBJS)"],
|
||||
deps,
|
||||
comment="Make sure our dependencies are built " "before any of us.",
|
||||
comment="Make sure our dependencies are built before any of us.",
|
||||
order_only=True,
|
||||
)
|
||||
|
||||
|
|
@ -1451,12 +1467,11 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
self.WriteMakeRule(
|
||||
["$(OBJS)"],
|
||||
extra_outputs,
|
||||
comment="Make sure our actions/rules run " "before any of us.",
|
||||
comment="Make sure our actions/rules run before any of us.",
|
||||
order_only=True,
|
||||
)
|
||||
|
||||
pchdeps = precompiled_header.GetObjDependencies(compilable, objs)
|
||||
if pchdeps:
|
||||
if pchdeps := precompiled_header.GetObjDependencies(compilable, objs):
|
||||
self.WriteLn("# Dependencies from obj files to their precompiled headers")
|
||||
for source, obj, gch in pchdeps:
|
||||
self.WriteLn(f"{obj}: {gch}")
|
||||
|
|
@ -1489,7 +1504,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
"$(OBJS): GYP_OBJCFLAGS := "
|
||||
"$(DEFS_$(BUILDTYPE)) "
|
||||
"$(INCS_$(BUILDTYPE)) "
|
||||
"%s " % precompiled_header.GetInclude("m")
|
||||
"%s "
|
||||
% precompiled_header.GetInclude("m")
|
||||
+ "$(CFLAGS_$(BUILDTYPE)) "
|
||||
"$(CFLAGS_C_$(BUILDTYPE)) "
|
||||
"$(CFLAGS_OBJC_$(BUILDTYPE))"
|
||||
|
|
@ -1498,7 +1514,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
"$(OBJS): GYP_OBJCXXFLAGS := "
|
||||
"$(DEFS_$(BUILDTYPE)) "
|
||||
"$(INCS_$(BUILDTYPE)) "
|
||||
"%s " % precompiled_header.GetInclude("mm")
|
||||
"%s "
|
||||
% precompiled_header.GetInclude("mm")
|
||||
+ "$(CFLAGS_$(BUILDTYPE)) "
|
||||
"$(CFLAGS_CC_$(BUILDTYPE)) "
|
||||
"$(CFLAGS_OBJCC_$(BUILDTYPE))"
|
||||
|
|
@ -1590,8 +1607,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
|
||||
target_prefix = spec.get("product_prefix", target_prefix)
|
||||
target = spec.get("product_name", target)
|
||||
product_ext = spec.get("product_extension")
|
||||
if product_ext:
|
||||
if product_ext := spec.get("product_extension"):
|
||||
target_ext = "." + product_ext
|
||||
|
||||
return target_prefix + target + target_ext
|
||||
|
|
@ -1689,7 +1705,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
self.WriteMakeRule(
|
||||
extra_outputs,
|
||||
deps,
|
||||
comment=("Preserve order dependency of " "special output on deps."),
|
||||
comment=("Preserve order dependency of special output on deps."),
|
||||
order_only=True,
|
||||
)
|
||||
|
||||
|
|
@ -1728,7 +1744,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# into the link command, so we need lots of escaping.
|
||||
ldflags.append(r"-Wl,-rpath=\$$ORIGIN/")
|
||||
ldflags.append(r"-Wl,-rpath-link=\$(builddir)/")
|
||||
library_dirs = config.get("library_dirs", [])
|
||||
if library_dirs := config.get("library_dirs", []):
|
||||
library_dirs = [Sourceify(self.Absolutify(i)) for i in library_dirs]
|
||||
ldflags += [("-L%s" % library_dir) for library_dir in library_dirs]
|
||||
self.WriteList(ldflags, "LDFLAGS_%s" % configname)
|
||||
if self.flavor == "mac":
|
||||
|
|
@ -1769,13 +1786,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# using ":=".
|
||||
self.WriteSortedXcodeEnv(self.output, self.GetSortedXcodePostbuildEnv())
|
||||
|
||||
for configname in target_postbuilds:
|
||||
for configname, value in target_postbuilds.items():
|
||||
self.WriteLn(
|
||||
"%s: TARGET_POSTBUILDS_%s := %s"
|
||||
% (
|
||||
QuoteSpaces(self.output),
|
||||
configname,
|
||||
gyp.common.EncodePOSIXShellList(target_postbuilds[configname]),
|
||||
gyp.common.EncodePOSIXShellList(value),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -1824,7 +1841,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# Since this target depends on binary and resources which are in
|
||||
# nested subfolders, the framework directory will be older than
|
||||
# its dependencies usually. To prevent this rule from executing
|
||||
# on every build (expensive, especially with postbuilds), expliclity
|
||||
# on every build (expensive, especially with postbuilds), explicitly
|
||||
# update the time on the framework directory.
|
||||
self.WriteLn("\t@touch -c %s" % QuoteSpaces(self.output))
|
||||
|
||||
|
|
@ -1834,7 +1851,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
"on the bundle, not the binary (target '%s')" % self.target
|
||||
)
|
||||
assert "product_dir" not in spec, (
|
||||
"Postbuilds do not work with " "custom product_dir"
|
||||
"Postbuilds do not work with custom product_dir"
|
||||
)
|
||||
|
||||
if self.type == "executable":
|
||||
|
|
@ -1871,7 +1888,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
self.flavor not in ("mac", "openbsd", "netbsd", "win")
|
||||
and not self.is_standalone_static_library
|
||||
):
|
||||
if self.flavor in ("linux", "android"):
|
||||
if self.flavor in ("linux", "android", "openharmony"):
|
||||
self.WriteMakeRule(
|
||||
[self.output_binary],
|
||||
link_deps,
|
||||
|
|
@ -1885,21 +1902,20 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
part_of_all,
|
||||
postbuilds=postbuilds,
|
||||
)
|
||||
elif self.flavor in ("linux", "android", "openharmony"):
|
||||
self.WriteMakeRule(
|
||||
[self.output_binary],
|
||||
link_deps,
|
||||
actions=["$(call create_archive,$@,$^)"],
|
||||
)
|
||||
else:
|
||||
if self.flavor in ("linux", "android"):
|
||||
self.WriteMakeRule(
|
||||
[self.output_binary],
|
||||
link_deps,
|
||||
actions=["$(call create_archive,$@,$^)"],
|
||||
)
|
||||
else:
|
||||
self.WriteDoCmd(
|
||||
[self.output_binary],
|
||||
link_deps,
|
||||
"alink",
|
||||
part_of_all,
|
||||
postbuilds=postbuilds,
|
||||
)
|
||||
self.WriteDoCmd(
|
||||
[self.output_binary],
|
||||
link_deps,
|
||||
"alink",
|
||||
part_of_all,
|
||||
postbuilds=postbuilds,
|
||||
)
|
||||
elif self.type == "shared_library":
|
||||
self.WriteLn(
|
||||
"%s: LD_INPUTS := %s"
|
||||
|
|
@ -1991,7 +2007,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
and "product_dir" not in spec
|
||||
and self.toolset == "target"
|
||||
):
|
||||
# On macOS, products are created in install_path immediately.
|
||||
# On mac, products are created in install_path immediately.
|
||||
assert install_path == self.output, f"{install_path} != {self.output}"
|
||||
|
||||
# Point the target alias to the final binary output.
|
||||
|
|
@ -2031,7 +2047,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
installable_deps.append(
|
||||
self.GetUnversionedSidedeckFromSidedeck(install_path)
|
||||
)
|
||||
if self.output != self.alias and self.alias != self.target:
|
||||
if self.alias not in (self.output, self.target):
|
||||
self.WriteMakeRule(
|
||||
[self.alias],
|
||||
installable_deps,
|
||||
|
|
@ -2066,7 +2082,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
"""
|
||||
values = ""
|
||||
if value_list:
|
||||
value_list = [quoter(prefix + value) for value in value_list]
|
||||
value_list = [replace_sep(quoter(prefix + value)) for value in value_list]
|
||||
values = " \\\n\t" + " \\\n\t".join(value_list)
|
||||
self.fp.write(f"{variable} :={values}\n\n")
|
||||
|
||||
|
|
@ -2153,7 +2169,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
|
|||
# - The multi-output rule will have an do-nothing recipe.
|
||||
|
||||
# Hash the target name to avoid generating overlong filenames.
|
||||
cmddigest = hashlib.sha1(
|
||||
cmddigest = hashlib.sha256(
|
||||
(command or self.target).encode("utf-8")
|
||||
).hexdigest()
|
||||
intermediate = "%s.intermediate" % cmddigest
|
||||
|
|
@ -2372,9 +2388,15 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files)
|
|||
"\t$(call do_cmd,regen_makefile)\n\n"
|
||||
% {
|
||||
"makefile_name": makefile_name,
|
||||
"deps": " ".join(SourceifyAndQuoteSpaces(bf) for bf in build_files),
|
||||
"cmd": gyp.common.EncodePOSIXShellList(
|
||||
[gyp_binary, "-fmake"] + gyp.RegenerateFlags(options) + build_files_args
|
||||
"deps": replace_sep(
|
||||
" ".join(sorted(SourceifyAndQuoteSpaces(bf) for bf in build_files))
|
||||
),
|
||||
"cmd": replace_sep(
|
||||
gyp.common.EncodePOSIXShellList(
|
||||
[gyp_binary, "-fmake"]
|
||||
+ gyp.RegenerateFlags(options)
|
||||
+ build_files_args
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
|
@ -2438,36 +2460,55 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
makefile_path = os.path.join(
|
||||
options.toplevel_dir, options.generator_output, makefile_name
|
||||
)
|
||||
srcdir = gyp.common.RelativePath(srcdir, options.generator_output)
|
||||
srcdir = replace_sep(gyp.common.RelativePath(srcdir, options.generator_output))
|
||||
srcdir_prefix = "$(srcdir)/"
|
||||
|
||||
flock_command = "flock"
|
||||
copy_archive_arguments = "-af"
|
||||
makedep_arguments = "-MMD"
|
||||
|
||||
# wasm-ld doesn't support --start-group/--end-group
|
||||
link_commands = LINK_COMMANDS_LINUX
|
||||
if flavor in ["wasi", "wasm"]:
|
||||
link_commands = link_commands.replace(" -Wl,--start-group", "").replace(
|
||||
" -Wl,--end-group", ""
|
||||
)
|
||||
|
||||
CC_target = replace_sep(GetEnvironFallback(("CC_target", "CC"), "$(CC)"))
|
||||
AR_target = replace_sep(GetEnvironFallback(("AR_target", "AR"), "$(AR)"))
|
||||
CXX_target = replace_sep(GetEnvironFallback(("CXX_target", "CXX"), "$(CXX)"))
|
||||
LINK_target = replace_sep(GetEnvironFallback(("LINK_target", "LINK"), "$(LINK)"))
|
||||
PLI_target = replace_sep(GetEnvironFallback(("PLI_target", "PLI"), "pli"))
|
||||
CC_host = replace_sep(GetEnvironFallback(("CC_host", "CC"), "gcc"))
|
||||
AR_host = replace_sep(GetEnvironFallback(("AR_host", "AR"), "ar"))
|
||||
CXX_host = replace_sep(GetEnvironFallback(("CXX_host", "CXX"), "g++"))
|
||||
LINK_host = replace_sep(GetEnvironFallback(("LINK_host", "LINK"), "$(CXX.host)"))
|
||||
PLI_host = replace_sep(GetEnvironFallback(("PLI_host", "PLI"), "pli"))
|
||||
|
||||
header_params = {
|
||||
"default_target": default_target,
|
||||
"builddir": builddir_name,
|
||||
"default_configuration": default_configuration,
|
||||
"flock": flock_command,
|
||||
"flock_index": 1,
|
||||
"link_commands": LINK_COMMANDS_LINUX,
|
||||
"link_commands": link_commands,
|
||||
"extra_commands": "",
|
||||
"srcdir": srcdir,
|
||||
"copy_archive_args": copy_archive_arguments,
|
||||
"makedep_args": makedep_arguments,
|
||||
"CC.target": GetEnvironFallback(("CC_target", "CC"), "$(CC)"),
|
||||
"AR.target": GetEnvironFallback(("AR_target", "AR"), "$(AR)"),
|
||||
"CXX.target": GetEnvironFallback(("CXX_target", "CXX"), "$(CXX)"),
|
||||
"LINK.target": GetEnvironFallback(("LINK_target", "LINK"), "$(LINK)"),
|
||||
"PLI.target": GetEnvironFallback(("PLI_target", "PLI"), "pli"),
|
||||
"CC.host": GetEnvironFallback(("CC_host", "CC"), "gcc"),
|
||||
"AR.host": GetEnvironFallback(("AR_host", "AR"), "ar"),
|
||||
"CXX.host": GetEnvironFallback(("CXX_host", "CXX"), "g++"),
|
||||
"LINK.host": GetEnvironFallback(("LINK_host", "LINK"), "$(CXX.host)"),
|
||||
"PLI.host": GetEnvironFallback(("PLI_host", "PLI"), "pli"),
|
||||
"CC.target": CC_target,
|
||||
"AR.target": AR_target,
|
||||
"CXX.target": CXX_target,
|
||||
"LINK.target": LINK_target,
|
||||
"PLI.target": PLI_target,
|
||||
"CC.host": CC_host,
|
||||
"AR.host": AR_host,
|
||||
"CXX.host": CXX_host,
|
||||
"LINK.host": LINK_host,
|
||||
"PLI.host": PLI_host,
|
||||
}
|
||||
if flavor == "mac":
|
||||
flock_command = "./gyp-mac-tool flock"
|
||||
flock_command = "%s gyp-mac-tool flock" % sys.executable
|
||||
header_params.update(
|
||||
{
|
||||
"flock": flock_command,
|
||||
|
|
@ -2517,7 +2558,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
header_params.update(
|
||||
{
|
||||
"copy_archive_args": copy_archive_arguments,
|
||||
"flock": "./gyp-flock-tool flock",
|
||||
"flock": "%s gyp-flock-tool flock" % sys.executable,
|
||||
"flock_index": 2,
|
||||
}
|
||||
)
|
||||
|
|
@ -2533,7 +2574,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
{
|
||||
"copy_archive_args": copy_archive_arguments,
|
||||
"link_commands": LINK_COMMANDS_AIX,
|
||||
"flock": "./gyp-flock-tool flock",
|
||||
"flock": "%s gyp-flock-tool flock" % sys.executable,
|
||||
"flock_index": 2,
|
||||
}
|
||||
)
|
||||
|
|
@ -2543,7 +2584,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
{
|
||||
"copy_archive_args": copy_archive_arguments,
|
||||
"link_commands": LINK_COMMANDS_OS400,
|
||||
"flock": "./gyp-flock-tool flock",
|
||||
"flock": "%s gyp-flock-tool flock" % sys.executable,
|
||||
"flock_index": 2,
|
||||
}
|
||||
)
|
||||
|
|
|
|||
1063
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py
generated
vendored
1063
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py
generated
vendored
File diff suppressed because it is too large
Load diff
6
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py
generated
vendored
6
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py
generated
vendored
|
|
@ -3,13 +3,13 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
""" Unit tests for the msvs.py file. """
|
||||
"""Unit tests for the msvs.py file."""
|
||||
|
||||
import gyp.generator.msvs as msvs
|
||||
import unittest
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from gyp.generator import msvs
|
||||
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
139
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py
generated
vendored
139
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py
generated
vendored
|
|
@ -5,24 +5,24 @@
|
|||
|
||||
import collections
|
||||
import copy
|
||||
import ctypes
|
||||
import hashlib
|
||||
import json
|
||||
import multiprocessing
|
||||
import os.path
|
||||
import re
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from io import StringIO
|
||||
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.msvs_emulation
|
||||
import gyp.MSVSUtil as MSVSUtil
|
||||
import gyp.xcode_emulation
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from gyp import MSVSUtil, ninja_syntax
|
||||
from gyp.common import GetEnvironFallback
|
||||
import gyp.ninja_syntax as ninja_syntax
|
||||
|
||||
generator_default_variables = {
|
||||
"EXECUTABLE_PREFIX": "",
|
||||
|
|
@ -246,7 +246,7 @@ class NinjaWriter:
|
|||
if flavor == "win":
|
||||
# See docstring of msvs_emulation.GenerateEnvironmentFiles().
|
||||
self.win_env = {}
|
||||
for arch in ("x86", "x64"):
|
||||
for arch in ("x86", "x64", "arm64"):
|
||||
self.win_env[arch] = "environment." + arch
|
||||
|
||||
# Relative path from build output dir to base dir.
|
||||
|
|
@ -264,8 +264,7 @@ class NinjaWriter:
|
|||
dir.
|
||||
"""
|
||||
|
||||
PRODUCT_DIR = "$!PRODUCT_DIR"
|
||||
if PRODUCT_DIR in path:
|
||||
if (PRODUCT_DIR := "$!PRODUCT_DIR") in path:
|
||||
if product_dir:
|
||||
path = path.replace(PRODUCT_DIR, product_dir)
|
||||
else:
|
||||
|
|
@ -273,8 +272,7 @@ class NinjaWriter:
|
|||
path = path.replace(PRODUCT_DIR + "\\", "")
|
||||
path = path.replace(PRODUCT_DIR, ".")
|
||||
|
||||
INTERMEDIATE_DIR = "$!INTERMEDIATE_DIR"
|
||||
if INTERMEDIATE_DIR in path:
|
||||
if (INTERMEDIATE_DIR := "$!INTERMEDIATE_DIR") in path:
|
||||
int_dir = self.GypPathToUniqueOutput("gen")
|
||||
# GypPathToUniqueOutput generates a path relative to the product dir,
|
||||
# so insert product_dir in front if it is provided.
|
||||
|
|
@ -811,9 +809,8 @@ class NinjaWriter:
|
|||
outputs = [self.GypPathToNinja(o, env) for o in outputs]
|
||||
if self.flavor == "win":
|
||||
# WriteNewNinjaRule uses unique_name to create a rsp file on win.
|
||||
extra_bindings.append(
|
||||
("unique_name", hashlib.md5(outputs[0]).hexdigest())
|
||||
)
|
||||
unique_name = hashlib.sha256(outputs[0].encode("utf-8")).hexdigest()
|
||||
extra_bindings.append(("unique_name", unique_name))
|
||||
|
||||
self.ninja.build(
|
||||
outputs,
|
||||
|
|
@ -1305,7 +1302,7 @@ class NinjaWriter:
|
|||
ninja_file.build(gch, cmd, input, variables=[(var_name, lang_flag)])
|
||||
|
||||
def WriteLink(self, spec, config_name, config, link_deps, compile_deps):
|
||||
"""Write out a link step. Fills out target.binary. """
|
||||
"""Write out a link step. Fills out target.binary."""
|
||||
if self.flavor != "mac" or len(self.archs) == 1:
|
||||
return self.WriteLinkForArch(
|
||||
self.ninja, spec, config_name, config, link_deps, compile_deps
|
||||
|
|
@ -1349,7 +1346,7 @@ class NinjaWriter:
|
|||
def WriteLinkForArch(
|
||||
self, ninja_file, spec, config_name, config, link_deps, compile_deps, arch=None
|
||||
):
|
||||
"""Write out a link step. Fills out target.binary. """
|
||||
"""Write out a link step. Fills out target.binary."""
|
||||
command = {
|
||||
"executable": "link",
|
||||
"loadable_module": "solink_module",
|
||||
|
|
@ -1464,7 +1461,7 @@ class NinjaWriter:
|
|||
# Respect environment variables related to build, but target-specific
|
||||
# flags can still override them.
|
||||
ldflags = env_ldflags + config.get("ldflags", [])
|
||||
if is_executable and len(solibs):
|
||||
if is_executable and solibs:
|
||||
rpath = "lib/"
|
||||
if self.toolset != "target":
|
||||
rpath += self.toolset
|
||||
|
|
@ -1554,7 +1551,7 @@ class NinjaWriter:
|
|||
if pdbname:
|
||||
output = [output, pdbname]
|
||||
|
||||
if len(solibs):
|
||||
if solibs:
|
||||
extra_bindings.append(
|
||||
("solibs", gyp.common.EncodePOSIXShellList(sorted(solibs)))
|
||||
)
|
||||
|
|
@ -1757,11 +1754,9 @@ class NinjaWriter:
|
|||
+ " && ".join([ninja_syntax.escape(command) for command in postbuilds])
|
||||
)
|
||||
command_string = (
|
||||
commands
|
||||
+ "); G=$$?; "
|
||||
commands + "); G=$$?; "
|
||||
# Remove the final output if any postbuild failed.
|
||||
"((exit $$G) || rm -rf %s) " % output
|
||||
+ "&& exit $$G)"
|
||||
"((exit $$G) || rm -rf %s) " % output + "&& exit $$G)"
|
||||
)
|
||||
if is_command_start:
|
||||
return "(" + command_string + " && "
|
||||
|
|
@ -1815,10 +1810,7 @@ class NinjaWriter:
|
|||
"executable": default_variables["EXECUTABLE_SUFFIX"],
|
||||
}
|
||||
extension = spec.get("product_extension")
|
||||
if extension:
|
||||
extension = "." + extension
|
||||
else:
|
||||
extension = DEFAULT_EXTENSION.get(type, "")
|
||||
extension = "." + extension if extension else DEFAULT_EXTENSION.get(type, "")
|
||||
|
||||
if "product_name" in spec:
|
||||
# If we were given an explicit name, use that.
|
||||
|
|
@ -1953,7 +1945,8 @@ class NinjaWriter:
|
|||
)
|
||||
else:
|
||||
rspfile_content = gyp.msvs_emulation.EncodeRspFileList(
|
||||
args, win_shell_flags.quote)
|
||||
args, win_shell_flags.quote
|
||||
)
|
||||
command = (
|
||||
"%s gyp-win-tool action-wrapper $arch " % sys.executable
|
||||
+ rspfile
|
||||
|
|
@ -1999,7 +1992,7 @@ def CalculateVariables(default_variables, params):
|
|||
|
||||
# Copy additional generator configuration data from Xcode, which is shared
|
||||
# by the Mac Ninja generator.
|
||||
import gyp.generator.xcode as xcode_generator
|
||||
import gyp.generator.xcode as xcode_generator # noqa: PLC0415
|
||||
|
||||
generator_additional_non_configuration_keys = getattr(
|
||||
xcode_generator, "generator_additional_non_configuration_keys", []
|
||||
|
|
@ -2022,7 +2015,7 @@ def CalculateVariables(default_variables, params):
|
|||
|
||||
# Copy additional generator configuration data from VS, which is shared
|
||||
# by the Windows Ninja generator.
|
||||
import gyp.generator.msvs as msvs_generator
|
||||
import gyp.generator.msvs as msvs_generator # noqa: PLC0415
|
||||
|
||||
generator_additional_non_configuration_keys = getattr(
|
||||
msvs_generator, "generator_additional_non_configuration_keys", []
|
||||
|
|
@ -2079,20 +2072,17 @@ def OpenOutput(path, mode="w"):
|
|||
|
||||
|
||||
def CommandWithWrapper(cmd, wrappers, prog):
|
||||
wrapper = wrappers.get(cmd, "")
|
||||
if wrapper:
|
||||
if wrapper := wrappers.get(cmd, ""):
|
||||
return wrapper + " " + prog
|
||||
return prog
|
||||
|
||||
|
||||
def GetDefaultConcurrentLinks():
|
||||
"""Returns a best-guess for a number of concurrent links."""
|
||||
pool_size = int(os.environ.get("GYP_LINK_CONCURRENCY", 0))
|
||||
if pool_size:
|
||||
if pool_size := int(os.environ.get("GYP_LINK_CONCURRENCY") or 0):
|
||||
return pool_size
|
||||
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
import ctypes
|
||||
|
||||
class MEMORYSTATUSEX(ctypes.Structure):
|
||||
_fields_ = [
|
||||
|
|
@ -2113,8 +2103,8 @@ def GetDefaultConcurrentLinks():
|
|||
|
||||
# VS 2015 uses 20% more working set than VS 2013 and can consume all RAM
|
||||
# on a 64 GiB machine.
|
||||
mem_limit = max(1, stat.ullTotalPhys // (5 * (2 ** 30))) # total / 5GiB
|
||||
hard_cap = max(1, int(os.environ.get("GYP_LINK_CONCURRENCY_MAX", 2 ** 32)))
|
||||
mem_limit = max(1, stat.ullTotalPhys // (5 * (2**30))) # total / 5GiB
|
||||
hard_cap = max(1, int(os.environ.get("GYP_LINK_CONCURRENCY_MAX") or 2**32))
|
||||
return min(mem_limit, hard_cap)
|
||||
elif sys.platform.startswith("linux"):
|
||||
if os.path.exists("/proc/meminfo"):
|
||||
|
|
@ -2125,14 +2115,14 @@ def GetDefaultConcurrentLinks():
|
|||
if not match:
|
||||
continue
|
||||
# Allow 8Gb per link on Linux because Gold is quite memory hungry
|
||||
return max(1, int(match.group(1)) // (8 * (2 ** 20)))
|
||||
return max(1, int(match.group(1)) // (8 * (2**20)))
|
||||
return 1
|
||||
elif sys.platform == "darwin":
|
||||
try:
|
||||
avail_bytes = int(subprocess.check_output(["sysctl", "-n", "hw.memsize"]))
|
||||
# A static library debug build of Chromium's unit_tests takes ~2.7GB, so
|
||||
# 4GB per ld process allows for some more bloat.
|
||||
return max(1, avail_bytes // (4 * (2 ** 30))) # total / 4GB
|
||||
return max(1, avail_bytes // (4 * (2**30))) # total / 4GB
|
||||
except subprocess.CalledProcessError:
|
||||
return 1
|
||||
else:
|
||||
|
|
@ -2213,6 +2203,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
options = params["options"]
|
||||
flavor = gyp.common.GetFlavor(params)
|
||||
generator_flags = params.get("generator_flags", {})
|
||||
generate_compile_commands = generator_flags.get("compile_commands", False)
|
||||
|
||||
# build_dir: relative path from source root to our output files.
|
||||
# e.g. "out/Debug"
|
||||
|
|
@ -2308,8 +2299,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
key_prefix = re.sub(r"\.HOST$", ".host", key_prefix)
|
||||
wrappers[key_prefix] = os.path.join(build_to_root, value)
|
||||
|
||||
mac_toolchain_dir = generator_flags.get("mac_toolchain_dir", None)
|
||||
if mac_toolchain_dir:
|
||||
if mac_toolchain_dir := generator_flags.get("mac_toolchain_dir", None):
|
||||
wrappers["LINK"] = "export DEVELOPER_DIR='%s' &&" % mac_toolchain_dir
|
||||
|
||||
if flavor == "win":
|
||||
|
|
@ -2349,6 +2339,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
master_ninja.variable("rc", "rc.exe")
|
||||
master_ninja.variable("ml_x86", "ml.exe")
|
||||
master_ninja.variable("ml_x64", "ml64.exe")
|
||||
master_ninja.variable("ml_arm64", "armasm64.exe")
|
||||
master_ninja.variable("mt", "mt.exe")
|
||||
else:
|
||||
master_ninja.variable("ld", CommandWithWrapper("LINK", wrappers, ld))
|
||||
|
|
@ -2420,8 +2411,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
"cc_s",
|
||||
description="CC $out",
|
||||
command=(
|
||||
"$cc $defines $includes $cflags $cflags_c "
|
||||
"$cflags_pch_c -c $in -o $out"
|
||||
"$cc $defines $includes $cflags $cflags_c $cflags_pch_c -c $in -o $out"
|
||||
),
|
||||
)
|
||||
master_ninja.rule(
|
||||
|
|
@ -2532,11 +2522,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
"solink",
|
||||
description="SOLINK $lib",
|
||||
restat=True,
|
||||
command=mtime_preserving_solink_base
|
||||
% {"suffix": "@$link_file_list"}, # noqa: E501
|
||||
command=mtime_preserving_solink_base % {"suffix": "@$link_file_list"},
|
||||
rspfile="$link_file_list",
|
||||
rspfile_content=(
|
||||
"-Wl,--whole-archive $in $solibs -Wl," "--no-whole-archive $libs"
|
||||
"-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive $libs"
|
||||
),
|
||||
pool="link_pool",
|
||||
)
|
||||
|
|
@ -2596,9 +2585,9 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
"alink",
|
||||
description="LIBTOOL-STATIC $out, POSTBUILDS",
|
||||
command="rm -f $out && "
|
||||
"./gyp-mac-tool filter-libtool libtool $libtool_flags "
|
||||
"%s gyp-mac-tool filter-libtool libtool $libtool_flags "
|
||||
"-static -o $out $in"
|
||||
"$postbuilds",
|
||||
"$postbuilds" % sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"lipo",
|
||||
|
|
@ -2685,7 +2674,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
master_ninja.rule(
|
||||
"link",
|
||||
description="LINK $out, POSTBUILDS",
|
||||
command=("$ld $ldflags -o $out " "$in $solibs $libs$postbuilds"),
|
||||
command=("$ld $ldflags -o $out $in $solibs $libs$postbuilds"),
|
||||
pool="link_pool",
|
||||
)
|
||||
master_ninja.rule(
|
||||
|
|
@ -2699,41 +2688,44 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
master_ninja.rule(
|
||||
"copy_infoplist",
|
||||
description="COPY INFOPLIST $in",
|
||||
command="$env ./gyp-mac-tool copy-info-plist $in $out $binary $keys",
|
||||
command="$env %s gyp-mac-tool copy-info-plist $in $out $binary $keys"
|
||||
% sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"merge_infoplist",
|
||||
description="MERGE INFOPLISTS $in",
|
||||
command="$env ./gyp-mac-tool merge-info-plist $out $in",
|
||||
command="$env %s gyp-mac-tool merge-info-plist $out $in" % sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"compile_xcassets",
|
||||
description="COMPILE XCASSETS $in",
|
||||
command="$env ./gyp-mac-tool compile-xcassets $keys $in",
|
||||
command="$env %s gyp-mac-tool compile-xcassets $keys $in" % sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"compile_ios_framework_headers",
|
||||
description="COMPILE HEADER MAPS AND COPY FRAMEWORK HEADERS $in",
|
||||
command="$env ./gyp-mac-tool compile-ios-framework-header-map $out "
|
||||
"$framework $in && $env ./gyp-mac-tool "
|
||||
"copy-ios-framework-headers $framework $copy_headers",
|
||||
command="$env %(python)s gyp-mac-tool compile-ios-framework-header-map "
|
||||
"$out $framework $in && $env %(python)s gyp-mac-tool "
|
||||
"copy-ios-framework-headers $framework $copy_headers"
|
||||
% {"python": sys.executable},
|
||||
)
|
||||
master_ninja.rule(
|
||||
"mac_tool",
|
||||
description="MACTOOL $mactool_cmd $in",
|
||||
command="$env ./gyp-mac-tool $mactool_cmd $in $out $binary",
|
||||
command="$env %s gyp-mac-tool $mactool_cmd $in $out $binary"
|
||||
% sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"package_framework",
|
||||
description="PACKAGE FRAMEWORK $out, POSTBUILDS",
|
||||
command="./gyp-mac-tool package-framework $out $version$postbuilds "
|
||||
"&& touch $out",
|
||||
command="%s gyp-mac-tool package-framework $out $version$postbuilds "
|
||||
"&& touch $out" % sys.executable,
|
||||
)
|
||||
master_ninja.rule(
|
||||
"package_ios_framework",
|
||||
description="PACKAGE IOS FRAMEWORK $out, POSTBUILDS",
|
||||
command="./gyp-mac-tool package-ios-framework $out $postbuilds "
|
||||
"&& touch $out",
|
||||
command="%s gyp-mac-tool package-ios-framework $out $postbuilds "
|
||||
"&& touch $out" % sys.executable,
|
||||
)
|
||||
if flavor == "win":
|
||||
master_ninja.rule(
|
||||
|
|
@ -2811,7 +2803,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
build_file, name, toolset
|
||||
)
|
||||
qualified_target_for_hash = qualified_target_for_hash.encode("utf-8")
|
||||
hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest()
|
||||
hash_for_rules = hashlib.sha256(qualified_target_for_hash).hexdigest()
|
||||
|
||||
base_path = os.path.dirname(build_file)
|
||||
obj = "obj"
|
||||
|
|
@ -2881,6 +2873,35 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
|
|||
|
||||
master_ninja_file.close()
|
||||
|
||||
if generate_compile_commands:
|
||||
compile_db = GenerateCompileDBWithNinja(toplevel_build)
|
||||
compile_db_file = OpenOutput(
|
||||
os.path.join(toplevel_build, "compile_commands.json")
|
||||
)
|
||||
compile_db_file.write(json.dumps(compile_db, indent=2))
|
||||
compile_db_file.close()
|
||||
|
||||
|
||||
def GenerateCompileDBWithNinja(path, targets=["all"]):
|
||||
"""Generates a compile database using ninja.
|
||||
|
||||
Args:
|
||||
path: The build directory to generate a compile database for.
|
||||
targets: Additional targets to pass to ninja.
|
||||
|
||||
Returns:
|
||||
List of the contents of the compile database.
|
||||
"""
|
||||
ninja_path = shutil.which("ninja")
|
||||
if ninja_path is None:
|
||||
raise Exception("ninja not found in PATH")
|
||||
json_compile_db = subprocess.check_output(
|
||||
[ninja_path, "-C", path]
|
||||
+ targets
|
||||
+ ["-t", "compdb", "cc", "cxx", "objc", "objcxx"]
|
||||
)
|
||||
return json.loads(json_compile_db)
|
||||
|
||||
|
||||
def PerformBuild(data, configurations, params):
|
||||
options = params["options"]
|
||||
|
|
|
|||
58
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
generated
vendored
58
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
generated
vendored
|
|
@ -4,32 +4,43 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
""" Unit tests for the ninja.py file. """
|
||||
"""Unit tests for the ninja.py file."""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
import gyp.generator.ninja as ninja
|
||||
from gyp.generator import ninja
|
||||
from gyp.MSVSVersion import SelectVisualStudioVersion
|
||||
|
||||
|
||||
def _has_visual_studio():
|
||||
"""Check if Visual Studio can be detected by gyp's registry-based detection."""
|
||||
if not sys.platform.startswith("win"):
|
||||
return False
|
||||
try:
|
||||
SelectVisualStudioVersion("auto", allow_fallback=False)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
class TestPrefixesAndSuffixes(unittest.TestCase):
|
||||
@unittest.skipUnless(
|
||||
_has_visual_studio(),
|
||||
"requires Windows with a Visual Studio installation detected via the registry",
|
||||
)
|
||||
def test_BinaryNamesWindows(self):
|
||||
# These cannot run on non-Windows as they require a VS installation to
|
||||
# correctly handle variable expansion.
|
||||
if sys.platform.startswith("win"):
|
||||
writer = ninja.NinjaWriter(
|
||||
"foo", "wee", ".", ".", "build.ninja", ".", "build.ninja", "win"
|
||||
)
|
||||
spec = {"target_name": "wee"}
|
||||
self.assertTrue(
|
||||
writer.ComputeOutputFileName(spec, "executable").endswith(".exe")
|
||||
)
|
||||
self.assertTrue(
|
||||
writer.ComputeOutputFileName(spec, "shared_library").endswith(".dll")
|
||||
)
|
||||
self.assertTrue(
|
||||
writer.ComputeOutputFileName(spec, "static_library").endswith(".lib")
|
||||
)
|
||||
writer = ninja.NinjaWriter(
|
||||
"foo", "wee", ".", ".", "build.ninja", ".", "build.ninja", "win"
|
||||
)
|
||||
spec = {"target_name": "wee"}
|
||||
for key, ext in {
|
||||
"executable": ".exe",
|
||||
"shared_library": ".dll",
|
||||
"static_library": ".lib",
|
||||
}.items():
|
||||
self.assertTrue(writer.ComputeOutputFileName(spec, key).endswith(ext))
|
||||
|
||||
def test_BinaryNamesLinux(self):
|
||||
writer = ninja.NinjaWriter(
|
||||
|
|
@ -50,6 +61,17 @@ class TestPrefixesAndSuffixes(unittest.TestCase):
|
|||
writer.ComputeOutputFileName(spec, "static_library").endswith(".a")
|
||||
)
|
||||
|
||||
def test_GenerateCompileDBWithNinja(self):
|
||||
build_dir = (
|
||||
Path(__file__).resolve().parent.parent.parent.parent / "data" / "ninja"
|
||||
)
|
||||
compile_db = ninja.GenerateCompileDBWithNinja(build_dir)
|
||||
assert len(compile_db) == 1
|
||||
assert compile_db[0]["directory"] == str(build_dir)
|
||||
assert compile_db[0]["command"] == "cc my.in my.out"
|
||||
assert compile_db[0]["file"] == "my.in"
|
||||
assert compile_db[0]["output"] == "my.out"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
61
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py
generated
vendored
61
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py
generated
vendored
|
|
@ -3,19 +3,19 @@
|
|||
# found in the LICENSE file.
|
||||
|
||||
|
||||
import filecmp
|
||||
import gyp.common
|
||||
import gyp.xcodeproj_file
|
||||
import gyp.xcode_ninja
|
||||
import errno
|
||||
import filecmp
|
||||
import os
|
||||
import sys
|
||||
import posixpath
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import gyp.common
|
||||
import gyp.xcode_ninja
|
||||
import gyp.xcodeproj_file
|
||||
|
||||
# Project files generated by this module will use _intermediate_var as a
|
||||
# custom Xcode setting whose value is a DerivedSources-like directory that's
|
||||
|
|
@ -439,7 +439,7 @@ sys.exit(subprocess.call(sys.argv[1:]))" """
|
|||
# it opens the project file, which will result in unnecessary diffs.
|
||||
# TODO(mark): This is evil because it relies on internal knowledge of
|
||||
# PBXProject._other_pbxprojects.
|
||||
for other_pbxproject in self.project._other_pbxprojects.keys():
|
||||
for other_pbxproject in self.project._other_pbxprojects:
|
||||
self.project.AddOrGetProjectReference(other_pbxproject)
|
||||
|
||||
self.project.SortRemoteProductReferences()
|
||||
|
|
@ -531,7 +531,7 @@ def AddSourceToTarget(source, type, pbxp, xct):
|
|||
library_extensions = ["a", "dylib", "framework", "o"]
|
||||
|
||||
basename = posixpath.basename(source)
|
||||
(root, ext) = posixpath.splitext(basename)
|
||||
(_root, ext) = posixpath.splitext(basename)
|
||||
if ext:
|
||||
ext = ext[1:].lower()
|
||||
|
||||
|
|
@ -564,12 +564,12 @@ _xcode_variable_re = re.compile(r"(\$\((.*?)\))")
|
|||
def ExpandXcodeVariables(string, expansions):
|
||||
"""Expands Xcode-style $(VARIABLES) in string per the expansions dict.
|
||||
|
||||
In some rare cases, it is appropriate to expand Xcode variables when a
|
||||
project file is generated. For any substring $(VAR) in string, if VAR is a
|
||||
key in the expansions dict, $(VAR) will be replaced with expansions[VAR].
|
||||
Any $(VAR) substring in string for which VAR is not a key in the expansions
|
||||
dict will remain in the returned string.
|
||||
"""
|
||||
In some rare cases, it is appropriate to expand Xcode variables when a
|
||||
project file is generated. For any substring $(VAR) in string, if VAR is a
|
||||
key in the expansions dict, $(VAR) will be replaced with expansions[VAR].
|
||||
Any $(VAR) substring in string for which VAR is not a key in the expansions
|
||||
dict will remain in the returned string.
|
||||
"""
|
||||
|
||||
matches = _xcode_variable_re.findall(string)
|
||||
if matches is None:
|
||||
|
|
@ -592,9 +592,9 @@ _xcode_define_re = re.compile(r"([\\\"\' ])")
|
|||
|
||||
def EscapeXcodeDefine(s):
|
||||
"""We must escape the defines that we give to XCode so that it knows not to
|
||||
split on spaces and to respect backslash and quote literals. However, we
|
||||
must not quote the define, or Xcode will incorrectly interpret variables
|
||||
especially $(inherited)."""
|
||||
split on spaces and to respect backslash and quote literals. However, we
|
||||
must not quote the define, or Xcode will incorrectly interpret variables
|
||||
especially $(inherited)."""
|
||||
return re.sub(_xcode_define_re, r"\\\1", s)
|
||||
|
||||
|
||||
|
|
@ -679,9 +679,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
project_attributes["BuildIndependentTargetsInParallel"] = "YES"
|
||||
if upgrade_check_project_version:
|
||||
project_attributes["LastUpgradeCheck"] = upgrade_check_project_version
|
||||
project_attributes[
|
||||
"LastTestingUpgradeCheck"
|
||||
] = upgrade_check_project_version
|
||||
project_attributes["LastTestingUpgradeCheck"] = (
|
||||
upgrade_check_project_version
|
||||
)
|
||||
project_attributes["LastSwiftUpdateCheck"] = upgrade_check_project_version
|
||||
pbxp.SetProperty("attributes", project_attributes)
|
||||
|
||||
|
|
@ -696,7 +696,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
xcode_targets = {}
|
||||
xcode_target_to_target_dict = {}
|
||||
for qualified_target in target_list:
|
||||
[build_file, target_name, toolset] = gyp.common.ParseQualifiedTarget(
|
||||
[build_file, target_name, _toolset] = gyp.common.ParseQualifiedTarget(
|
||||
qualified_target
|
||||
)
|
||||
|
||||
|
|
@ -734,8 +734,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
"loadable_module+xcuitest": "com.apple.product-type.bundle.ui-testing",
|
||||
"shared_library+bundle": "com.apple.product-type.framework",
|
||||
"executable+extension+bundle": "com.apple.product-type.app-extension",
|
||||
"executable+watch+extension+bundle":
|
||||
"com.apple.product-type.watchkit-extension",
|
||||
"executable+watch+extension+bundle": "com.apple.product-type.watchkit-extension", # noqa: E501
|
||||
"executable+watch+bundle": "com.apple.product-type.application.watchapp",
|
||||
"mac_kernel_extension+bundle": "com.apple.product-type.kernel-extension",
|
||||
}
|
||||
|
|
@ -780,8 +779,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
type_bundle_key += "+watch+extension+bundle"
|
||||
elif is_watch_app:
|
||||
assert is_bundle, (
|
||||
"ios_watch_app flag requires mac_bundle "
|
||||
"(target %s)" % target_name
|
||||
"ios_watch_app flag requires mac_bundle (target %s)" % target_name
|
||||
)
|
||||
type_bundle_key += "+watch+bundle"
|
||||
elif is_bundle:
|
||||
|
|
@ -793,7 +791,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
except KeyError as e:
|
||||
gyp.common.ExceptionAppend(
|
||||
e,
|
||||
"-- unknown product type while " "writing target %s" % target_name,
|
||||
"-- unknown product type while writing target %s" % target_name,
|
||||
)
|
||||
raise
|
||||
else:
|
||||
|
|
@ -959,7 +957,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
# would-be additional inputs are newer than the output. Modifying
|
||||
# the source tree - even just modification times - feels dirty.
|
||||
# 6564240 Xcode "custom script" build rules always dump all environment
|
||||
# variables. This is a low-prioroty problem and is not a
|
||||
# variables. This is a low-priority problem and is not a
|
||||
# show-stopper.
|
||||
rules_by_ext = {}
|
||||
for rule in spec_rules:
|
||||
|
|
@ -1103,7 +1101,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
eol = " \\"
|
||||
makefile.write(f" {concrete_output}{eol}\n")
|
||||
|
||||
for (rule_source, concrete_outputs, message, action) in zip(
|
||||
for rule_source, concrete_outputs, message, action in zip(
|
||||
rule["rule_sources"],
|
||||
concrete_outputs_by_rule_source,
|
||||
messages,
|
||||
|
|
@ -1118,10 +1116,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
|
|||
for concrete_output_index, concrete_output in enumerate(
|
||||
concrete_outputs
|
||||
):
|
||||
if concrete_output_index == 0:
|
||||
bol = ""
|
||||
else:
|
||||
bol = " "
|
||||
bol = "" if concrete_output_index == 0 else " "
|
||||
makefile.write(f"{bol}{concrete_output} \\\n")
|
||||
|
||||
concrete_output_dir = posixpath.dirname(concrete_output)
|
||||
|
|
@ -1220,7 +1215,7 @@ exit 1
|
|||
|
||||
# Add "sources".
|
||||
for source in spec.get("sources", []):
|
||||
(source_root, source_extension) = posixpath.splitext(source)
|
||||
(_source_root, source_extension) = posixpath.splitext(source)
|
||||
if source_extension[1:] not in rules_by_ext:
|
||||
# AddSourceToTarget will add the file to a root group if it's not
|
||||
# already there.
|
||||
|
|
@ -1232,7 +1227,7 @@ exit 1
|
|||
# it's a bundle of any type.
|
||||
if is_bundle:
|
||||
for resource in tgt_mac_bundle_resources:
|
||||
(resource_root, resource_extension) = posixpath.splitext(resource)
|
||||
(_resource_root, resource_extension) = posixpath.splitext(resource)
|
||||
if resource_extension[1:] not in rules_by_ext:
|
||||
AddResourceToTarget(resource, pbxp, xct)
|
||||
else:
|
||||
|
|
|
|||
7
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py
generated
vendored
7
electron/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py
generated
vendored
|
|
@ -4,11 +4,12 @@
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
""" Unit tests for the xcode.py file. """
|
||||
"""Unit tests for the xcode.py file."""
|
||||
|
||||
import gyp.generator.xcode as xcode
|
||||
import unittest
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from gyp.generator import xcode
|
||||
|
||||
|
||||
class TestEscapeXcodeDefine(unittest.TestCase):
|
||||
|
|
|
|||
513
electron/node_modules/node-gyp/gyp/pylib/gyp/input.py
generated
vendored
513
electron/node_modules/node-gyp/gyp/pylib/gyp/input.py
generated
vendored
File diff suppressed because it is too large
Load diff
3
electron/node_modules/node-gyp/gyp/pylib/gyp/input_test.py
generated
vendored
3
electron/node_modules/node-gyp/gyp/pylib/gyp/input_test.py
generated
vendored
|
|
@ -6,9 +6,10 @@
|
|||
|
||||
"""Unit tests for the input.py file."""
|
||||
|
||||
import gyp.input
|
||||
import unittest
|
||||
|
||||
import gyp.input
|
||||
|
||||
|
||||
class TestFindCycles(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
208
electron/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py
generated
vendored
208
electron/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py
generated
vendored
|
|
@ -8,7 +8,6 @@
|
|||
These functions are executed via gyp-mac-tool when using the Makefile generator.
|
||||
"""
|
||||
|
||||
|
||||
import fcntl
|
||||
import fnmatch
|
||||
import glob
|
||||
|
|
@ -25,14 +24,13 @@ import tempfile
|
|||
|
||||
def main(args):
|
||||
executor = MacTool()
|
||||
exit_code = executor.Dispatch(args)
|
||||
if exit_code is not None:
|
||||
if (exit_code := executor.Dispatch(args)) is not None:
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
class MacTool:
|
||||
"""This class performs all the Mac tooling steps. The methods can either be
|
||||
executed directly, or dispatched from an argument list."""
|
||||
executed directly, or dispatched from an argument list."""
|
||||
|
||||
def Dispatch(self, args):
|
||||
"""Dispatches a string command to a method."""
|
||||
|
|
@ -48,7 +46,7 @@ class MacTool:
|
|||
|
||||
def ExecCopyBundleResource(self, source, dest, convert_to_binary):
|
||||
"""Copies a resource file to the bundle/Resources directory, performing any
|
||||
necessary compilation on each resource."""
|
||||
necessary compilation on each resource."""
|
||||
convert_to_binary = convert_to_binary == "True"
|
||||
extension = os.path.splitext(source)[1].lower()
|
||||
if os.path.isdir(source):
|
||||
|
|
@ -59,9 +57,7 @@ class MacTool:
|
|||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(source, dest)
|
||||
elif extension == ".xib":
|
||||
return self._CopyXIBFile(source, dest)
|
||||
elif extension == ".storyboard":
|
||||
elif extension in {".xib", ".storyboard"}:
|
||||
return self._CopyXIBFile(source, dest)
|
||||
elif extension == ".strings" and not convert_to_binary:
|
||||
self._CopyStringsFile(source, dest)
|
||||
|
|
@ -70,7 +66,7 @@ class MacTool:
|
|||
os.unlink(dest)
|
||||
shutil.copy(source, dest)
|
||||
|
||||
if convert_to_binary and extension in (".plist", ".strings"):
|
||||
if convert_to_binary and extension in {".plist", ".strings"}:
|
||||
self._ConvertToBinary(dest)
|
||||
|
||||
def _CopyXIBFile(self, source, dest):
|
||||
|
|
@ -144,7 +140,7 @@ class MacTool:
|
|||
# CFPropertyListCreateFromXMLData(): Old-style plist parser: missing
|
||||
# semicolon in dictionary.
|
||||
# on invalid files. Do the same kind of validation.
|
||||
import CoreFoundation
|
||||
import CoreFoundation # noqa: PLC0415
|
||||
|
||||
with open(source, "rb") as in_file:
|
||||
s = in_file.read()
|
||||
|
|
@ -158,17 +154,15 @@ class MacTool:
|
|||
|
||||
def _DetectInputEncoding(self, file_name):
|
||||
"""Reads the first few bytes from file_name and tries to guess the text
|
||||
encoding. Returns None as a guess if it can't detect it."""
|
||||
encoding. Returns None as a guess if it can't detect it."""
|
||||
with open(file_name, "rb") as fp:
|
||||
try:
|
||||
header = fp.read(3)
|
||||
except Exception:
|
||||
return None
|
||||
if header.startswith(b"\xFE\xFF"):
|
||||
if header.startswith((b"\xfe\xff", b"\xff\xfe")):
|
||||
return "UTF-16"
|
||||
elif header.startswith(b"\xFF\xFE"):
|
||||
return "UTF-16"
|
||||
elif header.startswith(b"\xEF\xBB\xBF"):
|
||||
elif header.startswith(b"\xef\xbb\xbf"):
|
||||
return "UTF-8"
|
||||
else:
|
||||
return None
|
||||
|
|
@ -259,9 +253,9 @@ class MacTool:
|
|||
|
||||
def ExecFilterLibtool(self, *cmd_list):
|
||||
"""Calls libtool and filters out '/path/to/libtool: file: foo.o has no
|
||||
symbols'."""
|
||||
symbols'."""
|
||||
libtool_re = re.compile(
|
||||
r"^.*libtool: (?:for architecture: \S* )?" r"file: .* has no symbols$"
|
||||
r"^.*libtool: (?:for architecture: \S* )?file: .* has no symbols$"
|
||||
)
|
||||
libtool_re5 = re.compile(
|
||||
r"^.*libtool: warning for library: "
|
||||
|
|
@ -308,7 +302,7 @@ class MacTool:
|
|||
|
||||
def ExecPackageFramework(self, framework, version):
|
||||
"""Takes a path to Something.framework and the Current version of that and
|
||||
sets up all the symlinks."""
|
||||
sets up all the symlinks."""
|
||||
# Find the name of the binary based on the part before the ".framework".
|
||||
binary = os.path.basename(framework).split(".")[0]
|
||||
|
||||
|
|
@ -337,7 +331,7 @@ class MacTool:
|
|||
|
||||
def _Relink(self, dest, link):
|
||||
"""Creates a symlink to |dest| named |link|. If |link| already exists,
|
||||
it is overwritten."""
|
||||
it is overwritten."""
|
||||
if os.path.lexists(link):
|
||||
os.remove(link)
|
||||
os.symlink(dest, link)
|
||||
|
|
@ -362,14 +356,14 @@ class MacTool:
|
|||
def ExecCompileXcassets(self, keys, *inputs):
|
||||
"""Compiles multiple .xcassets files into a single .car file.
|
||||
|
||||
This invokes 'actool' to compile all the inputs .xcassets files. The
|
||||
|keys| arguments is a json-encoded dictionary of extra arguments to
|
||||
pass to 'actool' when the asset catalogs contains an application icon
|
||||
or a launch image.
|
||||
This invokes 'actool' to compile all the inputs .xcassets files. The
|
||||
|keys| arguments is a json-encoded dictionary of extra arguments to
|
||||
pass to 'actool' when the asset catalogs contains an application icon
|
||||
or a launch image.
|
||||
|
||||
Note that 'actool' does not create the Assets.car file if the asset
|
||||
catalogs does not contains imageset.
|
||||
"""
|
||||
Note that 'actool' does not create the Assets.car file if the asset
|
||||
catalogs does not contains imageset.
|
||||
"""
|
||||
command_line = [
|
||||
"xcrun",
|
||||
"actool",
|
||||
|
|
@ -442,13 +436,13 @@ class MacTool:
|
|||
def ExecCodeSignBundle(self, key, entitlements, provisioning, path, preserve):
|
||||
"""Code sign a bundle.
|
||||
|
||||
This function tries to code sign an iOS bundle, following the same
|
||||
algorithm as Xcode:
|
||||
1. pick the provisioning profile that best match the bundle identifier,
|
||||
and copy it into the bundle as embedded.mobileprovision,
|
||||
2. copy Entitlements.plist from user or SDK next to the bundle,
|
||||
3. code sign the bundle.
|
||||
"""
|
||||
This function tries to code sign an iOS bundle, following the same
|
||||
algorithm as Xcode:
|
||||
1. pick the provisioning profile that best match the bundle identifier,
|
||||
and copy it into the bundle as embedded.mobileprovision,
|
||||
2. copy Entitlements.plist from user or SDK next to the bundle,
|
||||
3. code sign the bundle.
|
||||
"""
|
||||
substitutions, overrides = self._InstallProvisioningProfile(
|
||||
provisioning, self._GetCFBundleIdentifier()
|
||||
)
|
||||
|
|
@ -467,16 +461,16 @@ class MacTool:
|
|||
def _InstallProvisioningProfile(self, profile, bundle_identifier):
|
||||
"""Installs embedded.mobileprovision into the bundle.
|
||||
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
|
||||
Returns:
|
||||
A tuple containing two dictionary: variables substitutions and values
|
||||
to overrides when generating the entitlements file.
|
||||
"""
|
||||
Returns:
|
||||
A tuple containing two dictionary: variables substitutions and values
|
||||
to overrides when generating the entitlements file.
|
||||
"""
|
||||
source_path, provisioning_data, team_id = self._FindProvisioningProfile(
|
||||
profile, bundle_identifier
|
||||
)
|
||||
|
|
@ -492,24 +486,24 @@ class MacTool:
|
|||
def _FindProvisioningProfile(self, profile, bundle_identifier):
|
||||
"""Finds the .mobileprovision file to use for signing the bundle.
|
||||
|
||||
Checks all the installed provisioning profiles (or if the user specified
|
||||
the PROVISIONING_PROFILE variable, only consult it) and select the most
|
||||
specific that correspond to the bundle identifier.
|
||||
Checks all the installed provisioning profiles (or if the user specified
|
||||
the PROVISIONING_PROFILE variable, only consult it) and select the most
|
||||
specific that correspond to the bundle identifier.
|
||||
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
|
||||
Returns:
|
||||
A tuple of the path to the selected provisioning profile, the data of
|
||||
the embedded plist in the provisioning profile and the team identifier
|
||||
to use for code signing.
|
||||
Returns:
|
||||
A tuple of the path to the selected provisioning profile, the data of
|
||||
the embedded plist in the provisioning profile and the team identifier
|
||||
to use for code signing.
|
||||
|
||||
Raises:
|
||||
SystemExit: if no .mobileprovision can be used to sign the bundle.
|
||||
"""
|
||||
Raises:
|
||||
SystemExit: if no .mobileprovision can be used to sign the bundle.
|
||||
"""
|
||||
profiles_dir = os.path.join(
|
||||
os.environ["HOME"], "Library", "MobileDevice", "Provisioning Profiles"
|
||||
)
|
||||
|
|
@ -551,18 +545,18 @@ class MacTool:
|
|||
# If the user has multiple provisioning profiles installed that can be
|
||||
# used for ${bundle_identifier}, pick the most specific one (ie. the
|
||||
# provisioning profile whose pattern is the longest).
|
||||
selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
|
||||
selected_key = max(valid_provisioning_profiles, key=len)
|
||||
return valid_provisioning_profiles[selected_key]
|
||||
|
||||
def _LoadProvisioningProfile(self, profile_path):
|
||||
"""Extracts the plist embedded in a provisioning profile.
|
||||
|
||||
Args:
|
||||
profile_path: string, path to the .mobileprovision file
|
||||
Args:
|
||||
profile_path: string, path to the .mobileprovision file
|
||||
|
||||
Returns:
|
||||
Content of the plist embedded in the provisioning profile as a dictionary.
|
||||
"""
|
||||
Returns:
|
||||
Content of the plist embedded in the provisioning profile as a dictionary.
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile() as temp:
|
||||
subprocess.check_call(
|
||||
["security", "cms", "-D", "-i", profile_path, "-o", temp.name]
|
||||
|
|
@ -585,16 +579,16 @@ class MacTool:
|
|||
def _LoadPlistMaybeBinary(self, plist_path):
|
||||
"""Loads into a memory a plist possibly encoded in binary format.
|
||||
|
||||
This is a wrapper around plistlib.readPlist that tries to convert the
|
||||
plist to the XML format if it can't be parsed (assuming that it is in
|
||||
the binary format).
|
||||
This is a wrapper around plistlib.readPlist that tries to convert the
|
||||
plist to the XML format if it can't be parsed (assuming that it is in
|
||||
the binary format).
|
||||
|
||||
Args:
|
||||
plist_path: string, path to a plist file, in XML or binary format
|
||||
Args:
|
||||
plist_path: string, path to a plist file, in XML or binary format
|
||||
|
||||
Returns:
|
||||
Content of the plist as a dictionary.
|
||||
"""
|
||||
Returns:
|
||||
Content of the plist as a dictionary.
|
||||
"""
|
||||
try:
|
||||
# First, try to read the file using plistlib that only supports XML,
|
||||
# and if an exception is raised, convert a temporary copy to XML and
|
||||
|
|
@ -610,13 +604,13 @@ class MacTool:
|
|||
def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix):
|
||||
"""Constructs a dictionary of variable substitutions for Entitlements.plist.
|
||||
|
||||
Args:
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
app_identifier_prefix: string, value for AppIdentifierPrefix
|
||||
Args:
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
app_identifier_prefix: string, value for AppIdentifierPrefix
|
||||
|
||||
Returns:
|
||||
Dictionary of substitutions to apply when generating Entitlements.plist.
|
||||
"""
|
||||
Returns:
|
||||
Dictionary of substitutions to apply when generating Entitlements.plist.
|
||||
"""
|
||||
return {
|
||||
"CFBundleIdentifier": bundle_identifier,
|
||||
"AppIdentifierPrefix": app_identifier_prefix,
|
||||
|
|
@ -625,9 +619,9 @@ class MacTool:
|
|||
def _GetCFBundleIdentifier(self):
|
||||
"""Extracts CFBundleIdentifier value from Info.plist in the bundle.
|
||||
|
||||
Returns:
|
||||
Value of CFBundleIdentifier in the Info.plist located in the bundle.
|
||||
"""
|
||||
Returns:
|
||||
Value of CFBundleIdentifier in the Info.plist located in the bundle.
|
||||
"""
|
||||
info_plist_path = os.path.join(
|
||||
os.environ["TARGET_BUILD_DIR"], os.environ["INFOPLIST_PATH"]
|
||||
)
|
||||
|
|
@ -637,19 +631,19 @@ class MacTool:
|
|||
def _InstallEntitlements(self, entitlements, substitutions, overrides):
|
||||
"""Generates and install the ${BundleName}.xcent entitlements file.
|
||||
|
||||
Expands variables "$(variable)" pattern in the source entitlements file,
|
||||
add extra entitlements defined in the .mobileprovision file and the copy
|
||||
the generated plist to "${BundlePath}.xcent".
|
||||
Expands variables "$(variable)" pattern in the source entitlements file,
|
||||
add extra entitlements defined in the .mobileprovision file and the copy
|
||||
the generated plist to "${BundlePath}.xcent".
|
||||
|
||||
Args:
|
||||
entitlements: string, optional, path to the Entitlements.plist template
|
||||
to use, defaults to "${SDKROOT}/Entitlements.plist"
|
||||
substitutions: dictionary, variable substitutions
|
||||
overrides: dictionary, values to add to the entitlements
|
||||
Args:
|
||||
entitlements: string, optional, path to the Entitlements.plist template
|
||||
to use, defaults to "${SDKROOT}/Entitlements.plist"
|
||||
substitutions: dictionary, variable substitutions
|
||||
overrides: dictionary, values to add to the entitlements
|
||||
|
||||
Returns:
|
||||
Path to the generated entitlements file.
|
||||
"""
|
||||
Returns:
|
||||
Path to the generated entitlements file.
|
||||
"""
|
||||
source_path = entitlements
|
||||
target_path = os.path.join(
|
||||
os.environ["BUILT_PRODUCTS_DIR"], os.environ["PRODUCT_NAME"] + ".xcent"
|
||||
|
|
@ -669,15 +663,15 @@ class MacTool:
|
|||
def _ExpandVariables(self, data, substitutions):
|
||||
"""Expands variables "$(variable)" in data.
|
||||
|
||||
Args:
|
||||
data: object, can be either string, list or dictionary
|
||||
substitutions: dictionary, variable substitutions to perform
|
||||
Args:
|
||||
data: object, can be either string, list or dictionary
|
||||
substitutions: dictionary, variable substitutions to perform
|
||||
|
||||
Returns:
|
||||
Copy of data where each references to "$(variable)" has been replaced
|
||||
by the corresponding value found in substitutions, or left intact if
|
||||
the key was not found.
|
||||
"""
|
||||
Returns:
|
||||
Copy of data where each references to "$(variable)" has been replaced
|
||||
by the corresponding value found in substitutions, or left intact if
|
||||
the key was not found.
|
||||
"""
|
||||
if isinstance(data, str):
|
||||
for key, value in substitutions.items():
|
||||
data = data.replace("$(%s)" % key, value)
|
||||
|
|
@ -696,15 +690,15 @@ def NextGreaterPowerOf2(x):
|
|||
def WriteHmap(output_name, filelist):
|
||||
"""Generates a header map based on |filelist|.
|
||||
|
||||
Per Mark Mentovai:
|
||||
A header map is structured essentially as a hash table, keyed by names used
|
||||
in #includes, and providing pathnames to the actual files.
|
||||
Per Mark Mentovai:
|
||||
A header map is structured essentially as a hash table, keyed by names used
|
||||
in #includes, and providing pathnames to the actual files.
|
||||
|
||||
The implementation below and the comment above comes from inspecting:
|
||||
http://www.opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py?txt
|
||||
while also looking at the implementation in clang in:
|
||||
https://llvm.org/svn/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp
|
||||
"""
|
||||
The implementation below and the comment above comes from inspecting:
|
||||
http://www.opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py?txt
|
||||
while also looking at the implementation in clang in:
|
||||
https://llvm.org/svn/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp
|
||||
"""
|
||||
magic = 1751998832
|
||||
version = 1
|
||||
_reserved = 0
|
||||
|
|
|
|||
76
electron/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
generated
vendored
76
electron/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
generated
vendored
|
|
@ -7,15 +7,15 @@ This module helps emulate Visual Studio 2008 behavior on top of other
|
|||
build systems, primarily ninja.
|
||||
"""
|
||||
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
|
||||
from gyp.common import OrderedSet
|
||||
import gyp.MSVSUtil
|
||||
import gyp.MSVSVersion
|
||||
from gyp.common import OrderedSet
|
||||
|
||||
windows_quoter_regex = re.compile(r'(\\*)"')
|
||||
|
||||
|
|
@ -74,8 +74,7 @@ def EncodeRspFileList(args, quote_cmd):
|
|||
program = call + " " + os.path.normpath(program)
|
||||
else:
|
||||
program = os.path.normpath(args[0])
|
||||
return (program + " "
|
||||
+ " ".join(QuoteForRspFile(arg, quote_cmd) for arg in args[1:]))
|
||||
return program + " " + " ".join(QuoteForRspFile(arg, quote_cmd) for arg in args[1:])
|
||||
|
||||
|
||||
def _GenericRetrieve(root, default, path):
|
||||
|
|
@ -93,7 +92,7 @@ def _AddPrefix(element, prefix):
|
|||
if element is None:
|
||||
return element
|
||||
# Note, not Iterable because we don't want to handle strings like that.
|
||||
if isinstance(element, list) or isinstance(element, tuple):
|
||||
if isinstance(element, (list, tuple)):
|
||||
return [prefix + e for e in element]
|
||||
else:
|
||||
return prefix + element
|
||||
|
|
@ -105,7 +104,7 @@ def _DoRemapping(element, map):
|
|||
if map is not None and element is not None:
|
||||
if not callable(map):
|
||||
map = map.get # Assume it's a dict, otherwise a callable to do the remap.
|
||||
if isinstance(element, list) or isinstance(element, tuple):
|
||||
if isinstance(element, (list, tuple)):
|
||||
element = filter(None, [map(elem) for elem in element])
|
||||
else:
|
||||
element = map(element)
|
||||
|
|
@ -117,7 +116,7 @@ def _AppendOrReturn(append, element):
|
|||
then add |element| to it, adding each item in |element| if it's a list or
|
||||
tuple."""
|
||||
if append is not None and element is not None:
|
||||
if isinstance(element, list) or isinstance(element, tuple):
|
||||
if isinstance(element, (list, tuple)):
|
||||
append.extend(element)
|
||||
else:
|
||||
append.append(element)
|
||||
|
|
@ -183,7 +182,7 @@ def ExtractSharedMSVSSystemIncludes(configs, generator_flags):
|
|||
expanded_system_includes = OrderedSet(
|
||||
[ExpandMacros(include, env) for include in all_system_includes]
|
||||
)
|
||||
if any(["$" in include for include in expanded_system_includes]):
|
||||
if any("$" in include for include in expanded_system_includes):
|
||||
# Some path relies on target-specific variables, bail.
|
||||
return None
|
||||
|
||||
|
|
@ -247,18 +246,13 @@ class MsvsSettings:
|
|||
the target type.
|
||||
"""
|
||||
ext = self.spec.get("product_extension", None)
|
||||
if ext:
|
||||
return ext
|
||||
return gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "")
|
||||
return ext or gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "")
|
||||
|
||||
def GetVSMacroEnv(self, base_to_build=None, config=None):
|
||||
"""Get a dict of variables mapping internal VS macro names to their gyp
|
||||
equivalents."""
|
||||
target_arch = self.GetArch(config)
|
||||
if target_arch == "x86":
|
||||
target_platform = "Win32"
|
||||
else:
|
||||
target_platform = target_arch
|
||||
target_platform = "Win32" if target_arch == "x86" else target_arch
|
||||
target_name = self.spec.get("product_prefix", "") + self.spec.get(
|
||||
"product_name", self.spec["target_name"]
|
||||
)
|
||||
|
|
@ -628,8 +622,7 @@ class MsvsSettings:
|
|||
def _GetDefFileAsLdflags(self, ldflags, gyp_to_build_path):
|
||||
""".def files get implicitly converted to a ModuleDefinitionFile for the
|
||||
linker in the VS generator. Emulate that behaviour here."""
|
||||
def_file = self.GetDefFile(gyp_to_build_path)
|
||||
if def_file:
|
||||
if def_file := self.GetDefFile(gyp_to_build_path):
|
||||
ldflags.append('/DEF:"%s"' % def_file)
|
||||
|
||||
def GetPGDName(self, config, expand_special):
|
||||
|
|
@ -677,14 +670,11 @@ class MsvsSettings:
|
|||
)
|
||||
ld("DelayLoadDLLs", prefix="/DELAYLOAD:")
|
||||
ld("TreatLinkerWarningAsErrors", prefix="/WX", map={"true": "", "false": ":NO"})
|
||||
out = self.GetOutputName(config, expand_special)
|
||||
if out:
|
||||
if out := self.GetOutputName(config, expand_special):
|
||||
ldflags.append("/OUT:" + out)
|
||||
pdb = self.GetPDBName(config, expand_special, output_name + ".pdb")
|
||||
if pdb:
|
||||
if pdb := self.GetPDBName(config, expand_special, output_name + ".pdb"):
|
||||
ldflags.append("/PDB:" + pdb)
|
||||
pgd = self.GetPGDName(config, expand_special)
|
||||
if pgd:
|
||||
if pgd := self.GetPGDName(config, expand_special):
|
||||
ldflags.append("/PGD:" + pgd)
|
||||
map_file = self.GetMapFileName(config, expand_special)
|
||||
ld("GenerateMapFile", map={"true": "/MAP:" + map_file if map_file else "/MAP"})
|
||||
|
|
@ -738,10 +728,7 @@ class MsvsSettings:
|
|||
# TODO(scottmg): This should sort of be somewhere else (not really a flag).
|
||||
ld("AdditionalDependencies", prefix="")
|
||||
|
||||
if self.GetArch(config) == "x86":
|
||||
safeseh_default = "true"
|
||||
else:
|
||||
safeseh_default = None
|
||||
safeseh_default = "true" if self.GetArch(config) == "x86" else None
|
||||
ld(
|
||||
"ImageHasSafeExceptionHandlers",
|
||||
map={"false": ":NO", "true": ""},
|
||||
|
|
@ -836,17 +823,15 @@ class MsvsSettings:
|
|||
("VCLinkerTool", "UACUIAccess"), config, default="false"
|
||||
)
|
||||
|
||||
inner = """
|
||||
level = execution_level_map[execution_level]
|
||||
inner = f"""
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level='{}' uiAccess='{}' />
|
||||
<requestedExecutionLevel level='{level}' uiAccess='{ui_access}' />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>""".format(
|
||||
execution_level_map[execution_level],
|
||||
ui_access,
|
||||
)
|
||||
</trustInfo>"""
|
||||
else:
|
||||
inner = ""
|
||||
|
||||
|
|
@ -941,34 +926,34 @@ class MsvsSettings:
|
|||
)
|
||||
return cmd
|
||||
|
||||
RuleShellFlags = collections.namedtuple("RuleShellFlags", ["cygwin", "quote"])
|
||||
RuleShellFlags = namedtuple("RuleShellFlags", ["cygwin", "quote"]) # noqa: PYI024
|
||||
|
||||
def GetRuleShellFlags(self, rule):
|
||||
"""Return RuleShellFlags about how the given rule should be run. This
|
||||
includes whether it should run under cygwin (msvs_cygwin_shell), and
|
||||
whether the commands should be quoted (msvs_quote_cmd)."""
|
||||
# If the variable is unset, or set to 1 we use cygwin
|
||||
cygwin = int(rule.get("msvs_cygwin_shell",
|
||||
self.spec.get("msvs_cygwin_shell", 1))) != 0
|
||||
cygwin = (
|
||||
int(rule.get("msvs_cygwin_shell", self.spec.get("msvs_cygwin_shell", 1)))
|
||||
!= 0
|
||||
)
|
||||
# Default to quoting. There's only a few special instances where the
|
||||
# target command uses non-standard command line parsing and handle quotes
|
||||
# and quote escaping differently.
|
||||
quote_cmd = int(rule.get("msvs_quote_cmd", 1))
|
||||
assert quote_cmd != 0 or cygwin != 1, \
|
||||
"msvs_quote_cmd=0 only applicable for msvs_cygwin_shell=0"
|
||||
assert quote_cmd != 0 or cygwin != 1, (
|
||||
"msvs_quote_cmd=0 only applicable for msvs_cygwin_shell=0"
|
||||
)
|
||||
return MsvsSettings.RuleShellFlags(cygwin, quote_cmd)
|
||||
|
||||
def _HasExplicitRuleForExtension(self, spec, extension):
|
||||
"""Determine if there's an explicit rule for a particular extension."""
|
||||
for rule in spec.get("rules", []):
|
||||
if rule["extension"] == extension:
|
||||
return True
|
||||
return False
|
||||
return any(rule["extension"] == extension for rule in spec.get("rules", []))
|
||||
|
||||
def _HasExplicitIdlActions(self, spec):
|
||||
"""Determine if an action should not run midl for .idl files."""
|
||||
return any(
|
||||
[action.get("explicit_idl_action", 0) for action in spec.get("actions", [])]
|
||||
action.get("explicit_idl_action", 0) for action in spec.get("actions", [])
|
||||
)
|
||||
|
||||
def HasExplicitIdlRulesOrActions(self, spec):
|
||||
|
|
@ -1146,8 +1131,7 @@ def _ExtractImportantEnvironment(output_of_set):
|
|||
for required in ("SYSTEMROOT", "TEMP", "TMP"):
|
||||
if required not in env:
|
||||
raise Exception(
|
||||
'Environment variable "%s" '
|
||||
"required to be set to valid path" % required
|
||||
'Environment variable "%s" required to be set to valid path' % required
|
||||
)
|
||||
return env
|
||||
|
||||
|
|
@ -1190,7 +1174,7 @@ def GenerateEnvironmentFiles(
|
|||
meet your requirement (e.g. for custom toolchains), you can pass
|
||||
"-G ninja_use_custom_environment_files" to the gyp to suppress file
|
||||
generation and use custom environment files prepared by yourself."""
|
||||
archs = ("x86", "x64")
|
||||
archs = ("x86", "x64", "arm64")
|
||||
if generator_flags.get("ninja_use_custom_environment_files", 0):
|
||||
cl_paths = {}
|
||||
for arch in archs:
|
||||
|
|
|
|||
8
electron/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py
generated
vendored
8
electron/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py
generated
vendored
|
|
@ -17,15 +17,15 @@ __all__ = ["Error", "deepcopy"]
|
|||
|
||||
def deepcopy(x):
|
||||
"""Deep copy operation on gyp objects such as strings, ints, dicts
|
||||
and lists. More than twice as fast as copy.deepcopy but much less
|
||||
generic."""
|
||||
and lists. More than twice as fast as copy.deepcopy but much less
|
||||
generic."""
|
||||
|
||||
try:
|
||||
return _deepcopy_dispatch[type(x)](x)
|
||||
except KeyError:
|
||||
raise Error(
|
||||
"Unsupported type %s for deepcopy. Use copy.deepcopy "
|
||||
+ "or expand simple_copy support." % type(x)
|
||||
f"Unsupported type {type(x)} for deepcopy. Use copy.deepcopy "
|
||||
+ "or expand simple_copy support."
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
47
electron/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
generated
vendored
47
electron/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
generated
vendored
|
|
@ -9,13 +9,12 @@
|
|||
These functions are executed via gyp-win-tool when using the ninja generator.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import stat
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
|
@ -27,18 +26,17 @@ _LINK_EXE_OUT_ARG = re.compile("/OUT:(?P<out>.+)$", re.IGNORECASE)
|
|||
|
||||
def main(args):
|
||||
executor = WinTool()
|
||||
exit_code = executor.Dispatch(args)
|
||||
if exit_code is not None:
|
||||
if (exit_code := executor.Dispatch(args)) is not None:
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
class WinTool:
|
||||
"""This class performs all the Windows tooling steps. The methods can either
|
||||
be executed directly, or dispatched from an argument list."""
|
||||
be executed directly, or dispatched from an argument list."""
|
||||
|
||||
def _UseSeparateMspdbsrv(self, env, args):
|
||||
"""Allows to use a unique instance of mspdbsrv.exe per linker instead of a
|
||||
shared one."""
|
||||
shared one."""
|
||||
if len(args) < 1:
|
||||
raise Exception("Not enough arguments")
|
||||
|
||||
|
|
@ -115,9 +113,9 @@ class WinTool:
|
|||
|
||||
def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args):
|
||||
"""Filter diagnostic output from link that looks like:
|
||||
' Creating library ui.dll.lib and object ui.dll.exp'
|
||||
This happens when there are exports from the dll or exe.
|
||||
"""
|
||||
' Creating library ui.dll.lib and object ui.dll.exp'
|
||||
This happens when there are exports from the dll or exe.
|
||||
"""
|
||||
env = self._GetEnv(arch)
|
||||
if use_separate_mspdbsrv == "True":
|
||||
self._UseSeparateMspdbsrv(env, args)
|
||||
|
|
@ -159,10 +157,10 @@ class WinTool:
|
|||
mt,
|
||||
rc,
|
||||
intermediate_manifest,
|
||||
*manifests
|
||||
*manifests,
|
||||
):
|
||||
"""A wrapper for handling creating a manifest resource and then executing
|
||||
a link command."""
|
||||
a link command."""
|
||||
# The 'normal' way to do manifests is to have link generate a manifest
|
||||
# based on gathering dependencies from the object files, then merge that
|
||||
# manifest with other manifests supplied as sources, convert the merged
|
||||
|
|
@ -219,11 +217,10 @@ class WinTool:
|
|||
our_manifest = "%(out)s.manifest" % variables
|
||||
# Load and normalize the manifests. mt.exe sometimes removes whitespace,
|
||||
# and sometimes doesn't unfortunately.
|
||||
with open(our_manifest) as our_f:
|
||||
with open(assert_manifest) as assert_f:
|
||||
translator = str.maketrans('', '', string.whitespace)
|
||||
our_data = our_f.read().translate(translator)
|
||||
assert_data = assert_f.read().translate(translator)
|
||||
with open(our_manifest) as our_f, open(assert_manifest) as assert_f:
|
||||
translator = str.maketrans("", "", string.whitespace)
|
||||
our_data = our_f.read().translate(translator)
|
||||
assert_data = assert_f.read().translate(translator)
|
||||
if our_data != assert_data:
|
||||
os.unlink(out)
|
||||
|
||||
|
|
@ -247,8 +244,8 @@ class WinTool:
|
|||
|
||||
def ExecManifestWrapper(self, arch, *args):
|
||||
"""Run manifest tool with environment set. Strip out undesirable warning
|
||||
(some XML blocks are recognized by the OS loader, but not the manifest
|
||||
tool)."""
|
||||
(some XML blocks are recognized by the OS loader, but not the manifest
|
||||
tool)."""
|
||||
env = self._GetEnv(arch)
|
||||
popen = subprocess.Popen(
|
||||
args, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
|
|
@ -261,8 +258,8 @@ class WinTool:
|
|||
|
||||
def ExecManifestToRc(self, arch, *args):
|
||||
"""Creates a resource file pointing a SxS assembly manifest.
|
||||
|args| is tuple containing path to resource file, path to manifest file
|
||||
and resource name which can be "1" (for executables) or "2" (for DLLs)."""
|
||||
|args| is tuple containing path to resource file, path to manifest file
|
||||
and resource name which can be "1" (for executables) or "2" (for DLLs)."""
|
||||
manifest_path, resource_path, resource_name = args
|
||||
with open(resource_path, "w") as output:
|
||||
output.write(
|
||||
|
|
@ -272,8 +269,8 @@ class WinTool:
|
|||
|
||||
def ExecMidlWrapper(self, arch, outdir, tlb, h, dlldata, iid, proxy, idl, *flags):
|
||||
"""Filter noisy filenames output from MIDL compile step that isn't
|
||||
quietable via command line flags.
|
||||
"""
|
||||
quietable via command line flags.
|
||||
"""
|
||||
args = (
|
||||
["midl", "/nologo"]
|
||||
+ list(flags)
|
||||
|
|
@ -329,7 +326,7 @@ class WinTool:
|
|||
|
||||
def ExecRcWrapper(self, arch, *args):
|
||||
"""Filter logo banner from invocations of rc.exe. Older versions of RC
|
||||
don't support the /nologo flag."""
|
||||
don't support the /nologo flag."""
|
||||
env = self._GetEnv(arch)
|
||||
popen = subprocess.Popen(
|
||||
args, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
|
|
@ -346,7 +343,7 @@ class WinTool:
|
|||
|
||||
def ExecActionWrapper(self, arch, rspfile, *dir):
|
||||
"""Runs an action command line from a response file using the environment
|
||||
for |arch|. If |dir| is supplied, use that as the working directory."""
|
||||
for |arch|. If |dir| is supplied, use that as the working directory."""
|
||||
env = self._GetEnv(arch)
|
||||
# TODO(scottmg): This is a temporary hack to get some specific variables
|
||||
# through to actions that are set after gyp-time. http://crbug.com/333738.
|
||||
|
|
@ -359,7 +356,7 @@ class WinTool:
|
|||
|
||||
def ExecClCompile(self, project_dir, selected_files):
|
||||
"""Executed by msvs-ninja projects when the 'ClCompile' target is used to
|
||||
build selected C/C++ files."""
|
||||
build selected C/C++ files."""
|
||||
project_dir = os.path.relpath(project_dir, BASE_DIR)
|
||||
selected_files = selected_files.split(";")
|
||||
ninja_targets = [
|
||||
|
|
|
|||
425
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
generated
vendored
425
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
generated
vendored
|
|
@ -7,15 +7,15 @@ This module contains classes that help to emulate xcodebuild behavior on top of
|
|||
other build systems, such as make and ninja.
|
||||
"""
|
||||
|
||||
|
||||
import copy
|
||||
import gyp.common
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import gyp.common
|
||||
from gyp.common import GypError
|
||||
|
||||
# Populated lazily by XcodeVersion, for efficiency, and to fix an issue when
|
||||
|
|
@ -30,7 +30,7 @@ XCODE_ARCHS_DEFAULT_CACHE = None
|
|||
|
||||
def XcodeArchsVariableMapping(archs, archs_including_64_bit=None):
|
||||
"""Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable,
|
||||
and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT)."""
|
||||
and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT)."""
|
||||
mapping = {"$(ARCHS_STANDARD)": archs}
|
||||
if archs_including_64_bit:
|
||||
mapping["$(ARCHS_STANDARD_INCLUDING_64_BIT)"] = archs_including_64_bit
|
||||
|
|
@ -39,10 +39,10 @@ def XcodeArchsVariableMapping(archs, archs_including_64_bit=None):
|
|||
|
||||
class XcodeArchsDefault:
|
||||
"""A class to resolve ARCHS variable from xcode_settings, resolving Xcode
|
||||
macros and implementing filtering by VALID_ARCHS. The expansion of macros
|
||||
depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and
|
||||
on the version of Xcode.
|
||||
"""
|
||||
macros and implementing filtering by VALID_ARCHS. The expansion of macros
|
||||
depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and
|
||||
on the version of Xcode.
|
||||
"""
|
||||
|
||||
# Match variable like $(ARCHS_STANDARD).
|
||||
variable_pattern = re.compile(r"\$\([a-zA-Z_][a-zA-Z0-9_]*\)$")
|
||||
|
|
@ -81,8 +81,8 @@ class XcodeArchsDefault:
|
|||
|
||||
def ActiveArchs(self, archs, valid_archs, sdkroot):
|
||||
"""Expands variables references in ARCHS, and filter by VALID_ARCHS if it
|
||||
is defined (if not set, Xcode accept any value in ARCHS, otherwise, only
|
||||
values present in VALID_ARCHS are kept)."""
|
||||
is defined (if not set, Xcode accept any value in ARCHS, otherwise, only
|
||||
values present in VALID_ARCHS are kept)."""
|
||||
expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or "")
|
||||
if valid_archs:
|
||||
filtered_archs = []
|
||||
|
|
@ -95,24 +95,24 @@ class XcodeArchsDefault:
|
|||
|
||||
def GetXcodeArchsDefault():
|
||||
"""Returns the |XcodeArchsDefault| object to use to expand ARCHS for the
|
||||
installed version of Xcode. The default values used by Xcode for ARCHS
|
||||
and the expansion of the variables depends on the version of Xcode used.
|
||||
installed version of Xcode. The default values used by Xcode for ARCHS
|
||||
and the expansion of the variables depends on the version of Xcode used.
|
||||
|
||||
For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included
|
||||
uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses
|
||||
$(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0
|
||||
and deprecated with Xcode 5.1.
|
||||
For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included
|
||||
uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses
|
||||
$(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0
|
||||
and deprecated with Xcode 5.1.
|
||||
|
||||
For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit
|
||||
architecture as part of $(ARCHS_STANDARD) and default to only building it.
|
||||
For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit
|
||||
architecture as part of $(ARCHS_STANDARD) and default to only building it.
|
||||
|
||||
For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part
|
||||
of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they
|
||||
are also part of $(ARCHS_STANDARD).
|
||||
For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part
|
||||
of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they
|
||||
are also part of $(ARCHS_STANDARD).
|
||||
|
||||
All these rules are coded in the construction of the |XcodeArchsDefault|
|
||||
object to use depending on the version of Xcode detected. The object is
|
||||
for performance reason."""
|
||||
All these rules are coded in the construction of the |XcodeArchsDefault|
|
||||
object to use depending on the version of Xcode detected. The object is
|
||||
for performance reason."""
|
||||
global XCODE_ARCHS_DEFAULT_CACHE
|
||||
if XCODE_ARCHS_DEFAULT_CACHE:
|
||||
return XCODE_ARCHS_DEFAULT_CACHE
|
||||
|
|
@ -189,8 +189,8 @@ class XcodeSettings:
|
|||
|
||||
def _ConvertConditionalKeys(self, configname):
|
||||
"""Converts or warns on conditional keys. Xcode supports conditional keys,
|
||||
such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation
|
||||
with some keys converted while the rest force a warning."""
|
||||
such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation
|
||||
with some keys converted while the rest force a warning."""
|
||||
settings = self.xcode_settings[configname]
|
||||
conditional_keys = [key for key in settings if key.endswith("]")]
|
||||
for key in conditional_keys:
|
||||
|
|
@ -255,13 +255,13 @@ class XcodeSettings:
|
|||
|
||||
def GetFrameworkVersion(self):
|
||||
"""Returns the framework version of the current target. Only valid for
|
||||
bundles."""
|
||||
bundles."""
|
||||
assert self._IsBundle()
|
||||
return self.GetPerTargetSetting("FRAMEWORK_VERSION", default="A")
|
||||
|
||||
def GetWrapperExtension(self):
|
||||
"""Returns the bundle extension (.app, .framework, .plugin, etc). Only
|
||||
valid for bundles."""
|
||||
valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
if self.spec["type"] in ("loadable_module", "shared_library"):
|
||||
default_wrapper_extension = {
|
||||
|
|
@ -296,13 +296,13 @@ class XcodeSettings:
|
|||
|
||||
def GetWrapperName(self):
|
||||
"""Returns the directory name of the bundle represented by this target.
|
||||
Only valid for bundles."""
|
||||
Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return self.GetProductName() + self.GetWrapperExtension()
|
||||
|
||||
def GetBundleContentsFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's contents folder. E.g.
|
||||
Chromium.app/Contents or Foo.bundle/Versions/A. Only valid for bundles."""
|
||||
Chromium.app/Contents or Foo.bundle/Versions/A. Only valid for bundles."""
|
||||
if self.isIOS:
|
||||
return self.GetWrapperName()
|
||||
assert self._IsBundle()
|
||||
|
|
@ -316,7 +316,7 @@ class XcodeSettings:
|
|||
|
||||
def GetBundleResourceFolder(self):
|
||||
"""Returns the qualified path to the bundle's resource folder. E.g.
|
||||
Chromium.app/Contents/Resources. Only valid for bundles."""
|
||||
Chromium.app/Contents/Resources. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
if self.isIOS:
|
||||
return self.GetBundleContentsFolderPath()
|
||||
|
|
@ -324,7 +324,7 @@ class XcodeSettings:
|
|||
|
||||
def GetBundleExecutableFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's executables folder. E.g.
|
||||
Chromium.app/Contents/MacOS. Only valid for bundles."""
|
||||
Chromium.app/Contents/MacOS. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
if self.spec["type"] in ("shared_library") or self.isIOS:
|
||||
return self.GetBundleContentsFolderPath()
|
||||
|
|
@ -333,25 +333,25 @@ class XcodeSettings:
|
|||
|
||||
def GetBundleJavaFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's Java resource folder.
|
||||
E.g. Chromium.app/Contents/Resources/Java. Only valid for bundles."""
|
||||
E.g. Chromium.app/Contents/Resources/Java. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(self.GetBundleResourceFolder(), "Java")
|
||||
|
||||
def GetBundleFrameworksFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's frameworks folder. E.g,
|
||||
Chromium.app/Contents/Frameworks. Only valid for bundles."""
|
||||
Chromium.app/Contents/Frameworks. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(self.GetBundleContentsFolderPath(), "Frameworks")
|
||||
|
||||
def GetBundleSharedFrameworksFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's frameworks folder. E.g,
|
||||
Chromium.app/Contents/SharedFrameworks. Only valid for bundles."""
|
||||
Chromium.app/Contents/SharedFrameworks. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(self.GetBundleContentsFolderPath(), "SharedFrameworks")
|
||||
|
||||
def GetBundleSharedSupportFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's shared support folder. E.g,
|
||||
Chromium.app/Contents/SharedSupport. Only valid for bundles."""
|
||||
Chromium.app/Contents/SharedSupport. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
if self.spec["type"] == "shared_library":
|
||||
return self.GetBundleResourceFolder()
|
||||
|
|
@ -360,19 +360,19 @@ class XcodeSettings:
|
|||
|
||||
def GetBundlePlugInsFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's plugins folder. E.g,
|
||||
Chromium.app/Contents/PlugIns. Only valid for bundles."""
|
||||
Chromium.app/Contents/PlugIns. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(self.GetBundleContentsFolderPath(), "PlugIns")
|
||||
|
||||
def GetBundleXPCServicesFolderPath(self):
|
||||
"""Returns the qualified path to the bundle's XPC services folder. E.g,
|
||||
Chromium.app/Contents/XPCServices. Only valid for bundles."""
|
||||
Chromium.app/Contents/XPCServices. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(self.GetBundleContentsFolderPath(), "XPCServices")
|
||||
|
||||
def GetBundlePlistPath(self):
|
||||
"""Returns the qualified path to the bundle's plist file. E.g.
|
||||
Chromium.app/Contents/Info.plist. Only valid for bundles."""
|
||||
Chromium.app/Contents/Info.plist. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
if (
|
||||
self.spec["type"] in ("executable", "loadable_module")
|
||||
|
|
@ -438,7 +438,7 @@ class XcodeSettings:
|
|||
|
||||
def _GetBundleBinaryPath(self):
|
||||
"""Returns the name of the bundle binary of by this target.
|
||||
E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles."""
|
||||
E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles."""
|
||||
assert self._IsBundle()
|
||||
return os.path.join(
|
||||
self.GetBundleExecutableFolderPath(), self.GetExecutableName()
|
||||
|
|
@ -469,19 +469,16 @@ class XcodeSettings:
|
|||
|
||||
def _GetStandaloneBinaryPath(self):
|
||||
"""Returns the name of the non-bundle binary represented by this target.
|
||||
E.g. hello_world. Only valid for non-bundles."""
|
||||
E.g. hello_world. Only valid for non-bundles."""
|
||||
assert not self._IsBundle()
|
||||
assert self.spec["type"] in (
|
||||
assert self.spec["type"] in {
|
||||
"executable",
|
||||
"shared_library",
|
||||
"static_library",
|
||||
"loadable_module",
|
||||
), ("Unexpected type %s" % self.spec["type"])
|
||||
}, "Unexpected type %s" % self.spec["type"]
|
||||
target = self.spec["target_name"]
|
||||
if self.spec["type"] == "static_library":
|
||||
if target[:3] == "lib":
|
||||
target = target[3:]
|
||||
elif self.spec["type"] in ("loadable_module", "shared_library"):
|
||||
if self.spec["type"] in {"loadable_module", "shared_library", "static_library"}:
|
||||
if target[:3] == "lib":
|
||||
target = target[3:]
|
||||
|
||||
|
|
@ -492,7 +489,7 @@ class XcodeSettings:
|
|||
|
||||
def GetExecutableName(self):
|
||||
"""Returns the executable name of the bundle represented by this target.
|
||||
E.g. Chromium."""
|
||||
E.g. Chromium."""
|
||||
if self._IsBundle():
|
||||
return self.spec.get("product_name", self.spec["target_name"])
|
||||
else:
|
||||
|
|
@ -500,7 +497,7 @@ class XcodeSettings:
|
|||
|
||||
def GetExecutablePath(self):
|
||||
"""Returns the qualified path to the primary executable of the bundle
|
||||
represented by this target. E.g. Chromium.app/Contents/MacOS/Chromium."""
|
||||
represented by this target. E.g. Chromium.app/Contents/MacOS/Chromium."""
|
||||
if self._IsBundle():
|
||||
return self._GetBundleBinaryPath()
|
||||
else:
|
||||
|
|
@ -523,7 +520,7 @@ class XcodeSettings:
|
|||
# most sensible route and should still do the right thing.
|
||||
try:
|
||||
return GetStdoutQuiet(["xcrun", "--sdk", sdk, infoitem])
|
||||
except GypError:
|
||||
except (GypError, OSError):
|
||||
pass
|
||||
|
||||
def _SdkRoot(self, configname):
|
||||
|
|
@ -570,7 +567,7 @@ class XcodeSettings:
|
|||
|
||||
def GetCflags(self, configname, arch=None):
|
||||
"""Returns flags that need to be added to .c, .cc, .m, and .mm
|
||||
compilations."""
|
||||
compilations."""
|
||||
# This functions (and the similar ones below) do not offer complete
|
||||
# emulation of all xcode_settings keys. They're implemented on demand.
|
||||
|
||||
|
|
@ -579,7 +576,8 @@ class XcodeSettings:
|
|||
|
||||
sdk_root = self._SdkPath()
|
||||
if "SDKROOT" in self._Settings() and sdk_root:
|
||||
cflags.append("-isysroot %s" % sdk_root)
|
||||
cflags.append("-isysroot")
|
||||
cflags.append(sdk_root)
|
||||
|
||||
if self.header_map_path:
|
||||
cflags.append("-I%s" % self.header_map_path)
|
||||
|
|
@ -664,7 +662,8 @@ class XcodeSettings:
|
|||
# TODO: Supporting fat binaries will be annoying.
|
||||
self._WarnUnimplemented("ARCHS")
|
||||
archs = ["i386"]
|
||||
cflags.append("-arch " + archs[0])
|
||||
cflags.append("-arch")
|
||||
cflags.append(archs[0])
|
||||
|
||||
if archs[0] in ("i386", "x86_64"):
|
||||
if self._Test("GCC_ENABLE_SSE3_EXTENSIONS", "YES", default="NO"):
|
||||
|
|
@ -685,10 +684,7 @@ class XcodeSettings:
|
|||
if platform_root:
|
||||
cflags.append("-F" + platform_root + "/Developer/Library/Frameworks/")
|
||||
|
||||
if sdk_root:
|
||||
framework_root = sdk_root
|
||||
else:
|
||||
framework_root = ""
|
||||
framework_root = sdk_root if sdk_root else ""
|
||||
config = self.spec["configurations"][self.configname]
|
||||
framework_dirs = config.get("mac_framework_dirs", [])
|
||||
for directory in framework_dirs:
|
||||
|
|
@ -866,7 +862,7 @@ class XcodeSettings:
|
|||
|
||||
def _MapLinkerFlagFilename(self, ldflag, gyp_to_build_path):
|
||||
"""Checks if ldflag contains a filename and if so remaps it from
|
||||
gyp-directory-relative to build-directory-relative."""
|
||||
gyp-directory-relative to build-directory-relative."""
|
||||
# This list is expanded on demand.
|
||||
# They get matched as:
|
||||
# -exported_symbols_list file
|
||||
|
|
@ -898,13 +894,13 @@ class XcodeSettings:
|
|||
def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None):
|
||||
"""Returns flags that need to be passed to the linker.
|
||||
|
||||
Args:
|
||||
configname: The name of the configuration to get ld flags for.
|
||||
product_dir: The directory where products such static and dynamic
|
||||
libraries are placed. This is added to the library search path.
|
||||
gyp_to_build_path: A function that converts paths relative to the
|
||||
current gyp file to paths relative to the build directory.
|
||||
"""
|
||||
Args:
|
||||
configname: The name of the configuration to get ld flags for.
|
||||
product_dir: The directory where products such static and dynamic
|
||||
libraries are placed. This is added to the library search path.
|
||||
gyp_to_build_path: A function that converts paths relative to the
|
||||
current gyp file to paths relative to the build directory.
|
||||
"""
|
||||
self.configname = configname
|
||||
ldflags = []
|
||||
|
||||
|
|
@ -927,17 +923,15 @@ class XcodeSettings:
|
|||
self._AppendPlatformVersionMinFlags(ldflags)
|
||||
|
||||
if "SDKROOT" in self._Settings() and self._SdkPath():
|
||||
ldflags.append("-isysroot " + self._SdkPath())
|
||||
ldflags.append("-isysroot")
|
||||
ldflags.append(self._SdkPath())
|
||||
|
||||
for library_path in self._Settings().get("LIBRARY_SEARCH_PATHS", []):
|
||||
ldflags.append("-L" + gyp_to_build_path(library_path))
|
||||
|
||||
if "ORDER_FILE" in self._Settings():
|
||||
ldflags.append(
|
||||
"-Wl,-order_file "
|
||||
+ "-Wl,"
|
||||
+ gyp_to_build_path(self._Settings()["ORDER_FILE"])
|
||||
)
|
||||
ldflags.append("-Wl,-order_file")
|
||||
ldflags.append("-Wl," + gyp_to_build_path(self._Settings()["ORDER_FILE"]))
|
||||
|
||||
if not gyp.common.CrossCompileRequested():
|
||||
if arch is not None:
|
||||
|
|
@ -949,7 +943,9 @@ class XcodeSettings:
|
|||
# TODO: Supporting fat binaries will be annoying.
|
||||
self._WarnUnimplemented("ARCHS")
|
||||
archs = ["i386"]
|
||||
ldflags.append("-arch " + archs[0])
|
||||
# Avoid quoting the space between -arch and the arch name
|
||||
ldflags.append("-arch")
|
||||
ldflags.append(archs[0])
|
||||
|
||||
# Xcode adds the product directory by default.
|
||||
# Rewrite -L. to -L./ to work around http://www.openradar.me/25313838
|
||||
|
|
@ -957,7 +953,8 @@ class XcodeSettings:
|
|||
|
||||
install_name = self.GetInstallName()
|
||||
if install_name and self.spec["type"] != "loadable_module":
|
||||
ldflags.append("-install_name " + install_name.replace(" ", r"\ "))
|
||||
ldflags.append("-install_name")
|
||||
ldflags.append(install_name.replace(" ", r"\ "))
|
||||
|
||||
for rpath in self._Settings().get("LD_RUNPATH_SEARCH_PATHS", []):
|
||||
ldflags.append("-Wl,-rpath," + rpath)
|
||||
|
|
@ -974,7 +971,8 @@ class XcodeSettings:
|
|||
platform_root = self._XcodePlatformPath(configname)
|
||||
if sdk_root and platform_root:
|
||||
ldflags.append("-F" + platform_root + "/Developer/Library/Frameworks/")
|
||||
ldflags.append("-framework XCTest")
|
||||
ldflags.append("-framework")
|
||||
ldflags.append("XCTest")
|
||||
|
||||
is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension()
|
||||
if sdk_root and is_extension:
|
||||
|
|
@ -990,7 +988,8 @@ class XcodeSettings:
|
|||
+ "/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit"
|
||||
)
|
||||
else:
|
||||
ldflags.append("-e _NSExtensionMain")
|
||||
ldflags.append("-e")
|
||||
ldflags.append("_NSExtensionMain")
|
||||
ldflags.append("-fapplication-extension")
|
||||
|
||||
self._Appendf(ldflags, "CLANG_CXX_LIBRARY", "-stdlib=%s")
|
||||
|
|
@ -1001,9 +1000,9 @@ class XcodeSettings:
|
|||
def GetLibtoolflags(self, configname):
|
||||
"""Returns flags that need to be passed to the static linker.
|
||||
|
||||
Args:
|
||||
configname: The name of the configuration to get ld flags for.
|
||||
"""
|
||||
Args:
|
||||
configname: The name of the configuration to get ld flags for.
|
||||
"""
|
||||
self.configname = configname
|
||||
libtoolflags = []
|
||||
|
||||
|
|
@ -1016,7 +1015,7 @@ class XcodeSettings:
|
|||
|
||||
def GetPerTargetSettings(self):
|
||||
"""Gets a list of all the per-target settings. This will only fetch keys
|
||||
whose values are the same across all configurations."""
|
||||
whose values are the same across all configurations."""
|
||||
first_pass = True
|
||||
result = {}
|
||||
for configname in sorted(self.xcode_settings.keys()):
|
||||
|
|
@ -1039,7 +1038,7 @@ class XcodeSettings:
|
|||
|
||||
def GetPerTargetSetting(self, setting, default=None):
|
||||
"""Tries to get xcode_settings.setting from spec. Assumes that the setting
|
||||
has the same value in all configurations and throws otherwise."""
|
||||
has the same value in all configurations and throws otherwise."""
|
||||
is_first_pass = True
|
||||
result = None
|
||||
for configname in sorted(self.xcode_settings.keys()):
|
||||
|
|
@ -1057,15 +1056,14 @@ class XcodeSettings:
|
|||
|
||||
def _GetStripPostbuilds(self, configname, output_binary, quiet):
|
||||
"""Returns a list of shell commands that contain the shell commands
|
||||
necessary to strip this target's binary. These should be run as postbuilds
|
||||
before the actual postbuilds run."""
|
||||
necessary to strip this target's binary. These should be run as postbuilds
|
||||
before the actual postbuilds run."""
|
||||
self.configname = configname
|
||||
|
||||
result = []
|
||||
if self._Test("DEPLOYMENT_POSTPROCESSING", "YES", default="NO") and self._Test(
|
||||
"STRIP_INSTALLED_PRODUCT", "YES", default="NO"
|
||||
):
|
||||
|
||||
default_strip_style = "debugging"
|
||||
if (
|
||||
self.spec["type"] == "loadable_module" or self._IsIosAppExtension()
|
||||
|
|
@ -1092,8 +1090,8 @@ class XcodeSettings:
|
|||
|
||||
def _GetDebugInfoPostbuilds(self, configname, output, output_binary, quiet):
|
||||
"""Returns a list of shell commands that contain the shell commands
|
||||
necessary to massage this target's debug information. These should be run
|
||||
as postbuilds before the actual postbuilds run."""
|
||||
necessary to massage this target's debug information. These should be run
|
||||
as postbuilds before the actual postbuilds run."""
|
||||
self.configname = configname
|
||||
|
||||
# For static libraries, no dSYMs are created.
|
||||
|
|
@ -1114,7 +1112,7 @@ class XcodeSettings:
|
|||
|
||||
def _GetTargetPostbuilds(self, configname, output, output_binary, quiet=False):
|
||||
"""Returns a list of shell commands that contain the shell commands
|
||||
to run as postbuilds for this target, before the actual postbuilds."""
|
||||
to run as postbuilds for this target, before the actual postbuilds."""
|
||||
# dSYMs need to build before stripping happens.
|
||||
return self._GetDebugInfoPostbuilds(
|
||||
configname, output, output_binary, quiet
|
||||
|
|
@ -1122,11 +1120,10 @@ class XcodeSettings:
|
|||
|
||||
def _GetIOSPostbuilds(self, configname, output_binary):
|
||||
"""Return a shell command to codesign the iOS output binary so it can
|
||||
be deployed to a device. This should be run as the very last step of the
|
||||
build."""
|
||||
be deployed to a device. This should be run as the very last step of the
|
||||
build."""
|
||||
if not (
|
||||
self.isIOS
|
||||
and (self.spec["type"] == "executable" or self._IsXCTest())
|
||||
(self.isIOS and (self.spec["type"] == "executable" or self._IsXCTest()))
|
||||
or self.IsIosFramework()
|
||||
):
|
||||
return []
|
||||
|
|
@ -1172,8 +1169,9 @@ class XcodeSettings:
|
|||
# Then re-sign everything with 'preserve=True'
|
||||
postbuilds.extend(
|
||||
[
|
||||
'%s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
'%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
% (
|
||||
sys.executable,
|
||||
os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"),
|
||||
key,
|
||||
settings.get("CODE_SIGN_ENTITLEMENTS", ""),
|
||||
|
|
@ -1188,8 +1186,9 @@ class XcodeSettings:
|
|||
for target in targets:
|
||||
postbuilds.extend(
|
||||
[
|
||||
'%s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
'%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
% (
|
||||
sys.executable,
|
||||
os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"),
|
||||
key,
|
||||
settings.get("CODE_SIGN_ENTITLEMENTS", ""),
|
||||
|
|
@ -1202,8 +1201,9 @@ class XcodeSettings:
|
|||
|
||||
postbuilds.extend(
|
||||
[
|
||||
'%s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
'%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s'
|
||||
% (
|
||||
sys.executable,
|
||||
os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"),
|
||||
key,
|
||||
settings.get("CODE_SIGN_ENTITLEMENTS", ""),
|
||||
|
|
@ -1237,7 +1237,7 @@ class XcodeSettings:
|
|||
self, configname, output, output_binary, postbuilds=[], quiet=False
|
||||
):
|
||||
"""Returns a list of shell commands that should run before and after
|
||||
|postbuilds|."""
|
||||
|postbuilds|."""
|
||||
assert output_binary is not None
|
||||
pre = self._GetTargetPostbuilds(configname, output, output_binary, quiet)
|
||||
post = self._GetIOSPostbuilds(configname, output_binary)
|
||||
|
|
@ -1248,10 +1248,7 @@ class XcodeSettings:
|
|||
l_flag = "-framework " + os.path.splitext(os.path.basename(library))[0]
|
||||
else:
|
||||
m = self.library_re.match(library)
|
||||
if m:
|
||||
l_flag = "-l" + m.group(1)
|
||||
else:
|
||||
l_flag = library
|
||||
l_flag = "-l" + m.group(1) if m else library
|
||||
|
||||
sdk_root = self._SdkPath(config_name)
|
||||
if not sdk_root:
|
||||
|
|
@ -1276,8 +1273,8 @@ class XcodeSettings:
|
|||
|
||||
def AdjustLibraries(self, libraries, config_name=None):
|
||||
"""Transforms entries like 'Cocoa.framework' in libraries into entries like
|
||||
'-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc.
|
||||
"""
|
||||
'-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc.
|
||||
"""
|
||||
libraries = [self._AdjustLibrary(library, config_name) for library in libraries]
|
||||
return libraries
|
||||
|
||||
|
|
@ -1342,20 +1339,19 @@ class XcodeSettings:
|
|||
def _DefaultSdkRoot(self):
|
||||
"""Returns the default SDKROOT to use.
|
||||
|
||||
Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode
|
||||
project, then the environment variable was empty. Starting with this
|
||||
version, Xcode uses the name of the newest SDK installed.
|
||||
"""
|
||||
Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode
|
||||
project, then the environment variable was empty. Starting with this
|
||||
version, Xcode uses the name of the newest SDK installed.
|
||||
"""
|
||||
xcode_version, _ = XcodeVersion()
|
||||
if xcode_version < "0500":
|
||||
return ""
|
||||
default_sdk_path = self._XcodeSdkPath("")
|
||||
default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path)
|
||||
if default_sdk_root:
|
||||
if default_sdk_root := XcodeSettings._sdk_root_cache.get(default_sdk_path):
|
||||
return default_sdk_root
|
||||
try:
|
||||
all_sdks = GetStdout(["xcodebuild", "-showsdks"])
|
||||
except GypError:
|
||||
except (GypError, OSError):
|
||||
# If xcodebuild fails, there will be no valid SDKs
|
||||
return ""
|
||||
for line in all_sdks.splitlines():
|
||||
|
|
@ -1371,39 +1367,39 @@ class XcodeSettings:
|
|||
class MacPrefixHeader:
|
||||
"""A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature.
|
||||
|
||||
This feature consists of several pieces:
|
||||
* If GCC_PREFIX_HEADER is present, all compilations in that project get an
|
||||
additional |-include path_to_prefix_header| cflag.
|
||||
* If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is
|
||||
instead compiled, and all other compilations in the project get an
|
||||
additional |-include path_to_compiled_header| instead.
|
||||
+ Compiled prefix headers have the extension gch. There is one gch file for
|
||||
every language used in the project (c, cc, m, mm), since gch files for
|
||||
different languages aren't compatible.
|
||||
+ gch files themselves are built with the target's normal cflags, but they
|
||||
obviously don't get the |-include| flag. Instead, they need a -x flag that
|
||||
describes their language.
|
||||
+ All o files in the target need to depend on the gch file, to make sure
|
||||
it's built before any o file is built.
|
||||
This feature consists of several pieces:
|
||||
* If GCC_PREFIX_HEADER is present, all compilations in that project get an
|
||||
additional |-include path_to_prefix_header| cflag.
|
||||
* If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is
|
||||
instead compiled, and all other compilations in the project get an
|
||||
additional |-include path_to_compiled_header| instead.
|
||||
+ Compiled prefix headers have the extension gch. There is one gch file for
|
||||
every language used in the project (c, cc, m, mm), since gch files for
|
||||
different languages aren't compatible.
|
||||
+ gch files themselves are built with the target's normal cflags, but they
|
||||
obviously don't get the |-include| flag. Instead, they need a -x flag that
|
||||
describes their language.
|
||||
+ All o files in the target need to depend on the gch file, to make sure
|
||||
it's built before any o file is built.
|
||||
|
||||
This class helps with some of these tasks, but it needs help from the build
|
||||
system for writing dependencies to the gch files, for writing build commands
|
||||
for the gch files, and for figuring out the location of the gch files.
|
||||
"""
|
||||
This class helps with some of these tasks, but it needs help from the build
|
||||
system for writing dependencies to the gch files, for writing build commands
|
||||
for the gch files, and for figuring out the location of the gch files.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, xcode_settings, gyp_path_to_build_path, gyp_path_to_build_output
|
||||
):
|
||||
"""If xcode_settings is None, all methods on this class are no-ops.
|
||||
|
||||
Args:
|
||||
gyp_path_to_build_path: A function that takes a gyp-relative path,
|
||||
and returns a path relative to the build directory.
|
||||
gyp_path_to_build_output: A function that takes a gyp-relative path and
|
||||
a language code ('c', 'cc', 'm', or 'mm'), and that returns a path
|
||||
to where the output of precompiling that path for that language
|
||||
should be placed (without the trailing '.gch').
|
||||
"""
|
||||
Args:
|
||||
gyp_path_to_build_path: A function that takes a gyp-relative path,
|
||||
and returns a path relative to the build directory.
|
||||
gyp_path_to_build_output: A function that takes a gyp-relative path and
|
||||
a language code ('c', 'cc', 'm', or 'mm'), and that returns a path
|
||||
to where the output of precompiling that path for that language
|
||||
should be placed (without the trailing '.gch').
|
||||
"""
|
||||
# This doesn't support per-configuration prefix headers. Good enough
|
||||
# for now.
|
||||
self.header = None
|
||||
|
|
@ -1448,9 +1444,9 @@ class MacPrefixHeader:
|
|||
|
||||
def GetObjDependencies(self, sources, objs, arch=None):
|
||||
"""Given a list of source files and the corresponding object files, returns
|
||||
a list of (source, object, gch) tuples, where |gch| is the build-directory
|
||||
relative path to the gch file each object file depends on. |compilable[i]|
|
||||
has to be the source file belonging to |objs[i]|."""
|
||||
a list of (source, object, gch) tuples, where |gch| is the build-directory
|
||||
relative path to the gch file each object file depends on. |compilable[i]|
|
||||
has to be the source file belonging to |objs[i]|."""
|
||||
if not self.header or not self.compile_headers:
|
||||
return []
|
||||
|
||||
|
|
@ -1471,8 +1467,8 @@ class MacPrefixHeader:
|
|||
|
||||
def GetPchBuildCommands(self, arch=None):
|
||||
"""Returns [(path_to_gch, language_flag, language, header)].
|
||||
|path_to_gch| and |header| are relative to the build directory.
|
||||
"""
|
||||
|path_to_gch| and |header| are relative to the build directory.
|
||||
"""
|
||||
if not self.header or not self.compile_headers:
|
||||
return []
|
||||
return [
|
||||
|
|
@ -1509,7 +1505,8 @@ def XcodeVersion():
|
|||
raise GypError("xcodebuild returned unexpected results")
|
||||
version = version_list[0].split()[-1] # Last word on first line
|
||||
build = version_list[-1].split()[-1] # Last word on last line
|
||||
except GypError: # Xcode not installed so look for XCode Command Line Tools
|
||||
except (GypError, OSError):
|
||||
# Xcode not installed so look for XCode Command Line Tools
|
||||
version = CLTVersion() # macOS Catalina returns 11.0.0.0.1.1567737322
|
||||
if not version:
|
||||
raise GypError("No Xcode or CLT version detected!")
|
||||
|
|
@ -1537,26 +1534,28 @@ def CLTVersion():
|
|||
FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
|
||||
MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables"
|
||||
|
||||
regex = re.compile("version: (?P<version>.+)")
|
||||
regex = re.compile(r"version: (?P<version>.+)")
|
||||
for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]:
|
||||
try:
|
||||
output = GetStdout(["/usr/sbin/pkgutil", "--pkg-info", key])
|
||||
return re.search(regex, output).groupdict()["version"]
|
||||
except GypError:
|
||||
if m := re.search(regex, output):
|
||||
return m.groupdict()["version"]
|
||||
except (GypError, OSError):
|
||||
continue
|
||||
|
||||
regex = re.compile(r'Command Line Tools for Xcode\s+(?P<version>\S+)')
|
||||
regex = re.compile(r"Command Line Tools for Xcode\s+(?P<version>\S+)")
|
||||
try:
|
||||
output = GetStdout(["/usr/sbin/softwareupdate", "--history"])
|
||||
return re.search(regex, output).groupdict()["version"]
|
||||
except GypError:
|
||||
if m := re.search(regex, output):
|
||||
return m.groupdict()["version"]
|
||||
except (GypError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def GetStdoutQuiet(cmdlist):
|
||||
"""Returns the content of standard output returned by invoking |cmdlist|.
|
||||
Ignores the stderr.
|
||||
Raises |GypError| if the command return with a non-zero return code."""
|
||||
Ignores the stderr.
|
||||
Raises |GypError| if the command return with a non-zero return code."""
|
||||
job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out = job.communicate()[0].decode("utf-8")
|
||||
if job.returncode != 0:
|
||||
|
|
@ -1566,7 +1565,7 @@ def GetStdoutQuiet(cmdlist):
|
|||
|
||||
def GetStdout(cmdlist):
|
||||
"""Returns the content of standard output returned by invoking |cmdlist|.
|
||||
Raises |GypError| if the command return with a non-zero return code."""
|
||||
Raises |GypError| if the command return with a non-zero return code."""
|
||||
job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE)
|
||||
out = job.communicate()[0].decode("utf-8")
|
||||
if job.returncode != 0:
|
||||
|
|
@ -1577,9 +1576,9 @@ def GetStdout(cmdlist):
|
|||
|
||||
def MergeGlobalXcodeSettingsToSpec(global_dict, spec):
|
||||
"""Merges the global xcode_settings dictionary into each configuration of the
|
||||
target represented by spec. For keys that are both in the global and the local
|
||||
xcode_settings dict, the local key gets precedence.
|
||||
"""
|
||||
target represented by spec. For keys that are both in the global and the local
|
||||
xcode_settings dict, the local key gets precedence.
|
||||
"""
|
||||
# The xcode generator special-cases global xcode_settings and does something
|
||||
# that amounts to merging in the global xcode_settings into each local
|
||||
# xcode_settings dict.
|
||||
|
|
@ -1594,9 +1593,9 @@ def MergeGlobalXcodeSettingsToSpec(global_dict, spec):
|
|||
def IsMacBundle(flavor, spec):
|
||||
"""Returns if |spec| should be treated as a bundle.
|
||||
|
||||
Bundles are directories with a certain subdirectory structure, instead of
|
||||
just a single file. Bundle rules do not produce a binary but also package
|
||||
resources into that directory."""
|
||||
Bundles are directories with a certain subdirectory structure, instead of
|
||||
just a single file. Bundle rules do not produce a binary but also package
|
||||
resources into that directory."""
|
||||
is_mac_bundle = (
|
||||
int(spec.get("mac_xctest_bundle", 0)) != 0
|
||||
or int(spec.get("mac_xcuitest_bundle", 0)) != 0
|
||||
|
|
@ -1613,14 +1612,14 @@ def IsMacBundle(flavor, spec):
|
|||
|
||||
def GetMacBundleResources(product_dir, xcode_settings, resources):
|
||||
"""Yields (output, resource) pairs for every resource in |resources|.
|
||||
Only call this for mac bundle targets.
|
||||
Only call this for mac bundle targets.
|
||||
|
||||
Args:
|
||||
product_dir: Path to the directory containing the output bundle,
|
||||
relative to the build directory.
|
||||
xcode_settings: The XcodeSettings of the current target.
|
||||
resources: A list of bundle resources, relative to the build directory.
|
||||
"""
|
||||
Args:
|
||||
product_dir: Path to the directory containing the output bundle,
|
||||
relative to the build directory.
|
||||
xcode_settings: The XcodeSettings of the current target.
|
||||
resources: A list of bundle resources, relative to the build directory.
|
||||
"""
|
||||
dest = os.path.join(product_dir, xcode_settings.GetBundleResourceFolder())
|
||||
for res in resources:
|
||||
output = dest
|
||||
|
|
@ -1651,24 +1650,24 @@ def GetMacBundleResources(product_dir, xcode_settings, resources):
|
|||
|
||||
def GetMacInfoPlist(product_dir, xcode_settings, gyp_path_to_build_path):
|
||||
"""Returns (info_plist, dest_plist, defines, extra_env), where:
|
||||
* |info_plist| is the source plist path, relative to the
|
||||
build directory,
|
||||
* |dest_plist| is the destination plist path, relative to the
|
||||
build directory,
|
||||
* |defines| is a list of preprocessor defines (empty if the plist
|
||||
shouldn't be preprocessed,
|
||||
* |extra_env| is a dict of env variables that should be exported when
|
||||
invoking |mac_tool copy-info-plist|.
|
||||
* |info_plist| is the source plist path, relative to the
|
||||
build directory,
|
||||
* |dest_plist| is the destination plist path, relative to the
|
||||
build directory,
|
||||
* |defines| is a list of preprocessor defines (empty if the plist
|
||||
shouldn't be preprocessed,
|
||||
* |extra_env| is a dict of env variables that should be exported when
|
||||
invoking |mac_tool copy-info-plist|.
|
||||
|
||||
Only call this for mac bundle targets.
|
||||
Only call this for mac bundle targets.
|
||||
|
||||
Args:
|
||||
product_dir: Path to the directory containing the output bundle,
|
||||
relative to the build directory.
|
||||
xcode_settings: The XcodeSettings of the current target.
|
||||
gyp_to_build_path: A function that converts paths relative to the
|
||||
current gyp file to paths relative to the build directory.
|
||||
"""
|
||||
Args:
|
||||
product_dir: Path to the directory containing the output bundle,
|
||||
relative to the build directory.
|
||||
xcode_settings: The XcodeSettings of the current target.
|
||||
gyp_to_build_path: A function that converts paths relative to the
|
||||
current gyp file to paths relative to the build directory.
|
||||
"""
|
||||
info_plist = xcode_settings.GetPerTargetSetting("INFOPLIST_FILE")
|
||||
if not info_plist:
|
||||
return None, None, [], {}
|
||||
|
|
@ -1706,18 +1705,18 @@ def _GetXcodeEnv(
|
|||
xcode_settings, built_products_dir, srcroot, configuration, additional_settings=None
|
||||
):
|
||||
"""Return the environment variables that Xcode would set. See
|
||||
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW153
|
||||
for a full list.
|
||||
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW153
|
||||
for a full list.
|
||||
|
||||
Args:
|
||||
xcode_settings: An XcodeSettings object. If this is None, this function
|
||||
returns an empty dict.
|
||||
built_products_dir: Absolute path to the built products dir.
|
||||
srcroot: Absolute path to the source root.
|
||||
configuration: The build configuration name.
|
||||
additional_settings: An optional dict with more values to add to the
|
||||
result.
|
||||
"""
|
||||
Args:
|
||||
xcode_settings: An XcodeSettings object. If this is None, this function
|
||||
returns an empty dict.
|
||||
built_products_dir: Absolute path to the built products dir.
|
||||
srcroot: Absolute path to the source root.
|
||||
configuration: The build configuration name.
|
||||
additional_settings: An optional dict with more values to add to the
|
||||
result.
|
||||
"""
|
||||
|
||||
if not xcode_settings:
|
||||
return {}
|
||||
|
|
@ -1771,27 +1770,25 @@ def _GetXcodeEnv(
|
|||
)
|
||||
env["CONTENTS_FOLDER_PATH"] = xcode_settings.GetBundleContentsFolderPath()
|
||||
env["EXECUTABLE_FOLDER_PATH"] = xcode_settings.GetBundleExecutableFolderPath()
|
||||
env[
|
||||
"UNLOCALIZED_RESOURCES_FOLDER_PATH"
|
||||
] = xcode_settings.GetBundleResourceFolder()
|
||||
env["UNLOCALIZED_RESOURCES_FOLDER_PATH"] = (
|
||||
xcode_settings.GetBundleResourceFolder()
|
||||
)
|
||||
env["JAVA_FOLDER_PATH"] = xcode_settings.GetBundleJavaFolderPath()
|
||||
env["FRAMEWORKS_FOLDER_PATH"] = xcode_settings.GetBundleFrameworksFolderPath()
|
||||
env[
|
||||
"SHARED_FRAMEWORKS_FOLDER_PATH"
|
||||
] = xcode_settings.GetBundleSharedFrameworksFolderPath()
|
||||
env[
|
||||
"SHARED_SUPPORT_FOLDER_PATH"
|
||||
] = xcode_settings.GetBundleSharedSupportFolderPath()
|
||||
env["SHARED_FRAMEWORKS_FOLDER_PATH"] = (
|
||||
xcode_settings.GetBundleSharedFrameworksFolderPath()
|
||||
)
|
||||
env["SHARED_SUPPORT_FOLDER_PATH"] = (
|
||||
xcode_settings.GetBundleSharedSupportFolderPath()
|
||||
)
|
||||
env["PLUGINS_FOLDER_PATH"] = xcode_settings.GetBundlePlugInsFolderPath()
|
||||
env["XPCSERVICES_FOLDER_PATH"] = xcode_settings.GetBundleXPCServicesFolderPath()
|
||||
env["INFOPLIST_PATH"] = xcode_settings.GetBundlePlistPath()
|
||||
env["WRAPPER_NAME"] = xcode_settings.GetWrapperName()
|
||||
|
||||
install_name = xcode_settings.GetInstallName()
|
||||
if install_name:
|
||||
if install_name := xcode_settings.GetInstallName():
|
||||
env["LD_DYLIB_INSTALL_NAME"] = install_name
|
||||
install_name_base = xcode_settings.GetInstallNameBase()
|
||||
if install_name_base:
|
||||
if install_name_base := xcode_settings.GetInstallNameBase():
|
||||
env["DYLIB_INSTALL_NAME_BASE"] = install_name_base
|
||||
xcode_version, _ = XcodeVersion()
|
||||
if xcode_version >= "0500" and not env.get("SDKROOT"):
|
||||
|
|
@ -1819,8 +1816,8 @@ def _GetXcodeEnv(
|
|||
|
||||
def _NormalizeEnvVarReferences(str):
|
||||
"""Takes a string containing variable references in the form ${FOO}, $(FOO),
|
||||
or $FOO, and returns a string with all variable references in the form ${FOO}.
|
||||
"""
|
||||
or $FOO, and returns a string with all variable references in the form ${FOO}.
|
||||
"""
|
||||
# $FOO -> ${FOO}
|
||||
str = re.sub(r"\$([a-zA-Z_][a-zA-Z0-9_]*)", r"${\1}", str)
|
||||
|
||||
|
|
@ -1836,9 +1833,9 @@ def _NormalizeEnvVarReferences(str):
|
|||
|
||||
def ExpandEnvVars(string, expansions):
|
||||
"""Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the
|
||||
expansions list. If the variable expands to something that references
|
||||
another variable, this variable is expanded as well if it's in env --
|
||||
until no variables present in env are left."""
|
||||
expansions list. If the variable expands to something that references
|
||||
another variable, this variable is expanded as well if it's in env --
|
||||
until no variables present in env are left."""
|
||||
for k, v in reversed(expansions):
|
||||
string = string.replace("${" + k + "}", v)
|
||||
string = string.replace("$(" + k + ")", v)
|
||||
|
|
@ -1848,18 +1845,18 @@ def ExpandEnvVars(string, expansions):
|
|||
|
||||
def _TopologicallySortedEnvVarKeys(env):
|
||||
"""Takes a dict |env| whose values are strings that can refer to other keys,
|
||||
for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of
|
||||
env such that key2 is after key1 in L if env[key2] refers to env[key1].
|
||||
for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of
|
||||
env such that key2 is after key1 in L if env[key2] refers to env[key1].
|
||||
|
||||
Throws an Exception in case of dependency cycles.
|
||||
"""
|
||||
Throws an Exception in case of dependency cycles.
|
||||
"""
|
||||
# Since environment variables can refer to other variables, the evaluation
|
||||
# order is important. Below is the logic to compute the dependency graph
|
||||
# and sort it.
|
||||
regex = re.compile(r"\$\{([a-zA-Z0-9\-_]+)\}")
|
||||
|
||||
def GetEdges(node):
|
||||
# Use a definition of edges such that user_of_variable -> used_varible.
|
||||
# Use a definition of edges such that user_of_variable -> used_variable.
|
||||
# This happens to be easier in this case, since a variable's
|
||||
# definition contains all variables it references in a single string.
|
||||
# We can then reverse the result of the topological sort at the end.
|
||||
|
|
@ -1893,7 +1890,7 @@ def GetSortedXcodeEnv(
|
|||
|
||||
def GetSpecPostbuildCommands(spec, quiet=False):
|
||||
"""Returns the list of postbuilds explicitly defined on |spec|, in a form
|
||||
executable by a shell."""
|
||||
executable by a shell."""
|
||||
postbuilds = []
|
||||
for postbuild in spec.get("postbuilds", []):
|
||||
if not quiet:
|
||||
|
|
@ -1907,7 +1904,7 @@ def GetSpecPostbuildCommands(spec, quiet=False):
|
|||
|
||||
def _HasIOSTarget(targets):
|
||||
"""Returns true if any target contains the iOS specific key
|
||||
IPHONEOS_DEPLOYMENT_TARGET."""
|
||||
IPHONEOS_DEPLOYMENT_TARGET."""
|
||||
for target_dict in targets.values():
|
||||
for config in target_dict["configurations"].values():
|
||||
if config.get("xcode_settings", {}).get("IPHONEOS_DEPLOYMENT_TARGET"):
|
||||
|
|
@ -1917,7 +1914,7 @@ def _HasIOSTarget(targets):
|
|||
|
||||
def _AddIOSDeviceConfigurations(targets):
|
||||
"""Clone all targets and append -iphoneos to the name. Configure these targets
|
||||
to build for iOS devices and use correct architectures for those builds."""
|
||||
to build for iOS devices and use correct architectures for those builds."""
|
||||
for target_dict in targets.values():
|
||||
toolset = target_dict["toolset"]
|
||||
configs = target_dict["configurations"]
|
||||
|
|
@ -1933,7 +1930,7 @@ def _AddIOSDeviceConfigurations(targets):
|
|||
|
||||
def CloneConfigurationForDeviceAndEmulator(target_dicts):
|
||||
"""If |target_dicts| contains any iOS targets, automatically create -iphoneos
|
||||
targets for iOS device builds."""
|
||||
targets for iOS device builds."""
|
||||
if _HasIOSTarget(target_dicts):
|
||||
return _AddIOSDeviceConfigurations(target_dicts)
|
||||
return target_dicts
|
||||
|
|
|
|||
54
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py
generated
vendored
Normal file
54
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""Unit tests for the xcode_emulation.py file."""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from gyp.xcode_emulation import XcodeSettings
|
||||
|
||||
|
||||
class TestXcodeSettings(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if sys.platform != "darwin":
|
||||
self.skipTest("This test only runs on macOS")
|
||||
|
||||
def test_GetCflags(self):
|
||||
target = {
|
||||
"type": "static_library",
|
||||
"configurations": {
|
||||
"Release": {},
|
||||
},
|
||||
}
|
||||
configuration_name = "Release"
|
||||
xcode_settings = XcodeSettings(target)
|
||||
cflags = xcode_settings.GetCflags(configuration_name, "arm64")
|
||||
|
||||
# Do not quote `-arch arm64` with spaces in one string.
|
||||
self.assertEqual(
|
||||
cflags,
|
||||
["-fasm-blocks", "-mpascal-strings", "-Os", "-gdwarf-2", "-arch", "arm64"],
|
||||
)
|
||||
|
||||
def GypToBuildPath(self, path):
|
||||
return path
|
||||
|
||||
def test_GetLdflags(self):
|
||||
target = {
|
||||
"type": "static_library",
|
||||
"configurations": {
|
||||
"Release": {},
|
||||
},
|
||||
}
|
||||
configuration_name = "Release"
|
||||
xcode_settings = XcodeSettings(target)
|
||||
ldflags = xcode_settings.GetLdflags(
|
||||
configuration_name, "PRODUCT_DIR", self.GypToBuildPath, "arm64"
|
||||
)
|
||||
|
||||
# Do not quote `-arch arm64` with spaces in one string.
|
||||
self.assertEqual(ldflags, ["-arch", "arm64", "-LPRODUCT_DIR"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
49
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py
generated
vendored
49
electron/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py
generated
vendored
|
|
@ -13,15 +13,16 @@ of targets within Xcode.
|
|||
"""
|
||||
|
||||
import errno
|
||||
import gyp.generator.ninja
|
||||
import os
|
||||
import re
|
||||
import xml.sax.saxutils
|
||||
|
||||
import gyp.generator.ninja
|
||||
|
||||
|
||||
def _WriteWorkspace(main_gyp, sources_gyp, params):
|
||||
""" Create a workspace to wrap main and sources gyp paths. """
|
||||
(build_file_root, build_file_ext) = os.path.splitext(main_gyp)
|
||||
"""Create a workspace to wrap main and sources gyp paths."""
|
||||
(build_file_root, _build_file_ext) = os.path.splitext(main_gyp)
|
||||
workspace_path = build_file_root + ".xcworkspace"
|
||||
options = params["options"]
|
||||
if options.generator_output:
|
||||
|
|
@ -56,7 +57,7 @@ def _WriteWorkspace(main_gyp, sources_gyp, params):
|
|||
|
||||
|
||||
def _TargetFromSpec(old_spec, params):
|
||||
""" Create fake target for xcode-ninja wrapper. """
|
||||
"""Create fake target for xcode-ninja wrapper."""
|
||||
# Determine ninja top level build dir (e.g. /path/to/out).
|
||||
ninja_toplevel = None
|
||||
jobs = 0
|
||||
|
|
@ -69,12 +70,11 @@ def _TargetFromSpec(old_spec, params):
|
|||
|
||||
target_name = old_spec.get("target_name")
|
||||
product_name = old_spec.get("product_name", target_name)
|
||||
product_extension = old_spec.get("product_extension")
|
||||
|
||||
ninja_target = {}
|
||||
ninja_target["target_name"] = target_name
|
||||
ninja_target["product_name"] = product_name
|
||||
if product_extension:
|
||||
if product_extension := old_spec.get("product_extension"):
|
||||
ninja_target["product_extension"] = product_extension
|
||||
ninja_target["toolset"] = old_spec.get("toolset")
|
||||
ninja_target["default_configuration"] = old_spec.get("default_configuration")
|
||||
|
|
@ -102,9 +102,9 @@ def _TargetFromSpec(old_spec, params):
|
|||
new_xcode_settings[key] = old_xcode_settings[key]
|
||||
|
||||
ninja_target["configurations"][config] = {}
|
||||
ninja_target["configurations"][config][
|
||||
"xcode_settings"
|
||||
] = new_xcode_settings
|
||||
ninja_target["configurations"][config]["xcode_settings"] = (
|
||||
new_xcode_settings
|
||||
)
|
||||
|
||||
ninja_target["mac_bundle"] = old_spec.get("mac_bundle", 0)
|
||||
ninja_target["mac_xctest_bundle"] = old_spec.get("mac_xctest_bundle", 0)
|
||||
|
|
@ -137,13 +137,13 @@ def _TargetFromSpec(old_spec, params):
|
|||
def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec):
|
||||
"""Limit targets for Xcode wrapper.
|
||||
|
||||
Xcode sometimes performs poorly with too many targets, so only include
|
||||
proper executable targets, with filters to customize.
|
||||
Arguments:
|
||||
target_extras: Regular expression to always add, matching any target.
|
||||
executable_target_pattern: Regular expression limiting executable targets.
|
||||
spec: Specifications for target.
|
||||
"""
|
||||
Xcode sometimes performs poorly with too many targets, so only include
|
||||
proper executable targets, with filters to customize.
|
||||
Arguments:
|
||||
target_extras: Regular expression to always add, matching any target.
|
||||
executable_target_pattern: Regular expression limiting executable targets.
|
||||
spec: Specifications for target.
|
||||
"""
|
||||
target_name = spec.get("target_name")
|
||||
# Always include targets matching target_extras.
|
||||
if target_extras is not None and re.search(target_extras, target_name):
|
||||
|
|
@ -154,7 +154,6 @@ def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec):
|
|||
spec.get("type", "") == "executable"
|
||||
and spec.get("product_extension", "") != "bundle"
|
||||
):
|
||||
|
||||
# If there is a filter and the target does not match, exclude the target.
|
||||
if executable_target_pattern is not None:
|
||||
if not re.search(executable_target_pattern, target_name):
|
||||
|
|
@ -166,14 +165,14 @@ def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec):
|
|||
def CreateWrapper(target_list, target_dicts, data, params):
|
||||
"""Initialize targets for the ninja wrapper.
|
||||
|
||||
This sets up the necessary variables in the targets to generate Xcode projects
|
||||
that use ninja as an external builder.
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
data: Dict of flattened build files keyed on gyp path.
|
||||
params: Dict of global options for gyp.
|
||||
"""
|
||||
This sets up the necessary variables in the targets to generate Xcode projects
|
||||
that use ninja as an external builder.
|
||||
Arguments:
|
||||
target_list: List of target pairs: 'base/base.gyp:base'.
|
||||
target_dicts: Dict of target properties keyed on target pair.
|
||||
data: Dict of flattened build files keyed on gyp path.
|
||||
params: Dict of global options for gyp.
|
||||
"""
|
||||
orig_gyp = params["build_files"][0]
|
||||
for gyp_name, gyp_dict in data.items():
|
||||
if gyp_name == orig_gyp:
|
||||
|
|
|
|||
669
electron/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py
generated
vendored
669
electron/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py
generated
vendored
File diff suppressed because it is too large
Load diff
1
electron/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py
generated
vendored
1
electron/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py
generated
vendored
|
|
@ -9,7 +9,6 @@ Working around this: http://bugs.python.org/issue5752
|
|||
TODO(bradnelson): Consider dropping this when we drop XP support.
|
||||
"""
|
||||
|
||||
|
||||
import xml.dom.minidom
|
||||
|
||||
|
||||
|
|
|
|||
3
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE
generated
vendored
Normal file
3
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
This software is made available under the terms of *either* of the licenses
|
||||
found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made
|
||||
under the terms of *both* these licenses.
|
||||
177
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE
generated
vendored
Normal file
177
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE
generated
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
23
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD
generated
vendored
Normal file
23
electron/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Copyright (c) Donald Stufft and individual contributors.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
15
electron/node_modules/node-gyp/gyp/pylib/packaging/__init__.py
generated
vendored
Normal file
15
electron/node_modules/node-gyp/gyp/pylib/packaging/__init__.py
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
__title__ = "packaging"
|
||||
__summary__ = "Core utilities for Python packages"
|
||||
__uri__ = "https://github.com/pypa/packaging"
|
||||
|
||||
__version__ = "23.3.dev0"
|
||||
|
||||
__author__ = "Donald Stufft and individual contributors"
|
||||
__email__ = "donald@stufft.io"
|
||||
|
||||
__license__ = "BSD-2-Clause or Apache-2.0"
|
||||
__copyright__ = "2014 %s" % __author__
|
||||
107
electron/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py
generated
vendored
Normal file
107
electron/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"""
|
||||
ELF file parser.
|
||||
|
||||
This provides a class ``ELFFile`` that parses an ELF executable in a similar
|
||||
interface to ``ZipFile``. Only the read interface is implemented.
|
||||
|
||||
Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca
|
||||
ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
|
||||
"""
|
||||
|
||||
import enum
|
||||
import os
|
||||
import struct
|
||||
from typing import IO, Optional, Tuple
|
||||
|
||||
|
||||
class ELFInvalid(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class EIClass(enum.IntEnum):
|
||||
C32 = 1
|
||||
C64 = 2
|
||||
|
||||
|
||||
class EIData(enum.IntEnum):
|
||||
Lsb = 1
|
||||
Msb = 2
|
||||
|
||||
|
||||
class EMachine(enum.IntEnum):
|
||||
I386 = 3
|
||||
S390 = 22
|
||||
Arm = 40
|
||||
X8664 = 62
|
||||
AArc64 = 183
|
||||
|
||||
|
||||
class ELFFile:
|
||||
"""
|
||||
Representation of an ELF executable.
|
||||
"""
|
||||
|
||||
def __init__(self, f: IO[bytes]) -> None:
|
||||
self._f = f
|
||||
|
||||
try:
|
||||
ident = self._read("16B")
|
||||
except struct.error:
|
||||
raise ELFInvalid("unable to parse identification")
|
||||
if (magic := bytes(ident[:4])) != b"\x7fELF":
|
||||
raise ELFInvalid(f"invalid magic: {magic!r}")
|
||||
|
||||
self.capacity = ident[4] # Format for program header (bitness).
|
||||
self.encoding = ident[5] # Data structure encoding (endianness).
|
||||
|
||||
try:
|
||||
# e_fmt: Format for program header.
|
||||
# p_fmt: Format for section header.
|
||||
# p_idx: Indexes to find p_type, p_offset, and p_filesz.
|
||||
e_fmt, self._p_fmt, self._p_idx = {
|
||||
(1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB.
|
||||
(1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB.
|
||||
(2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB.
|
||||
(2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB.
|
||||
}[(self.capacity, self.encoding)]
|
||||
except KeyError:
|
||||
raise ELFInvalid(
|
||||
f"unrecognized capacity ({self.capacity}) or "
|
||||
f"encoding ({self.encoding})"
|
||||
)
|
||||
|
||||
try:
|
||||
(
|
||||
_,
|
||||
self.machine, # Architecture type.
|
||||
_,
|
||||
_,
|
||||
self._e_phoff, # Offset of program header.
|
||||
_,
|
||||
self.flags, # Processor-specific flags.
|
||||
_,
|
||||
self._e_phentsize, # Size of section.
|
||||
self._e_phnum, # Number of sections.
|
||||
) = self._read(e_fmt)
|
||||
except struct.error as e:
|
||||
raise ELFInvalid("unable to parse machine and section information") from e
|
||||
|
||||
def _read(self, fmt: str) -> Tuple[int, ...]:
|
||||
return struct.unpack(fmt, self._f.read(struct.calcsize(fmt)))
|
||||
|
||||
@property
|
||||
def interpreter(self) -> Optional[str]:
|
||||
"""
|
||||
The path recorded in the ``PT_INTERP`` section header.
|
||||
"""
|
||||
for index in range(self._e_phnum):
|
||||
self._f.seek(self._e_phoff + self._e_phentsize * index)
|
||||
try:
|
||||
data = self._read(self._p_fmt)
|
||||
except struct.error:
|
||||
continue
|
||||
if data[self._p_idx[0]] != 3: # Not PT_INTERP.
|
||||
continue
|
||||
self._f.seek(data[self._p_idx[1]])
|
||||
return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0")
|
||||
return None
|
||||
252
electron/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py
generated
vendored
Normal file
252
electron/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py
generated
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
import collections
|
||||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
from typing import Dict, Generator, Iterator, NamedTuple, Optional, Sequence, Tuple
|
||||
|
||||
from ._elffile import EIClass, EIData, ELFFile, EMachine
|
||||
|
||||
EF_ARM_ABIMASK = 0xFF000000
|
||||
EF_ARM_ABI_VER5 = 0x05000000
|
||||
EF_ARM_ABI_FLOAT_HARD = 0x00000400
|
||||
|
||||
|
||||
# `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
|
||||
# as the type for `path` until then.
|
||||
@contextlib.contextmanager
|
||||
def _parse_elf(path: str) -> Generator[Optional[ELFFile], None, None]:
|
||||
try:
|
||||
with open(path, "rb") as f:
|
||||
yield ELFFile(f)
|
||||
except (OSError, TypeError, ValueError):
|
||||
yield None
|
||||
|
||||
|
||||
def _is_linux_armhf(executable: str) -> bool:
|
||||
# hard-float ABI can be detected from the ELF header of the running
|
||||
# process
|
||||
# https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
|
||||
with _parse_elf(executable) as f:
|
||||
return (
|
||||
f is not None
|
||||
and f.capacity == EIClass.C32
|
||||
and f.encoding == EIData.Lsb
|
||||
and f.machine == EMachine.Arm
|
||||
and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5
|
||||
and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD
|
||||
)
|
||||
|
||||
|
||||
def _is_linux_i686(executable: str) -> bool:
|
||||
with _parse_elf(executable) as f:
|
||||
return (
|
||||
f is not None
|
||||
and f.capacity == EIClass.C32
|
||||
and f.encoding == EIData.Lsb
|
||||
and f.machine == EMachine.I386
|
||||
)
|
||||
|
||||
|
||||
def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
|
||||
if "armv7l" in archs:
|
||||
return _is_linux_armhf(executable)
|
||||
if "i686" in archs:
|
||||
return _is_linux_i686(executable)
|
||||
allowed_archs = {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x", "loongarch64"}
|
||||
return any(arch in allowed_archs for arch in archs)
|
||||
|
||||
|
||||
# If glibc ever changes its major version, we need to know what the last
|
||||
# minor version was, so we can build the complete list of all versions.
|
||||
# For now, guess what the highest minor version might be, assume it will
|
||||
# be 50 for testing. Once this actually happens, update the dictionary
|
||||
# with the actual value.
|
||||
_LAST_GLIBC_MINOR: Dict[int, int] = collections.defaultdict(lambda: 50)
|
||||
|
||||
|
||||
class _GLibCVersion(NamedTuple):
|
||||
major: int
|
||||
minor: int
|
||||
|
||||
|
||||
def _glibc_version_string_confstr() -> Optional[str]:
|
||||
"""
|
||||
Primary implementation of glibc_version_string using os.confstr.
|
||||
"""
|
||||
# os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
|
||||
# to be broken or missing. This strategy is used in the standard library
|
||||
# platform module.
|
||||
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
|
||||
try:
|
||||
# Should be a string like "glibc 2.17".
|
||||
version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION")
|
||||
assert version_string is not None
|
||||
_, version = version_string.rsplit()
|
||||
except (AssertionError, AttributeError, OSError, ValueError):
|
||||
# os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
|
||||
return None
|
||||
return version
|
||||
|
||||
|
||||
def _glibc_version_string_ctypes() -> Optional[str]:
|
||||
"""
|
||||
Fallback implementation of glibc_version_string using ctypes.
|
||||
"""
|
||||
try:
|
||||
import ctypes
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
# ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
|
||||
# manpage says, "If filename is NULL, then the returned handle is for the
|
||||
# main program". This way we can let the linker do the work to figure out
|
||||
# which libc our process is actually using.
|
||||
#
|
||||
# We must also handle the special case where the executable is not a
|
||||
# dynamically linked executable. This can occur when using musl libc,
|
||||
# for example. In this situation, dlopen() will error, leading to an
|
||||
# OSError. Interestingly, at least in the case of musl, there is no
|
||||
# errno set on the OSError. The single string argument used to construct
|
||||
# OSError comes from libc itself and is therefore not portable to
|
||||
# hard code here. In any case, failure to call dlopen() means we
|
||||
# can proceed, so we bail on our attempt.
|
||||
try:
|
||||
process_namespace = ctypes.CDLL(None)
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
try:
|
||||
gnu_get_libc_version = process_namespace.gnu_get_libc_version
|
||||
except AttributeError:
|
||||
# Symbol doesn't exist -> therefore, we are not linked to
|
||||
# glibc.
|
||||
return None
|
||||
|
||||
# Call gnu_get_libc_version, which returns a string like "2.5"
|
||||
gnu_get_libc_version.restype = ctypes.c_char_p
|
||||
version_str: str = gnu_get_libc_version()
|
||||
# py2 / py3 compatibility:
|
||||
if not isinstance(version_str, str):
|
||||
version_str = version_str.decode("ascii")
|
||||
|
||||
return version_str
|
||||
|
||||
|
||||
def _glibc_version_string() -> Optional[str]:
|
||||
"""Returns glibc version string, or None if not using glibc."""
|
||||
return _glibc_version_string_confstr() or _glibc_version_string_ctypes()
|
||||
|
||||
|
||||
def _parse_glibc_version(version_str: str) -> Tuple[int, int]:
|
||||
"""Parse glibc version.
|
||||
|
||||
We use a regexp instead of str.split because we want to discard any
|
||||
random junk that might come after the minor version -- this might happen
|
||||
in patched/forked versions of glibc (e.g. Linaro's version of glibc
|
||||
uses version strings like "2.20-2014.11"). See gh-3588.
|
||||
"""
|
||||
m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
|
||||
if not m:
|
||||
warnings.warn(
|
||||
f"Expected glibc version with 2 components major.minor,"
|
||||
f" got: {version_str}",
|
||||
RuntimeWarning,
|
||||
)
|
||||
return -1, -1
|
||||
return int(m.group("major")), int(m.group("minor"))
|
||||
|
||||
|
||||
@functools.lru_cache()
|
||||
def _get_glibc_version() -> Tuple[int, int]:
|
||||
version_str = _glibc_version_string()
|
||||
if version_str is None:
|
||||
return (-1, -1)
|
||||
return _parse_glibc_version(version_str)
|
||||
|
||||
|
||||
# From PEP 513, PEP 600
|
||||
def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
|
||||
sys_glibc = _get_glibc_version()
|
||||
if sys_glibc < version:
|
||||
return False
|
||||
# Check for presence of _manylinux module.
|
||||
try:
|
||||
import _manylinux # noqa
|
||||
except ImportError:
|
||||
return True
|
||||
if hasattr(_manylinux, "manylinux_compatible"):
|
||||
result = _manylinux.manylinux_compatible(version[0], version[1], arch)
|
||||
if result is not None:
|
||||
return bool(result)
|
||||
return True
|
||||
if version == _GLibCVersion(2, 5):
|
||||
if hasattr(_manylinux, "manylinux1_compatible"):
|
||||
return bool(_manylinux.manylinux1_compatible)
|
||||
if version == _GLibCVersion(2, 12):
|
||||
if hasattr(_manylinux, "manylinux2010_compatible"):
|
||||
return bool(_manylinux.manylinux2010_compatible)
|
||||
if version == _GLibCVersion(2, 17):
|
||||
if hasattr(_manylinux, "manylinux2014_compatible"):
|
||||
return bool(_manylinux.manylinux2014_compatible)
|
||||
return True
|
||||
|
||||
|
||||
_LEGACY_MANYLINUX_MAP = {
|
||||
# CentOS 7 w/ glibc 2.17 (PEP 599)
|
||||
(2, 17): "manylinux2014",
|
||||
# CentOS 6 w/ glibc 2.12 (PEP 571)
|
||||
(2, 12): "manylinux2010",
|
||||
# CentOS 5 w/ glibc 2.5 (PEP 513)
|
||||
(2, 5): "manylinux1",
|
||||
}
|
||||
|
||||
|
||||
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
|
||||
"""Generate manylinux tags compatible to the current platform.
|
||||
|
||||
:param archs: Sequence of compatible architectures.
|
||||
The first one shall be the closest to the actual architecture and be the part of
|
||||
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
|
||||
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
|
||||
be manylinux-compatible.
|
||||
|
||||
:returns: An iterator of compatible manylinux tags.
|
||||
"""
|
||||
if not _have_compatible_abi(sys.executable, archs):
|
||||
return
|
||||
# Oldest glibc to be supported regardless of architecture is (2, 17).
|
||||
too_old_glibc2 = _GLibCVersion(2, 16)
|
||||
if set(archs) & {"x86_64", "i686"}:
|
||||
# On x86/i686 also oldest glibc to be supported is (2, 5).
|
||||
too_old_glibc2 = _GLibCVersion(2, 4)
|
||||
current_glibc = _GLibCVersion(*_get_glibc_version())
|
||||
glibc_max_list = [current_glibc]
|
||||
# We can assume compatibility across glibc major versions.
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=24636
|
||||
#
|
||||
# Build a list of maximum glibc versions so that we can
|
||||
# output the canonical list of all glibc from current_glibc
|
||||
# down to too_old_glibc2, including all intermediary versions.
|
||||
for glibc_major in range(current_glibc.major - 1, 1, -1):
|
||||
glibc_minor = _LAST_GLIBC_MINOR[glibc_major]
|
||||
glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor))
|
||||
for arch in archs:
|
||||
for glibc_max in glibc_max_list:
|
||||
if glibc_max.major == too_old_glibc2.major:
|
||||
min_minor = too_old_glibc2.minor
|
||||
else:
|
||||
# For other glibc major versions oldest supported is (x, 0).
|
||||
min_minor = -1
|
||||
for glibc_minor in range(glibc_max.minor, min_minor, -1):
|
||||
glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
|
||||
tag = "manylinux_{}_{}".format(*glibc_version)
|
||||
if _is_compatible(arch, glibc_version):
|
||||
yield f"{tag}_{arch}"
|
||||
# Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
|
||||
if glibc_version in _LEGACY_MANYLINUX_MAP:
|
||||
legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
|
||||
if _is_compatible(arch, glibc_version):
|
||||
yield f"{legacy_tag}_{arch}"
|
||||
83
electron/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py
generated
vendored
Normal file
83
electron/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
"""PEP 656 support.
|
||||
|
||||
This module implements logic to detect if the currently running Python is
|
||||
linked against musl, and what musl version is used.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Iterator, NamedTuple, Optional, Sequence
|
||||
|
||||
from ._elffile import ELFFile
|
||||
|
||||
|
||||
class _MuslVersion(NamedTuple):
|
||||
major: int
|
||||
minor: int
|
||||
|
||||
|
||||
def _parse_musl_version(output: str) -> Optional[_MuslVersion]:
|
||||
lines = [n for n in (n.strip() for n in output.splitlines()) if n]
|
||||
if len(lines) < 2 or lines[0][:4] != "musl":
|
||||
return None
|
||||
m = re.match(r"Version (\d+)\.(\d+)", lines[1])
|
||||
if not m:
|
||||
return None
|
||||
return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
|
||||
|
||||
|
||||
@functools.lru_cache()
|
||||
def _get_musl_version(executable: str) -> Optional[_MuslVersion]:
|
||||
"""Detect currently-running musl runtime version.
|
||||
|
||||
This is done by checking the specified executable's dynamic linking
|
||||
information, and invoking the loader to parse its output for a version
|
||||
string. If the loader is musl, the output would be something like::
|
||||
|
||||
musl libc (x86_64)
|
||||
Version 1.2.2
|
||||
Dynamic Program Loader
|
||||
"""
|
||||
try:
|
||||
with open(executable, "rb") as f:
|
||||
ld = ELFFile(f).interpreter
|
||||
except (OSError, TypeError, ValueError):
|
||||
return None
|
||||
if ld is None or "musl" not in ld:
|
||||
return None
|
||||
proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)
|
||||
return _parse_musl_version(proc.stderr)
|
||||
|
||||
|
||||
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
|
||||
"""Generate musllinux tags compatible to the current platform.
|
||||
|
||||
:param archs: Sequence of compatible architectures.
|
||||
The first one shall be the closest to the actual architecture and be the part of
|
||||
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
|
||||
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
|
||||
be musllinux-compatible.
|
||||
|
||||
:returns: An iterator of compatible musllinux tags.
|
||||
"""
|
||||
sys_musl = _get_musl_version(sys.executable)
|
||||
if sys_musl is None: # Python not dynamically linked against musl.
|
||||
return
|
||||
for arch in archs:
|
||||
for minor in range(sys_musl.minor, -1, -1):
|
||||
yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import sysconfig
|
||||
|
||||
plat = sysconfig.get_platform()
|
||||
assert plat.startswith("linux-"), "not linux"
|
||||
|
||||
print("plat:", plat)
|
||||
print("musl:", _get_musl_version(sys.executable))
|
||||
print("tags:", end=" ")
|
||||
for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):
|
||||
print(t, end="\n ")
|
||||
359
electron/node_modules/node-gyp/gyp/pylib/packaging/_parser.py
generated
vendored
Normal file
359
electron/node_modules/node-gyp/gyp/pylib/packaging/_parser.py
generated
vendored
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
"""Handwritten parser of dependency specifiers.
|
||||
|
||||
The docstring for each __parse_* function contains ENBF-inspired grammar representing
|
||||
the implementation.
|
||||
"""
|
||||
|
||||
import ast
|
||||
from typing import Any, List, NamedTuple, Optional, Tuple, Union
|
||||
|
||||
from ._tokenizer import DEFAULT_RULES, Tokenizer
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, value: str) -> None:
|
||||
self.value = value
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__}('{self}')>"
|
||||
|
||||
def serialize(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Variable(Node):
|
||||
def serialize(self) -> str:
|
||||
return str(self)
|
||||
|
||||
|
||||
class Value(Node):
|
||||
def serialize(self) -> str:
|
||||
return f'"{self}"'
|
||||
|
||||
|
||||
class Op(Node):
|
||||
def serialize(self) -> str:
|
||||
return str(self)
|
||||
|
||||
|
||||
MarkerVar = Union[Variable, Value]
|
||||
MarkerItem = Tuple[MarkerVar, Op, MarkerVar]
|
||||
# MarkerAtom = Union[MarkerItem, List["MarkerAtom"]]
|
||||
# MarkerList = List[Union["MarkerList", MarkerAtom, str]]
|
||||
# mypy does not support recursive type definition
|
||||
# https://github.com/python/mypy/issues/731
|
||||
MarkerAtom = Any
|
||||
MarkerList = List[Any]
|
||||
|
||||
|
||||
class ParsedRequirement(NamedTuple):
|
||||
name: str
|
||||
url: str
|
||||
extras: List[str]
|
||||
specifier: str
|
||||
marker: Optional[MarkerList]
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
# Recursive descent parser for dependency specifier
|
||||
# --------------------------------------------------------------------------------------
|
||||
def parse_requirement(source: str) -> ParsedRequirement:
|
||||
return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES))
|
||||
|
||||
|
||||
def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement:
|
||||
"""
|
||||
requirement = WS? IDENTIFIER WS? extras WS? requirement_details
|
||||
"""
|
||||
tokenizer.consume("WS")
|
||||
|
||||
name_token = tokenizer.expect(
|
||||
"IDENTIFIER", expected="package name at the start of dependency specifier"
|
||||
)
|
||||
name = name_token.text
|
||||
tokenizer.consume("WS")
|
||||
|
||||
extras = _parse_extras(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
|
||||
url, specifier, marker = _parse_requirement_details(tokenizer)
|
||||
tokenizer.expect("END", expected="end of dependency specifier")
|
||||
|
||||
return ParsedRequirement(name, url, extras, specifier, marker)
|
||||
|
||||
|
||||
def _parse_requirement_details(
|
||||
tokenizer: Tokenizer,
|
||||
) -> Tuple[str, str, Optional[MarkerList]]:
|
||||
"""
|
||||
requirement_details = AT URL (WS requirement_marker?)?
|
||||
| specifier WS? (requirement_marker)?
|
||||
"""
|
||||
|
||||
specifier = ""
|
||||
url = ""
|
||||
marker = None
|
||||
|
||||
if tokenizer.check("AT"):
|
||||
tokenizer.read()
|
||||
tokenizer.consume("WS")
|
||||
|
||||
url_start = tokenizer.position
|
||||
url = tokenizer.expect("URL", expected="URL after @").text
|
||||
if tokenizer.check("END", peek=True):
|
||||
return (url, specifier, marker)
|
||||
|
||||
tokenizer.expect("WS", expected="whitespace after URL")
|
||||
|
||||
# The input might end after whitespace.
|
||||
if tokenizer.check("END", peek=True):
|
||||
return (url, specifier, marker)
|
||||
|
||||
marker = _parse_requirement_marker(
|
||||
tokenizer, span_start=url_start, after="URL and whitespace"
|
||||
)
|
||||
else:
|
||||
specifier_start = tokenizer.position
|
||||
specifier = _parse_specifier(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
|
||||
if tokenizer.check("END", peek=True):
|
||||
return (url, specifier, marker)
|
||||
|
||||
marker = _parse_requirement_marker(
|
||||
tokenizer,
|
||||
span_start=specifier_start,
|
||||
after=(
|
||||
"version specifier"
|
||||
if specifier
|
||||
else "name and no valid version specifier"
|
||||
),
|
||||
)
|
||||
|
||||
return (url, specifier, marker)
|
||||
|
||||
|
||||
def _parse_requirement_marker(
|
||||
tokenizer: Tokenizer, *, span_start: int, after: str
|
||||
) -> MarkerList:
|
||||
"""
|
||||
requirement_marker = SEMICOLON marker WS?
|
||||
"""
|
||||
|
||||
if not tokenizer.check("SEMICOLON"):
|
||||
tokenizer.raise_syntax_error(
|
||||
f"Expected end or semicolon (after {after})",
|
||||
span_start=span_start,
|
||||
)
|
||||
tokenizer.read()
|
||||
|
||||
marker = _parse_marker(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
|
||||
return marker
|
||||
|
||||
|
||||
def _parse_extras(tokenizer: Tokenizer) -> List[str]:
|
||||
"""
|
||||
extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)?
|
||||
"""
|
||||
if not tokenizer.check("LEFT_BRACKET", peek=True):
|
||||
return []
|
||||
|
||||
with tokenizer.enclosing_tokens(
|
||||
"LEFT_BRACKET",
|
||||
"RIGHT_BRACKET",
|
||||
around="extras",
|
||||
):
|
||||
tokenizer.consume("WS")
|
||||
extras = _parse_extras_list(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
|
||||
return extras
|
||||
|
||||
|
||||
def _parse_extras_list(tokenizer: Tokenizer) -> List[str]:
|
||||
"""
|
||||
extras_list = identifier (wsp* ',' wsp* identifier)*
|
||||
"""
|
||||
extras: List[str] = []
|
||||
|
||||
if not tokenizer.check("IDENTIFIER"):
|
||||
return extras
|
||||
|
||||
extras.append(tokenizer.read().text)
|
||||
|
||||
while True:
|
||||
tokenizer.consume("WS")
|
||||
if tokenizer.check("IDENTIFIER", peek=True):
|
||||
tokenizer.raise_syntax_error("Expected comma between extra names")
|
||||
elif not tokenizer.check("COMMA"):
|
||||
break
|
||||
|
||||
tokenizer.read()
|
||||
tokenizer.consume("WS")
|
||||
|
||||
extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma")
|
||||
extras.append(extra_token.text)
|
||||
|
||||
return extras
|
||||
|
||||
|
||||
def _parse_specifier(tokenizer: Tokenizer) -> str:
|
||||
"""
|
||||
specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
|
||||
| WS? version_many WS?
|
||||
"""
|
||||
with tokenizer.enclosing_tokens(
|
||||
"LEFT_PARENTHESIS",
|
||||
"RIGHT_PARENTHESIS",
|
||||
around="version specifier",
|
||||
):
|
||||
tokenizer.consume("WS")
|
||||
parsed_specifiers = _parse_version_many(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
|
||||
return parsed_specifiers
|
||||
|
||||
|
||||
def _parse_version_many(tokenizer: Tokenizer) -> str:
|
||||
"""
|
||||
version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)?
|
||||
"""
|
||||
parsed_specifiers = ""
|
||||
while tokenizer.check("SPECIFIER"):
|
||||
span_start = tokenizer.position
|
||||
parsed_specifiers += tokenizer.read().text
|
||||
if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):
|
||||
tokenizer.raise_syntax_error(
|
||||
".* suffix can only be used with `==` or `!=` operators",
|
||||
span_start=span_start,
|
||||
span_end=tokenizer.position + 1,
|
||||
)
|
||||
if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
|
||||
tokenizer.raise_syntax_error(
|
||||
"Local version label can only be used with `==` or `!=` operators",
|
||||
span_start=span_start,
|
||||
span_end=tokenizer.position,
|
||||
)
|
||||
tokenizer.consume("WS")
|
||||
if not tokenizer.check("COMMA"):
|
||||
break
|
||||
parsed_specifiers += tokenizer.read().text
|
||||
tokenizer.consume("WS")
|
||||
|
||||
return parsed_specifiers
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
# Recursive descent parser for marker expression
|
||||
# --------------------------------------------------------------------------------------
|
||||
def parse_marker(source: str) -> MarkerList:
|
||||
return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES))
|
||||
|
||||
|
||||
def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList:
|
||||
retval = _parse_marker(tokenizer)
|
||||
tokenizer.expect("END", expected="end of marker expression")
|
||||
return retval
|
||||
|
||||
|
||||
def _parse_marker(tokenizer: Tokenizer) -> MarkerList:
|
||||
"""
|
||||
marker = marker_atom (BOOLOP marker_atom)+
|
||||
"""
|
||||
expression = [_parse_marker_atom(tokenizer)]
|
||||
while tokenizer.check("BOOLOP"):
|
||||
token = tokenizer.read()
|
||||
expr_right = _parse_marker_atom(tokenizer)
|
||||
expression.extend((token.text, expr_right))
|
||||
return expression
|
||||
|
||||
|
||||
def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom:
|
||||
"""
|
||||
marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS?
|
||||
| WS? marker_item WS?
|
||||
"""
|
||||
|
||||
tokenizer.consume("WS")
|
||||
if tokenizer.check("LEFT_PARENTHESIS", peek=True):
|
||||
with tokenizer.enclosing_tokens(
|
||||
"LEFT_PARENTHESIS",
|
||||
"RIGHT_PARENTHESIS",
|
||||
around="marker expression",
|
||||
):
|
||||
tokenizer.consume("WS")
|
||||
marker: MarkerAtom = _parse_marker(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
else:
|
||||
marker = _parse_marker_item(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
return marker
|
||||
|
||||
|
||||
def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem:
|
||||
"""
|
||||
marker_item = WS? marker_var WS? marker_op WS? marker_var WS?
|
||||
"""
|
||||
tokenizer.consume("WS")
|
||||
marker_var_left = _parse_marker_var(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
marker_op = _parse_marker_op(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
marker_var_right = _parse_marker_var(tokenizer)
|
||||
tokenizer.consume("WS")
|
||||
return (marker_var_left, marker_op, marker_var_right)
|
||||
|
||||
|
||||
def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
|
||||
"""
|
||||
marker_var = VARIABLE | QUOTED_STRING
|
||||
"""
|
||||
if tokenizer.check("VARIABLE"):
|
||||
return process_env_var(tokenizer.read().text.replace(".", "_"))
|
||||
elif tokenizer.check("QUOTED_STRING"):
|
||||
return process_python_str(tokenizer.read().text)
|
||||
else:
|
||||
tokenizer.raise_syntax_error(
|
||||
message="Expected a marker variable or quoted string"
|
||||
)
|
||||
|
||||
|
||||
def process_env_var(env_var: str) -> Variable:
|
||||
if (
|
||||
env_var == "platform_python_implementation"
|
||||
or env_var == "python_implementation"
|
||||
):
|
||||
return Variable("platform_python_implementation")
|
||||
else:
|
||||
return Variable(env_var)
|
||||
|
||||
|
||||
def process_python_str(python_str: str) -> Value:
|
||||
value = ast.literal_eval(python_str)
|
||||
return Value(str(value))
|
||||
|
||||
|
||||
def _parse_marker_op(tokenizer: Tokenizer) -> Op:
|
||||
"""
|
||||
marker_op = IN | NOT IN | OP
|
||||
"""
|
||||
if tokenizer.check("IN"):
|
||||
tokenizer.read()
|
||||
return Op("in")
|
||||
elif tokenizer.check("NOT"):
|
||||
tokenizer.read()
|
||||
tokenizer.expect("WS", expected="whitespace after 'not'")
|
||||
tokenizer.expect("IN", expected="'in' after 'not'")
|
||||
return Op("not in")
|
||||
elif tokenizer.check("OP"):
|
||||
return Op(tokenizer.read().text)
|
||||
else:
|
||||
return tokenizer.raise_syntax_error(
|
||||
"Expected marker operator, one of "
|
||||
"<=, <, !=, ==, >=, >, ~=, ===, in, not in"
|
||||
)
|
||||
61
electron/node_modules/node-gyp/gyp/pylib/packaging/_structures.py
generated
vendored
Normal file
61
electron/node_modules/node-gyp/gyp/pylib/packaging/_structures.py
generated
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
|
||||
class InfinityType:
|
||||
def __repr__(self) -> str:
|
||||
return "Infinity"
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(repr(self))
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
return False
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
return False
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
return isinstance(other, self.__class__)
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
return True
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
return True
|
||||
|
||||
def __neg__(self: object) -> "NegativeInfinityType":
|
||||
return NegativeInfinity
|
||||
|
||||
|
||||
Infinity = InfinityType()
|
||||
|
||||
|
||||
class NegativeInfinityType:
|
||||
def __repr__(self) -> str:
|
||||
return "-Infinity"
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(repr(self))
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
return True
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
return isinstance(other, self.__class__)
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
return False
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
return False
|
||||
|
||||
def __neg__(self: object) -> InfinityType:
|
||||
return Infinity
|
||||
|
||||
|
||||
NegativeInfinity = NegativeInfinityType()
|
||||
192
electron/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py
generated
vendored
Normal file
192
electron/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py
generated
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
import contextlib
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, Iterator, NoReturn, Optional, Tuple, Union
|
||||
|
||||
from .specifiers import Specifier
|
||||
|
||||
|
||||
@dataclass
|
||||
class Token:
|
||||
name: str
|
||||
text: str
|
||||
position: int
|
||||
|
||||
|
||||
class ParserSyntaxError(Exception):
|
||||
"""The provided source text could not be parsed correctly."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str,
|
||||
*,
|
||||
source: str,
|
||||
span: Tuple[int, int],
|
||||
) -> None:
|
||||
self.span = span
|
||||
self.message = message
|
||||
self.source = source
|
||||
|
||||
super().__init__()
|
||||
|
||||
def __str__(self) -> str:
|
||||
marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^"
|
||||
return "\n ".join([self.message, self.source, marker])
|
||||
|
||||
|
||||
DEFAULT_RULES: "Dict[str, Union[str, re.Pattern[str]]]" = {
|
||||
"LEFT_PARENTHESIS": r"\(",
|
||||
"RIGHT_PARENTHESIS": r"\)",
|
||||
"LEFT_BRACKET": r"\[",
|
||||
"RIGHT_BRACKET": r"\]",
|
||||
"SEMICOLON": r";",
|
||||
"COMMA": r",",
|
||||
"QUOTED_STRING": re.compile(
|
||||
r"""
|
||||
(
|
||||
('[^']*')
|
||||
|
|
||||
("[^"]*")
|
||||
)
|
||||
""",
|
||||
re.VERBOSE,
|
||||
),
|
||||
"OP": r"(===|==|~=|!=|<=|>=|<|>)",
|
||||
"BOOLOP": r"\b(or|and)\b",
|
||||
"IN": r"\bin\b",
|
||||
"NOT": r"\bnot\b",
|
||||
"VARIABLE": re.compile(
|
||||
r"""
|
||||
\b(
|
||||
python_version
|
||||
|python_full_version
|
||||
|os[._]name
|
||||
|sys[._]platform
|
||||
|platform_(release|system)
|
||||
|platform[._](version|machine|python_implementation)
|
||||
|python_implementation
|
||||
|implementation_(name|version)
|
||||
|extra
|
||||
)\b
|
||||
""",
|
||||
re.VERBOSE,
|
||||
),
|
||||
"SPECIFIER": re.compile(
|
||||
Specifier._operator_regex_str + Specifier._version_regex_str,
|
||||
re.VERBOSE | re.IGNORECASE,
|
||||
),
|
||||
"AT": r"\@",
|
||||
"URL": r"[^ \t]+",
|
||||
"IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
|
||||
"VERSION_PREFIX_TRAIL": r"\.\*",
|
||||
"VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
|
||||
"WS": r"[ \t]+",
|
||||
"END": r"$",
|
||||
}
|
||||
|
||||
|
||||
class Tokenizer:
|
||||
"""Context-sensitive token parsing.
|
||||
|
||||
Provides methods to examine the input stream to check whether the next token
|
||||
matches.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
source: str,
|
||||
*,
|
||||
rules: "Dict[str, Union[str, re.Pattern[str]]]",
|
||||
) -> None:
|
||||
self.source = source
|
||||
self.rules: Dict[str, re.Pattern[str]] = {
|
||||
name: re.compile(pattern) for name, pattern in rules.items()
|
||||
}
|
||||
self.next_token: Optional[Token] = None
|
||||
self.position = 0
|
||||
|
||||
def consume(self, name: str) -> None:
|
||||
"""Move beyond provided token name, if at current position."""
|
||||
if self.check(name):
|
||||
self.read()
|
||||
|
||||
def check(self, name: str, *, peek: bool = False) -> bool:
|
||||
"""Check whether the next token has the provided name.
|
||||
|
||||
By default, if the check succeeds, the token *must* be read before
|
||||
another check. If `peek` is set to `True`, the token is not loaded and
|
||||
would need to be checked again.
|
||||
"""
|
||||
assert (
|
||||
self.next_token is None
|
||||
), f"Cannot check for {name!r}, already have {self.next_token!r}"
|
||||
assert name in self.rules, f"Unknown token name: {name!r}"
|
||||
|
||||
expression = self.rules[name]
|
||||
|
||||
match = expression.match(self.source, self.position)
|
||||
if match is None:
|
||||
return False
|
||||
if not peek:
|
||||
self.next_token = Token(name, match[0], self.position)
|
||||
return True
|
||||
|
||||
def expect(self, name: str, *, expected: str) -> Token:
|
||||
"""Expect a certain token name next, failing with a syntax error otherwise.
|
||||
|
||||
The token is *not* read.
|
||||
"""
|
||||
if not self.check(name):
|
||||
raise self.raise_syntax_error(f"Expected {expected}")
|
||||
return self.read()
|
||||
|
||||
def read(self) -> Token:
|
||||
"""Consume the next token and return it."""
|
||||
token = self.next_token
|
||||
assert token is not None
|
||||
|
||||
self.position += len(token.text)
|
||||
self.next_token = None
|
||||
|
||||
return token
|
||||
|
||||
def raise_syntax_error(
|
||||
self,
|
||||
message: str,
|
||||
*,
|
||||
span_start: Optional[int] = None,
|
||||
span_end: Optional[int] = None,
|
||||
) -> NoReturn:
|
||||
"""Raise ParserSyntaxError at the given position."""
|
||||
span = (
|
||||
self.position if span_start is None else span_start,
|
||||
self.position if span_end is None else span_end,
|
||||
)
|
||||
raise ParserSyntaxError(
|
||||
message,
|
||||
source=self.source,
|
||||
span=span,
|
||||
)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def enclosing_tokens(
|
||||
self, open_token: str, close_token: str, *, around: str
|
||||
) -> Iterator[None]:
|
||||
if self.check(open_token):
|
||||
open_position = self.position
|
||||
self.read()
|
||||
else:
|
||||
open_position = None
|
||||
|
||||
yield
|
||||
|
||||
if open_position is None:
|
||||
return
|
||||
|
||||
if not self.check(close_token):
|
||||
self.raise_syntax_error(
|
||||
f"Expected matching {close_token} for {open_token}, after {around}",
|
||||
span_start=open_position,
|
||||
)
|
||||
|
||||
self.read()
|
||||
251
electron/node_modules/node-gyp/gyp/pylib/packaging/markers.py
generated
vendored
Normal file
251
electron/node_modules/node-gyp/gyp/pylib/packaging/markers.py
generated
vendored
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
import operator
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from ._parser import (
|
||||
MarkerAtom,
|
||||
MarkerList,
|
||||
Op,
|
||||
Value,
|
||||
Variable,
|
||||
parse_marker as _parse_marker,
|
||||
)
|
||||
from ._tokenizer import ParserSyntaxError
|
||||
from .specifiers import InvalidSpecifier, Specifier
|
||||
from .utils import canonicalize_name
|
||||
|
||||
__all__ = [
|
||||
"InvalidMarker",
|
||||
"UndefinedComparison",
|
||||
"UndefinedEnvironmentName",
|
||||
"Marker",
|
||||
"default_environment",
|
||||
]
|
||||
|
||||
Operator = Callable[[str, str], bool]
|
||||
|
||||
|
||||
class InvalidMarker(ValueError):
|
||||
"""
|
||||
An invalid marker was found, users should refer to PEP 508.
|
||||
"""
|
||||
|
||||
|
||||
class UndefinedComparison(ValueError):
|
||||
"""
|
||||
An invalid operation was attempted on a value that doesn't support it.
|
||||
"""
|
||||
|
||||
|
||||
class UndefinedEnvironmentName(ValueError):
|
||||
"""
|
||||
A name was attempted to be used that does not exist inside of the
|
||||
environment.
|
||||
"""
|
||||
|
||||
|
||||
def _normalize_extra_values(results: Any) -> Any:
|
||||
"""
|
||||
Normalize extra values.
|
||||
"""
|
||||
if isinstance(results[0], tuple):
|
||||
lhs, op, rhs = results[0]
|
||||
if isinstance(lhs, Variable) and lhs.value == "extra":
|
||||
normalized_extra = canonicalize_name(rhs.value)
|
||||
rhs = Value(normalized_extra)
|
||||
elif isinstance(rhs, Variable) and rhs.value == "extra":
|
||||
normalized_extra = canonicalize_name(lhs.value)
|
||||
lhs = Value(normalized_extra)
|
||||
results[0] = lhs, op, rhs
|
||||
return results
|
||||
|
||||
|
||||
def _format_marker(
|
||||
marker: Union[List[str], MarkerAtom, str], first: Optional[bool] = True
|
||||
) -> str:
|
||||
|
||||
assert isinstance(marker, (list, tuple, str))
|
||||
|
||||
# Sometimes we have a structure like [[...]] which is a single item list
|
||||
# where the single item is itself it's own list. In that case we want skip
|
||||
# the rest of this function so that we don't get extraneous () on the
|
||||
# outside.
|
||||
if (
|
||||
isinstance(marker, list)
|
||||
and len(marker) == 1
|
||||
and isinstance(marker[0], (list, tuple))
|
||||
):
|
||||
return _format_marker(marker[0])
|
||||
|
||||
if isinstance(marker, list):
|
||||
inner = (_format_marker(m, first=False) for m in marker)
|
||||
if first:
|
||||
return " ".join(inner)
|
||||
else:
|
||||
return "(" + " ".join(inner) + ")"
|
||||
elif isinstance(marker, tuple):
|
||||
return " ".join([m.serialize() for m in marker])
|
||||
else:
|
||||
return marker
|
||||
|
||||
|
||||
_operators: Dict[str, Operator] = {
|
||||
"in": lambda lhs, rhs: lhs in rhs,
|
||||
"not in": lambda lhs, rhs: lhs not in rhs,
|
||||
"<": operator.lt,
|
||||
"<=": operator.le,
|
||||
"==": operator.eq,
|
||||
"!=": operator.ne,
|
||||
">=": operator.ge,
|
||||
">": operator.gt,
|
||||
}
|
||||
|
||||
|
||||
def _eval_op(lhs: str, op: Op, rhs: str) -> bool:
|
||||
try:
|
||||
spec = Specifier("".join([op.serialize(), rhs]))
|
||||
except InvalidSpecifier:
|
||||
pass
|
||||
else:
|
||||
return spec.contains(lhs, prereleases=True)
|
||||
|
||||
oper: Optional[Operator] = _operators.get(op.serialize())
|
||||
if oper is None:
|
||||
raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.")
|
||||
|
||||
return oper(lhs, rhs)
|
||||
|
||||
|
||||
def _normalize(*values: str, key: str) -> Tuple[str, ...]:
|
||||
# PEP 685 – Comparison of extra names for optional distribution dependencies
|
||||
# https://peps.python.org/pep-0685/
|
||||
# > When comparing extra names, tools MUST normalize the names being
|
||||
# > compared using the semantics outlined in PEP 503 for names
|
||||
if key == "extra":
|
||||
return tuple(canonicalize_name(v) for v in values)
|
||||
|
||||
# other environment markers don't have such standards
|
||||
return values
|
||||
|
||||
|
||||
def _evaluate_markers(markers: MarkerList, environment: Dict[str, str]) -> bool:
|
||||
groups: List[List[bool]] = [[]]
|
||||
|
||||
for marker in markers:
|
||||
assert isinstance(marker, (list, tuple, str))
|
||||
|
||||
if isinstance(marker, list):
|
||||
groups[-1].append(_evaluate_markers(marker, environment))
|
||||
elif isinstance(marker, tuple):
|
||||
lhs, op, rhs = marker
|
||||
|
||||
if isinstance(lhs, Variable):
|
||||
environment_key = lhs.value
|
||||
lhs_value = environment[environment_key]
|
||||
rhs_value = rhs.value
|
||||
else:
|
||||
lhs_value = lhs.value
|
||||
environment_key = rhs.value
|
||||
rhs_value = environment[environment_key]
|
||||
|
||||
lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key)
|
||||
groups[-1].append(_eval_op(lhs_value, op, rhs_value))
|
||||
else:
|
||||
assert marker in ["and", "or"]
|
||||
if marker == "or":
|
||||
groups.append([])
|
||||
|
||||
return any(all(item) for item in groups)
|
||||
|
||||
|
||||
def format_full_version(info: "sys._version_info") -> str:
|
||||
version = "{0.major}.{0.minor}.{0.micro}".format(info)
|
||||
if (kind := info.releaselevel) != "final":
|
||||
version += kind[0] + str(info.serial)
|
||||
return version
|
||||
|
||||
|
||||
def default_environment() -> Dict[str, str]:
|
||||
iver = format_full_version(sys.implementation.version)
|
||||
implementation_name = sys.implementation.name
|
||||
return {
|
||||
"implementation_name": implementation_name,
|
||||
"implementation_version": iver,
|
||||
"os_name": os.name,
|
||||
"platform_machine": platform.machine(),
|
||||
"platform_release": platform.release(),
|
||||
"platform_system": platform.system(),
|
||||
"platform_version": platform.version(),
|
||||
"python_full_version": platform.python_version(),
|
||||
"platform_python_implementation": platform.python_implementation(),
|
||||
"python_version": ".".join(platform.python_version_tuple()[:2]),
|
||||
"sys_platform": sys.platform,
|
||||
}
|
||||
|
||||
|
||||
class Marker:
|
||||
def __init__(self, marker: str) -> None:
|
||||
# Note: We create a Marker object without calling this constructor in
|
||||
# packaging.requirements.Requirement. If any additional logic is
|
||||
# added here, make sure to mirror/adapt Requirement.
|
||||
try:
|
||||
self._markers = _normalize_extra_values(_parse_marker(marker))
|
||||
# The attribute `_markers` can be described in terms of a recursive type:
|
||||
# MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]]
|
||||
#
|
||||
# For example, the following expression:
|
||||
# python_version > "3.6" or (python_version == "3.6" and os_name == "unix")
|
||||
#
|
||||
# is parsed into:
|
||||
# [
|
||||
# (<Variable('python_version')>, <Op('>')>, <Value('3.6')>),
|
||||
# 'and',
|
||||
# [
|
||||
# (<Variable('python_version')>, <Op('==')>, <Value('3.6')>),
|
||||
# 'or',
|
||||
# (<Variable('os_name')>, <Op('==')>, <Value('unix')>)
|
||||
# ]
|
||||
# ]
|
||||
except ParserSyntaxError as e:
|
||||
raise InvalidMarker(str(e)) from e
|
||||
|
||||
def __str__(self) -> str:
|
||||
return _format_marker(self._markers)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Marker('{self}')>"
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self.__class__.__name__, str(self)))
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, Marker):
|
||||
return NotImplemented
|
||||
|
||||
return str(self) == str(other)
|
||||
|
||||
def evaluate(self, environment: Optional[Dict[str, str]] = None) -> bool:
|
||||
"""Evaluate a marker.
|
||||
|
||||
Return the boolean from evaluating the given marker against the
|
||||
environment. environment is an optional argument to override all or
|
||||
part of the determined environment.
|
||||
|
||||
The environment is determined from the current Python process.
|
||||
"""
|
||||
current_environment = default_environment()
|
||||
current_environment["extra"] = ""
|
||||
if environment is not None:
|
||||
current_environment.update(environment)
|
||||
# The API used to allow setting extra to None. We need to handle this
|
||||
# case for backwards compatibility.
|
||||
if current_environment["extra"] is None:
|
||||
current_environment["extra"] = ""
|
||||
|
||||
return _evaluate_markers(self._markers, current_environment)
|
||||
807
electron/node_modules/node-gyp/gyp/pylib/packaging/metadata.py
generated
vendored
Normal file
807
electron/node_modules/node-gyp/gyp/pylib/packaging/metadata.py
generated
vendored
Normal file
|
|
@ -0,0 +1,807 @@
|
|||
import email.feedparser
|
||||
import email.header
|
||||
import email.message
|
||||
import email.parser
|
||||
import email.policy
|
||||
import sys
|
||||
import typing
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Optional,
|
||||
Tuple,
|
||||
Type,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
|
||||
from . import requirements, specifiers, utils, version as version_module
|
||||
|
||||
T = typing.TypeVar("T")
|
||||
from typing import Literal, TypedDict
|
||||
|
||||
try:
|
||||
ExceptionGroup # Added in Python 3.11+
|
||||
except NameError: # pragma: no cover
|
||||
|
||||
class ExceptionGroup(Exception): # noqa: N818
|
||||
"""A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11.
|
||||
|
||||
If :external:exc:`ExceptionGroup` is already defined by Python itself,
|
||||
that version is used instead.
|
||||
"""
|
||||
|
||||
message: str
|
||||
exceptions: List[Exception]
|
||||
|
||||
def __init__(self, message: str, exceptions: List[Exception]) -> None:
|
||||
self.message = message
|
||||
self.exceptions = exceptions
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})"
|
||||
|
||||
else: # pragma: no cover
|
||||
ExceptionGroup = ExceptionGroup
|
||||
|
||||
|
||||
class InvalidMetadata(ValueError):
|
||||
"""A metadata field contains invalid data."""
|
||||
|
||||
field: str
|
||||
"""The name of the field that contains invalid data."""
|
||||
|
||||
def __init__(self, field: str, message: str) -> None:
|
||||
self.field = field
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
# The RawMetadata class attempts to make as few assumptions about the underlying
|
||||
# serialization formats as possible. The idea is that as long as a serialization
|
||||
# formats offer some very basic primitives in *some* way then we can support
|
||||
# serializing to and from that format.
|
||||
class RawMetadata(TypedDict, total=False):
|
||||
"""A dictionary of raw core metadata.
|
||||
|
||||
Each field in core metadata maps to a key of this dictionary (when data is
|
||||
provided). The key is lower-case and underscores are used instead of dashes
|
||||
compared to the equivalent core metadata field. Any core metadata field that
|
||||
can be specified multiple times or can hold multiple values in a single
|
||||
field have a key with a plural name. See :class:`Metadata` whose attributes
|
||||
match the keys of this dictionary.
|
||||
|
||||
Core metadata fields that can be specified multiple times are stored as a
|
||||
list or dict depending on which is appropriate for the field. Any fields
|
||||
which hold multiple values in a single field are stored as a list.
|
||||
|
||||
"""
|
||||
|
||||
# Metadata 1.0 - PEP 241
|
||||
metadata_version: str
|
||||
name: str
|
||||
version: str
|
||||
platforms: List[str]
|
||||
summary: str
|
||||
description: str
|
||||
keywords: List[str]
|
||||
home_page: str
|
||||
author: str
|
||||
author_email: str
|
||||
license: str
|
||||
|
||||
# Metadata 1.1 - PEP 314
|
||||
supported_platforms: List[str]
|
||||
download_url: str
|
||||
classifiers: List[str]
|
||||
requires: List[str]
|
||||
provides: List[str]
|
||||
obsoletes: List[str]
|
||||
|
||||
# Metadata 1.2 - PEP 345
|
||||
maintainer: str
|
||||
maintainer_email: str
|
||||
requires_dist: List[str]
|
||||
provides_dist: List[str]
|
||||
obsoletes_dist: List[str]
|
||||
requires_python: str
|
||||
requires_external: List[str]
|
||||
project_urls: Dict[str, str]
|
||||
|
||||
# Metadata 2.0
|
||||
# PEP 426 attempted to completely revamp the metadata format
|
||||
# but got stuck without ever being able to build consensus on
|
||||
# it and ultimately ended up withdrawn.
|
||||
#
|
||||
# However, a number of tools had started emitting METADATA with
|
||||
# `2.0` Metadata-Version, so for historical reasons, this version
|
||||
# was skipped.
|
||||
|
||||
# Metadata 2.1 - PEP 566
|
||||
description_content_type: str
|
||||
provides_extra: List[str]
|
||||
|
||||
# Metadata 2.2 - PEP 643
|
||||
dynamic: List[str]
|
||||
|
||||
# Metadata 2.3 - PEP 685
|
||||
# No new fields were added in PEP 685, just some edge case were
|
||||
# tightened up to provide better interoperability.
|
||||
|
||||
|
||||
_STRING_FIELDS = {
|
||||
"author",
|
||||
"author_email",
|
||||
"description",
|
||||
"description_content_type",
|
||||
"download_url",
|
||||
"home_page",
|
||||
"license",
|
||||
"maintainer",
|
||||
"maintainer_email",
|
||||
"metadata_version",
|
||||
"name",
|
||||
"requires_python",
|
||||
"summary",
|
||||
"version",
|
||||
}
|
||||
|
||||
_LIST_FIELDS = {
|
||||
"classifiers",
|
||||
"dynamic",
|
||||
"obsoletes",
|
||||
"obsoletes_dist",
|
||||
"platforms",
|
||||
"provides",
|
||||
"provides_dist",
|
||||
"provides_extra",
|
||||
"requires",
|
||||
"requires_dist",
|
||||
"requires_external",
|
||||
"supported_platforms",
|
||||
}
|
||||
|
||||
_DICT_FIELDS = {
|
||||
"project_urls",
|
||||
}
|
||||
|
||||
|
||||
def _parse_keywords(data: str) -> List[str]:
|
||||
"""Split a string of comma-separate keyboards into a list of keywords."""
|
||||
return [k.strip() for k in data.split(",")]
|
||||
|
||||
|
||||
def _parse_project_urls(data: List[str]) -> Dict[str, str]:
|
||||
"""Parse a list of label/URL string pairings separated by a comma."""
|
||||
urls = {}
|
||||
for pair in data:
|
||||
# Our logic is slightly tricky here as we want to try and do
|
||||
# *something* reasonable with malformed data.
|
||||
#
|
||||
# The main thing that we have to worry about, is data that does
|
||||
# not have a ',' at all to split the label from the Value. There
|
||||
# isn't a singular right answer here, and we will fail validation
|
||||
# later on (if the caller is validating) so it doesn't *really*
|
||||
# matter, but since the missing value has to be an empty str
|
||||
# and our return value is dict[str, str], if we let the key
|
||||
# be the missing value, then they'd have multiple '' values that
|
||||
# overwrite each other in a accumulating dict.
|
||||
#
|
||||
# The other potential issue is that it's possible to have the
|
||||
# same label multiple times in the metadata, with no solid "right"
|
||||
# answer with what to do in that case. As such, we'll do the only
|
||||
# thing we can, which is treat the field as unparsable and add it
|
||||
# to our list of unparsed fields.
|
||||
parts = [p.strip() for p in pair.split(",", 1)]
|
||||
parts.extend([""] * (max(0, 2 - len(parts)))) # Ensure 2 items
|
||||
|
||||
# TODO: The spec doesn't say anything about if the keys should be
|
||||
# considered case sensitive or not... logically they should
|
||||
# be case-preserving and case-insensitive, but doing that
|
||||
# would open up more cases where we might have duplicate
|
||||
# entries.
|
||||
label, url = parts
|
||||
if label in urls:
|
||||
# The label already exists in our set of urls, so this field
|
||||
# is unparsable, and we can just add the whole thing to our
|
||||
# unparsable data and stop processing it.
|
||||
raise KeyError("duplicate labels in project urls")
|
||||
urls[label] = url
|
||||
|
||||
return urls
|
||||
|
||||
|
||||
def _get_payload(msg: email.message.Message, source: Union[bytes, str]) -> str:
|
||||
"""Get the body of the message."""
|
||||
# If our source is a str, then our caller has managed encodings for us,
|
||||
# and we don't need to deal with it.
|
||||
if isinstance(source, str):
|
||||
payload: str = msg.get_payload()
|
||||
return payload
|
||||
# If our source is a bytes, then we're managing the encoding and we need
|
||||
# to deal with it.
|
||||
else:
|
||||
bpayload: bytes = msg.get_payload(decode=True)
|
||||
try:
|
||||
return bpayload.decode("utf8", "strict")
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError("payload in an invalid encoding")
|
||||
|
||||
|
||||
# The various parse_FORMAT functions here are intended to be as lenient as
|
||||
# possible in their parsing, while still returning a correctly typed
|
||||
# RawMetadata.
|
||||
#
|
||||
# To aid in this, we also generally want to do as little touching of the
|
||||
# data as possible, except where there are possibly some historic holdovers
|
||||
# that make valid data awkward to work with.
|
||||
#
|
||||
# While this is a lower level, intermediate format than our ``Metadata``
|
||||
# class, some light touch ups can make a massive difference in usability.
|
||||
|
||||
# Map METADATA fields to RawMetadata.
|
||||
_EMAIL_TO_RAW_MAPPING = {
|
||||
"author": "author",
|
||||
"author-email": "author_email",
|
||||
"classifier": "classifiers",
|
||||
"description": "description",
|
||||
"description-content-type": "description_content_type",
|
||||
"download-url": "download_url",
|
||||
"dynamic": "dynamic",
|
||||
"home-page": "home_page",
|
||||
"keywords": "keywords",
|
||||
"license": "license",
|
||||
"maintainer": "maintainer",
|
||||
"maintainer-email": "maintainer_email",
|
||||
"metadata-version": "metadata_version",
|
||||
"name": "name",
|
||||
"obsoletes": "obsoletes",
|
||||
"obsoletes-dist": "obsoletes_dist",
|
||||
"platform": "platforms",
|
||||
"project-url": "project_urls",
|
||||
"provides": "provides",
|
||||
"provides-dist": "provides_dist",
|
||||
"provides-extra": "provides_extra",
|
||||
"requires": "requires",
|
||||
"requires-dist": "requires_dist",
|
||||
"requires-external": "requires_external",
|
||||
"requires-python": "requires_python",
|
||||
"summary": "summary",
|
||||
"supported-platform": "supported_platforms",
|
||||
"version": "version",
|
||||
}
|
||||
_RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()}
|
||||
|
||||
|
||||
def parse_email(data: Union[bytes, str]) -> Tuple[RawMetadata, Dict[str, List[str]]]:
|
||||
"""Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``).
|
||||
|
||||
This function returns a two-item tuple of dicts. The first dict is of
|
||||
recognized fields from the core metadata specification. Fields that can be
|
||||
parsed and translated into Python's built-in types are converted
|
||||
appropriately. All other fields are left as-is. Fields that are allowed to
|
||||
appear multiple times are stored as lists.
|
||||
|
||||
The second dict contains all other fields from the metadata. This includes
|
||||
any unrecognized fields. It also includes any fields which are expected to
|
||||
be parsed into a built-in type but were not formatted appropriately. Finally,
|
||||
any fields that are expected to appear only once but are repeated are
|
||||
included in this dict.
|
||||
|
||||
"""
|
||||
raw: Dict[str, Union[str, List[str], Dict[str, str]]] = {}
|
||||
unparsed: Dict[str, List[str]] = {}
|
||||
|
||||
if isinstance(data, str):
|
||||
parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data)
|
||||
else:
|
||||
parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data)
|
||||
|
||||
# We have to wrap parsed.keys() in a set, because in the case of multiple
|
||||
# values for a key (a list), the key will appear multiple times in the
|
||||
# list of keys, but we're avoiding that by using get_all().
|
||||
for name in frozenset(parsed.keys()):
|
||||
# Header names in RFC are case insensitive, so we'll normalize to all
|
||||
# lower case to make comparisons easier.
|
||||
name = name.lower()
|
||||
|
||||
# We use get_all() here, even for fields that aren't multiple use,
|
||||
# because otherwise someone could have e.g. two Name fields, and we
|
||||
# would just silently ignore it rather than doing something about it.
|
||||
headers = parsed.get_all(name) or []
|
||||
|
||||
# The way the email module works when parsing bytes is that it
|
||||
# unconditionally decodes the bytes as ascii using the surrogateescape
|
||||
# handler. When you pull that data back out (such as with get_all() ),
|
||||
# it looks to see if the str has any surrogate escapes, and if it does
|
||||
# it wraps it in a Header object instead of returning the string.
|
||||
#
|
||||
# As such, we'll look for those Header objects, and fix up the encoding.
|
||||
value = []
|
||||
# Flag if we have run into any issues processing the headers, thus
|
||||
# signalling that the data belongs in 'unparsed'.
|
||||
valid_encoding = True
|
||||
for h in headers:
|
||||
# It's unclear if this can return more types than just a Header or
|
||||
# a str, so we'll just assert here to make sure.
|
||||
assert isinstance(h, (email.header.Header, str))
|
||||
|
||||
# If it's a header object, we need to do our little dance to get
|
||||
# the real data out of it. In cases where there is invalid data
|
||||
# we're going to end up with mojibake, but there's no obvious, good
|
||||
# way around that without reimplementing parts of the Header object
|
||||
# ourselves.
|
||||
#
|
||||
# That should be fine since, if mojibacked happens, this key is
|
||||
# going into the unparsed dict anyways.
|
||||
if isinstance(h, email.header.Header):
|
||||
# The Header object stores it's data as chunks, and each chunk
|
||||
# can be independently encoded, so we'll need to check each
|
||||
# of them.
|
||||
chunks: List[Tuple[bytes, Optional[str]]] = []
|
||||
for bin, encoding in email.header.decode_header(h):
|
||||
try:
|
||||
bin.decode("utf8", "strict")
|
||||
except UnicodeDecodeError:
|
||||
# Enable mojibake.
|
||||
encoding = "latin1"
|
||||
valid_encoding = False
|
||||
else:
|
||||
encoding = "utf8"
|
||||
chunks.append((bin, encoding))
|
||||
|
||||
# Turn our chunks back into a Header object, then let that
|
||||
# Header object do the right thing to turn them into a
|
||||
# string for us.
|
||||
value.append(str(email.header.make_header(chunks)))
|
||||
# This is already a string, so just add it.
|
||||
else:
|
||||
value.append(h)
|
||||
|
||||
# We've processed all of our values to get them into a list of str,
|
||||
# but we may have mojibake data, in which case this is an unparsed
|
||||
# field.
|
||||
if not valid_encoding:
|
||||
unparsed[name] = value
|
||||
continue
|
||||
|
||||
raw_name = _EMAIL_TO_RAW_MAPPING.get(name)
|
||||
if raw_name is None:
|
||||
# This is a bit of a weird situation, we've encountered a key that
|
||||
# we don't know what it means, so we don't know whether it's meant
|
||||
# to be a list or not.
|
||||
#
|
||||
# Since we can't really tell one way or another, we'll just leave it
|
||||
# as a list, even though it may be a single item list, because that's
|
||||
# what makes the most sense for email headers.
|
||||
unparsed[name] = value
|
||||
continue
|
||||
|
||||
# If this is one of our string fields, then we'll check to see if our
|
||||
# value is a list of a single item. If it is then we'll assume that
|
||||
# it was emitted as a single string, and unwrap the str from inside
|
||||
# the list.
|
||||
#
|
||||
# If it's any other kind of data, then we haven't the faintest clue
|
||||
# what we should parse it as, and we have to just add it to our list
|
||||
# of unparsed stuff.
|
||||
if raw_name in _STRING_FIELDS and len(value) == 1:
|
||||
raw[raw_name] = value[0]
|
||||
# If this is one of our list of string fields, then we can just assign
|
||||
# the value, since email *only* has strings, and our get_all() call
|
||||
# above ensures that this is a list.
|
||||
elif raw_name in _LIST_FIELDS:
|
||||
raw[raw_name] = value
|
||||
# Special Case: Keywords
|
||||
# The keywords field is implemented in the metadata spec as a str,
|
||||
# but it conceptually is a list of strings, and is serialized using
|
||||
# ", ".join(keywords), so we'll do some light data massaging to turn
|
||||
# this into what it logically is.
|
||||
elif raw_name == "keywords" and len(value) == 1:
|
||||
raw[raw_name] = _parse_keywords(value[0])
|
||||
# Special Case: Project-URL
|
||||
# The project urls is implemented in the metadata spec as a list of
|
||||
# specially-formatted strings that represent a key and a value, which
|
||||
# is fundamentally a mapping, however the email format doesn't support
|
||||
# mappings in a sane way, so it was crammed into a list of strings
|
||||
# instead.
|
||||
#
|
||||
# We will do a little light data massaging to turn this into a map as
|
||||
# it logically should be.
|
||||
elif raw_name == "project_urls":
|
||||
try:
|
||||
raw[raw_name] = _parse_project_urls(value)
|
||||
except KeyError:
|
||||
unparsed[name] = value
|
||||
# Nothing that we've done has managed to parse this, so it'll just
|
||||
# throw it in our unparsable data and move on.
|
||||
else:
|
||||
unparsed[name] = value
|
||||
|
||||
# We need to support getting the Description from the message payload in
|
||||
# addition to getting it from the the headers. This does mean, though, there
|
||||
# is the possibility of it being set both ways, in which case we put both
|
||||
# in 'unparsed' since we don't know which is right.
|
||||
try:
|
||||
payload = _get_payload(parsed, data)
|
||||
except ValueError:
|
||||
unparsed.setdefault("description", []).append(
|
||||
parsed.get_payload(decode=isinstance(data, bytes))
|
||||
)
|
||||
else:
|
||||
if payload:
|
||||
# Check to see if we've already got a description, if so then both
|
||||
# it, and this body move to unparsable.
|
||||
if "description" in raw:
|
||||
description_header = cast(str, raw.pop("description"))
|
||||
unparsed.setdefault("description", []).extend(
|
||||
[description_header, payload]
|
||||
)
|
||||
elif "description" in unparsed:
|
||||
unparsed["description"].append(payload)
|
||||
else:
|
||||
raw["description"] = payload
|
||||
|
||||
# We need to cast our `raw` to a metadata, because a TypedDict only support
|
||||
# literal key names, but we're computing our key names on purpose, but the
|
||||
# way this function is implemented, our `TypedDict` can only have valid key
|
||||
# names.
|
||||
return cast(RawMetadata, raw), unparsed
|
||||
|
||||
|
||||
_NOT_FOUND = object()
|
||||
|
||||
|
||||
# Keep the two values in sync.
|
||||
_VALID_METADATA_VERSIONS = ["1.0", "1.1", "1.2", "2.1", "2.2", "2.3"]
|
||||
_MetadataVersion = Literal["1.0", "1.1", "1.2", "2.1", "2.2", "2.3"]
|
||||
|
||||
_REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"])
|
||||
|
||||
|
||||
class _Validator(Generic[T]):
|
||||
"""Validate a metadata field.
|
||||
|
||||
All _process_*() methods correspond to a core metadata field. The method is
|
||||
called with the field's raw value. If the raw value is valid it is returned
|
||||
in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field).
|
||||
If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause
|
||||
as appropriate).
|
||||
"""
|
||||
|
||||
name: str
|
||||
raw_name: str
|
||||
added: _MetadataVersion
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
added: _MetadataVersion = "1.0",
|
||||
) -> None:
|
||||
self.added = added
|
||||
|
||||
def __set_name__(self, _owner: "Metadata", name: str) -> None:
|
||||
self.name = name
|
||||
self.raw_name = _RAW_TO_EMAIL_MAPPING[name]
|
||||
|
||||
def __get__(self, instance: "Metadata", _owner: Type["Metadata"]) -> T:
|
||||
# With Python 3.8+, the caching can be replaced with functools.cached_property().
|
||||
# No need to check the cache as attribute lookup will resolve into the
|
||||
# instance's __dict__ before __get__ is called.
|
||||
cache = instance.__dict__
|
||||
value = instance._raw.get(self.name)
|
||||
|
||||
# To make the _process_* methods easier, we'll check if the value is None
|
||||
# and if this field is NOT a required attribute, and if both of those
|
||||
# things are true, we'll skip the the converter. This will mean that the
|
||||
# converters never have to deal with the None union.
|
||||
if self.name in _REQUIRED_ATTRS or value is not None:
|
||||
try:
|
||||
converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}")
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
value = converter(value)
|
||||
|
||||
cache[self.name] = value
|
||||
try:
|
||||
del instance._raw[self.name] # type: ignore[misc]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return cast(T, value)
|
||||
|
||||
def _invalid_metadata(
|
||||
self, msg: str, cause: Optional[Exception] = None
|
||||
) -> InvalidMetadata:
|
||||
exc = InvalidMetadata(
|
||||
self.raw_name, msg.format_map({"field": repr(self.raw_name)})
|
||||
)
|
||||
exc.__cause__ = cause
|
||||
return exc
|
||||
|
||||
def _process_metadata_version(self, value: str) -> _MetadataVersion:
|
||||
# Implicitly makes Metadata-Version required.
|
||||
if value not in _VALID_METADATA_VERSIONS:
|
||||
raise self._invalid_metadata(f"{value!r} is not a valid metadata version")
|
||||
return cast(_MetadataVersion, value)
|
||||
|
||||
def _process_name(self, value: str) -> str:
|
||||
if not value:
|
||||
raise self._invalid_metadata("{field} is a required field")
|
||||
# Validate the name as a side-effect.
|
||||
try:
|
||||
utils.canonicalize_name(value, validate=True)
|
||||
except utils.InvalidName as exc:
|
||||
raise self._invalid_metadata(
|
||||
f"{value!r} is invalid for {{field}}", cause=exc
|
||||
)
|
||||
else:
|
||||
return value
|
||||
|
||||
def _process_version(self, value: str) -> version_module.Version:
|
||||
if not value:
|
||||
raise self._invalid_metadata("{field} is a required field")
|
||||
try:
|
||||
return version_module.parse(value)
|
||||
except version_module.InvalidVersion as exc:
|
||||
raise self._invalid_metadata(
|
||||
f"{value!r} is invalid for {{field}}", cause=exc
|
||||
)
|
||||
|
||||
def _process_summary(self, value: str) -> str:
|
||||
"""Check the field contains no newlines."""
|
||||
if "\n" in value:
|
||||
raise self._invalid_metadata("{field} must be a single line")
|
||||
return value
|
||||
|
||||
def _process_description_content_type(self, value: str) -> str:
|
||||
content_types = {"text/plain", "text/x-rst", "text/markdown"}
|
||||
message = email.message.EmailMessage()
|
||||
message["content-type"] = value
|
||||
|
||||
content_type, parameters = (
|
||||
# Defaults to `text/plain` if parsing failed.
|
||||
message.get_content_type().lower(),
|
||||
message["content-type"].params,
|
||||
)
|
||||
# Check if content-type is valid or defaulted to `text/plain` and thus was
|
||||
# not parseable.
|
||||
if content_type not in content_types or content_type not in value.lower():
|
||||
raise self._invalid_metadata(
|
||||
f"{{field}} must be one of {list(content_types)}, not {value!r}"
|
||||
)
|
||||
|
||||
if (charset := parameters.get("charset", "UTF-8")) != "UTF-8":
|
||||
raise self._invalid_metadata(
|
||||
f"{{field}} can only specify the UTF-8 charset, not {list(charset)}"
|
||||
)
|
||||
|
||||
markdown_variants = {"GFM", "CommonMark"}
|
||||
variant = parameters.get("variant", "GFM") # Use an acceptable default.
|
||||
if content_type == "text/markdown" and variant not in markdown_variants:
|
||||
raise self._invalid_metadata(
|
||||
f"valid Markdown variants for {{field}} are {list(markdown_variants)}, "
|
||||
f"not {variant!r}",
|
||||
)
|
||||
return value
|
||||
|
||||
def _process_dynamic(self, value: List[str]) -> List[str]:
|
||||
for dynamic_field in map(str.lower, value):
|
||||
if dynamic_field in {"name", "version", "metadata-version"}:
|
||||
raise self._invalid_metadata(
|
||||
f"{value!r} is not allowed as a dynamic field"
|
||||
)
|
||||
elif dynamic_field not in _EMAIL_TO_RAW_MAPPING:
|
||||
raise self._invalid_metadata(f"{value!r} is not a valid dynamic field")
|
||||
return list(map(str.lower, value))
|
||||
|
||||
def _process_provides_extra(
|
||||
self,
|
||||
value: List[str],
|
||||
) -> List[utils.NormalizedName]:
|
||||
normalized_names = []
|
||||
try:
|
||||
for name in value:
|
||||
normalized_names.append(utils.canonicalize_name(name, validate=True))
|
||||
except utils.InvalidName as exc:
|
||||
raise self._invalid_metadata(
|
||||
f"{name!r} is invalid for {{field}}", cause=exc
|
||||
)
|
||||
else:
|
||||
return normalized_names
|
||||
|
||||
def _process_requires_python(self, value: str) -> specifiers.SpecifierSet:
|
||||
try:
|
||||
return specifiers.SpecifierSet(value)
|
||||
except specifiers.InvalidSpecifier as exc:
|
||||
raise self._invalid_metadata(
|
||||
f"{value!r} is invalid for {{field}}", cause=exc
|
||||
)
|
||||
|
||||
def _process_requires_dist(
|
||||
self,
|
||||
value: List[str],
|
||||
) -> List[requirements.Requirement]:
|
||||
reqs = []
|
||||
try:
|
||||
for req in value:
|
||||
reqs.append(requirements.Requirement(req))
|
||||
except requirements.InvalidRequirement as exc:
|
||||
raise self._invalid_metadata(f"{req!r} is invalid for {{field}}", cause=exc)
|
||||
else:
|
||||
return reqs
|
||||
|
||||
|
||||
class Metadata:
|
||||
"""Representation of distribution metadata.
|
||||
|
||||
Compared to :class:`RawMetadata`, this class provides objects representing
|
||||
metadata fields instead of only using built-in types. Any invalid metadata
|
||||
will cause :exc:`InvalidMetadata` to be raised (with a
|
||||
:py:attr:`~BaseException.__cause__` attribute as appropriate).
|
||||
"""
|
||||
|
||||
_raw: RawMetadata
|
||||
|
||||
@classmethod
|
||||
def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> "Metadata":
|
||||
"""Create an instance from :class:`RawMetadata`.
|
||||
|
||||
If *validate* is true, all metadata will be validated. All exceptions
|
||||
related to validation will be gathered and raised as an :class:`ExceptionGroup`.
|
||||
"""
|
||||
ins = cls()
|
||||
ins._raw = data.copy() # Mutations occur due to caching enriched values.
|
||||
|
||||
if validate:
|
||||
exceptions: List[Exception] = []
|
||||
try:
|
||||
metadata_version = ins.metadata_version
|
||||
metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version)
|
||||
except InvalidMetadata as metadata_version_exc:
|
||||
exceptions.append(metadata_version_exc)
|
||||
metadata_version = None
|
||||
|
||||
# Make sure to check for the fields that are present, the required
|
||||
# fields (so their absence can be reported).
|
||||
fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS
|
||||
# Remove fields that have already been checked.
|
||||
fields_to_check -= {"metadata_version"}
|
||||
|
||||
for key in fields_to_check:
|
||||
try:
|
||||
if metadata_version:
|
||||
# Can't use getattr() as that triggers descriptor protocol which
|
||||
# will fail due to no value for the instance argument.
|
||||
try:
|
||||
field_metadata_version = cls.__dict__[key].added
|
||||
except KeyError:
|
||||
exc = InvalidMetadata(key, f"unrecognized field: {key!r}")
|
||||
exceptions.append(exc)
|
||||
continue
|
||||
field_age = _VALID_METADATA_VERSIONS.index(
|
||||
field_metadata_version
|
||||
)
|
||||
if field_age > metadata_age:
|
||||
field = _RAW_TO_EMAIL_MAPPING[key]
|
||||
exc = InvalidMetadata(
|
||||
field,
|
||||
"{field} introduced in metadata version "
|
||||
"{field_metadata_version}, not {metadata_version}",
|
||||
)
|
||||
exceptions.append(exc)
|
||||
continue
|
||||
getattr(ins, key)
|
||||
except InvalidMetadata as exc:
|
||||
exceptions.append(exc)
|
||||
|
||||
if exceptions:
|
||||
raise ExceptionGroup("invalid metadata", exceptions)
|
||||
|
||||
return ins
|
||||
|
||||
@classmethod
|
||||
def from_email(
|
||||
cls, data: Union[bytes, str], *, validate: bool = True
|
||||
) -> "Metadata":
|
||||
"""Parse metadata from email headers.
|
||||
|
||||
If *validate* is true, the metadata will be validated. All exceptions
|
||||
related to validation will be gathered and raised as an :class:`ExceptionGroup`.
|
||||
"""
|
||||
raw, unparsed = parse_email(data)
|
||||
|
||||
if validate:
|
||||
exceptions: list[Exception] = []
|
||||
for unparsed_key in unparsed:
|
||||
if unparsed_key in _EMAIL_TO_RAW_MAPPING:
|
||||
message = f"{unparsed_key!r} has invalid data"
|
||||
else:
|
||||
message = f"unrecognized field: {unparsed_key!r}"
|
||||
exceptions.append(InvalidMetadata(unparsed_key, message))
|
||||
|
||||
if exceptions:
|
||||
raise ExceptionGroup("unparsed", exceptions)
|
||||
|
||||
try:
|
||||
return cls.from_raw(raw, validate=validate)
|
||||
except ExceptionGroup as exc_group:
|
||||
raise ExceptionGroup(
|
||||
"invalid or unparsed metadata", exc_group.exceptions
|
||||
) from None
|
||||
|
||||
metadata_version: _Validator[_MetadataVersion] = _Validator()
|
||||
""":external:ref:`core-metadata-metadata-version`
|
||||
(required; validated to be a valid metadata version)"""
|
||||
name: _Validator[str] = _Validator()
|
||||
""":external:ref:`core-metadata-name`
|
||||
(required; validated using :func:`~packaging.utils.canonicalize_name` and its
|
||||
*validate* parameter)"""
|
||||
version: _Validator[version_module.Version] = _Validator()
|
||||
""":external:ref:`core-metadata-version` (required)"""
|
||||
dynamic: _Validator[Optional[List[str]]] = _Validator(
|
||||
added="2.2",
|
||||
)
|
||||
""":external:ref:`core-metadata-dynamic`
|
||||
(validated against core metadata field names and lowercased)"""
|
||||
platforms: _Validator[Optional[List[str]]] = _Validator()
|
||||
""":external:ref:`core-metadata-platform`"""
|
||||
supported_platforms: _Validator[Optional[List[str]]] = _Validator(added="1.1")
|
||||
""":external:ref:`core-metadata-supported-platform`"""
|
||||
summary: _Validator[Optional[str]] = _Validator()
|
||||
""":external:ref:`core-metadata-summary` (validated to contain no newlines)"""
|
||||
description: _Validator[Optional[str]] = _Validator() # TODO 2.1: can be in body
|
||||
""":external:ref:`core-metadata-description`"""
|
||||
description_content_type: _Validator[Optional[str]] = _Validator(added="2.1")
|
||||
""":external:ref:`core-metadata-description-content-type` (validated)"""
|
||||
keywords: _Validator[Optional[List[str]]] = _Validator()
|
||||
""":external:ref:`core-metadata-keywords`"""
|
||||
home_page: _Validator[Optional[str]] = _Validator()
|
||||
""":external:ref:`core-metadata-home-page`"""
|
||||
download_url: _Validator[Optional[str]] = _Validator(added="1.1")
|
||||
""":external:ref:`core-metadata-download-url`"""
|
||||
author: _Validator[Optional[str]] = _Validator()
|
||||
""":external:ref:`core-metadata-author`"""
|
||||
author_email: _Validator[Optional[str]] = _Validator()
|
||||
""":external:ref:`core-metadata-author-email`"""
|
||||
maintainer: _Validator[Optional[str]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-maintainer`"""
|
||||
maintainer_email: _Validator[Optional[str]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-maintainer-email`"""
|
||||
license: _Validator[Optional[str]] = _Validator()
|
||||
""":external:ref:`core-metadata-license`"""
|
||||
classifiers: _Validator[Optional[List[str]]] = _Validator(added="1.1")
|
||||
""":external:ref:`core-metadata-classifier`"""
|
||||
requires_dist: _Validator[Optional[List[requirements.Requirement]]] = _Validator(
|
||||
added="1.2"
|
||||
)
|
||||
""":external:ref:`core-metadata-requires-dist`"""
|
||||
requires_python: _Validator[Optional[specifiers.SpecifierSet]] = _Validator(
|
||||
added="1.2"
|
||||
)
|
||||
""":external:ref:`core-metadata-requires-python`"""
|
||||
# Because `Requires-External` allows for non-PEP 440 version specifiers, we
|
||||
# don't do any processing on the values.
|
||||
requires_external: _Validator[Optional[List[str]]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-requires-external`"""
|
||||
project_urls: _Validator[Optional[Dict[str, str]]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-project-url`"""
|
||||
# PEP 685 lets us raise an error if an extra doesn't pass `Name` validation
|
||||
# regardless of metadata version.
|
||||
provides_extra: _Validator[Optional[List[utils.NormalizedName]]] = _Validator(
|
||||
added="2.1",
|
||||
)
|
||||
""":external:ref:`core-metadata-provides-extra`"""
|
||||
provides_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-provides-dist`"""
|
||||
obsoletes_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2")
|
||||
""":external:ref:`core-metadata-obsoletes-dist`"""
|
||||
requires: _Validator[Optional[List[str]]] = _Validator(added="1.1")
|
||||
"""``Requires`` (deprecated)"""
|
||||
provides: _Validator[Optional[List[str]]] = _Validator(added="1.1")
|
||||
"""``Provides`` (deprecated)"""
|
||||
obsoletes: _Validator[Optional[List[str]]] = _Validator(added="1.1")
|
||||
"""``Obsoletes`` (deprecated)"""
|
||||
0
electron/node_modules/node-gyp/gyp/pylib/packaging/py.typed
generated
vendored
Normal file
0
electron/node_modules/node-gyp/gyp/pylib/packaging/py.typed
generated
vendored
Normal file
90
electron/node_modules/node-gyp/gyp/pylib/packaging/requirements.py
generated
vendored
Normal file
90
electron/node_modules/node-gyp/gyp/pylib/packaging/requirements.py
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from typing import Any, Iterator, Optional, Set
|
||||
|
||||
from ._parser import parse_requirement as _parse_requirement
|
||||
from ._tokenizer import ParserSyntaxError
|
||||
from .markers import Marker, _normalize_extra_values
|
||||
from .specifiers import SpecifierSet
|
||||
from .utils import canonicalize_name
|
||||
|
||||
|
||||
class InvalidRequirement(ValueError):
|
||||
"""
|
||||
An invalid requirement was found, users should refer to PEP 508.
|
||||
"""
|
||||
|
||||
|
||||
class Requirement:
|
||||
"""Parse a requirement.
|
||||
|
||||
Parse a given requirement string into its parts, such as name, specifier,
|
||||
URL, and extras. Raises InvalidRequirement on a badly-formed requirement
|
||||
string.
|
||||
"""
|
||||
|
||||
# TODO: Can we test whether something is contained within a requirement?
|
||||
# If so how do we do that? Do we need to test against the _name_ of
|
||||
# the thing as well as the version? What about the markers?
|
||||
# TODO: Can we normalize the name and extra name?
|
||||
|
||||
def __init__(self, requirement_string: str) -> None:
|
||||
try:
|
||||
parsed = _parse_requirement(requirement_string)
|
||||
except ParserSyntaxError as e:
|
||||
raise InvalidRequirement(str(e)) from e
|
||||
|
||||
self.name: str = parsed.name
|
||||
self.url: Optional[str] = parsed.url or None
|
||||
self.extras: Set[str] = set(parsed.extras if parsed.extras else [])
|
||||
self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)
|
||||
self.marker: Optional[Marker] = None
|
||||
if parsed.marker is not None:
|
||||
self.marker = Marker.__new__(Marker)
|
||||
self.marker._markers = _normalize_extra_values(parsed.marker)
|
||||
|
||||
def _iter_parts(self, name: str) -> Iterator[str]:
|
||||
yield name
|
||||
|
||||
if self.extras:
|
||||
formatted_extras = ",".join(sorted(self.extras))
|
||||
yield f"[{formatted_extras}]"
|
||||
|
||||
if self.specifier:
|
||||
yield str(self.specifier)
|
||||
|
||||
if self.url:
|
||||
yield f"@ {self.url}"
|
||||
if self.marker:
|
||||
yield " "
|
||||
|
||||
if self.marker:
|
||||
yield f"; {self.marker}"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "".join(self._iter_parts(self.name))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Requirement('{self}')>"
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(
|
||||
(
|
||||
self.__class__.__name__,
|
||||
*self._iter_parts(canonicalize_name(self.name)),
|
||||
)
|
||||
)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, Requirement):
|
||||
return NotImplemented
|
||||
|
||||
return (
|
||||
canonicalize_name(self.name) == canonicalize_name(other.name)
|
||||
and self.extras == other.extras
|
||||
and self.specifier == other.specifier
|
||||
and self.url == other.url
|
||||
and self.marker == other.marker
|
||||
)
|
||||
1030
electron/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py
generated
vendored
Normal file
1030
electron/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
541
electron/node_modules/node-gyp/gyp/pylib/packaging/tags.py
generated
vendored
Normal file
541
electron/node_modules/node-gyp/gyp/pylib/packaging/tags.py
generated
vendored
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
import logging
|
||||
import platform
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
from importlib.machinery import EXTENSION_SUFFIXES
|
||||
from typing import (
|
||||
Dict,
|
||||
FrozenSet,
|
||||
Iterable,
|
||||
Iterator,
|
||||
List,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
|
||||
from . import _manylinux, _musllinux
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PythonVersion = Sequence[int]
|
||||
MacVersion = Tuple[int, int]
|
||||
|
||||
INTERPRETER_SHORT_NAMES: Dict[str, str] = {
|
||||
"python": "py", # Generic.
|
||||
"cpython": "cp",
|
||||
"pypy": "pp",
|
||||
"ironpython": "ip",
|
||||
"jython": "jy",
|
||||
}
|
||||
|
||||
|
||||
_32_BIT_INTERPRETER = struct.calcsize("P") == 4
|
||||
|
||||
|
||||
class Tag:
|
||||
"""
|
||||
A representation of the tag triple for a wheel.
|
||||
|
||||
Instances are considered immutable and thus are hashable. Equality checking
|
||||
is also supported.
|
||||
"""
|
||||
|
||||
__slots__ = ["_interpreter", "_abi", "_platform", "_hash"]
|
||||
|
||||
def __init__(self, interpreter: str, abi: str, platform: str) -> None:
|
||||
self._interpreter = interpreter.lower()
|
||||
self._abi = abi.lower()
|
||||
self._platform = platform.lower()
|
||||
# The __hash__ of every single element in a Set[Tag] will be evaluated each time
|
||||
# that a set calls its `.disjoint()` method, which may be called hundreds of
|
||||
# times when scanning a page of links for packages with tags matching that
|
||||
# Set[Tag]. Pre-computing the value here produces significant speedups for
|
||||
# downstream consumers.
|
||||
self._hash = hash((self._interpreter, self._abi, self._platform))
|
||||
|
||||
@property
|
||||
def interpreter(self) -> str:
|
||||
return self._interpreter
|
||||
|
||||
@property
|
||||
def abi(self) -> str:
|
||||
return self._abi
|
||||
|
||||
@property
|
||||
def platform(self) -> str:
|
||||
return self._platform
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, Tag):
|
||||
return NotImplemented
|
||||
|
||||
return (
|
||||
(self._hash == other._hash) # Short-circuit ASAP for perf reasons.
|
||||
and (self._platform == other._platform)
|
||||
and (self._abi == other._abi)
|
||||
and (self._interpreter == other._interpreter)
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return self._hash
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self._interpreter}-{self._abi}-{self._platform}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self} @ {id(self)}>"
|
||||
|
||||
|
||||
def parse_tag(tag: str) -> FrozenSet[Tag]:
|
||||
"""
|
||||
Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances.
|
||||
|
||||
Returning a set is required due to the possibility that the tag is a
|
||||
compressed tag set.
|
||||
"""
|
||||
tags = set()
|
||||
interpreters, abis, platforms = tag.split("-")
|
||||
for interpreter in interpreters.split("."):
|
||||
for abi in abis.split("."):
|
||||
for platform_ in platforms.split("."):
|
||||
tags.add(Tag(interpreter, abi, platform_))
|
||||
return frozenset(tags)
|
||||
|
||||
|
||||
def _get_config_var(name: str, warn: bool = False) -> Union[int, str, None]:
|
||||
value: Union[int, str, None] = sysconfig.get_config_var(name)
|
||||
if value is None and warn:
|
||||
logger.debug(
|
||||
"Config variable '%s' is unset, Python ABI tag may be incorrect", name
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
def _normalize_string(string: str) -> str:
|
||||
return string.replace(".", "_").replace("-", "_").replace(" ", "_")
|
||||
|
||||
|
||||
def _abi3_applies(python_version: PythonVersion) -> bool:
|
||||
"""
|
||||
Determine if the Python version supports abi3.
|
||||
"""
|
||||
return len(python_version) > 1
|
||||
|
||||
|
||||
def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]:
|
||||
py_version = tuple(py_version) # To allow for version comparison.
|
||||
abis = []
|
||||
version = _version_nodot(py_version[:2])
|
||||
debug = pymalloc = ucs4 = ""
|
||||
with_debug = _get_config_var("Py_DEBUG", warn)
|
||||
has_refcount = hasattr(sys, "gettotalrefcount")
|
||||
# Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
|
||||
# extension modules is the best option.
|
||||
# https://github.com/pypa/pip/issues/3383#issuecomment-173267692
|
||||
has_ext = "_d.pyd" in EXTENSION_SUFFIXES
|
||||
if with_debug or (with_debug is None and (has_refcount or has_ext)):
|
||||
debug = "d"
|
||||
if debug:
|
||||
# Debug builds can also load "normal" extension modules.
|
||||
# We can also assume no UCS-4 or pymalloc requirement.
|
||||
abis.append(f"cp{version}")
|
||||
abis.insert(
|
||||
0,
|
||||
"cp{version}{debug}{pymalloc}{ucs4}".format(
|
||||
version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
|
||||
),
|
||||
)
|
||||
return abis
|
||||
|
||||
|
||||
def cpython_tags(
|
||||
python_version: Optional[PythonVersion] = None,
|
||||
abis: Optional[Iterable[str]] = None,
|
||||
platforms: Optional[Iterable[str]] = None,
|
||||
*,
|
||||
warn: bool = False,
|
||||
) -> Iterator[Tag]:
|
||||
"""
|
||||
Yields the tags for a CPython interpreter.
|
||||
|
||||
The tags consist of:
|
||||
- cp<python_version>-<abi>-<platform>
|
||||
- cp<python_version>-abi3-<platform>
|
||||
- cp<python_version>-none-<platform>
|
||||
- cp<less than python_version>-abi3-<platform> # Older Python versions down to 3.2.
|
||||
|
||||
If python_version only specifies a major version then user-provided ABIs and
|
||||
the 'none' ABItag will be used.
|
||||
|
||||
If 'abi3' or 'none' are specified in 'abis' then they will be yielded at
|
||||
their normal position and not at the beginning.
|
||||
"""
|
||||
if not python_version:
|
||||
python_version = sys.version_info[:2]
|
||||
|
||||
interpreter = f"cp{_version_nodot(python_version[:2])}"
|
||||
|
||||
if abis is None:
|
||||
if len(python_version) > 1:
|
||||
abis = _cpython_abis(python_version, warn)
|
||||
else:
|
||||
abis = []
|
||||
abis = list(abis)
|
||||
# 'abi3' and 'none' are explicitly handled later.
|
||||
for explicit_abi in ("abi3", "none"):
|
||||
try:
|
||||
abis.remove(explicit_abi)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
platforms = list(platforms or platform_tags())
|
||||
for abi in abis:
|
||||
for platform_ in platforms:
|
||||
yield Tag(interpreter, abi, platform_)
|
||||
if _abi3_applies(python_version):
|
||||
yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms)
|
||||
yield from (Tag(interpreter, "none", platform_) for platform_ in platforms)
|
||||
|
||||
if _abi3_applies(python_version):
|
||||
for minor_version in range(python_version[1] - 1, 1, -1):
|
||||
for platform_ in platforms:
|
||||
interpreter = "cp{version}".format(
|
||||
version=_version_nodot((python_version[0], minor_version))
|
||||
)
|
||||
yield Tag(interpreter, "abi3", platform_)
|
||||
|
||||
|
||||
def _generic_abi() -> List[str]:
|
||||
"""
|
||||
Return the ABI tag based on EXT_SUFFIX.
|
||||
"""
|
||||
# The following are examples of `EXT_SUFFIX`.
|
||||
# We want to keep the parts which are related to the ABI and remove the
|
||||
# parts which are related to the platform:
|
||||
# - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310
|
||||
# - mac: '.cpython-310-darwin.so' => cp310
|
||||
# - win: '.cp310-win_amd64.pyd' => cp310
|
||||
# - win: '.pyd' => cp37 (uses _cpython_abis())
|
||||
# - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73
|
||||
# - graalpy: '.graalpy-38-native-x86_64-darwin.dylib'
|
||||
# => graalpy_38_native
|
||||
|
||||
ext_suffix = _get_config_var("EXT_SUFFIX", warn=True)
|
||||
if not isinstance(ext_suffix, str) or ext_suffix[0] != ".":
|
||||
raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")
|
||||
parts = ext_suffix.split(".")
|
||||
if len(parts) < 3:
|
||||
# CPython3.7 and earlier uses ".pyd" on Windows.
|
||||
return _cpython_abis(sys.version_info[:2])
|
||||
soabi = parts[1]
|
||||
if soabi.startswith("cpython"):
|
||||
# non-windows
|
||||
abi = "cp" + soabi.split("-")[1]
|
||||
elif soabi.startswith("cp"):
|
||||
# windows
|
||||
abi = soabi.split("-")[0]
|
||||
elif soabi.startswith("pypy"):
|
||||
abi = "-".join(soabi.split("-")[:2])
|
||||
elif soabi.startswith("graalpy"):
|
||||
abi = "-".join(soabi.split("-")[:3])
|
||||
elif soabi:
|
||||
# pyston, ironpython, others?
|
||||
abi = soabi
|
||||
else:
|
||||
return []
|
||||
return [_normalize_string(abi)]
|
||||
|
||||
|
||||
def generic_tags(
|
||||
interpreter: Optional[str] = None,
|
||||
abis: Optional[Iterable[str]] = None,
|
||||
platforms: Optional[Iterable[str]] = None,
|
||||
*,
|
||||
warn: bool = False,
|
||||
) -> Iterator[Tag]:
|
||||
"""
|
||||
Yields the tags for a generic interpreter.
|
||||
|
||||
The tags consist of:
|
||||
- <interpreter>-<abi>-<platform>
|
||||
|
||||
The "none" ABI will be added if it was not explicitly provided.
|
||||
"""
|
||||
if not interpreter:
|
||||
interp_name = interpreter_name()
|
||||
interp_version = interpreter_version(warn=warn)
|
||||
interpreter = "".join([interp_name, interp_version])
|
||||
if abis is None:
|
||||
abis = _generic_abi()
|
||||
else:
|
||||
abis = list(abis)
|
||||
platforms = list(platforms or platform_tags())
|
||||
if "none" not in abis:
|
||||
abis.append("none")
|
||||
for abi in abis:
|
||||
for platform_ in platforms:
|
||||
yield Tag(interpreter, abi, platform_)
|
||||
|
||||
|
||||
def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]:
|
||||
"""
|
||||
Yields Python versions in descending order.
|
||||
|
||||
After the latest version, the major-only version will be yielded, and then
|
||||
all previous versions of that major version.
|
||||
"""
|
||||
if len(py_version) > 1:
|
||||
yield f"py{_version_nodot(py_version[:2])}"
|
||||
yield f"py{py_version[0]}"
|
||||
if len(py_version) > 1:
|
||||
for minor in range(py_version[1] - 1, -1, -1):
|
||||
yield f"py{_version_nodot((py_version[0], minor))}"
|
||||
|
||||
|
||||
def compatible_tags(
|
||||
python_version: Optional[PythonVersion] = None,
|
||||
interpreter: Optional[str] = None,
|
||||
platforms: Optional[Iterable[str]] = None,
|
||||
) -> Iterator[Tag]:
|
||||
"""
|
||||
Yields the sequence of tags that are compatible with a specific version of Python.
|
||||
|
||||
The tags consist of:
|
||||
- py*-none-<platform>
|
||||
- <interpreter>-none-any # ... if `interpreter` is provided.
|
||||
- py*-none-any
|
||||
"""
|
||||
if not python_version:
|
||||
python_version = sys.version_info[:2]
|
||||
platforms = list(platforms or platform_tags())
|
||||
for version in _py_interpreter_range(python_version):
|
||||
for platform_ in platforms:
|
||||
yield Tag(version, "none", platform_)
|
||||
if interpreter:
|
||||
yield Tag(interpreter, "none", "any")
|
||||
for version in _py_interpreter_range(python_version):
|
||||
yield Tag(version, "none", "any")
|
||||
|
||||
|
||||
def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str:
|
||||
if not is_32bit:
|
||||
return arch
|
||||
|
||||
if arch.startswith("ppc"):
|
||||
return "ppc"
|
||||
|
||||
return "i386"
|
||||
|
||||
|
||||
def _mac_binary_formats(version: MacVersion, cpu_arch: str) -> List[str]:
|
||||
formats = [cpu_arch]
|
||||
if cpu_arch == "x86_64":
|
||||
if version < (10, 4):
|
||||
return []
|
||||
formats.extend(["intel", "fat64", "fat32"])
|
||||
|
||||
elif cpu_arch == "i386":
|
||||
if version < (10, 4):
|
||||
return []
|
||||
formats.extend(["intel", "fat32", "fat"])
|
||||
|
||||
elif cpu_arch == "ppc64":
|
||||
# TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
|
||||
if version > (10, 5) or version < (10, 4):
|
||||
return []
|
||||
formats.append("fat64")
|
||||
|
||||
elif cpu_arch == "ppc":
|
||||
if version > (10, 6):
|
||||
return []
|
||||
formats.extend(["fat32", "fat"])
|
||||
|
||||
if cpu_arch in {"arm64", "x86_64"}:
|
||||
formats.append("universal2")
|
||||
|
||||
if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}:
|
||||
formats.append("universal")
|
||||
|
||||
return formats
|
||||
|
||||
|
||||
def mac_platforms(
|
||||
version: Optional[MacVersion] = None, arch: Optional[str] = None
|
||||
) -> Iterator[str]:
|
||||
"""
|
||||
Yields the platform tags for a macOS system.
|
||||
|
||||
The `version` parameter is a two-item tuple specifying the macOS version to
|
||||
generate platform tags for. The `arch` parameter is the CPU architecture to
|
||||
generate platform tags for. Both parameters default to the appropriate value
|
||||
for the current system.
|
||||
"""
|
||||
version_str, _, cpu_arch = platform.mac_ver()
|
||||
if version is None:
|
||||
version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2])))
|
||||
if version == (10, 16):
|
||||
# When built against an older macOS SDK, Python will report macOS 10.16
|
||||
# instead of the real version.
|
||||
version_str = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-sS",
|
||||
"-c",
|
||||
"import platform; print(platform.mac_ver()[0])",
|
||||
],
|
||||
check=True,
|
||||
env={"SYSTEM_VERSION_COMPAT": "0"},
|
||||
stdout=subprocess.PIPE,
|
||||
text=True,
|
||||
).stdout
|
||||
version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2])))
|
||||
else:
|
||||
version = version
|
||||
if arch is None:
|
||||
arch = _mac_arch(cpu_arch)
|
||||
else:
|
||||
arch = arch
|
||||
|
||||
if (10, 0) <= version and version < (11, 0):
|
||||
# Prior to Mac OS 11, each yearly release of Mac OS bumped the
|
||||
# "minor" version number. The major version was always 10.
|
||||
for minor_version in range(version[1], -1, -1):
|
||||
compat_version = 10, minor_version
|
||||
binary_formats = _mac_binary_formats(compat_version, arch)
|
||||
for binary_format in binary_formats:
|
||||
yield "macosx_{major}_{minor}_{binary_format}".format(
|
||||
major=10, minor=minor_version, binary_format=binary_format
|
||||
)
|
||||
|
||||
if version >= (11, 0):
|
||||
# Starting with Mac OS 11, each yearly release bumps the major version
|
||||
# number. The minor versions are now the midyear updates.
|
||||
for major_version in range(version[0], 10, -1):
|
||||
compat_version = major_version, 0
|
||||
binary_formats = _mac_binary_formats(compat_version, arch)
|
||||
for binary_format in binary_formats:
|
||||
yield "macosx_{major}_{minor}_{binary_format}".format(
|
||||
major=major_version, minor=0, binary_format=binary_format
|
||||
)
|
||||
|
||||
if version >= (11, 0):
|
||||
# Mac OS 11 on x86_64 is compatible with binaries from previous releases.
|
||||
# Arm64 support was introduced in 11.0, so no Arm binaries from previous
|
||||
# releases exist.
|
||||
#
|
||||
# However, the "universal2" binary format can have a
|
||||
# macOS version earlier than 11.0 when the x86_64 part of the binary supports
|
||||
# that version of macOS.
|
||||
if arch == "x86_64":
|
||||
for minor_version in range(16, 3, -1):
|
||||
compat_version = 10, minor_version
|
||||
binary_formats = _mac_binary_formats(compat_version, arch)
|
||||
for binary_format in binary_formats:
|
||||
yield "macosx_{major}_{minor}_{binary_format}".format(
|
||||
major=compat_version[0],
|
||||
minor=compat_version[1],
|
||||
binary_format=binary_format,
|
||||
)
|
||||
else:
|
||||
for minor_version in range(16, 3, -1):
|
||||
compat_version = 10, minor_version
|
||||
binary_format = "universal2"
|
||||
yield "macosx_{major}_{minor}_{binary_format}".format(
|
||||
major=compat_version[0],
|
||||
minor=compat_version[1],
|
||||
binary_format=binary_format,
|
||||
)
|
||||
|
||||
|
||||
def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]:
|
||||
linux = _normalize_string(sysconfig.get_platform())
|
||||
if not linux.startswith("linux_"):
|
||||
# we should never be here, just yield the sysconfig one and return
|
||||
yield linux
|
||||
return
|
||||
if is_32bit:
|
||||
if linux == "linux_x86_64":
|
||||
linux = "linux_i686"
|
||||
elif linux == "linux_aarch64":
|
||||
linux = "linux_armv8l"
|
||||
_, arch = linux.split("_", 1)
|
||||
archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch])
|
||||
yield from _manylinux.platform_tags(archs)
|
||||
yield from _musllinux.platform_tags(archs)
|
||||
for arch in archs:
|
||||
yield f"linux_{arch}"
|
||||
|
||||
|
||||
def _generic_platforms() -> Iterator[str]:
|
||||
yield _normalize_string(sysconfig.get_platform())
|
||||
|
||||
|
||||
def platform_tags() -> Iterator[str]:
|
||||
"""
|
||||
Provides the platform tags for this installation.
|
||||
"""
|
||||
if platform.system() == "Darwin":
|
||||
return mac_platforms()
|
||||
elif platform.system() == "Linux":
|
||||
return _linux_platforms()
|
||||
else:
|
||||
return _generic_platforms()
|
||||
|
||||
|
||||
def interpreter_name() -> str:
|
||||
"""
|
||||
Returns the name of the running interpreter.
|
||||
|
||||
Some implementations have a reserved, two-letter abbreviation which will
|
||||
be returned when appropriate.
|
||||
"""
|
||||
name = sys.implementation.name
|
||||
return INTERPRETER_SHORT_NAMES.get(name) or name
|
||||
|
||||
|
||||
def interpreter_version(*, warn: bool = False) -> str:
|
||||
"""
|
||||
Returns the version of the running interpreter.
|
||||
"""
|
||||
version = _get_config_var("py_version_nodot", warn=warn)
|
||||
if version:
|
||||
version = str(version)
|
||||
else:
|
||||
version = _version_nodot(sys.version_info[:2])
|
||||
return version
|
||||
|
||||
|
||||
def _version_nodot(version: PythonVersion) -> str:
|
||||
return "".join(map(str, version))
|
||||
|
||||
|
||||
def sys_tags(*, warn: bool = False) -> Iterator[Tag]:
|
||||
"""
|
||||
Returns the sequence of tag triples for the running interpreter.
|
||||
|
||||
The order of the sequence corresponds to priority order for the
|
||||
interpreter, from most to least important.
|
||||
"""
|
||||
|
||||
interp_name = interpreter_name()
|
||||
if interp_name == "cp":
|
||||
yield from cpython_tags(warn=warn)
|
||||
else:
|
||||
yield from generic_tags()
|
||||
|
||||
if interp_name == "pp":
|
||||
interp = "pp3"
|
||||
elif interp_name == "cp":
|
||||
interp = "cp" + interpreter_version(warn=warn)
|
||||
else:
|
||||
interp = None
|
||||
yield from compatible_tags(interpreter=interp)
|
||||
172
electron/node_modules/node-gyp/gyp/pylib/packaging/utils.py
generated
vendored
Normal file
172
electron/node_modules/node-gyp/gyp/pylib/packaging/utils.py
generated
vendored
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
import re
|
||||
from typing import FrozenSet, NewType, Tuple, Union, cast
|
||||
|
||||
from .tags import Tag, parse_tag
|
||||
from .version import InvalidVersion, Version
|
||||
|
||||
BuildTag = Union[Tuple[()], Tuple[int, str]]
|
||||
NormalizedName = NewType("NormalizedName", str)
|
||||
|
||||
|
||||
class InvalidName(ValueError):
|
||||
"""
|
||||
An invalid distribution name; users should refer to the packaging user guide.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidWheelFilename(ValueError):
|
||||
"""
|
||||
An invalid wheel filename was found, users should refer to PEP 427.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidSdistFilename(ValueError):
|
||||
"""
|
||||
An invalid sdist filename was found, users should refer to the packaging user guide.
|
||||
"""
|
||||
|
||||
|
||||
# Core metadata spec for `Name`
|
||||
_validate_regex = re.compile(
|
||||
r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
|
||||
)
|
||||
_canonicalize_regex = re.compile(r"[-_.]+")
|
||||
_normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
|
||||
# PEP 427: The build number must start with a digit.
|
||||
_build_tag_regex = re.compile(r"(\d+)(.*)")
|
||||
|
||||
|
||||
def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
|
||||
if validate and not _validate_regex.match(name):
|
||||
raise InvalidName(f"name is invalid: {name!r}")
|
||||
# This is taken from PEP 503.
|
||||
value = _canonicalize_regex.sub("-", name).lower()
|
||||
return cast(NormalizedName, value)
|
||||
|
||||
|
||||
def is_normalized_name(name: str) -> bool:
|
||||
return _normalized_regex.match(name) is not None
|
||||
|
||||
|
||||
def canonicalize_version(
|
||||
version: Union[Version, str], *, strip_trailing_zero: bool = True
|
||||
) -> str:
|
||||
"""
|
||||
This is very similar to Version.__str__, but has one subtle difference
|
||||
with the way it handles the release segment.
|
||||
"""
|
||||
if isinstance(version, str):
|
||||
try:
|
||||
parsed = Version(version)
|
||||
except InvalidVersion:
|
||||
# Legacy versions cannot be normalized
|
||||
return version
|
||||
else:
|
||||
parsed = version
|
||||
|
||||
parts = []
|
||||
|
||||
# Epoch
|
||||
if parsed.epoch != 0:
|
||||
parts.append(f"{parsed.epoch}!")
|
||||
|
||||
# Release segment
|
||||
release_segment = ".".join(str(x) for x in parsed.release)
|
||||
if strip_trailing_zero:
|
||||
# NB: This strips trailing '.0's to normalize
|
||||
release_segment = re.sub(r"(\.0)+$", "", release_segment)
|
||||
parts.append(release_segment)
|
||||
|
||||
# Pre-release
|
||||
if parsed.pre is not None:
|
||||
parts.append("".join(str(x) for x in parsed.pre))
|
||||
|
||||
# Post-release
|
||||
if parsed.post is not None:
|
||||
parts.append(f".post{parsed.post}")
|
||||
|
||||
# Development release
|
||||
if parsed.dev is not None:
|
||||
parts.append(f".dev{parsed.dev}")
|
||||
|
||||
# Local version segment
|
||||
if parsed.local is not None:
|
||||
parts.append(f"+{parsed.local}")
|
||||
|
||||
return "".join(parts)
|
||||
|
||||
|
||||
def parse_wheel_filename(
|
||||
filename: str,
|
||||
) -> Tuple[NormalizedName, Version, BuildTag, FrozenSet[Tag]]:
|
||||
if not filename.endswith(".whl"):
|
||||
raise InvalidWheelFilename(
|
||||
f"Invalid wheel filename (extension must be '.whl'): {filename}"
|
||||
)
|
||||
|
||||
filename = filename[:-4]
|
||||
dashes = filename.count("-")
|
||||
if dashes not in (4, 5):
|
||||
raise InvalidWheelFilename(
|
||||
f"Invalid wheel filename (wrong number of parts): {filename}"
|
||||
)
|
||||
|
||||
parts = filename.split("-", dashes - 2)
|
||||
name_part = parts[0]
|
||||
# See PEP 427 for the rules on escaping the project name.
|
||||
if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
|
||||
raise InvalidWheelFilename(f"Invalid project name: {filename}")
|
||||
name = canonicalize_name(name_part)
|
||||
|
||||
try:
|
||||
version = Version(parts[1])
|
||||
except InvalidVersion as e:
|
||||
raise InvalidWheelFilename(
|
||||
f"Invalid wheel filename (invalid version): {filename}"
|
||||
) from e
|
||||
|
||||
if dashes == 5:
|
||||
build_part = parts[2]
|
||||
build_match = _build_tag_regex.match(build_part)
|
||||
if build_match is None:
|
||||
raise InvalidWheelFilename(
|
||||
f"Invalid build number: {build_part} in '{filename}'"
|
||||
)
|
||||
build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
|
||||
else:
|
||||
build = ()
|
||||
tags = parse_tag(parts[-1])
|
||||
return (name, version, build, tags)
|
||||
|
||||
|
||||
def parse_sdist_filename(filename: str) -> Tuple[NormalizedName, Version]:
|
||||
if filename.endswith(".tar.gz"):
|
||||
file_stem = filename[: -len(".tar.gz")]
|
||||
elif filename.endswith(".zip"):
|
||||
file_stem = filename[: -len(".zip")]
|
||||
else:
|
||||
raise InvalidSdistFilename(
|
||||
f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
|
||||
f" {filename}"
|
||||
)
|
||||
|
||||
# We are requiring a PEP 440 version, which cannot contain dashes,
|
||||
# so we split on the last dash.
|
||||
name_part, sep, version_part = file_stem.rpartition("-")
|
||||
if not sep:
|
||||
raise InvalidSdistFilename(f"Invalid sdist filename: {filename}")
|
||||
|
||||
name = canonicalize_name(name_part)
|
||||
|
||||
try:
|
||||
version = Version(version_part)
|
||||
except InvalidVersion as e:
|
||||
raise InvalidSdistFilename(
|
||||
f"Invalid sdist filename (invalid version): {filename}"
|
||||
) from e
|
||||
|
||||
return (name, version)
|
||||
563
electron/node_modules/node-gyp/gyp/pylib/packaging/version.py
generated
vendored
Normal file
563
electron/node_modules/node-gyp/gyp/pylib/packaging/version.py
generated
vendored
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
"""
|
||||
.. testsetup::
|
||||
|
||||
from packaging.version import parse, Version
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import re
|
||||
from typing import Any, Callable, NamedTuple, Optional, SupportsInt, Tuple, Union
|
||||
|
||||
from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType
|
||||
|
||||
__all__ = ["VERSION_PATTERN", "parse", "Version", "InvalidVersion"]
|
||||
|
||||
LocalType = Tuple[Union[int, str], ...]
|
||||
|
||||
CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, Tuple[str, int]]
|
||||
CmpLocalType = Union[
|
||||
NegativeInfinityType,
|
||||
Tuple[Union[Tuple[int, str], Tuple[NegativeInfinityType, Union[int, str]]], ...],
|
||||
]
|
||||
CmpKey = Tuple[
|
||||
int,
|
||||
Tuple[int, ...],
|
||||
CmpPrePostDevType,
|
||||
CmpPrePostDevType,
|
||||
CmpPrePostDevType,
|
||||
CmpLocalType,
|
||||
]
|
||||
VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool]
|
||||
|
||||
|
||||
class _Version(NamedTuple):
|
||||
epoch: int
|
||||
release: Tuple[int, ...]
|
||||
dev: Optional[Tuple[str, int]]
|
||||
pre: Optional[Tuple[str, int]]
|
||||
post: Optional[Tuple[str, int]]
|
||||
local: Optional[LocalType]
|
||||
|
||||
|
||||
def parse(version: str) -> "Version":
|
||||
"""Parse the given version string.
|
||||
|
||||
>>> parse('1.0.dev1')
|
||||
<Version('1.0.dev1')>
|
||||
|
||||
:param version: The version string to parse.
|
||||
:raises InvalidVersion: When the version string is not a valid version.
|
||||
"""
|
||||
return Version(version)
|
||||
|
||||
|
||||
class InvalidVersion(ValueError):
|
||||
"""Raised when a version string is not a valid version.
|
||||
|
||||
>>> Version("invalid")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
packaging.version.InvalidVersion: Invalid version: 'invalid'
|
||||
"""
|
||||
|
||||
|
||||
class _BaseVersion:
|
||||
_key: Tuple[Any, ...]
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self._key)
|
||||
|
||||
# Please keep the duplicated `isinstance` check
|
||||
# in the six comparisons hereunder
|
||||
# unless you find a way to avoid adding overhead function calls.
|
||||
def __lt__(self, other: "_BaseVersion") -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key < other._key
|
||||
|
||||
def __le__(self, other: "_BaseVersion") -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key <= other._key
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key == other._key
|
||||
|
||||
def __ge__(self, other: "_BaseVersion") -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key >= other._key
|
||||
|
||||
def __gt__(self, other: "_BaseVersion") -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key > other._key
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if not isinstance(other, _BaseVersion):
|
||||
return NotImplemented
|
||||
|
||||
return self._key != other._key
|
||||
|
||||
|
||||
# Deliberately not anchored to the start and end of the string, to make it
|
||||
# easier for 3rd party code to reuse
|
||||
_VERSION_PATTERN = r"""
|
||||
v?
|
||||
(?:
|
||||
(?:(?P<epoch>[0-9]+)!)? # epoch
|
||||
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
|
||||
(?P<pre> # pre-release
|
||||
[-_\.]?
|
||||
(?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
|
||||
[-_\.]?
|
||||
(?P<pre_n>[0-9]+)?
|
||||
)?
|
||||
(?P<post> # post release
|
||||
(?:-(?P<post_n1>[0-9]+))
|
||||
|
|
||||
(?:
|
||||
[-_\.]?
|
||||
(?P<post_l>post|rev|r)
|
||||
[-_\.]?
|
||||
(?P<post_n2>[0-9]+)?
|
||||
)
|
||||
)?
|
||||
(?P<dev> # dev release
|
||||
[-_\.]?
|
||||
(?P<dev_l>dev)
|
||||
[-_\.]?
|
||||
(?P<dev_n>[0-9]+)?
|
||||
)?
|
||||
)
|
||||
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
|
||||
"""
|
||||
|
||||
VERSION_PATTERN = _VERSION_PATTERN
|
||||
"""
|
||||
A string containing the regular expression used to match a valid version.
|
||||
|
||||
The pattern is not anchored at either end, and is intended for embedding in larger
|
||||
expressions (for example, matching a version number as part of a file name). The
|
||||
regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
|
||||
flags set.
|
||||
|
||||
:meta hide-value:
|
||||
"""
|
||||
|
||||
|
||||
class Version(_BaseVersion):
|
||||
"""This class abstracts handling of a project's versions.
|
||||
|
||||
A :class:`Version` instance is comparison aware and can be compared and
|
||||
sorted using the standard Python interfaces.
|
||||
|
||||
>>> v1 = Version("1.0a5")
|
||||
>>> v2 = Version("1.0")
|
||||
>>> v1
|
||||
<Version('1.0a5')>
|
||||
>>> v2
|
||||
<Version('1.0')>
|
||||
>>> v1 < v2
|
||||
True
|
||||
>>> v1 == v2
|
||||
False
|
||||
>>> v1 > v2
|
||||
False
|
||||
>>> v1 >= v2
|
||||
False
|
||||
>>> v1 <= v2
|
||||
True
|
||||
"""
|
||||
|
||||
_regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_key: CmpKey
|
||||
|
||||
def __init__(self, version: str) -> None:
|
||||
"""Initialize a Version object.
|
||||
|
||||
:param version:
|
||||
The string representation of a version which will be parsed and normalized
|
||||
before use.
|
||||
:raises InvalidVersion:
|
||||
If the ``version`` does not conform to PEP 440 in any way then this
|
||||
exception will be raised.
|
||||
"""
|
||||
|
||||
# Validate the version and parse it into pieces
|
||||
match = self._regex.search(version)
|
||||
if not match:
|
||||
raise InvalidVersion(f"Invalid version: '{version}'")
|
||||
|
||||
# Store the parsed out pieces of the version
|
||||
self._version = _Version(
|
||||
epoch=int(match.group("epoch")) if match.group("epoch") else 0,
|
||||
release=tuple(int(i) for i in match.group("release").split(".")),
|
||||
pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
|
||||
post=_parse_letter_version(
|
||||
match.group("post_l"), match.group("post_n1") or match.group("post_n2")
|
||||
),
|
||||
dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
|
||||
local=_parse_local_version(match.group("local")),
|
||||
)
|
||||
|
||||
# Generate a key which will be used for sorting
|
||||
self._key = _cmpkey(
|
||||
self._version.epoch,
|
||||
self._version.release,
|
||||
self._version.pre,
|
||||
self._version.post,
|
||||
self._version.dev,
|
||||
self._version.local,
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""A representation of the Version that shows all internal state.
|
||||
|
||||
>>> Version('1.0.0')
|
||||
<Version('1.0.0')>
|
||||
"""
|
||||
return f"<Version('{self}')>"
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""A string representation of the version that can be rounded-tripped.
|
||||
|
||||
>>> str(Version("1.0a5"))
|
||||
'1.0a5'
|
||||
"""
|
||||
parts = []
|
||||
|
||||
# Epoch
|
||||
if self.epoch != 0:
|
||||
parts.append(f"{self.epoch}!")
|
||||
|
||||
# Release segment
|
||||
parts.append(".".join(str(x) for x in self.release))
|
||||
|
||||
# Pre-release
|
||||
if self.pre is not None:
|
||||
parts.append("".join(str(x) for x in self.pre))
|
||||
|
||||
# Post-release
|
||||
if self.post is not None:
|
||||
parts.append(f".post{self.post}")
|
||||
|
||||
# Development release
|
||||
if self.dev is not None:
|
||||
parts.append(f".dev{self.dev}")
|
||||
|
||||
# Local version segment
|
||||
if self.local is not None:
|
||||
parts.append(f"+{self.local}")
|
||||
|
||||
return "".join(parts)
|
||||
|
||||
@property
|
||||
def epoch(self) -> int:
|
||||
"""The epoch of the version.
|
||||
|
||||
>>> Version("2.0.0").epoch
|
||||
0
|
||||
>>> Version("1!2.0.0").epoch
|
||||
1
|
||||
"""
|
||||
return self._version.epoch
|
||||
|
||||
@property
|
||||
def release(self) -> Tuple[int, ...]:
|
||||
"""The components of the "release" segment of the version.
|
||||
|
||||
>>> Version("1.2.3").release
|
||||
(1, 2, 3)
|
||||
>>> Version("2.0.0").release
|
||||
(2, 0, 0)
|
||||
>>> Version("1!2.0.0.post0").release
|
||||
(2, 0, 0)
|
||||
|
||||
Includes trailing zeroes but not the epoch or any pre-release / development /
|
||||
post-release suffixes.
|
||||
"""
|
||||
return self._version.release
|
||||
|
||||
@property
|
||||
def pre(self) -> Optional[Tuple[str, int]]:
|
||||
"""The pre-release segment of the version.
|
||||
|
||||
>>> print(Version("1.2.3").pre)
|
||||
None
|
||||
>>> Version("1.2.3a1").pre
|
||||
('a', 1)
|
||||
>>> Version("1.2.3b1").pre
|
||||
('b', 1)
|
||||
>>> Version("1.2.3rc1").pre
|
||||
('rc', 1)
|
||||
"""
|
||||
return self._version.pre
|
||||
|
||||
@property
|
||||
def post(self) -> Optional[int]:
|
||||
"""The post-release number of the version.
|
||||
|
||||
>>> print(Version("1.2.3").post)
|
||||
None
|
||||
>>> Version("1.2.3.post1").post
|
||||
1
|
||||
"""
|
||||
return self._version.post[1] if self._version.post else None
|
||||
|
||||
@property
|
||||
def dev(self) -> Optional[int]:
|
||||
"""The development number of the version.
|
||||
|
||||
>>> print(Version("1.2.3").dev)
|
||||
None
|
||||
>>> Version("1.2.3.dev1").dev
|
||||
1
|
||||
"""
|
||||
return self._version.dev[1] if self._version.dev else None
|
||||
|
||||
@property
|
||||
def local(self) -> Optional[str]:
|
||||
"""The local version segment of the version.
|
||||
|
||||
>>> print(Version("1.2.3").local)
|
||||
None
|
||||
>>> Version("1.2.3+abc").local
|
||||
'abc'
|
||||
"""
|
||||
if self._version.local:
|
||||
return ".".join(str(x) for x in self._version.local)
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def public(self) -> str:
|
||||
"""The public portion of the version.
|
||||
|
||||
>>> Version("1.2.3").public
|
||||
'1.2.3'
|
||||
>>> Version("1.2.3+abc").public
|
||||
'1.2.3'
|
||||
>>> Version("1.2.3+abc.dev1").public
|
||||
'1.2.3'
|
||||
"""
|
||||
return str(self).split("+", 1)[0]
|
||||
|
||||
@property
|
||||
def base_version(self) -> str:
|
||||
"""The "base version" of the version.
|
||||
|
||||
>>> Version("1.2.3").base_version
|
||||
'1.2.3'
|
||||
>>> Version("1.2.3+abc").base_version
|
||||
'1.2.3'
|
||||
>>> Version("1!1.2.3+abc.dev1").base_version
|
||||
'1!1.2.3'
|
||||
|
||||
The "base version" is the public version of the project without any pre or post
|
||||
release markers.
|
||||
"""
|
||||
parts = []
|
||||
|
||||
# Epoch
|
||||
if self.epoch != 0:
|
||||
parts.append(f"{self.epoch}!")
|
||||
|
||||
# Release segment
|
||||
parts.append(".".join(str(x) for x in self.release))
|
||||
|
||||
return "".join(parts)
|
||||
|
||||
@property
|
||||
def is_prerelease(self) -> bool:
|
||||
"""Whether this version is a pre-release.
|
||||
|
||||
>>> Version("1.2.3").is_prerelease
|
||||
False
|
||||
>>> Version("1.2.3a1").is_prerelease
|
||||
True
|
||||
>>> Version("1.2.3b1").is_prerelease
|
||||
True
|
||||
>>> Version("1.2.3rc1").is_prerelease
|
||||
True
|
||||
>>> Version("1.2.3dev1").is_prerelease
|
||||
True
|
||||
"""
|
||||
return self.dev is not None or self.pre is not None
|
||||
|
||||
@property
|
||||
def is_postrelease(self) -> bool:
|
||||
"""Whether this version is a post-release.
|
||||
|
||||
>>> Version("1.2.3").is_postrelease
|
||||
False
|
||||
>>> Version("1.2.3.post1").is_postrelease
|
||||
True
|
||||
"""
|
||||
return self.post is not None
|
||||
|
||||
@property
|
||||
def is_devrelease(self) -> bool:
|
||||
"""Whether this version is a development release.
|
||||
|
||||
>>> Version("1.2.3").is_devrelease
|
||||
False
|
||||
>>> Version("1.2.3.dev1").is_devrelease
|
||||
True
|
||||
"""
|
||||
return self.dev is not None
|
||||
|
||||
@property
|
||||
def major(self) -> int:
|
||||
"""The first item of :attr:`release` or ``0`` if unavailable.
|
||||
|
||||
>>> Version("1.2.3").major
|
||||
1
|
||||
"""
|
||||
return self.release[0] if len(self.release) >= 1 else 0
|
||||
|
||||
@property
|
||||
def minor(self) -> int:
|
||||
"""The second item of :attr:`release` or ``0`` if unavailable.
|
||||
|
||||
>>> Version("1.2.3").minor
|
||||
2
|
||||
>>> Version("1").minor
|
||||
0
|
||||
"""
|
||||
return self.release[1] if len(self.release) >= 2 else 0
|
||||
|
||||
@property
|
||||
def micro(self) -> int:
|
||||
"""The third item of :attr:`release` or ``0`` if unavailable.
|
||||
|
||||
>>> Version("1.2.3").micro
|
||||
3
|
||||
>>> Version("1").micro
|
||||
0
|
||||
"""
|
||||
return self.release[2] if len(self.release) >= 3 else 0
|
||||
|
||||
|
||||
def _parse_letter_version(
|
||||
letter: Optional[str], number: Union[str, bytes, SupportsInt, None]
|
||||
) -> Optional[Tuple[str, int]]:
|
||||
|
||||
if letter:
|
||||
# We consider there to be an implicit 0 in a pre-release if there is
|
||||
# not a numeral associated with it.
|
||||
if number is None:
|
||||
number = 0
|
||||
|
||||
# We normalize any letters to their lower case form
|
||||
letter = letter.lower()
|
||||
|
||||
# We consider some words to be alternate spellings of other words and
|
||||
# in those cases we want to normalize the spellings to our preferred
|
||||
# spelling.
|
||||
if letter == "alpha":
|
||||
letter = "a"
|
||||
elif letter == "beta":
|
||||
letter = "b"
|
||||
elif letter in ["c", "pre", "preview"]:
|
||||
letter = "rc"
|
||||
elif letter in ["rev", "r"]:
|
||||
letter = "post"
|
||||
|
||||
return letter, int(number)
|
||||
if not letter and number:
|
||||
# We assume if we are given a number, but we are not given a letter
|
||||
# then this is using the implicit post release syntax (e.g. 1.0-1)
|
||||
letter = "post"
|
||||
|
||||
return letter, int(number)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
_local_version_separators = re.compile(r"[\._-]")
|
||||
|
||||
|
||||
def _parse_local_version(local: Optional[str]) -> Optional[LocalType]:
|
||||
"""
|
||||
Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
|
||||
"""
|
||||
if local is not None:
|
||||
return tuple(
|
||||
part.lower() if not part.isdigit() else int(part)
|
||||
for part in _local_version_separators.split(local)
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def _cmpkey(
|
||||
epoch: int,
|
||||
release: Tuple[int, ...],
|
||||
pre: Optional[Tuple[str, int]],
|
||||
post: Optional[Tuple[str, int]],
|
||||
dev: Optional[Tuple[str, int]],
|
||||
local: Optional[LocalType],
|
||||
) -> CmpKey:
|
||||
|
||||
# When we compare a release version, we want to compare it with all of the
|
||||
# trailing zeros removed. So we'll use a reverse the list, drop all the now
|
||||
# leading zeros until we come to something non zero, then take the rest
|
||||
# re-reverse it back into the correct order and make it a tuple and use
|
||||
# that for our sorting key.
|
||||
_release = tuple(
|
||||
reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
|
||||
)
|
||||
|
||||
# We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
|
||||
# We'll do this by abusing the pre segment, but we _only_ want to do this
|
||||
# if there is not a pre or a post segment. If we have one of those then
|
||||
# the normal sorting rules will handle this case correctly.
|
||||
if pre is None and post is None and dev is not None:
|
||||
_pre: CmpPrePostDevType = NegativeInfinity
|
||||
# Versions without a pre-release (except as noted above) should sort after
|
||||
# those with one.
|
||||
elif pre is None:
|
||||
_pre = Infinity
|
||||
else:
|
||||
_pre = pre
|
||||
|
||||
# Versions without a post segment should sort before those with one.
|
||||
if post is None:
|
||||
_post: CmpPrePostDevType = NegativeInfinity
|
||||
|
||||
else:
|
||||
_post = post
|
||||
|
||||
# Versions without a development segment should sort after those with one.
|
||||
if dev is None:
|
||||
_dev: CmpPrePostDevType = Infinity
|
||||
|
||||
else:
|
||||
_dev = dev
|
||||
|
||||
if local is None:
|
||||
# Versions without a local segment should sort before those with one.
|
||||
_local: CmpLocalType = NegativeInfinity
|
||||
else:
|
||||
# Versions with a local segment need that segment parsed to implement
|
||||
# the sorting rules in PEP440.
|
||||
# - Alpha numeric segments sort before numeric segments
|
||||
# - Alpha numeric segments sort lexicographically
|
||||
# - Numeric segments sort numerically
|
||||
# - Shorter versions sort before longer versions when the prefixes
|
||||
# match exactly
|
||||
_local = tuple(
|
||||
(i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local
|
||||
)
|
||||
|
||||
return epoch, _release, _pre, _post, _dev, _local
|
||||
91
electron/node_modules/node-gyp/gyp/pyproject.toml
generated
vendored
91
electron/node_modules/node-gyp/gyp/pyproject.toml
generated
vendored
|
|
@ -4,31 +4,33 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "gyp-next"
|
||||
version = "0.14.0"
|
||||
version = "0.22.2"
|
||||
authors = [
|
||||
{ name="Node.js contributors", email="ryzokuken@disroot.org" },
|
||||
]
|
||||
description = "A fork of the GYP build system for use in the Node.js projects"
|
||||
readme = "README.md"
|
||||
license = { file="LICENSE" }
|
||||
requires-python = ">=3.6"
|
||||
license = "BSD-3-Clause"
|
||||
license-files = ["LICENSE"]
|
||||
requires-python = ">=3.9"
|
||||
dependencies = ["packaging>=24.0", "setuptools>=77.0.3"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Environment :: Console",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Natural Language :: English",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = ["flake8", "pytest"]
|
||||
dev = ["pytest", "ruff"]
|
||||
|
||||
[project.scripts]
|
||||
gyp = "gyp:script_main"
|
||||
|
|
@ -36,6 +38,79 @@ gyp = "gyp:script_main"
|
|||
[project.urls]
|
||||
"Homepage" = "https://github.com/nodejs/gyp-next"
|
||||
|
||||
[tool.ruff]
|
||||
extend-exclude = ["pylib/packaging"]
|
||||
line-length = 88
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"C4", # flake8-comprehensions
|
||||
"C90", # McCabe cyclomatic complexity
|
||||
"DTZ", # flake8-datetimez
|
||||
"E", # pycodestyle
|
||||
"F", # Pyflakes
|
||||
"G", # flake8-logging-format
|
||||
"ICN", # flake8-import-conventions
|
||||
"INT", # flake8-gettext
|
||||
"PL", # Pylint
|
||||
"PYI", # flake8-pyi
|
||||
"RSE", # flake8-raise
|
||||
"RUF", # Ruff-specific rules
|
||||
"T10", # flake8-debugger
|
||||
"TCH", # flake8-type-checking
|
||||
"TID", # flake8-tidy-imports
|
||||
"UP", # pyupgrade
|
||||
"W", # pycodestyle
|
||||
"YTT", # flake8-2020
|
||||
# "A", # flake8-builtins
|
||||
# "ANN", # flake8-annotations
|
||||
# "ARG", # flake8-unused-arguments
|
||||
# "B", # flake8-bugbear
|
||||
# "BLE", # flake8-blind-except
|
||||
# "COM", # flake8-commas
|
||||
# "D", # pydocstyle
|
||||
# "DJ", # flake8-django
|
||||
# "EM", # flake8-errmsg
|
||||
# "ERA", # eradicate
|
||||
# "EXE", # flake8-executable
|
||||
# "FBT", # flake8-boolean-trap
|
||||
# "I", # isort
|
||||
# "INP", # flake8-no-pep420
|
||||
# "ISC", # flake8-implicit-str-concat
|
||||
# "N", # pep8-naming
|
||||
# "NPY", # NumPy-specific rules
|
||||
# "PD", # pandas-vet
|
||||
# "PGH", # pygrep-hooks
|
||||
# "PIE", # flake8-pie
|
||||
# "PT", # flake8-pytest-style
|
||||
# "PTH", # flake8-use-pathlib
|
||||
# "Q", # flake8-quotes
|
||||
# "RET", # flake8-return
|
||||
# "S", # flake8-bandit
|
||||
# "SIM", # flake8-simplify
|
||||
# "SLF", # flake8-self
|
||||
# "T20", # flake8-print
|
||||
# "TRY", # tryceratops
|
||||
]
|
||||
ignore = [
|
||||
"PLR1714",
|
||||
"PLW0603",
|
||||
"PLW2901",
|
||||
"RUF005",
|
||||
"RUF012",
|
||||
"UP031",
|
||||
]
|
||||
|
||||
[tool.ruff.lint.mccabe]
|
||||
max-complexity = 101
|
||||
|
||||
[tool.ruff.lint.pylint]
|
||||
allow-magic-value-types = ["float", "int", "str"]
|
||||
max-args = 11
|
||||
max-branches = 108
|
||||
max-returns = 10
|
||||
max-statements = 286
|
||||
|
||||
[tool.setuptools]
|
||||
package-dir = {"" = "pylib"}
|
||||
packages = ["gyp", "gyp.generator"]
|
||||
|
|
|
|||
11
electron/node_modules/node-gyp/gyp/release-please-config.json
generated
vendored
Normal file
11
electron/node_modules/node-gyp/gyp/release-please-config.json
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"last-release-sha": "78756421b0d7bb335992a9c7d26ba3cc8b619708",
|
||||
"packages": {
|
||||
".": {
|
||||
"release-type": "python",
|
||||
"package-name": "gyp-next",
|
||||
"bump-minor-pre-major": true,
|
||||
"include-component-in-tag": false
|
||||
}
|
||||
}
|
||||
}
|
||||
5
electron/node_modules/node-gyp/gyp/test_gyp.py
generated
vendored
5
electron/node_modules/node-gyp/gyp/test_gyp.py
generated
vendored
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
"""gyptest.py -- test runner for GYP tests."""
|
||||
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
|
|
@ -148,13 +147,13 @@ def print_configuration_info():
|
|||
print("Test configuration:")
|
||||
if sys.platform == "darwin":
|
||||
sys.path.append(os.path.abspath("test/lib"))
|
||||
import TestMac
|
||||
import TestMac # noqa: PLC0415
|
||||
|
||||
print(f" Mac {platform.mac_ver()[0]} {platform.mac_ver()[2]}")
|
||||
print(f" Xcode {TestMac.Xcode.Version()}")
|
||||
elif sys.platform == "win32":
|
||||
sys.path.append(os.path.abspath("pylib"))
|
||||
import gyp.MSVSVersion
|
||||
import gyp.MSVSVersion # noqa: PLC0415
|
||||
|
||||
print(" Win %s %s\n" % platform.win32_ver()[0:2])
|
||||
print(" MSVS %s" % gyp.MSVSVersion.SelectVisualStudioVersion().Description())
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue